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 @@ ...@@ -2,7 +2,7 @@
* libioRIFF.c : AVI file Stream input module for vlc * libioRIFF.c : AVI file Stream input module for vlc
***************************************************************************** *****************************************************************************
* Copyright (C) 2001 VideoLAN * 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> * Authors: Laurent Aimar <fenrir@via.ecp.fr>
* *
* This program is free software; you can redistribute it and/or modify * This program is free software; you can redistribute it and/or modify
...@@ -20,54 +20,39 @@ ...@@ -20,54 +20,39 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111, USA. * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111, USA.
*****************************************************************************/ *****************************************************************************/
typedef struct riffchunk_s #include <stdlib.h>
{ #include <vlc/vlc.h>
u32 i_id; #include <vlc/input.h>
u32 i_size; #include <video.h>
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 "libioRIFF.h"
static int RIFF_GoToChunk(input_thread_t * p_input,riffchunk_t *p_riff); inline u16 __GetWLE( byte_t *p_buff )
{
static char * RIFF_IToStr(u32 i); return( (*p_buff) + ( *(p_buff+1) <<8 ) );
}
/*************************************************************************/
/******************************************** inline u32 __GetDWLE( byte_t *p_buff )
* Fonction locale maintenant * {
********************************************/ 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 ); 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 ); vlc_mutex_unlock( &p_input->stream.stream_lock );
*pos = i;
return 0; 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; data_packet_t *p_pack;
int i; int i;
...@@ -105,7 +90,7 @@ static int __RIFF_SkipBytes(input_thread_t * p_input,int nb) ...@@ -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) if( p_chunk != NULL)
{ {
...@@ -117,43 +102,30 @@ static void RIFF_DeleteChunk( input_thread_t *p_input, riffchunk_t * ...@@ -117,43 +102,30 @@ static void RIFF_DeleteChunk( input_thread_t *p_input, riffchunk_t *
} }
} }
/* ****************************************** riffchunk_t * RIFF_ReadChunk(input_thread_t * p_input)
* lit une structure riffchunk sans avancer *
********************************************/
static riffchunk_t * RIFF_ReadChunk(input_thread_t * p_input)
{ {
riffchunk_t * p_riff; riffchunk_t * p_riff;
int count; int count;
byte_t * p_peek; 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_data = NULL;
p_riff->p_next = NULL;
p_riff->p_subchunk = NULL;
/* peek to have the begining, 8+4 where 4 are to get type */ /* peek to have the begining, 8+4 where 4 are to get type */
count=input_Peek( p_input, &p_peek, 12 ); if( ( count = input_Peek( p_input, &p_peek, 12 ) ) < 8 )
if( count < 8 )
{ {
msg_Err( p_input, "cannot peek()" ); msg_Err( p_input, "cannot peek()" );
free(p_riff); free(p_riff);
return NULL; return( NULL );
} }
p_riff->i_id = __GetDoubleWordLittleEndianFromBuff( p_peek ); p_riff->i_id = __GetDWLE( p_peek );
p_riff->i_size =__GetDoubleWordLittleEndianFromBuff( p_peek + 4 ); p_riff->i_size =__GetDWLE( p_peek + 4 );
if( count == 12 ) p_riff->i_type = ( count == 12 ) ? __GetDWLE( p_peek + 8 ) : 0 ;
{
p_riff->i_type = __GetDoubleWordLittleEndianFromBuff( p_peek + 8 );
}
else
{
p_riff->i_type = 0;
}
__RIFF_TellPos(p_input, &(p_riff->i_pos) ); __RIFF_TellPos(p_input, &(p_riff->i_pos) );
return( p_riff ); return( p_riff );
...@@ -163,7 +135,7 @@ static riffchunk_t * RIFF_ReadChunk(input_thread_t * p_input) ...@@ -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 * * Va au chunk juste d'apres si il en a encore *
* -1 si erreur , 1 si y'en a plus * * -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_len;
int i_lenfather; int i_lenfather;
...@@ -174,16 +146,14 @@ static int RIFF_NextChunk( input_thread_t * p_input,riffchunk_t *p_rifffather) ...@@ -174,16 +146,14 @@ static int RIFF_NextChunk( input_thread_t * p_input,riffchunk_t *p_rifffather)
msg_Err( p_input, "cannot read chunk" ); msg_Err( p_input, "cannot read chunk" );
return( -1 ); return( -1 );
} }
i_len = p_riff->i_size; i_len = __EVEN( p_riff->i_size );
if( i_len%2 != 0 ) {i_len++;} /* align sur un mot */
if ( p_rifffather != NULL ) if ( p_rifffather != NULL )
{ {
i_lenfather=p_rifffather->i_size; i_lenfather = __EVEN( p_rifffather->i_size );
if ( i_lenfather%2 !=0 ) {i_lenfather++;}
if ( p_rifffather->i_pos + i_lenfather <= p_riff->i_pos + i_len + 8 ) 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 ); free( p_riff );
return( 1 ); /* pas dans nos frontiere */ return( 1 ); /* pas dans nos frontiere */
} }
...@@ -201,14 +171,9 @@ static int RIFF_NextChunk( input_thread_t * p_input,riffchunk_t *p_rifffather) ...@@ -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 * * 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) return( __RIFF_SkipBytes(p_input,12) != 0 ? -1 : 0 );
{
msg_Err( p_input, "cannot go into chunk" );
return ( -1 );
}
return( 0 );
} }
/*************************************************************** /***************************************************************
...@@ -216,34 +181,25 @@ static int RIFF_DescendChunk(input_thread_t * p_input) ...@@ -216,34 +181,25 @@ static int RIFF_DescendChunk(input_thread_t * p_input)
* chunk * * 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; int i_skip;
u32 i_posactu; 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); __RIFF_TellPos(p_input, &i_posactu);
i_skip-=i_posactu; i_skip = __EVEN( p_riff->i_pos + p_riff->i_size + 8 ) - i_posactu;
return( (( __RIFF_SkipBytes(p_input,i_skip)) != 0) ? -1 : 0 );
if (( __RIFF_SkipBytes(p_input,i_skip)) != 0)
{
msg_Err( p_input, "cannot exit from subchunk" );
return( -1 );
}
return( 0 );
} }
/*************************************************************** /***************************************************************
* Permet de se deplacer jusqu'au premier chunk avec le bon id * * 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 do
{ {
if (p_riff!=NULL) if ( p_riff )
{ {
free(p_riff); free(p_riff);
if ( RIFF_NextChunk(p_input ,p_rifffather) != 0 ) 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 ...@@ -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); 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 ); return( -1 );
} }
...@@ -265,32 +221,32 @@ static int RIFF_FindChunk(input_thread_t * p_input ,u32 i_id,riffchunk_t *p_riff ...@@ -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 * * 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( ( __RIFF_SkipBytes(p_input,8) != 0 ) ? -1 : 0 );
{
return( -1 );
}
return( 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); 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 " ); msg_Err( p_input, "cannot read enough data " );
return ( -1 ); return ( -1 );
} }
if ( p_riff->i_size%2 != 0)
if( p_riff->i_size&1 )
{ {
__RIFF_SkipBytes(p_input,1); p_riff->p_data->p_payload_end--;
} /* aligne sur un mot */ }
return( 0 ); return( 0 );
} }
static int RIFF_LoadChunkDataInPES(input_thread_t * p_input, int RIFF_LoadChunkDataInPES(input_thread_t * p_input,
pes_packet_t **pp_pes, pes_packet_t **pp_pes,
int i_size_index) int i_size_index)
{ {
...@@ -298,6 +254,7 @@ static int RIFF_LoadChunkDataInPES(input_thread_t * p_input, ...@@ -298,6 +254,7 @@ static int RIFF_LoadChunkDataInPES(input_thread_t * p_input,
data_packet_t *p_data; data_packet_t *p_data;
riffchunk_t *p_riff; riffchunk_t *p_riff;
int i_size; int i_size;
int b_pad = 0;
if( (p_riff = RIFF_ReadChunk( p_input )) == NULL ) if( (p_riff = RIFF_ReadChunk( p_input )) == NULL )
{ {
...@@ -321,7 +278,7 @@ static int RIFF_LoadChunkDataInPES(input_thread_t * p_input, ...@@ -321,7 +278,7 @@ static int RIFF_LoadChunkDataInPES(input_thread_t * p_input,
i_size = __MIN( p_riff->i_size, i_size_index ); 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 ); p_data = input_NewPacket( p_input->p_method_data, 0 );
(*pp_pes)->p_first = p_data; (*pp_pes)->p_first = p_data;
...@@ -330,14 +287,19 @@ static int RIFF_LoadChunkDataInPES(input_thread_t * p_input, ...@@ -330,14 +287,19 @@ static int RIFF_LoadChunkDataInPES(input_thread_t * p_input,
(*pp_pes)->i_pes_size = 0; (*pp_pes)->i_pes_size = 0;
return( 0 ); return( 0 );
} }
if( i_size&1 )
{
i_size++;
b_pad = 1;
}
do do
{ {
i_read = input_SplitBuffer(p_input, &p_data, i_size - i_read = input_SplitBuffer(p_input, &p_data, i_size -
(*pp_pes)->i_pes_size ); (*pp_pes)->i_pes_size );
if( i_read < 0 ) if( i_read < 0 )
{ {
/* FIXME free sur tout les packets */ /* FIXME free on all packets */
return( -1 ); return( -1 );
} }
if( (*pp_pes)->p_first == NULL ) if( (*pp_pes)->p_first == NULL )
...@@ -357,58 +319,33 @@ static int RIFF_LoadChunkDataInPES(input_thread_t * p_input, ...@@ -357,58 +319,33 @@ static int RIFF_LoadChunkDataInPES(input_thread_t * p_input,
p_data->p_payload_start ); p_data->p_payload_start );
} }
} while( ((*pp_pes)->i_pes_size < i_size)&&(i_read != 0) ); } 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); (*pp_pes)->i_pes_size--;
} /* aligne sur un mot */ (*pp_pes)->p_last->p_payload_end--;
}
return( 0 ); return( 0 );
} }
int RIFF_GoToChunk(input_thread_t * p_input, riffchunk_t *p_riff)
static int RIFF_GoToChunk(input_thread_t * p_input, riffchunk_t *p_riff)
{ {
/* TODO rajouter les test */
if( p_input->stream.b_seekable ) if( p_input->stream.b_seekable )
{ {
p_input->pf_seek( p_input, (off_t)p_riff->i_pos ); p_input->pf_seek( p_input, (off_t)p_riff->i_pos );
input_AccessReinit( p_input ); input_AccessReinit( p_input );
return 0; return( 0 );
} }
return( -1 ); return( -1 );
} }
static char * RIFF_IToStr(u32 l) int RIFF_TestFileHeader( input_thread_t * p_input, riffchunk_t ** pp_riff, u32 i_type )
{
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 )
{ {
*pp_riff = RIFF_ReadChunk( p_input ); if( !( *pp_riff = RIFF_ReadChunk( p_input ) ) )
if( *pp_riff == NULL )
{ {
msg_Err( p_input, "cannot retrieve header" );
return( -1 ); return( -1 );
} }
if( (*pp_riff)->i_id != FOURCC_RIFF ) if( ( (*pp_riff)->i_id != FOURCC_RIFF )||( (*pp_riff)->i_type != i_type ) )
{
free( *pp_riff );
return( -1 );
}
if( (*pp_riff)->i_type != i_type )
{ {
free( *pp_riff ); free( *pp_riff );
return( -1 ); return( -1 );
...@@ -417,22 +354,26 @@ static int RIFF_TestFileHeader( input_thread_t * p_input, riffchunk_t ** pp_ri ...@@ -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; *pp_fmt = NULL;
if ( RIFF_FindChunk( p_input, i_type, p_riff ) != 0) if ( RIFF_FindChunk( p_input, i_type, p_riff ) != 0)
{ {
return( -1 ); 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( -1 );
} }
return( 0 ); 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; *pp_data = NULL;
if ( RIFF_FindChunk( p_input, i_type, p_riff ) != 0) 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 ...@@ -451,7 +392,7 @@ static int RIFF_FindAndGotoDataChunk( input_thread_t * p_input, riffchunk_t *p
return( 0 ); 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; 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