[FFmpeg-devel] [PATCH 3/3] WIP: lavf/utils: try to avoid decoding a frame to get the codec parameters

Matthieu Bouron matthieu.bouron at gmail.com
Sat Oct 17 22:34:24 CEST 2015


From: Matthieu Bouron <matthieu.bouron at stupeflix.com>

Avoid decoding twice images such as jpeg and png, once in the
avformat_find_stream_info and once when the actual decode is made.

The decoder must honor the skip_frame option in order to skip
decoding. For now the AVDISCARD_ALL flag is only set for the mjpeg and
png decoders.
---
 libavformat/utils.c | 15 +++++++++++++++
 1 file changed, 15 insertions(+)

diff --git a/libavformat/utils.c b/libavformat/utils.c
index 689473e..67dfffc 100644
--- a/libavformat/utils.c
+++ b/libavformat/utils.c
@@ -2676,11 +2676,16 @@ static int has_codec_parameters(AVStream *st, const char **errmsg_ptr)
 static int try_decode_frame(AVFormatContext *s, AVStream *st, AVPacket *avpkt,
                             AVDictionary **options)
 {
+    int i;
     const AVCodec *codec;
     int got_picture = 1, ret = 0;
     AVFrame *frame = av_frame_alloc();
     AVSubtitle subtitle;
     AVPacket pkt = *avpkt;
+    int skip_frame;
+    static const enum AVCodecID no_decode_codecs[] = {
+        AV_CODEC_ID_MJPEG, AV_CODEC_ID_PNG,
+    };
 
     if (!frame)
         return AVERROR(ENOMEM);
@@ -2719,6 +2724,14 @@ static int try_decode_frame(AVFormatContext *s, AVStream *st, AVPacket *avpkt,
         goto fail;
     }
 
+    skip_frame = st->codec->skip_frame;
+    for (i = 0; i < FF_ARRAY_ELEMS(no_decode_codecs); i++) {
+        if (st->codec->codec_id == no_decode_codecs[i]) {
+            st->codec->skip_frame = AVDISCARD_ALL;
+            break;
+        }
+    }
+
     while ((pkt.size > 0 || (!pkt.data && got_picture)) &&
            ret >= 0 &&
            (!has_codec_parameters(st, NULL) || !has_decode_delay_been_guessed(st) ||
@@ -2753,6 +2766,8 @@ static int try_decode_frame(AVFormatContext *s, AVStream *st, AVPacket *avpkt,
     if (!pkt.data && !got_picture)
         ret = -1;
 
+    st->codec->skip_frame = skip_frame;
+
 fail:
     av_frame_free(&frame);
     return ret;
-- 
2.6.1



More information about the ffmpeg-devel mailing list