Commit 31f47190 authored by Laurent Aimar's avatar Laurent Aimar

* all : I've forgotten theses ...

parent b2b07494
avi_SOURCES = avi.c
avi_SOURCES = avi.c libioRIFF.c
......@@ -2,7 +2,7 @@
* libioRIFF.c : AVI file Stream input module for vlc
*****************************************************************************
* Copyright (C) 2001 VideoLAN
* $Id: libioRIFF.c,v 1.7 2002/06/01 12:31:58 sam Exp $
* $Id: libioRIFF.c,v 1.8 2002/06/27 18:10:16 fenrir Exp $
* Authors: Laurent Aimar <fenrir@via.ecp.fr>
*
* This program is free software; you can redistribute it and/or modify
......@@ -20,54 +20,39 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111, USA.
*****************************************************************************/
typedef struct riffchunk_s
{
u32 i_id;
u32 i_size;
u32 i_type;
u32 i_pos;
data_packet_t *p_data;
struct riffchunk_s *p_next;
struct riffchunk_s *p_subchunk;
} riffchunk_t;
static riffchunk_t * RIFF_ReadChunk(input_thread_t * p_input);
static int RIFF_NextChunk(input_thread_t * p_input,riffchunk_t *p_rifffather);
static int RIFF_DescendChunk(input_thread_t * p_input);
static int RIFF_AscendChunk(input_thread_t * p_input,riffchunk_t *p_rifffather);
static int RIFF_FindChunk(input_thread_t * p_input,u32 i_id,riffchunk_t *p_rifffather);
static int RIFF_GoToChunkData(input_thread_t * p_input);
static int RIFF_LoadChunkData(input_thread_t * p_input,riffchunk_t *p_riff);
static int RIFF_TestFileHeader(input_thread_t * p_input, riffchunk_t **pp_riff, u32 i_type);
static int RIFF_FindAndLoadChunk( input_thread_t * p_input, riffchunk_t *p_riff, riffchunk_t **pp_fmt, u32 i_type );
static int RIFF_FindAndGotoDataChunk( input_thread_t * p_input, riffchunk_t *p_riff, riffchunk_t **pp_data, u32 i_type );
static int RIFF_FindListChunk( input_thread_t *p_input, riffchunk_t **pp_riff, riffchunk_t *p_rifffather, u32 i_type );
static void RIFF_DeleteChunk( input_thread_t * p_input, riffchunk_t *p_chunk );
#include <stdlib.h>
#include <vlc/vlc.h>
#include <vlc/input.h>
#include <video.h>
#include "libioRIFF.h"
static int RIFF_GoToChunk(input_thread_t * p_input,riffchunk_t *p_riff);
static char * RIFF_IToStr(u32 i);
/*************************************************************************/
inline u16 __GetWLE( byte_t *p_buff )
{
return( (*p_buff) + ( *(p_buff+1) <<8 ) );
}
/********************************************
* Fonction locale maintenant *
********************************************/
inline u32 __GetDWLE( byte_t *p_buff )
{
return( *(p_buff) + ( *(p_buff+1) <<8 ) +
( *(p_buff+2) <<16 ) + ( *(p_buff+3) <<24 ) );
}
static int __RIFF_TellPos( input_thread_t *p_input, u32 *pos )
inline u32 __EVEN( u32 i )
{
return( (i & 1) ? ++i : i );
}
int __RIFF_TellPos( input_thread_t *p_input, u32 *pos )
{
u32 i;
vlc_mutex_lock( &p_input->stream.stream_lock );
i = p_input->stream.p_selected_area->i_tell - ( p_input->p_last_data - p_input->p_current_data );
*pos= p_input->stream.p_selected_area->i_tell -
( p_input->p_last_data - p_input->p_current_data );
vlc_mutex_unlock( &p_input->stream.stream_lock );
*pos = i;
return 0;
}
static int __RIFF_SkipBytes(input_thread_t * p_input,int nb)
int __RIFF_SkipBytes(input_thread_t * p_input,int nb)
{
data_packet_t *p_pack;
int i;
......@@ -105,7 +90,7 @@ static int __RIFF_SkipBytes(input_thread_t * p_input,int nb)
}
static void RIFF_DeleteChunk( input_thread_t *p_input, riffchunk_t *p_chunk )
void RIFF_DeleteChunk( input_thread_t *p_input, riffchunk_t *p_chunk )
{
if( p_chunk != NULL)
{
......@@ -117,43 +102,30 @@ static void RIFF_DeleteChunk( input_thread_t *p_input, riffchunk_t *
}
}
/* ******************************************
* lit une structure riffchunk sans avancer *
********************************************/
static riffchunk_t * RIFF_ReadChunk(input_thread_t * p_input)
riffchunk_t * RIFF_ReadChunk(input_thread_t * p_input)
{
riffchunk_t * p_riff;
int count;
byte_t * p_peek;
if((p_riff = malloc( sizeof(riffchunk_t))) == NULL)
if( !(p_riff = malloc( sizeof(riffchunk_t))) )
{
msg_Err( p_input, "out of memory" );
return NULL;
return( NULL );
}
p_riff->p_data = NULL; /* Par defaut */
p_riff->p_next = NULL;
p_riff->p_subchunk = NULL;
p_riff->p_data = NULL;
/* peek to have the begining, 8+4 where 4 are to get type */
count=input_Peek( p_input, &p_peek, 12 );
if( count < 8 )
if( ( count = input_Peek( p_input, &p_peek, 12 ) ) < 8 )
{
msg_Err( p_input, "cannot peek()" );
free(p_riff);
return NULL;
return( NULL );
}
p_riff->i_id = __GetDoubleWordLittleEndianFromBuff( p_peek );
p_riff->i_size =__GetDoubleWordLittleEndianFromBuff( p_peek + 4 );
if( count == 12 )
{
p_riff->i_type = __GetDoubleWordLittleEndianFromBuff( p_peek + 8 );
}
else
{
p_riff->i_type = 0;
}
p_riff->i_id = __GetDWLE( p_peek );
p_riff->i_size =__GetDWLE( p_peek + 4 );
p_riff->i_type = ( count == 12 ) ? __GetDWLE( p_peek + 8 ) : 0 ;
__RIFF_TellPos(p_input, &(p_riff->i_pos) );
return( p_riff );
......@@ -163,7 +135,7 @@ static riffchunk_t * RIFF_ReadChunk(input_thread_t * p_input)
* Va au chunk juste d'apres si il en a encore *
* -1 si erreur , 1 si y'en a plus *
**************************************************/
static int RIFF_NextChunk( input_thread_t * p_input,riffchunk_t *p_rifffather)
int RIFF_NextChunk( input_thread_t * p_input,riffchunk_t *p_rifffather)
{
int i_len;
int i_lenfather;
......@@ -174,16 +146,14 @@ static int RIFF_NextChunk( input_thread_t * p_input,riffchunk_t *p_rifffather)
msg_Err( p_input, "cannot read chunk" );
return( -1 );
}
i_len = p_riff->i_size;
if( i_len%2 != 0 ) {i_len++;} /* align sur un mot */
i_len = __EVEN( p_riff->i_size );
if ( p_rifffather != NULL )
{
i_lenfather=p_rifffather->i_size;
if ( i_lenfather%2 !=0 ) {i_lenfather++;}
i_lenfather = __EVEN( p_rifffather->i_size );
if ( p_rifffather->i_pos + i_lenfather <= p_riff->i_pos + i_len + 8 )
{
msg_Err( p_input, "next chunk out of bounds" );
msg_Err( p_input, "next chunk out of bounds" );
free( p_riff );
return( 1 ); /* pas dans nos frontiere */
}
......@@ -201,14 +171,9 @@ static int RIFF_NextChunk( input_thread_t * p_input,riffchunk_t *p_rifffather)
/****************************************************************
* Permet de rentrer dans un ck RIFF ou LIST *
****************************************************************/
static int RIFF_DescendChunk(input_thread_t * p_input)
int RIFF_DescendChunk(input_thread_t * p_input)
{
if ( __RIFF_SkipBytes(p_input,12) != 0)
{
msg_Err( p_input, "cannot go into chunk" );
return ( -1 );
}
return( 0 );
return( __RIFF_SkipBytes(p_input,12) != 0 ? -1 : 0 );
}
/***************************************************************
......@@ -216,34 +181,25 @@ static int RIFF_DescendChunk(input_thread_t * p_input)
* chunk *
***************************************************************/
static int RIFF_AscendChunk(input_thread_t * p_input ,riffchunk_t *p_rifffather)
int RIFF_AscendChunk(input_thread_t * p_input ,riffchunk_t *p_riff)
{
int i_skip;
u32 i_posactu;
i_skip = p_rifffather->i_pos + p_rifffather->i_size + 8;
if ( i_skip%2 != 0) {i_skip++;}
__RIFF_TellPos(p_input, &i_posactu);
i_skip-=i_posactu;
if (( __RIFF_SkipBytes(p_input,i_skip)) != 0)
{
msg_Err( p_input, "cannot exit from subchunk" );
return( -1 );
}
return( 0 );
i_skip = __EVEN( p_riff->i_pos + p_riff->i_size + 8 ) - i_posactu;
return( (( __RIFF_SkipBytes(p_input,i_skip)) != 0) ? -1 : 0 );
}
/***************************************************************
* Permet de se deplacer jusqu'au premier chunk avec le bon id *
* *************************************************************/
static int RIFF_FindChunk(input_thread_t * p_input ,u32 i_id,riffchunk_t *p_rifffather)
int RIFF_FindChunk(input_thread_t * p_input ,u32 i_id,riffchunk_t *p_rifffather)
{
riffchunk_t *p_riff=NULL;
riffchunk_t *p_riff = NULL;
do
{
if (p_riff!=NULL)
if ( p_riff )
{
free(p_riff);
if ( RIFF_NextChunk(p_input ,p_rifffather) != 0 )
......@@ -252,9 +208,9 @@ static int RIFF_FindChunk(input_thread_t * p_input ,u32 i_id,riffchunk_t *p_riff
}
}
p_riff=RIFF_ReadChunk(p_input);
} while ( ( p_riff != NULL )&&( p_riff->i_id != i_id ) );
} while ( ( p_riff )&&( p_riff->i_id != i_id ) );
if ( ( p_riff == NULL )||( p_riff->i_id != i_id ) )
if ( ( !p_riff )||( p_riff->i_id != i_id ) )
{
return( -1 );
}
......@@ -265,32 +221,32 @@ static int RIFF_FindChunk(input_thread_t * p_input ,u32 i_id,riffchunk_t *p_riff
/*****************************************************************
* Permet de pointer sur la zone de donn du chunk courant *
*****************************************************************/
static int RIFF_GoToChunkData(input_thread_t * p_input)
int RIFF_GoToChunkData(input_thread_t * p_input)
{
if ( __RIFF_SkipBytes(p_input,8) != 0 )
{
return( -1 );
}
return( 0 );
return( ( __RIFF_SkipBytes(p_input,8) != 0 ) ? -1 : 0 );
}
static int RIFF_LoadChunkData(input_thread_t * p_input,riffchunk_t *p_riff )
int RIFF_LoadChunkData(input_thread_t * p_input,riffchunk_t *p_riff )
{
off_t i_read = __EVEN( p_riff->i_size );
RIFF_GoToChunkData(p_input);
if ( input_SplitBuffer( p_input, &p_riff->p_data, p_riff->i_size ) != p_riff->i_size )
if ( input_SplitBuffer( p_input,
&p_riff->p_data,
i_read ) != i_read )
{
msg_Err( p_input, "cannot read enough data " );
return ( -1 );
}
if ( p_riff->i_size%2 != 0)
if( p_riff->i_size&1 )
{
__RIFF_SkipBytes(p_input,1);
} /* aligne sur un mot */
p_riff->p_data->p_payload_end--;
}
return( 0 );
}
static int RIFF_LoadChunkDataInPES(input_thread_t * p_input,
int RIFF_LoadChunkDataInPES(input_thread_t * p_input,
pes_packet_t **pp_pes,
int i_size_index)
{
......@@ -298,6 +254,7 @@ static int RIFF_LoadChunkDataInPES(input_thread_t * p_input,
data_packet_t *p_data;
riffchunk_t *p_riff;
int i_size;
int b_pad = 0;
if( (p_riff = RIFF_ReadChunk( p_input )) == NULL )
{
......@@ -321,7 +278,7 @@ static int RIFF_LoadChunkDataInPES(input_thread_t * p_input,
i_size = __MIN( p_riff->i_size, i_size_index );
}
if( p_riff->i_size == 0 )
if( !p_riff->i_size )
{
p_data = input_NewPacket( p_input->p_method_data, 0 );
(*pp_pes)->p_first = p_data;
......@@ -330,14 +287,19 @@ static int RIFF_LoadChunkDataInPES(input_thread_t * p_input,
(*pp_pes)->i_pes_size = 0;
return( 0 );
}
if( i_size&1 )
{
i_size++;
b_pad = 1;
}
do
{
i_read = input_SplitBuffer(p_input, &p_data, i_size -
(*pp_pes)->i_pes_size );
if( i_read < 0 )
{
/* FIXME free sur tout les packets */
/* FIXME free on all packets */
return( -1 );
}
if( (*pp_pes)->p_first == NULL )
......@@ -357,58 +319,33 @@ static int RIFF_LoadChunkDataInPES(input_thread_t * p_input,
p_data->p_payload_start );
}
} while( ((*pp_pes)->i_pes_size < i_size)&&(i_read != 0) );
/* i_read = 0 si fin du stream sinon block */
if ( i_size%2 != 0)
if( b_pad )
{
__RIFF_SkipBytes(p_input,1);
} /* aligne sur un mot */
(*pp_pes)->i_pes_size--;
(*pp_pes)->p_last->p_payload_end--;
}
return( 0 );
}
static int RIFF_GoToChunk(input_thread_t * p_input, riffchunk_t *p_riff)
int RIFF_GoToChunk(input_thread_t * p_input, riffchunk_t *p_riff)
{
/* TODO rajouter les test */
if( p_input->stream.b_seekable )
{
p_input->pf_seek( p_input, (off_t)p_riff->i_pos );
input_AccessReinit( p_input );
return 0;
return( 0 );
}
return( -1 );
}
static char * RIFF_IToStr(u32 l)
{
char *str;
int i;
str=calloc(5,sizeof(char));
for( i = 0; i < 4; i++)
{
str[i] = ( l >> ( i * 8) )&0xFF;
}
str[5] = 0;
return( str );
}
static int RIFF_TestFileHeader( input_thread_t * p_input, riffchunk_t ** pp_riff, u32 i_type )
int RIFF_TestFileHeader( input_thread_t * p_input, riffchunk_t ** pp_riff, u32 i_type )
{
*pp_riff = RIFF_ReadChunk( p_input );
if( *pp_riff == NULL )
if( !( *pp_riff = RIFF_ReadChunk( p_input ) ) )
{
msg_Err( p_input, "cannot retrieve header" );
return( -1 );
}
if( (*pp_riff)->i_id != FOURCC_RIFF )
{
free( *pp_riff );
return( -1 );
}
if( (*pp_riff)->i_type != i_type )
if( ( (*pp_riff)->i_id != FOURCC_RIFF )||( (*pp_riff)->i_type != i_type ) )
{
free( *pp_riff );
return( -1 );
......@@ -417,22 +354,26 @@ static int RIFF_TestFileHeader( input_thread_t * p_input, riffchunk_t ** pp_ri
}
static int RIFF_FindAndLoadChunk( input_thread_t * p_input, riffchunk_t *p_riff, riffchunk_t **pp_fmt, u32 i_type )
int RIFF_FindAndLoadChunk( input_thread_t * p_input, riffchunk_t *p_riff, riffchunk_t **pp_fmt, u32 i_type )
{
*pp_fmt = NULL;
if ( RIFF_FindChunk( p_input, i_type, p_riff ) != 0)
{
return( -1 );
}
if ( ( (*pp_fmt = RIFF_ReadChunk( p_input )) == NULL) || ( RIFF_LoadChunkData( p_input, *pp_fmt ) != 0 ) )
if ( ( (*pp_fmt = RIFF_ReadChunk( p_input )) == NULL)
|| ( RIFF_LoadChunkData( p_input, *pp_fmt ) != 0 ) )
{
if( *pp_fmt != NULL ) { RIFF_DeleteChunk( p_input, *pp_fmt ); }
if( *pp_fmt != NULL )
{
RIFF_DeleteChunk( p_input, *pp_fmt );
}
return( -1 );
}
return( 0 );
}
static int RIFF_FindAndGotoDataChunk( input_thread_t * p_input, riffchunk_t *p_riff, riffchunk_t **pp_data, u32 i_type )
int RIFF_FindAndGotoDataChunk( input_thread_t * p_input, riffchunk_t *p_riff, riffchunk_t **pp_data, u32 i_type )
{
*pp_data = NULL;
if ( RIFF_FindChunk( p_input, i_type, p_riff ) != 0)
......@@ -451,7 +392,7 @@ static int RIFF_FindAndGotoDataChunk( input_thread_t * p_input, riffchunk_t *p
return( 0 );
}
static int RIFF_FindListChunk( input_thread_t *p_input, riffchunk_t **pp_riff, riffchunk_t *p_rifffather, u32 i_type )
int RIFF_FindListChunk( input_thread_t *p_input, riffchunk_t **pp_riff, riffchunk_t *p_rifffather, u32 i_type )
{
int i_ok;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment