summaryrefslogtreecommitdiff
path: root/libavformat/dv.c
diff options
context:
space:
mode:
authorMichael Niedermayer <michaelni@gmx.at>2004-10-12 01:51:04 +0000
committerMichael Niedermayer <michaelni@gmx.at>2004-10-12 01:51:04 +0000
commit83582de4c1a9a65167e3e033e9481a3be3aa6679 (patch)
tree377a0cd36fb6da1fb30938cfa011755017536b12 /libavformat/dv.c
parent7b3c1382bf46615e3faea72b62b6dab83e4142a7 (diff)
flags, rounding and cliping fix by (Nathan Kurz <nate at verse dot com>)
max_pos, buffer flush, audio and video timestamp fix by me Originally committed as revision 3586 to svn://svn.ffmpeg.org/ffmpeg/trunk
Diffstat (limited to 'libavformat/dv.c')
-rw-r--r--libavformat/dv.c61
1 files changed, 48 insertions, 13 deletions
diff --git a/libavformat/dv.c b/libavformat/dv.c
index 5b2c41da3b..10dcee64f9 100644
--- a/libavformat/dv.c
+++ b/libavformat/dv.c
@@ -816,20 +816,30 @@ int dv_produce_packet(DVDemuxContext *c, AVPacket *pkt,
return size;
}
-int64_t dv_frame_offset(DVDemuxContext *c, int64_t timestamp)
+static int64_t dv_frame_offset(AVFormatContext *s, DVDemuxContext *c,
+ int64_t timestamp, int flags)
{
- const DVprofile* sys;
- int64_t frame_number, offset;
-
// FIXME: sys may be wrong if last dv_read_packet() failed (buffer is junk)
- sys = dv_codec_profile(&c->vst->codec);
+ const DVprofile* sys = dv_codec_profile(&c->vst->codec);
+ int64_t frame_number, offset;
+ int64_t size = url_filesize(url_fileno(&s->pb));
+ int64_t max_offset = ((size-1) / sys->frame_size) * sys->frame_size;
- // timestamp was scaled by time_base/AV_BASE_RATE by av_seek_frame()
- frame_number = (timestamp * sys->frame_rate) /
- ((int64_t) 30000 * sys->frame_rate_base);
+ if (flags & AVSEEK_FLAG_BACKWARD) {
+ frame_number = av_rescale_rnd(timestamp, sys->frame_rate,
+ (int64_t) 30000 * sys->frame_rate_base,
+ AV_ROUND_DOWN);
+ }
+ else {
+ frame_number = av_rescale_rnd(timestamp, sys->frame_rate,
+ (int64_t) 30000 * sys->frame_rate_base,
+ AV_ROUND_UP);
+ }
- // offset must be a multiple of frame_size else dv_read_packet() will fail
- offset = (int64_t) sys->frame_size * frame_number;
+ offset = sys->frame_size * frame_number;
+
+ if (offset > max_offset) offset = max_offset;
+ else if (offset < 0) offset = 0;
return offset;
}
@@ -883,11 +893,36 @@ static int dv_read_packet(AVFormatContext *s, AVPacket *pkt)
return size;
}
-static int dv_read_seek(AVFormatContext *s, int stream_index, int64_t timestamp)
+static int dv_read_seek(AVFormatContext *s, int stream_index,
+ int64_t timestamp, int flags)
{
- RawDVContext *c = s->priv_data;
+ RawDVContext *r = s->priv_data;
+ DVDemuxContext *c = r->dv_demux;
+ int i;
+ int64_t offset= dv_frame_offset(s, c, timestamp, flags);
+ const DVprofile* sys = dv_codec_profile(&c->vst->codec);
+
+ c->frames= offset / sys->frame_size;
+ c->abytes= av_rescale(c->frames,
+ c->ast[0]->codec.bit_rate * (int64_t)sys->frame_rate_base,
+ 8*sys->frame_rate);
+ for (i=0; i<c->ach; i++) {
+ if (c->ast[i] && c->audio_pkt[i].size) {
+ av_free_packet(&c->audio_pkt[i]);
+ c->audio_pkt[i].size = 0;
+ }
+ }
+
+ for(i = 0; i < s->nb_streams; i++) {
+ AVStream *st = s->streams[stream_index];
+ AVStream *st2 = s->streams[i];
+
+ st->cur_dts = av_rescale(timestamp,
+ st2->time_base.den * (int64_t)st ->time_base.num,
+ st ->time_base.den * (int64_t)st2->time_base.num);
+ }
- return url_fseek(&s->pb, dv_frame_offset(c->dv_demux, timestamp), SEEK_SET);
+ return url_fseek(&s->pb, offset, SEEK_SET);
}
static int dv_read_close(AVFormatContext *s)