[FFmpeg-cvslog] Add skip_to_keyframe stream variable.

Reimar Döffinger git at videolan.org
Mon Apr 16 22:14:32 CEST 2012


ffmpeg | branch: master | Reimar Döffinger <Reimar.Doeffinger at gmx.de> | Sat Apr 14 00:17:30 2012 +0200| [4a95876f4df29f69dca45da4013b276cb2dd4cc6] | committer: Reimar Döffinger

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 at gmx.de>

> http://git.videolan.org/gitweb.cgi/ffmpeg.git/?a=commit;h=4a95876f4df29f69dca45da4013b276cb2dd4cc6
---

 libavformat/avformat.h    |    5 +++++
 libavformat/matroskadec.c |   11 +++++++++--
 libavformat/utils.c       |    6 ++++++
 3 files changed, 20 insertions(+), 2 deletions(-)

diff --git a/libavformat/avformat.h b/libavformat/avformat.h
index 5a11fdc..d2727d4 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 e9c3101..27d84ad 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 3c3ced7..0636742 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)



More information about the ffmpeg-cvslog mailing list