]> git.sesse.net Git - ffmpeg/blobdiff - ffmpeg_opt.c
avdevice/avdevice.c: Use av_freep(), avoid leaving stale pointers
[ffmpeg] / ffmpeg_opt.c
index 454da986806102e45337f4a9aea1b7ec206da2f3..85466c78c1e9808367342286eae22c5cf517036a 100644 (file)
@@ -794,6 +794,7 @@ static int open_input_file(OptionsContext *o, const char *filename)
     char *   video_codec_name = NULL;
     char *   audio_codec_name = NULL;
     char *subtitle_codec_name = NULL;
+    int scan_all_pmts_set = 0;
 
     if (o->format) {
         if (!(file_iformat = av_find_input_format(o->format))) {
@@ -864,12 +865,18 @@ static int open_input_file(OptionsContext *o, const char *filename)
     ic->flags |= AVFMT_FLAG_NONBLOCK;
     ic->interrupt_callback = int_cb;
 
+    if (!av_dict_get(o->g->format_opts, "scan_all_pmts", NULL, AV_DICT_MATCH_CASE)) {
+        av_dict_set(&o->g->format_opts, "scan_all_pmts", "1", AV_DICT_DONT_OVERWRITE);
+        scan_all_pmts_set = 1;
+    }
     /* open the input file with generic avformat function */
     err = avformat_open_input(&ic, filename, file_iformat, &o->g->format_opts);
     if (err < 0) {
         print_error(filename, err);
         exit_program(1);
     }
+    if (scan_all_pmts_set)
+        av_dict_set(&o->g->format_opts, "scan_all_pmts", NULL, AV_DICT_MATCH_CASE);
     remove_avoptions(&o->g->format_opts, o->g->codec_opts);
     assert_avoptions(o->g->format_opts);
 
@@ -1610,6 +1617,31 @@ static int copy_chapters(InputFile *ifile, OutputFile *ofile, int copy_metadata)
     return 0;
 }
 
+static int ffserver_streams_copy_context(AVCodecContext *dest, const AVCodecContext *src,
+                                         const char *configuration)
+{
+    int ret;
+    if ((ret = avcodec_copy_context(dest, src)) < 0)
+        return ret;
+    dest->codec = avcodec_find_encoder(src->codec_id);
+    if (!dest->codec)
+        return AVERROR(EINVAL);
+    if (!dest->codec->priv_class || !dest->codec->priv_data_size)
+        return 0;
+    if (!dest->priv_data) {
+        dest->priv_data = av_mallocz(dest->codec->priv_data_size);
+        if (!dest->priv_data)
+            return AVERROR(ENOMEM);
+        *(const AVClass**)dest->priv_data = dest->codec->priv_class;
+    }
+    av_opt_set_defaults(dest->priv_data);
+    if (av_set_options_string(dest->priv_data, configuration, "=", ",") < 0) {
+        av_log(dest, AV_LOG_WARNING, "Cannot copy private codec options. Using defaults.\n");
+        av_opt_set_defaults(dest->priv_data);
+    }
+    return 0;
+}
+
 static int read_ffserver_streams(OptionsContext *o, AVFormatContext *s, const char *filename)
 {
     int i, err;
@@ -1624,35 +1656,28 @@ static int read_ffserver_streams(OptionsContext *o, AVFormatContext *s, const ch
         AVStream *st;
         OutputStream *ost;
         AVCodec *codec;
-        AVCodecContext *avctx;
 
         codec = avcodec_find_encoder(ic->streams[i]->codec->codec_id);
         if (!codec) {
             av_log(s, AV_LOG_ERROR, "no encoder found for codec id %i\n", ic->streams[i]->codec->codec_id);
             return AVERROR(EINVAL);
         }
+        if (codec->type == AVMEDIA_TYPE_AUDIO)
+            opt_audio_codec(o, "c:a", codec->name);
+        else if (codec->type == AVMEDIA_TYPE_VIDEO)
+            opt_video_codec(o, "c:v", codec->name);
         ost   = new_output_stream(o, s, codec->type, -1);
         st    = ost->st;
-        avctx = st->codec;
-        ost->enc = codec;
 
-        // FIXME: a more elegant solution is needed
-        memcpy(st, ic->streams[i], sizeof(AVStream));
-        st->cur_dts = 0;
-        st->info = av_malloc(sizeof(*st->info));
-        memcpy(st->info, ic->streams[i]->info, sizeof(*st->info));
-        st->codec= avctx;
-        avcodec_copy_context(st->codec, ic->streams[i]->codec);
+        ffserver_streams_copy_context(st->codec, ic->streams[i]->codec,
+                                      av_stream_get_recommended_encoder_configuration(ic->streams[i]));
 
         if (st->codec->codec_type == AVMEDIA_TYPE_AUDIO && !ost->stream_copy)
             choose_sample_fmt(st, codec);
         else if (st->codec->codec_type == AVMEDIA_TYPE_VIDEO && !ost->stream_copy)
             choose_pixel_fmt(st, st->codec, codec, st->codec->pix_fmt);
-        avcodec_copy_context(ost->enc_ctx, st->codec);
-        if (ost->enc_ctx->priv_data) {
-            av_opt_free(ost->enc_ctx->priv_data);
-            av_freep(&ost->enc_ctx->priv_data);
-        }
+        ffserver_streams_copy_context(ost->enc_ctx, st->codec,
+                                      av_stream_get_recommended_encoder_configuration(ic->streams[i]));
     }
 
     avformat_close_input(&ic);