Commit e4ef10de authored by Laurent Aimar's avatar Laurent Aimar

* avi: Support for OpenDML file.

 Not tested with file size > 2Go, so report status.
parent 020af3bf
......@@ -2,7 +2,7 @@
* avi.c : AVI file Stream input module for vlc
*****************************************************************************
* Copyright (C) 2001 VideoLAN
* $Id: avi.c,v 1.42 2003/03/30 18:14:37 gbazin Exp $
* $Id: avi.c,v 1.43 2003/04/27 11:55:03 fenrir Exp $
* Authors: Laurent Aimar <fenrir@via.ecp.fr>
*
* This program is free software; you can redistribute it and/or modify
......@@ -334,7 +334,7 @@ static int AVI_PacketGetHeader( input_thread_t *p_input, avi_packet_t *p_pk )
p_pk->i_fourcc = GetFOURCC( p_peek );
p_pk->i_size = GetDWLE( p_peek + 4 );
p_pk->i_pos = AVI_TellAbsolute( p_input );
if( p_pk->i_fourcc == AVIFOURCC_LIST )
if( p_pk->i_fourcc == AVIFOURCC_LIST || p_pk->i_fourcc == AVIFOURCC_RIFF )
{
p_pk->i_type = GetFOURCC( p_peek + 8 );
}
......@@ -357,10 +357,15 @@ static int AVI_PacketNext( input_thread_t *p_input )
{
return VLC_EGENERIC;
}
if( avi_ck.i_fourcc == AVIFOURCC_LIST && avi_ck.i_type == AVIFOURCC_rec )
{
return AVI_SkipBytes( p_input, 12 );
}
else if( avi_ck.i_fourcc == AVIFOURCC_RIFF && avi_ck.i_type == AVIFOURCC_AVIX )
{
return AVI_SkipBytes( p_input, 24 );
}
else
{
return AVI_SkipBytes( p_input, __EVEN( avi_ck.i_size ) + 8 );
......@@ -413,6 +418,7 @@ static int AVI_PacketSearch( input_thread_t *p_input )
{
case AVIFOURCC_JUNK:
case AVIFOURCC_LIST:
case AVIFOURCC_RIFF:
case AVIFOURCC_idx1:
return VLC_SUCCESS;
}
......@@ -472,7 +478,7 @@ static void AVI_IndexAddEntry( demux_sys_t *p_avi,
}
}
static void AVI_IndexLoad( input_thread_t *p_input )
static void AVI_IndexLoad_idx1( input_thread_t *p_input )
{
demux_sys_t *p_avi = p_input->p_demux_data;
......@@ -495,12 +501,7 @@ static void AVI_IndexLoad( input_thread_t *p_input )
msg_Warn( p_input, "cannot find idx1 chunk, no index defined" );
return;
}
for( i_stream = 0; i_stream < p_avi->i_streams; i_stream++ )
{
p_avi->pp_info[i_stream]->i_idxnb = 0;
p_avi->pp_info[i_stream]->i_idxmax = 0;
p_avi->pp_info[i_stream]->p_index = NULL;
}
/* *** calculate offset *** */
if( p_idx1->i_entry_count > 0 &&
p_idx1->entry[0].i_pos < p_movi->i_chunk_pos )
......@@ -531,16 +532,129 @@ static void AVI_IndexLoad( input_thread_t *p_input )
AVI_IndexAddEntry( p_avi, i_stream, &index );
}
}
}
static void __Parse_indx( input_thread_t *p_input,
int i_stream,
avi_chunk_indx_t *p_indx )
{
demux_sys_t *p_avi = p_input->p_demux_data;
AVIIndexEntry_t index;
int32_t i;
msg_Dbg( p_input, "loading subindex(0x%x) %d entries", p_indx->i_indextype, p_indx->i_entriesinuse );
if( p_indx->i_indexsubtype == 0 )
{
for( i = 0; i < p_indx->i_entriesinuse; i++ )
{
index.i_id = p_indx->i_id;
index.i_flags = p_indx->idx.std[i].i_size & 0x80000000 ? 0 : AVIIF_KEYFRAME;
index.i_pos = p_indx->i_baseoffset + p_indx->idx.std[i].i_offset - 8;
index.i_length = p_indx->idx.std[i].i_size&0x7fffffff;
AVI_IndexAddEntry( p_avi, i_stream, &index );
}
}
else if( p_indx->i_indexsubtype == AVI_INDEX_2FIELD )
{
for( i = 0; i < p_indx->i_entriesinuse; i++ )
{
index.i_id = p_indx->i_id;
index.i_flags = p_indx->idx.field[i].i_size & 0x80000000 ? 0 : AVIIF_KEYFRAME;
index.i_pos = p_indx->i_baseoffset + p_indx->idx.field[i].i_offset - 8;
index.i_length = p_indx->idx.field[i].i_size;
AVI_IndexAddEntry( p_avi, i_stream, &index );
}
}
else
{
msg_Warn( p_input, "unknow subtype index(0x%x)", p_indx->i_indexsubtype );
}
}
static void AVI_IndexLoad_indx( input_thread_t *p_input )
{
demux_sys_t *p_avi = p_input->p_demux_data;
unsigned int i_stream;
int32_t i;
avi_chunk_list_t *p_riff;
avi_chunk_list_t *p_hdrl;
p_riff = (void*)AVI_ChunkFind( &p_avi->ck_root,
AVIFOURCC_RIFF, 0);
p_hdrl = (void*)AVI_ChunkFind( p_riff, AVIFOURCC_hdrl, 0 );
for( i_stream = 0; i_stream < p_avi->i_streams; i_stream++ )
{
avi_chunk_list_t *p_strl;
avi_chunk_indx_t *p_indx;
#define p_stream p_avi->pp_info[i_stream]
p_strl = (void*)AVI_ChunkFind( p_hdrl, AVIFOURCC_strl, i_stream );
p_indx = (void*)AVI_ChunkFind( p_strl, AVIFOURCC_indx, 0 );
if( !p_indx )
{
msg_Warn( p_input, "cannot find indx (misdetect/broken OpenDML file?)" );
continue;
}
if( p_indx->i_indextype == AVI_INDEX_OF_CHUNKS )
{
__Parse_indx( p_input, i_stream, p_indx );
}
else if( p_indx->i_indextype == AVI_INDEX_OF_INDEXES )
{
avi_chunk_indx_t ck_sub;
for( i = 0; i < p_indx->i_entriesinuse; i++ )
{
AVI_SeekAbsolute( p_input, p_indx->idx.super[i].i_offset );
if( !AVI_ChunkRead( p_input, &ck_sub, NULL, p_avi->b_seekable ) )
{
__Parse_indx( p_input, i_stream, &ck_sub );
}
}
}
else
{
msg_Warn( p_input, "unknow type index(0x%x)", p_indx->i_indextype );
}
#undef p_stream
}
}
static void AVI_IndexLoad( input_thread_t *p_input )
{
demux_sys_t *p_avi = p_input->p_demux_data;
unsigned int i_stream;
for( i_stream = 0; i_stream < p_avi->i_streams; i_stream++ )
{
p_avi->pp_info[i_stream]->i_idxnb = 0;
p_avi->pp_info[i_stream]->i_idxmax = 0;
p_avi->pp_info[i_stream]->p_index = NULL;
}
if( p_avi->b_odml )
{
AVI_IndexLoad_indx( p_input );
}
else
{
AVI_IndexLoad_idx1( p_input );
}
for( i_stream = 0; i_stream < p_avi->i_streams; i_stream++ )
{
msg_Dbg( p_input,
"stream[%d] creating %d index entries",
"stream[%d] created %d index entries",
i_stream,
p_avi->pp_info[i_stream]->i_idxnb );
}
}
static void AVI_IndexCreate( input_thread_t *p_input )
{
demux_sys_t *p_avi = p_input->p_demux_data;
......@@ -596,7 +710,22 @@ static void AVI_IndexCreate( input_thread_t *p_input )
switch( pk.i_fourcc )
{
case AVIFOURCC_idx1:
if( p_avi->b_odml )
{
avi_chunk_list_t *p_avix;
p_avix = (void*)AVI_ChunkFind( &p_avi->ck_root,
AVIFOURCC_RIFF, 1 );
msg_Dbg( p_input, "looking for new RIFF chunk" );
if( AVI_SeekAbsolute( p_input, p_avix->i_chunk_pos + 24) )
{
goto print_stat;
}
break;
}
goto print_stat;
case AVIFOURCC_RIFF:
msg_Dbg( p_input, "new RIFF chunk found" );
case AVIFOURCC_rec:
case AVIFOURCC_JUNK:
break;
......@@ -609,7 +738,8 @@ static void AVI_IndexCreate( input_thread_t *p_input )
}
}
}
if( pk.i_pos + pk.i_size >= i_movi_end ||
if( ( !p_avi->b_odml && pk.i_pos + pk.i_size >= i_movi_end ) ||
AVI_PacketNext( p_input ) )
{
break;
......@@ -844,6 +974,7 @@ static int AVIInit( vlc_object_t * p_this )
p_avi->b_seekable = ( ( p_input->stream.b_seekable )
&&( p_input->stream.i_method == INPUT_METHOD_FILE ) );
p_avi->i_movi_lastchunk_pos = 0;
p_avi->b_odml = VLC_FALSE;
/* *** for unseekable stream, automaticaly use AVIDemux_interleaved *** */
if( !p_avi->b_seekable || config_GetInt( p_input, "avi-interleaved" ) )
......@@ -858,6 +989,29 @@ static int AVIInit( vlc_object_t * p_this )
}
AVI_ChunkDumpDebug( p_input, &p_avi->ck_root );
if( AVI_ChunkCount( &p_avi->ck_root, AVIFOURCC_RIFF ) > 1 )
{
int i_count = AVI_ChunkCount( &p_avi->ck_root, AVIFOURCC_RIFF );
int i;
msg_Warn( p_input, "multiple riff -> OpenDML ?" );
for( i = 1; i < i_count; i++ )
{
avi_chunk_list_t *p_avix;
p_avix = (avi_chunk_list_t*)AVI_ChunkFind( &p_avi->ck_root,
AVIFOURCC_RIFF, i );
if( p_avix->i_type == AVIFOURCC_AVIX )
{
msg_Warn( p_input, "detected OpenDML file" );
p_avi->b_odml = VLC_TRUE;
break;
}
}
p_avi->b_odml = VLC_TRUE;
}
p_riff = (avi_chunk_list_t*)AVI_ChunkFind( &p_avi->ck_root,
AVIFOURCC_RIFF, 0 );
......@@ -1331,6 +1485,59 @@ static mtime_t AVI_GetPTS( avi_stream_t *p_info )
}
}
#if 0
static void AVI_FixPTS( avi_stream_t *p_stream, pes_packet_t *p_pes )
{
data_packet_t *p_data;
uint8_t *p;
int i_pos = 0;
switch( p_stream->i_fourcc )
{
case VLC_FOURCC( 'm', 'p', 'g', 'a' ):
p_data = p_pes->p_first;
while( p_data )
{
p = p_data->p_payload_start;
while( p < p_data->p_payload_end - 2 )
{
if( p[0] == 0xff && ( p[1]&0xe0) == 0xe0 )
{
mtime_t i_diff = AVI_GetDPTS( p_stream, i_pos );
p_pes->i_dts += i_diff;
p_pes->i_pts += i_diff;
return;
}
p++; i_pos++;
}
p_data = p_data->p_next;
}
return;
case VLC_FOURCC( 'a', '5', '2', ' ' ):
p_data = p_pes->p_first;
while( p_data )
{
p = p_data->p_payload_start;
while( p < p_data->p_payload_end - 2 )
{
if( p[0] == 0x0b && p[1] == 0x77 )
{
mtime_t i_diff = AVI_GetDPTS( p_stream, i_pos );
p_pes->i_dts += i_diff;
p_pes->i_pts += i_diff;
}
p++; i_pos++;
}
p_data = p_data->p_next;
}
return;
default:
/* we can't fix :( */
return;
}
}
#endif
static int AVI_StreamChunkFind( input_thread_t *p_input,
unsigned int i_stream )
{
......@@ -1363,18 +1570,10 @@ static int AVI_StreamChunkFind( input_thread_t *p_input,
if( avi_pk.i_stream >= p_avi->i_streams ||
( avi_pk.i_cat != AUDIO_ES && avi_pk.i_cat != VIDEO_ES ) )
{
switch( avi_pk.i_fourcc )
{
case AVIFOURCC_LIST:
AVI_SkipBytes( p_input, 12 );
break;
default:
if( AVI_PacketNext( p_input ) )
{
return VLC_EGENERIC;
}
break;
}
}
else
{
......@@ -1585,7 +1784,7 @@ static int AVISeek ( input_thread_t *p_input,
if( !p_avi->i_length )
{
avi_stream_t *p_stream;
uint64_t i_pos;
int64_t i_pos;
/* use i_percent to create a true i_date */
msg_Warn( p_input,
......@@ -2068,6 +2267,14 @@ static int AVIDemux_Seekable( input_thread_t *p_input )
p_pes->i_pts = AVI_GetPTS( p_stream );
#if 0
/* fix pts for audio: ie pts sould be for the first byte of the first frame */
if( p_stream->i_samplesize == 1 )
{
AVI_FixPTS( p_stream, p_pes );
}
#endif
/* read data */
if( p_stream->i_samplesize )
{
......@@ -2199,8 +2406,13 @@ static int AVIDemux_UnSeekable( input_thread_t *p_input )
{
case AVIFOURCC_JUNK:
case AVIFOURCC_LIST:
case AVIFOURCC_RIFF:
return( !AVI_PacketNext( p_input ) ? 1 : 0 );
case AVIFOURCC_idx1:
if( p_avi->b_odml )
{
return( !AVI_PacketNext( p_input ) ? 1 : 0 );
}
return( 0 ); // eof
default:
msg_Warn( p_input,
......
......@@ -2,7 +2,7 @@
* avi.h : AVI file Stream input module for vlc
*****************************************************************************
* Copyright (C) 2001 VideoLAN
* $Id: avi.h,v 1.8 2002/12/06 16:34:06 sam Exp $
* $Id: avi.h,v 1.9 2003/04/27 11:55:03 fenrir Exp $
* Authors: Laurent Aimar <fenrir@via.ecp.fr>
*
* This program is free software; you can redistribute it and/or modify
......@@ -38,7 +38,7 @@ typedef struct AVIIndexEntry_s
{
vlc_fourcc_t i_id;
uint32_t i_flags;
uint32_t i_pos;
off_t i_pos;
uint32_t i_length;
uint32_t i_lengthtotal;
......@@ -76,6 +76,8 @@ struct demux_sys_t
vlc_bool_t b_seekable;
avi_chunk_t ck_root;
vlc_bool_t b_odml;
off_t i_movi_begin;
off_t i_movi_lastchunk_pos; /* XXX position of last valid chunk */
......
......@@ -2,7 +2,7 @@
* libavi.c :
*****************************************************************************
* Copyright (C) 2001 VideoLAN
* $Id: libavi.c,v 1.17 2003/03/10 01:07:09 fenrir Exp $
* $Id: libavi.c,v 1.18 2003/04/27 11:55:03 fenrir Exp $
* Authors: Laurent Aimar <fenrir@via.ecp.fr>
*
* This program is free software; you can redistribute it and/or modify
......@@ -31,11 +31,6 @@
#include "libavi.h"
#define AVI_DEBUG 1
#define AVIFOURCC_PRINT( x ) \
(x)&0xff, \
( (x) >> 8 )&0xff, \
( (x) >> 16 )&0xff, \
( (x) >> 24 )&0xff
#define FREE( p ) \
if( p ) {free( p ); p = NULL; }
......@@ -53,6 +48,15 @@ static uint32_t GetDWLE( uint8_t *p_buff )
return (uint32_t)p_buff[0] | ( ((uint32_t)p_buff[1]) << 8 ) |
( ((uint32_t)p_buff[2]) << 16 ) | ( ((uint32_t)p_buff[3]) << 24 );
}
static uint64_t GetQWLE( uint8_t *p )
{
return (uint64_t)p[0] | ( ((uint64_t)p[1]) << 8 ) |
( ((uint64_t)p[2]) << 16 ) | ( ((uint64_t)p[3]) << 24 ) |
( ((uint64_t)p[4]) << 32 ) | ( ((uint64_t)p[5]) << 40 ) |
( ((uint64_t)p[6]) << 48 ) | ( ((uint64_t)p[7]) << 56 );
}
static vlc_fourcc_t GetFOURCC( byte_t *p_buff )
{
return VLC_FOURCC( p_buff[0], p_buff[1], p_buff[2], p_buff[3] );
......@@ -261,9 +265,9 @@ static int AVI_ChunkReadCommon( input_thread_t *p_input,
p_chk->common.p_next = NULL;
#ifdef AVI_DEBUG
msg_Dbg( p_input,
"Found Chunk fourcc:%8.8x (%c%c%c%c) size:"I64Fd" pos:"I64Fd,
"Found Chunk fourcc:%8.8x (%4.4s) size:"I64Fd" pos:"I64Fd,
p_chk->common.i_chunk_fourcc,
AVIFOURCC_PRINT( p_chk->common.i_chunk_fourcc ),
(char*)&p_chk->common.i_chunk_fourcc,
p_chk->common.i_chunk_size,
p_chk->common.i_chunk_pos );
#endif
......@@ -355,10 +359,10 @@ static int AVI_ChunkRead_list( input_thread_t *p_input,
}
#ifdef AVI_DEBUG
msg_Dbg( p_input,
"found LIST chunk: \'%c%c%c%c\'",
AVIFOURCC_PRINT( p_container->list.i_type ) );
"found LIST chunk: \'%4.4s\'",
(char*)&p_container->list.i_type );
#endif
msg_Dbg( p_input, "<list \'%c%c%c%c\'>", AVIFOURCC_PRINT( p_container->list.i_type ) );
msg_Dbg( p_input, "<list \'%4.4s\'>", (char*)&p_container->list.i_type );
for( ; ; )
{
p_chk = malloc( sizeof( avi_chunk_t ) );
......@@ -388,7 +392,7 @@ static int AVI_ChunkRead_list( input_thread_t *p_input,
}
}
msg_Dbg( p_input, "</list \'%c%c%c%c\'>", AVIFOURCC_PRINT( p_container->list.i_type ) );
msg_Dbg( p_input, "</list \'%4.4s\'>", (char*)&p_container->list.i_type );
return VLC_SUCCESS;
}
......@@ -411,6 +415,12 @@ static int AVI_ChunkRead_list( input_thread_t *p_input,
msg_Warn( p_input, "not enough data" ); \
} \
return code
#define AVI_READ1BYTE( i_byte ) \
i_byte = *p_read; \
p_read++; \
i_read--
#define AVI_READ2BYTES( i_word ) \
i_word = GetWLE( p_read ); \
p_read += 2; \
......@@ -421,6 +431,11 @@ static int AVI_ChunkRead_list( input_thread_t *p_input,
p_read += 4; \
i_read -= 4
#define AVI_READ8BYTES( i_dword ) \
i_dword = GetQWLE( p_read ); \
p_read += 8; \
i_read -= 8
#define AVI_READFOURCC( i_dword ) \
i_dword = GetFOURCC( p_read ); \
p_read += 4; \
......@@ -479,8 +494,8 @@ static int AVI_ChunkRead_strh( input_thread_t *p_input,
AVI_READ4BYTES( p_chk->strh.i_samplesize );
#ifdef AVI_DEBUG
msg_Dbg( p_input,
"strh: type:%c%c%c%c handler:0x%8.8x samplesize:%d %.2ffps",
AVIFOURCC_PRINT( p_chk->strh.i_type ),
"strh: type:%4.4s handler:0x%8.8x samplesize:%d %.2ffps",
(char*)&p_chk->strh.i_type,
p_chk->strh.i_handler,
p_chk->strh.i_samplesize,
( p_chk->strh.i_scale ?
......@@ -580,8 +595,8 @@ static int AVI_ChunkRead_strf( input_thread_t *p_input,
}
#ifdef AVI_DEBUG
msg_Dbg( p_input,
"strf: video:%c%c%c%c %dx%d planes:%d %dbpp",
AVIFOURCC_PRINT( p_chk->strf.vids.p_bih->biCompression ),
"strf: video:%4.4s %dx%d planes:%d %dbpp",
(char*)&p_chk->strf.vids.p_bih->biCompression,
p_chk->strf.vids.p_bih->biWidth,
p_chk->strf.vids.p_bih->biHeight,
p_chk->strf.vids.p_bih->biPlanes,
......@@ -632,7 +647,7 @@ static int AVI_ChunkRead_idx1( input_thread_t *p_input,
AVI_READCHUNK_ENTER;
i_count = __MIN( p_chk->common.i_chunk_size, i_read ) / 16;
i_count = __MIN( (int64_t)p_chk->common.i_chunk_size, i_read ) / 16;
p_chk->idx1.i_entry_count = i_count;
p_chk->idx1.i_entry_max = i_count;
......@@ -666,6 +681,98 @@ static void AVI_ChunkFree_idx1( input_thread_t *p_input,
FREE( p_chk->idx1.entry )
}
static int AVI_ChunkRead_indx( input_thread_t *p_input,
avi_chunk_t *p_chk,
vlc_bool_t b_seekable )
{
unsigned int i_count, i;
int32_t i_dummy;
avi_chunk_indx_t *p_indx = (avi_chunk_indx_t*)p_chk;
AVI_READCHUNK_ENTER;
AVI_READ2BYTES( p_indx->i_longsperentry );
AVI_READ1BYTE ( p_indx->i_indexsubtype );
AVI_READ1BYTE ( p_indx->i_indextype );
AVI_READ4BYTES( p_indx->i_entriesinuse );
AVI_READ4BYTES( p_indx->i_id );
p_indx->idx.std = NULL;
p_indx->idx.field = NULL;
p_indx->idx.super = NULL;
if( p_indx->i_indextype == AVI_INDEX_OF_CHUNKS && p_indx->i_indexsubtype == 0 )
{
AVI_READ8BYTES( p_indx->i_baseoffset );
AVI_READ4BYTES( i_dummy );
i_count = __MIN( p_indx->i_entriesinuse, i_read / 8 );
p_indx->i_entriesinuse = i_count;
p_indx->idx.std = calloc( sizeof( indx_std_entry_t ), i_count );
for( i = 0; i < i_count; i++ )
{
AVI_READ4BYTES( p_indx->idx.std[i].i_offset );
AVI_READ4BYTES( p_indx->idx.std[i].i_size );
}
}
else if( p_indx->i_indextype == AVI_INDEX_OF_CHUNKS && p_indx->i_indexsubtype == AVI_INDEX_2FIELD )
{
AVI_READ8BYTES( p_indx->i_baseoffset );
AVI_READ4BYTES( i_dummy );
i_count = __MIN( p_indx->i_entriesinuse, i_read / 12 );
p_indx->i_entriesinuse = i_count;
p_indx->idx.field = calloc( sizeof( indx_field_entry_t ), i_count );
for( i = 0; i < i_count; i++ )
{
AVI_READ4BYTES( p_indx->idx.field[i].i_offset );
AVI_READ4BYTES( p_indx->idx.field[i].i_size );
AVI_READ4BYTES( p_indx->idx.field[i].i_offsetfield2 );
}
}
else if( p_indx->i_indextype == AVI_INDEX_OF_INDEXES )
{
p_indx->i_baseoffset = 0;
AVI_READ4BYTES( i_dummy );
AVI_READ4BYTES( i_dummy );
AVI_READ4BYTES( i_dummy );
i_count = __MIN( p_indx->i_entriesinuse, i_read / 16 );
p_indx->i_entriesinuse = i_count;
p_indx->idx.super = calloc( sizeof( indx_super_entry_t ), i_count );
for( i = 0; i < i_count; i++ )
{
AVI_READ8BYTES( p_indx->idx.super[i].i_offset );
AVI_READ4BYTES( p_indx->idx.super[i].i_size );
AVI_READ4BYTES( p_indx->idx.super[i].i_duration );
}
}
else
{
msg_Warn( p_input, "unknow type/subtype index" );
}
#ifdef AVI_DEBUG
msg_Dbg( p_input, "indx: type=%d subtype=%d entry=%d", p_indx->i_indextype, p_indx->i_indexsubtype, p_indx->i_entriesinuse );
#endif
AVI_READCHUNK_EXIT( VLC_SUCCESS );
}
static void AVI_ChunkFree_indx( input_thread_t *p_input,
avi_chunk_t *p_chk )
{
avi_chunk_indx_t *p_indx = (avi_chunk_indx_t*)p_chk;
FREE( p_indx->idx.std );
FREE( p_indx->idx.field );
FREE( p_indx->idx.super );
}
static struct
{
vlc_fourcc_t i_fourcc;
......@@ -725,8 +832,8 @@ static int AVI_ChunkRead_strz( input_thread_t *p_input,
p_strz->p_str[i_read] = 0;
#ifdef AVI_DEBUG
msg_Dbg( p_input, "%c%c%c%c: %s : %s",
AVIFOURCC_PRINT( p_strz->i_chunk_fourcc), p_strz->p_type, p_strz->p_str);
msg_Dbg( p_input, "%4.4s: %s : %s",
(char*)&p_strz->i_chunk_fourcc, p_strz->p_type, p_strz->p_str);
#endif
AVI_READCHUNK_EXIT( VLC_SUCCESS );
}
......@@ -767,6 +874,7 @@ static struct
{ AVIFOURCC_strf, AVI_ChunkRead_strf, AVI_ChunkFree_strf },
{ AVIFOURCC_strd, AVI_ChunkRead_strd, AVI_ChunkFree_nothing },
{ AVIFOURCC_idx1, AVI_ChunkRead_idx1, AVI_ChunkFree_idx1 },
{ AVIFOURCC_indx, AVI_ChunkRead_indx, AVI_ChunkFree_indx },
{ AVIFOURCC_JUNK, AVI_ChunkRead_nothing, AVI_ChunkFree_nothing },
{ AVIFOURCC_IARL, AVI_ChunkRead_strz, AVI_ChunkFree_strz },
......@@ -841,7 +949,12 @@ int _AVI_ChunkRead( input_thread_t *p_input,
return AVI_Chunk_Function[i_index].
AVI_ChunkRead_function( p_input, p_chk, b_seekable );
}
else if( ((char*)&p_chk->common.i_chunk_fourcc)[0] == 'i' &&
((char*)&p_chk->common.i_chunk_fourcc)[1] == 'x' )
{
p_chk->common.i_chunk_fourcc = AVIFOURCC_indx;
return AVI_ChunkRead_indx( p_input, p_chk, b_seekable );
}
msg_Warn( p_input, "unknown chunk (not loaded)" );
return AVI_NextChunk( p_input, p_chk );
}
......@@ -871,8 +984,8 @@ void _AVI_ChunkFree( input_thread_t *p_input,
if( AVI_Chunk_Function[i_index].AVI_ChunkFree_function )
{
#ifdef AVI_DEBUG
msg_Dbg( p_input, "free chunk %c%c%c%c",
AVIFOURCC_PRINT( p_chk->common.i_chunk_fourcc ) );
msg_Dbg( p_input, "free chunk %4.4s",
(char*)&p_chk->common.i_chunk_fourcc );
#endif
AVI_Chunk_Function[i_index].AVI_ChunkFree_function( p_input, p_chk);
}
......@@ -1012,18 +1125,18 @@ static void AVI_ChunkDumpDebug_level( input_thread_t *p_input,
p_chk->common.i_chunk_fourcc == AVIFOURCC_LIST )
{
sprintf( str + i_level * 5,
"%c %c%c%c%c-%c%c%c%c size:"I64Fu" pos:"I64Fu,
"%c %4.4s-%4.4s size:"I64Fu" pos:"I64Fu,
i_level ? '+' : '*',
AVIFOURCC_PRINT( p_chk->common.i_chunk_fourcc ),
AVIFOURCC_PRINT( p_chk->list.i_type ),
(char*)&p_chk->common.i_chunk_fourcc,
(char*)&p_chk->list.i_type,
p_chk->common.i_chunk_size,
p_chk->common.i_chunk_pos );
}
else
{
sprintf( str + i_level * 5,
"+ %c%c%c%c size:"I64Fu" pos:"I64Fu,
AVIFOURCC_PRINT( p_chk->common.i_chunk_fourcc ),
"+ %4.4s size:"I64Fu" pos:"I64Fu,
(char*)&p_chk->common.i_chunk_fourcc,
p_chk->common.i_chunk_size,
p_chk->common.i_chunk_pos );
}
......
......@@ -2,7 +2,7 @@
* libavi.h : LibAVI library
******************************************************************************
* Copyright (C) 2001 VideoLAN
* $Id: libavi.h,v 1.8 2003/03/13 16:09:20 hartman Exp $
* $Id: libavi.h,v 1.9 2003/04/27 11:55:03 fenrir Exp $
* Authors: Laurent Aimar <fenrir@via.ecp.fr>
*
* This program is free software; you can redistribute it and/or modify
......@@ -46,6 +46,7 @@
#define AVIFOURCC_LIST VLC_FOURCC('L','I','S','T')
#define AVIFOURCC_JUNK VLC_FOURCC('J','U','N','K')
#define AVIFOURCC_AVI VLC_FOURCC('A','V','I',' ')
#define AVIFOURCC_AVIX VLC_FOURCC('A','V','I','X')
#define AVIFOURCC_WAVE VLC_FOURCC('W','A','V','E')
#define AVIFOURCC_INFO VLC_FOURCC('I','N','F','O')
......@@ -58,6 +59,7 @@
#define AVIFOURCC_strh VLC_FOURCC('s','t','r','h')
#define AVIFOURCC_strf VLC_FOURCC('s','t','r','f')
#define AVIFOURCC_strd VLC_FOURCC('s','t','r','d')
#define AVIFOURCC_indx VLC_FOURCC('i','n','d','x')
#define AVIFOURCC_rec VLC_FOURCC('r','e','c',' ')
#define AVIFOURCC_auds VLC_FOURCC('a','u','d','s')
......@@ -273,6 +275,51 @@ typedef struct avi_chunk_strd_s
uint8_t *p_data;
} avi_chunk_strd_t;
#define AVI_INDEX_OF_INDEXES 0x00
#define AVI_INDEX_OF_CHUNKS 0x01
#define AVI_INDEX_IS_DATA 0x80
#define AVI_INDEX_2FIELD 0x01
typedef struct
{
uint32_t i_offset;
uint32_t i_size;
} indx_std_entry_t;
typedef struct
{
uint32_t i_offset;
uint32_t i_size;
uint32_t i_offsetfield2;
} indx_field_entry_t;
typedef struct
{
uint64_t i_offset;
uint32_t i_size;
uint32_t i_duration;
} indx_super_entry_t;
typedef struct avi_chunk_indx_s
{
AVI_CHUNK_COMMON
int16_t i_longsperentry;
int8_t i_indexsubtype;
int8_t i_indextype;
int32_t i_entriesinuse;
vlc_fourcc_t i_id;
int64_t i_baseoffset;
union
{
indx_std_entry_t *std;
indx_field_entry_t *field;
indx_super_entry_t *super;
} idx;
} avi_chunk_indx_t;
typedef struct avi_chunk_STRING_s
{
AVI_CHUNK_COMMON
......@@ -289,6 +336,7 @@ typedef union avi_chunk_u
avi_chunk_strh_t strh;
avi_chunk_strf_t strf;
avi_chunk_strd_t strd;
avi_chunk_indx_t indx;
avi_chunk_STRING_t strz;
} avi_chunk_t;
......
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