Mercurial > libavformat.hg
changeset 1629:aedce96c28ff libavformat
* Fixing seeking with DV-AVI (by Jeff Downs <heydowns at borg dot com>)
author | romansh |
---|---|
date | Thu, 11 Jan 2007 22:32:19 +0000 |
parents | 421c130983da |
children | e7c247a67e20 |
files | avidec.c dv.c dv.h |
diffstat | 3 files changed, 38 insertions(+), 11 deletions(-) [+] |
line wrap: on
line diff
--- a/avidec.c Wed Jan 10 10:30:03 2007 +0000 +++ b/avidec.c Thu Jan 11 22:32:19 2007 +0000 @@ -289,6 +289,8 @@ print_tag("strh", tag1, -1); #endif if(tag1 == MKTAG('i', 'a', 'v', 's') || tag1 == MKTAG('i', 'v', 'a', 's')){ + int64_t dv_dur; + /* * After some consideration -- I don't think we * have to support anything but DV in a type1 AVIs. @@ -314,8 +316,20 @@ url_fskip(pb, 3 * 4); ast->scale = get_le32(pb); ast->rate = get_le32(pb); + url_fskip(pb, 4); /* start time */ + + dv_dur = get_le32(pb); + if (ast->scale > 0 && ast->rate > 0 && dv_dur > 0) { + dv_dur *= AV_TIME_BASE; + s->duration = av_rescale(dv_dur, ast->scale, ast->rate); + } + /* + * else, leave duration alone; timing estimation in utils.c + * will make a guess based on bit rate. + */ + stream_index = s->nb_streams - 1; - url_fskip(pb, size - 7*4); + url_fskip(pb, size - 9*4); break; } @@ -903,6 +917,21 @@ // av_log(NULL, AV_LOG_DEBUG, "XX %"PRId64" %d %"PRId64"\n", timestamp, index, st->index_entries[index].timestamp); + if (ENABLE_DV_DEMUXER && avi->dv_demux) { + /* One and only one real stream for DV in AVI, and it has video */ + /* offsets. Calling with other stream indices should have failed */ + /* the av_index_search_timestamp call above. */ + assert(stream_index == 0); + + /* Feed the DV video stream version of the timestamp to the */ + /* DV demux so it can synth correct timestamps */ + dv_offset_reset(avi->dv_demux, timestamp); + + url_fseek(&s->pb, pos, SEEK_SET); + avi->stream_index= -1; + return 0; + } + for(i = 0; i < s->nb_streams; i++) { AVStream *st2 = s->streams[i]; AVIStream *ast2 = st2->priv_data; @@ -937,8 +966,6 @@ ast2->frame_offset *=ast2->sample_size; } - if (ENABLE_DV_DEMUXER && avi->dv_demux) - dv_flush_audio_packets(avi->dv_demux); /* do the seek */ url_fseek(&s->pb, pos, SEEK_SET); avi->stream_index= -1;
--- a/dv.c Wed Jan 10 10:30:03 2007 +0000 +++ b/dv.c Thu Jan 11 22:32:19 2007 +0000 @@ -358,8 +358,13 @@ return offset; } -void dv_flush_audio_packets(DVDemuxContext *c) +void dv_offset_reset(DVDemuxContext *c, int64_t frame_offset) { + c->frames= frame_offset; + if (c->ach) + c->abytes= av_rescale(c->frames, + c->ast[0]->codec->bit_rate * (int64_t)c->sys->frame_rate_base, + 8*c->sys->frame_rate); c->audio_pkt[0].size = c->audio_pkt[1].size = 0; } @@ -419,13 +424,8 @@ DVDemuxContext *c = r->dv_demux; int64_t offset= dv_frame_offset(s, c, timestamp, flags); - c->frames= offset / c->sys->frame_size; - if (c->ach) - c->abytes= av_rescale(c->frames, - c->ast[0]->codec->bit_rate * (int64_t)c->sys->frame_rate_base, - 8*c->sys->frame_rate); + dv_offset_reset(c, offset / c->sys->frame_size); - dv_flush_audio_packets(c); return url_fseek(&s->pb, offset, SEEK_SET); }
--- a/dv.h Wed Jan 10 10:30:03 2007 +0000 +++ b/dv.h Thu Jan 11 22:32:19 2007 +0000 @@ -29,7 +29,7 @@ DVDemuxContext* dv_init_demux(AVFormatContext* s); int dv_get_packet(DVDemuxContext*, AVPacket *); int dv_produce_packet(DVDemuxContext*, AVPacket*, uint8_t*, int); -void dv_flush_audio_packets(DVDemuxContext*); +void dv_offset_reset(DVDemuxContext *c, int64_t frame_offset); typedef struct DVMuxContext DVMuxContext; DVMuxContext* dv_init_mux(AVFormatContext* s);