Commit f7b5ee65 authored by romansh's avatar romansh

* Fixing seeking with DV-AVI (by Jeff Downs <heydowns at borg dot com>)



git-svn-id: file:///var/local/repositories/ffmpeg/trunk@7439 9553f0bf-9b14-0410-a0b8-cfaf0461ba5b
parent e31d7b2e
...@@ -289,6 +289,8 @@ static int avi_read_header(AVFormatContext *s, AVFormatParameters *ap) ...@@ -289,6 +289,8 @@ static int avi_read_header(AVFormatContext *s, AVFormatParameters *ap)
print_tag("strh", tag1, -1); print_tag("strh", tag1, -1);
#endif #endif
if(tag1 == MKTAG('i', 'a', 'v', 's') || tag1 == MKTAG('i', 'v', 'a', 's')){ 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 * After some consideration -- I don't think we
* have to support anything but DV in a type1 AVIs. * have to support anything but DV in a type1 AVIs.
...@@ -314,8 +316,20 @@ static int avi_read_header(AVFormatContext *s, AVFormatParameters *ap) ...@@ -314,8 +316,20 @@ static int avi_read_header(AVFormatContext *s, AVFormatParameters *ap)
url_fskip(pb, 3 * 4); url_fskip(pb, 3 * 4);
ast->scale = get_le32(pb); ast->scale = get_le32(pb);
ast->rate = 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; stream_index = s->nb_streams - 1;
url_fskip(pb, size - 7*4); url_fskip(pb, size - 9*4);
break; break;
} }
...@@ -903,6 +917,21 @@ static int avi_read_seek(AVFormatContext *s, int stream_index, int64_t timestamp ...@@ -903,6 +917,21 @@ static int avi_read_seek(AVFormatContext *s, int stream_index, int64_t timestamp
// av_log(NULL, AV_LOG_DEBUG, "XX %"PRId64" %d %"PRId64"\n", timestamp, index, st->index_entries[index].timestamp); // 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++) { for(i = 0; i < s->nb_streams; i++) {
AVStream *st2 = s->streams[i]; AVStream *st2 = s->streams[i];
AVIStream *ast2 = st2->priv_data; AVIStream *ast2 = st2->priv_data;
...@@ -937,8 +966,6 @@ static int avi_read_seek(AVFormatContext *s, int stream_index, int64_t timestamp ...@@ -937,8 +966,6 @@ static int avi_read_seek(AVFormatContext *s, int stream_index, int64_t timestamp
ast2->frame_offset *=ast2->sample_size; ast2->frame_offset *=ast2->sample_size;
} }
if (ENABLE_DV_DEMUXER && avi->dv_demux)
dv_flush_audio_packets(avi->dv_demux);
/* do the seek */ /* do the seek */
url_fseek(&s->pb, pos, SEEK_SET); url_fseek(&s->pb, pos, SEEK_SET);
avi->stream_index= -1; avi->stream_index= -1;
......
...@@ -358,8 +358,13 @@ static int64_t dv_frame_offset(AVFormatContext *s, DVDemuxContext *c, ...@@ -358,8 +358,13 @@ static int64_t dv_frame_offset(AVFormatContext *s, DVDemuxContext *c,
return offset; 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; c->audio_pkt[0].size = c->audio_pkt[1].size = 0;
} }
...@@ -419,13 +424,8 @@ static int dv_read_seek(AVFormatContext *s, int stream_index, ...@@ -419,13 +424,8 @@ static int dv_read_seek(AVFormatContext *s, int stream_index,
DVDemuxContext *c = r->dv_demux; DVDemuxContext *c = r->dv_demux;
int64_t offset= dv_frame_offset(s, c, timestamp, flags); int64_t offset= dv_frame_offset(s, c, timestamp, flags);
c->frames= offset / c->sys->frame_size; dv_offset_reset(c, 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_flush_audio_packets(c);
return url_fseek(&s->pb, offset, SEEK_SET); return url_fseek(&s->pb, offset, SEEK_SET);
} }
......
...@@ -29,7 +29,7 @@ typedef struct DVDemuxContext DVDemuxContext; ...@@ -29,7 +29,7 @@ typedef struct DVDemuxContext DVDemuxContext;
DVDemuxContext* dv_init_demux(AVFormatContext* s); DVDemuxContext* dv_init_demux(AVFormatContext* s);
int dv_get_packet(DVDemuxContext*, AVPacket *); int dv_get_packet(DVDemuxContext*, AVPacket *);
int dv_produce_packet(DVDemuxContext*, AVPacket*, uint8_t*, int); 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; typedef struct DVMuxContext DVMuxContext;
DVMuxContext* dv_init_mux(AVFormatContext* s); DVMuxContext* dv_init_mux(AVFormatContext* s);
......
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