aboutsummaryrefslogtreecommitdiffstats
path: root/libavformat
diff options
context:
space:
mode:
authorReimar Döffinger <Reimar.Doeffinger@gmx.de>2012-04-14 00:17:30 +0200
committerReimar Döffinger <Reimar.Doeffinger@gmx.de>2012-04-16 22:13:11 +0200
commit4a95876f4df29f69dca45da4013b276cb2dd4cc6 (patch)
tree378a690ccdba3bc8c6ec03c16e44aeeff09bc032 /libavformat
parent4fa706a4a64f9e06b08c1a42a62893ff2f7de82f (diff)
downloadffmpeg-4a95876f4df29f69dca45da4013b276cb2dd4cc6.tar.gz
Add skip_to_keyframe stream variable.
This replaces the matroskadec one with the same name. The advantage is not only easier reuse in other demuxers but also that we can make the decisions after the parser. This fixes seeking in files that mark the keyframes incorrectly, for example the file in track ticket #1003. The matroska variable is still kept to be able to complain about such broken files. Signed-off-by: Reimar Döffinger <Reimar.Doeffinger@gmx.de>
Diffstat (limited to 'libavformat')
-rw-r--r--libavformat/avformat.h5
-rw-r--r--libavformat/matroskadec.c11
-rw-r--r--libavformat/utils.c6
3 files changed, 20 insertions, 2 deletions
diff --git a/libavformat/avformat.h b/libavformat/avformat.h
index 5a11fdcc9f..d2727d4d1d 100644
--- a/libavformat/avformat.h
+++ b/libavformat/avformat.h
@@ -787,6 +787,11 @@ typedef struct AVStream {
* NOT PART OF PUBLIC API
*/
int request_probe;
+ /**
+ * Indicates that everything up to the next keyframe
+ * should be discarded.
+ */
+ int skip_to_keyframe;
} AVStream;
#define AV_PROGRAM_RUNNING 1
diff --git a/libavformat/matroskadec.c b/libavformat/matroskadec.c
index e9c31013cd..27d84adbc2 100644
--- a/libavformat/matroskadec.c
+++ b/libavformat/matroskadec.c
@@ -1839,9 +1839,14 @@ static int matroska_parse_block(MatroskaDemuxContext *matroska, uint8_t *data,
}
if (matroska->skip_to_keyframe && track->type != MATROSKA_TRACK_TYPE_SUBTITLE) {
- if (!is_keyframe || timecode < matroska->skip_to_timecode)
+ if (timecode < matroska->skip_to_timecode)
return res;
- matroska->skip_to_keyframe = 0;
+ if (!st->skip_to_keyframe) {
+ av_log(matroska->ctx, AV_LOG_ERROR, "File is broken, keyframes not correctly marked!\n");
+ matroska->skip_to_keyframe = 0;
+ }
+ if (is_keyframe)
+ matroska->skip_to_keyframe = 0;
}
switch ((flags & 0x06) >> 1) {
@@ -2147,6 +2152,7 @@ static int matroska_read_seek(AVFormatContext *s, int stream_index,
avio_seek(s->pb, st->index_entries[index_min].pos, SEEK_SET);
matroska->current_id = 0;
+ st->skip_to_keyframe =
matroska->skip_to_keyframe = !(flags & AVSEEK_FLAG_ANY);
matroska->skip_to_timecode = st->index_entries[index].timestamp;
matroska->done = 0;
@@ -2158,6 +2164,7 @@ err:
// the generic seeking code.
matroska_clear_queue(matroska);
matroska->current_id = 0;
+ st->skip_to_keyframe =
matroska->skip_to_keyframe = 0;
matroska->done = 0;
matroska->num_levels = 0;
diff --git a/libavformat/utils.c b/libavformat/utils.c
index 3c3ced75a0..0636742b4e 100644
--- a/libavformat/utils.c
+++ b/libavformat/utils.c
@@ -1315,6 +1315,12 @@ static int read_frame_internal(AVFormatContext *s, AVPacket *pkt)
/* free packet */
av_free_packet(&cur_pkt);
}
+ if (pkt->flags & AV_PKT_FLAG_KEY)
+ st->skip_to_keyframe = 0;
+ if (st->skip_to_keyframe) {
+ av_free_packet(&cur_pkt);
+ got_packet = 0;
+ }
}
if (!got_packet && s->parse_queue)