diff options
author | Alex Converse <alex.converse@gmail.com> | 2011-06-30 00:30:09 +0400 |
---|---|---|
committer | Alex Converse <alex.converse@gmail.com> | 2011-07-01 21:27:06 +0400 |
commit | 8b84af748865105a6520a1e486792e8a5a82e2a6 (patch) | |
tree | 7ed6fcccf51f8399fbe79898f29303132692b4d1 /libavformat | |
parent | 29651e1d44f7e702a43133752a31398f4e73fe09 (diff) |
avidec: Factor out the sync fucntionality.
Diffstat (limited to 'libavformat')
-rw-r--r-- | libavformat/avidec.c | 244 |
1 files changed, 128 insertions, 116 deletions
diff --git a/libavformat/avidec.c b/libavformat/avidec.c index 85fc794362..7e509ce8ce 100644 --- a/libavformat/avidec.c +++ b/libavformat/avidec.c @@ -836,13 +836,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); !pb->eof_reached; 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) { @@ -993,121 +1117,9 @@ resync: return size; } - memset(d, -1, sizeof(int)*8); - for(i=sync=avio_tell(pb); !pb->eof_reached; 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 |