lavf: add avformat_find_stream_info()
authorAnton Khirnov <anton@khirnov.net>
Sun, 22 May 2011 17:24:59 +0000 (19:24 +0200)
committerAnton Khirnov <anton@khirnov.net>
Sun, 10 Jul 2011 15:07:05 +0000 (17:07 +0200)
It supports passing options to codecs.

libavfilter/vsrc_movie.c
libavformat/avformat.h
libavformat/utils.c

index bd74f95..b018ba7 100644 (file)
@@ -96,7 +96,7 @@ static int movie_init(AVFilterContext *ctx)
                "Failed to avformat_open_input '%s'\n", movie->file_name);
         return ret;
     }
-    if ((ret = av_find_stream_info(movie->format_ctx)) < 0)
+    if ((ret = avformat_find_stream_info(movie->format_ctx, NULL)) < 0)
         av_log(ctx, AV_LOG_WARNING, "Failed to find stream info\n");
 
     // if seeking requested, we execute it
index 2cdf11b..6e861de 100644 (file)
@@ -1093,6 +1093,7 @@ int avformat_open_input(AVFormatContext **ps, const char *filename, AVInputForma
  */
 AVFormatContext *avformat_alloc_context(void);
 
+#if FF_API_FORMAT_PARAMETERS
 /**
  * Read packets of a media file to get stream information. This
  * is useful for file formats with no headers such as MPEG. This
@@ -1105,8 +1106,34 @@ AVFormatContext *avformat_alloc_context(void);
  * @return >=0 if OK, AVERROR_xxx on error
  * @todo Let the user decide somehow what information is needed so that
  *       we do not waste time getting stuff the user does not need.
+ *
+ * @deprecated use avformat_find_stream_info.
  */
 int av_find_stream_info(AVFormatContext *ic);
+#endif
+
+/**
+ * Read packets of a media file to get stream information. This
+ * is useful for file formats with no headers such as MPEG. This
+ * function also computes the real framerate in case of MPEG-2 repeat
+ * frame mode.
+ * The logical file position is not changed by this function;
+ * examined packets may be buffered for later processing.
+ *
+ * @param ic media file handle
+ * @param options  If non-NULL, an ic.nb_streams long array of pointers to
+ *                 dictionaries, where i-th member contains options for
+ *                 codec corresponding to i-th stream.
+ *                 On return each dictionary will be filled with options that were not found.
+ * @return >=0 if OK, AVERROR_xxx on error
+ *
+ * @note this function isn't guaranteed to open all the codecs, so
+ *       options being non-empty at return is a perfectly normal behavior.
+ *
+ * @todo Let the user decide somehow what information is needed so that
+ *       we do not waste time getting stuff the user does not need.
+ */
+int avformat_find_stream_info(AVFormatContext *ic, AVDictionary **options);
 
 /**
  * Find the "best" stream in the file.
index e38d9ef..a3825a0 100644 (file)
@@ -2074,7 +2074,7 @@ static int has_decode_delay_been_guessed(AVStream *st)
         st->codec_info_nb_frames >= 6 + st->codec->has_b_frames;
 }
 
-static int try_decode_frame(AVStream *st, AVPacket *avpkt)
+static int try_decode_frame(AVStream *st, AVPacket *avpkt, AVDictionary **options)
 {
     int16_t *samples;
     AVCodec *codec;
@@ -2085,7 +2085,7 @@ static int try_decode_frame(AVStream *st, AVPacket *avpkt)
         codec = avcodec_find_decoder(st->codec->codec_id);
         if (!codec)
             return -1;
-        ret = avcodec_open(st->codec, codec);
+        ret = avcodec_open2(st->codec, codec, options);
         if (ret < 0)
             return ret;
     }
@@ -2204,12 +2204,20 @@ static int tb_unreliable(AVCodecContext *c){
     return 0;
 }
 
+#if FF_API_FORMAT_PARAMETERS
 int av_find_stream_info(AVFormatContext *ic)
+{
+    return avformat_find_stream_info(ic, NULL);
+}
+#endif
+
+int avformat_find_stream_info(AVFormatContext *ic, AVDictionary **options)
 {
     int i, count, ret, read_size, j;
     AVStream *st;
     AVPacket pkt1, *pkt;
     int64_t old_offset = avio_tell(ic->pb);
+    int orig_nb_streams = ic->nb_streams;        // new streams might appear, no options for those
 
     for(i=0;i<ic->nb_streams;i++) {
         AVCodec *codec;
@@ -2235,12 +2243,12 @@ int av_find_stream_info(AVFormatContext *ic)
         /* Ensure that subtitle_header is properly set. */
         if (st->codec->codec_type == AVMEDIA_TYPE_SUBTITLE
             && codec && !st->codec->codec)
-            avcodec_open(st->codec, codec);
+            avcodec_open2(st->codec, codec, options ? &options[i] : NULL);
 
         //try to just open decoders, in case this is enough to get parameters
         if(!has_codec_parameters(st->codec)){
             if (codec && !st->codec->codec)
-                avcodec_open(st->codec, codec);
+                avcodec_open2(st->codec, codec, options ? &options[i] : NULL);
         }
     }
 
@@ -2383,7 +2391,7 @@ int av_find_stream_info(AVFormatContext *ic)
             !has_decode_delay_been_guessed(st) ||
             (st->codec->codec &&
              st->codec->codec->capabilities & CODEC_CAP_CHANNEL_CONF))
-            try_decode_frame(st, pkt);
+            try_decode_frame(st, pkt, (options && i <= orig_nb_streams )? &options[i] : NULL);
 
         st->codec_info_nb_frames++;
         count++;