@ -861,13 +861,137 @@ static int get_stream_idx(int *d){
}
}
static int avi_read_packet ( AVFormatContext * s , AVPacket * pkt )
static int avi_sync ( AVFormatContext * s )
{
AVIContext * avi = s - > priv_data ;
AVIOContext * pb = s - > pb ;
int n , d [ 8 ] ;
unsigned int size ;
int64_t i , sync ;
start_sync :
memset ( d , - 1 , sizeof ( int ) * 8 ) ;
for ( i = sync = avio_tell ( pb ) ; ! url_feof ( pb ) ; i + + ) {
int j ;
for ( j = 0 ; j < 7 ; j + + )
d [ j ] = d [ j + 1 ] ;
d [ 7 ] = avio_r8 ( pb ) ;
size = d [ 4 ] + ( d [ 5 ] < < 8 ) + ( d [ 6 ] < < 16 ) + ( d [ 7 ] < < 24 ) ;
n = get_stream_idx ( d + 2 ) ;
//av_log(s, AV_LOG_DEBUG, "%X %X %X %X %X %X %X %X %"PRId64" %d %d\n", d[0], d[1], d[2], d[3], d[4], d[5], d[6], d[7], i, size, n);
if ( i + ( uint64_t ) size > avi - > fsize | | d [ 0 ] < 0 )
continue ;
//parse ix##
if ( ( d [ 0 ] = = ' i ' & & d [ 1 ] = = ' x ' & & n < s - > nb_streams )
//parse JUNK
| | ( d [ 0 ] = = ' J ' & & d [ 1 ] = = ' U ' & & d [ 2 ] = = ' N ' & & d [ 3 ] = = ' K ' )
| | ( d [ 0 ] = = ' i ' & & d [ 1 ] = = ' d ' & & d [ 2 ] = = ' x ' & & d [ 3 ] = = ' 1 ' ) ) {
avio_skip ( pb , size ) ;
//av_log(s, AV_LOG_DEBUG, "SKIP\n");
goto start_sync ;
}
//parse stray LIST
if ( d [ 0 ] = = ' L ' & & d [ 1 ] = = ' I ' & & d [ 2 ] = = ' S ' & & d [ 3 ] = = ' T ' ) {
avio_skip ( pb , 4 ) ;
goto start_sync ;
}
n = get_stream_idx ( d ) ;
if ( ! ( ( i - avi - > last_pkt_pos ) & 1 ) & & get_stream_idx ( d + 1 ) < s - > nb_streams )
continue ;
//detect ##ix chunk and skip
if ( d [ 2 ] = = ' i ' & & d [ 3 ] = = ' x ' & & n < s - > nb_streams ) {
avio_skip ( pb , size ) ;
goto start_sync ;
}
//parse ##dc/##wb
if ( n < s - > nb_streams ) {
AVStream * st ;
AVIStream * ast ;
st = s - > streams [ n ] ;
ast = st - > priv_data ;
if ( s - > nb_streams > = 2 ) {
AVStream * st1 = s - > streams [ 1 ] ;
AVIStream * ast1 = st1 - > priv_data ;
//workaround for broken small-file-bug402.avi
if ( d [ 2 ] = = ' w ' & & d [ 3 ] = = ' b '
& & n = = 0
& & st - > codec - > codec_type = = AVMEDIA_TYPE_VIDEO
& & st1 - > codec - > codec_type = = AVMEDIA_TYPE_AUDIO
& & ast - > prefix = = ' d ' * 256 + ' c '
& & ( d [ 2 ] * 256 + d [ 3 ] = = ast1 - > prefix | | ! ast1 - > prefix_count )
) {
n = 1 ;
st = st1 ;
ast = ast1 ;
av_log ( s , AV_LOG_WARNING , " Invalid stream + prefix combination, assuming audio. \n " ) ;
}
}
if ( ( st - > discard > = AVDISCARD_DEFAULT & & size = = 0 )
/*|| (st->discard >= AVDISCARD_NONKEY && !(pkt->flags & AV_PKT_FLAG_KEY))*/ //FIXME needs a little reordering
| | st - > discard > = AVDISCARD_ALL ) {
ast - > frame_offset + = get_duration ( ast , size ) ;
avio_skip ( pb , size ) ;
goto start_sync ;
}
if ( d [ 2 ] = = ' p ' & & d [ 3 ] = = ' c ' & & size < = 4 * 256 + 4 ) {
int k = avio_r8 ( pb ) ;
int last = ( k + avio_r8 ( pb ) - 1 ) & 0xFF ;
avio_rl16 ( pb ) ; //flags
for ( ; k < = last ; k + + )
ast - > pal [ k ] = avio_rb32 ( pb ) > > 8 ; // b + (g << 8) + (r << 16);
ast - > has_pal = 1 ;
goto start_sync ;
} else if ( ( ( ast - > prefix_count < 5 | | sync + 9 > i ) & & d [ 2 ] < 128 & & d [ 3 ] < 128 ) | |
d [ 2 ] * 256 + d [ 3 ] = = ast - > prefix /*||
( d [ 2 ] = = ' d ' & & d [ 3 ] = = ' c ' ) | |
( d [ 2 ] = = ' w ' & & d [ 3 ] = = ' b ' ) */ ) {
//av_log(s, AV_LOG_DEBUG, "OK\n");
if ( d [ 2 ] * 256 + d [ 3 ] = = ast - > prefix )
ast - > prefix_count + + ;
else {
ast - > prefix = d [ 2 ] * 256 + d [ 3 ] ;
ast - > prefix_count = 0 ;
}
avi - > stream_index = n ;
ast - > packet_size = size + 8 ;
ast - > remaining = size ;
if ( size | | ! ast - > sample_size ) {
uint64_t pos = avio_tell ( pb ) - 8 ;
if ( ! st - > index_entries | | ! st - > nb_index_entries | | st - > index_entries [ st - > nb_index_entries - 1 ] . pos < pos ) {
av_add_index_entry ( st , pos , ast - > frame_offset , size , 0 , AVINDEX_KEYFRAME ) ;
}
}
return 0 ;
}
}
}
return AVERROR_EOF ;
}
static int avi_read_packet ( AVFormatContext * s , AVPacket * pkt )
{
AVIContext * avi = s - > priv_data ;
AVIOContext * pb = s - > pb ;
int err ;
void * dstr ;
if ( CONFIG_DV_DEMUXER & & avi - > dv_demux ) {
@ -1041,121 +1165,9 @@ resync:
return size ;
}
memset ( d , - 1 , sizeof ( int ) * 8 ) ;
for ( i = sync = avio_tell ( pb ) ; ! url_feof ( pb ) ; i + + ) {
int j ;
for ( j = 0 ; j < 7 ; j + + )
d [ j ] = d [ j + 1 ] ;
d [ 7 ] = avio_r8 ( pb ) ;
size = d [ 4 ] + ( d [ 5 ] < < 8 ) + ( d [ 6 ] < < 16 ) + ( d [ 7 ] < < 24 ) ;
n = get_stream_idx ( d + 2 ) ;
//av_log(s, AV_LOG_DEBUG, "%X %X %X %X %X %X %X %X %"PRId64" %d %d\n", d[0], d[1], d[2], d[3], d[4], d[5], d[6], d[7], i, size, n);
if ( i + ( uint64_t ) size > avi - > fsize | | d [ 0 ] < 0 )
continue ;
//parse ix##
if ( ( d [ 0 ] = = ' i ' & & d [ 1 ] = = ' x ' & & n < s - > nb_streams )
//parse JUNK
| | ( d [ 0 ] = = ' J ' & & d [ 1 ] = = ' U ' & & d [ 2 ] = = ' N ' & & d [ 3 ] = = ' K ' )
| | ( d [ 0 ] = = ' i ' & & d [ 1 ] = = ' d ' & & d [ 2 ] = = ' x ' & & d [ 3 ] = = ' 1 ' ) ) {
avio_skip ( pb , size ) ;
//av_log(s, AV_LOG_DEBUG, "SKIP\n");
goto resync ;
}
//parse stray LIST
if ( d [ 0 ] = = ' L ' & & d [ 1 ] = = ' I ' & & d [ 2 ] = = ' S ' & & d [ 3 ] = = ' T ' ) {
avio_skip ( pb , 4 ) ;
goto resync ;
}
n = get_stream_idx ( d ) ;
if ( ! ( ( i - avi - > last_pkt_pos ) & 1 ) & & get_stream_idx ( d + 1 ) < s - > nb_streams )
continue ;
//detect ##ix chunk and skip
if ( d [ 2 ] = = ' i ' & & d [ 3 ] = = ' x ' & & n < s - > nb_streams ) {
avio_skip ( pb , size ) ;
goto resync ;
}
//parse ##dc/##wb
if ( n < s - > nb_streams ) {
AVStream * st ;
AVIStream * ast ;
st = s - > streams [ n ] ;
ast = st - > priv_data ;
if ( s - > nb_streams > = 2 ) {
AVStream * st1 = s - > streams [ 1 ] ;
AVIStream * ast1 = st1 - > priv_data ;
//workaround for broken small-file-bug402.avi
if ( d [ 2 ] = = ' w ' & & d [ 3 ] = = ' b '
& & n = = 0
& & st - > codec - > codec_type = = AVMEDIA_TYPE_VIDEO
& & st1 - > codec - > codec_type = = AVMEDIA_TYPE_AUDIO
& & ast - > prefix = = ' d ' * 256 + ' c '
& & ( d [ 2 ] * 256 + d [ 3 ] = = ast1 - > prefix | | ! ast1 - > prefix_count )
) {
n = 1 ;
st = st1 ;
ast = ast1 ;
av_log ( s , AV_LOG_WARNING , " Invalid stream + prefix combination, assuming audio. \n " ) ;
}
}
if ( ( st - > discard > = AVDISCARD_DEFAULT & & size = = 0 )
/*|| (st->discard >= AVDISCARD_NONKEY && !(pkt->flags & AV_PKT_FLAG_KEY))*/ //FIXME needs a little reordering
| | st - > discard > = AVDISCARD_ALL ) {
ast - > frame_offset + = get_duration ( ast , size ) ;
avio_skip ( pb , size ) ;
goto resync ;
}
if ( d [ 2 ] = = ' p ' & & d [ 3 ] = = ' c ' & & size < = 4 * 256 + 4 ) {
int k = avio_r8 ( pb ) ;
int last = ( k + avio_r8 ( pb ) - 1 ) & 0xFF ;
avio_rl16 ( pb ) ; //flags
for ( ; k < = last ; k + + )
ast - > pal [ k ] = avio_rb32 ( pb ) > > 8 ; // b + (g << 8) + (r << 16);
ast - > has_pal = 1 ;
goto resync ;
} else if ( ( ( ast - > prefix_count < 5 | | sync + 9 > i ) & & d [ 2 ] < 128 & & d [ 3 ] < 128 ) | |
d [ 2 ] * 256 + d [ 3 ] = = ast - > prefix /*||
( d [ 2 ] = = ' d ' & & d [ 3 ] = = ' c ' ) | |
( d [ 2 ] = = ' w ' & & d [ 3 ] = = ' b ' ) */ ) {
//av_log(s, AV_LOG_DEBUG, "OK\n");
if ( d [ 2 ] * 256 + d [ 3 ] = = ast - > prefix )
ast - > prefix_count + + ;
else {
ast - > prefix = d [ 2 ] * 256 + d [ 3 ] ;
ast - > prefix_count = 0 ;
}
avi - > stream_index = n ;
ast - > packet_size = size + 8 ;
ast - > remaining = size ;
if ( size | | ! ast - > sample_size ) {
uint64_t pos = avio_tell ( pb ) - 8 ;
if ( ! st - > index_entries | | ! st - > nb_index_entries | | st - > index_entries [ st - > nb_index_entries - 1 ] . pos < pos ) {
av_add_index_entry ( st , pos , ast - > frame_offset , size , 0 , AVINDEX_KEYFRAME ) ;
}
}
goto resync ;
}
}
}
return AVERROR_EOF ;
if ( ( err = avi_sync ( s ) ) < 0 )
return err ;
goto resync ;
}
/* XXX: We make the implicit supposition that the positions are sorted