summaryrefslogtreecommitdiff
path: root/libavformat
diff options
context:
space:
mode:
authorReimar Döffinger <Reimar.Doeffinger@gmx.de>2012-02-04 20:31:21 +0100
committerReimar Döffinger <Reimar.Doeffinger@gmx.de>2012-02-05 14:21:16 +0100
commit1b0dc96fc98f29fbd0d8d4bd8335982e5d47f2c8 (patch)
tree738ffb3c7229b55d7f0a62a4ea4e15fd55b8ac56 /libavformat
parent982783ac49c1a1f0739cad9cf0ec8a7b5d427e62 (diff)
oggdec: fix keyframe seeking when granule_is_start is 0.
In this case, the pts values will be delayed by one, but at the same time pts values might only be supplied for e.g. keyframes. This results on only the frame after the keyframe having a pts value. As a hack, make read_timestamp return the keyframe position together with the pts from a following frame when seeking to a keyframe. Fixes trac issue #438. However it causes the read_timestamp function to return a pos value that is actually before the packet with the indicated pts. Signed-off-by: Reimar Döffinger <Reimar.Doeffinger@gmx.de>
Diffstat (limited to 'libavformat')
-rw-r--r--libavformat/oggdec.c13
1 files changed, 11 insertions, 2 deletions
diff --git a/libavformat/oggdec.c b/libavformat/oggdec.c
index 4280f8f842..9e6832b61f 100644
--- a/libavformat/oggdec.c
+++ b/libavformat/oggdec.c
@@ -637,6 +637,7 @@ static int64_t ogg_read_timestamp(AVFormatContext *s, int stream_index,
struct ogg *ogg = s->priv_data;
AVIOContext *bc = s->pb;
int64_t pts = AV_NOPTS_VALUE;
+ int64_t keypos = -1;
int i = -1;
avio_seek(bc, *pos_arg, SEEK_SET);
ogg_reset(ogg);
@@ -645,8 +646,16 @@ static int64_t ogg_read_timestamp(AVFormatContext *s, int stream_index,
if (i == stream_index) {
struct ogg_stream *os = ogg->streams + stream_index;
pts = ogg_calc_pts(s, i, NULL);
- if (os->keyframe_seek && !(os->pflags & AV_PKT_FLAG_KEY))
- pts = AV_NOPTS_VALUE;
+ if (os->pflags & AV_PKT_FLAG_KEY) {
+ keypos = *pos_arg;
+ } else if (os->keyframe_seek) {
+ // if we had a previous keyframe but no pts for it,
+ // return that keyframe with this pts value.
+ if (keypos >= 0)
+ *pos_arg = keypos;
+ else
+ pts = AV_NOPTS_VALUE;
+ }
}
if (pts != AV_NOPTS_VALUE)
break;