Browse code

User application side of Codec specific parameters.

Originally committed as revision 25266 to svn://svn.ffmpeg.org/ffmpeg/trunk

Michael Niedermayer authored on 2010/09/30 08:06:51
Showing 5 changed files
... ...
@@ -49,6 +49,7 @@
49 49
 #endif
50 50
 
51 51
 const char **opt_names;
52
+const char **opt_values;
52 53
 static int opt_name_count;
53 54
 AVCodecContext *avcodec_opts[AVMEDIA_TYPE_NB];
54 55
 AVFormatContext *avformat_opts;
... ...
@@ -220,15 +221,25 @@ int opt_default(const char *opt, const char *arg){
220 220
         exit(1);
221 221
     }
222 222
     if (!o) {
223
+        AVCodec *p = NULL;
224
+        while ((p=av_codec_next(p))){
225
+            AVClass *c= p->priv_class;
226
+            if(c && av_find_opt(&c, opt, NULL, 0, 0))
227
+                break;
228
+        }
229
+        if(!p){
223 230
         fprintf(stderr, "Unrecognized option '%s'\n", opt);
224 231
         exit(1);
232
+        }
225 233
     }
226 234
 
227 235
 //    av_log(NULL, AV_LOG_ERROR, "%s:%s: %f 0x%0X\n", opt, arg, av_get_double(avcodec_opts, opt, NULL), (int)av_get_int(avcodec_opts, opt, NULL));
228 236
 
229 237
     //FIXME we should always use avcodec_opts, ... for storing options so there will not be any need to keep track of what i set over this
238
+    opt_values= av_realloc(opt_values, sizeof(void*)*(opt_name_count+1));
239
+    opt_values[opt_name_count]= o ? NULL : arg;
230 240
     opt_names= av_realloc(opt_names, sizeof(void*)*(opt_name_count+1));
231
-    opt_names[opt_name_count++]= o->name;
241
+    opt_names[opt_name_count++]= o ? o->name : opt;
232 242
 
233 243
     if ((*avcodec_opts && avcodec_opts[0]->debug) || (avformat_opts && avformat_opts->debug))
234 244
         av_log_set_level(AV_LOG_DEBUG);
... ...
@@ -283,9 +294,16 @@ int opt_timelimit(const char *opt, const char *arg)
283 283
     return 0;
284 284
 }
285 285
 
286
-void set_context_opts(void *ctx, void *opts_ctx, int flags)
286
+void set_context_opts(void *ctx, void *opts_ctx, int flags, AVCodec *codec)
287 287
 {
288 288
     int i;
289
+    void *priv_ctx=NULL;
290
+    if(!strcmp("AVCodecContext", (*(AVClass**)ctx)->class_name)){
291
+        AVCodecContext *avctx= ctx;
292
+        if(codec && codec->priv_class && avctx->priv_data){
293
+            priv_ctx= avctx->priv_data;
294
+        }
295
+    }
289 296
     for(i=0; i<opt_name_count; i++){
290 297
         char buf[256];
291 298
         const AVOption *opt;
... ...
@@ -293,6 +311,12 @@ void set_context_opts(void *ctx, void *opts_ctx, int flags)
293 293
         /* if an option with name opt_names[i] is present in opts_ctx then str is non-NULL */
294 294
         if(str && ((opt->flags & flags) == flags))
295 295
             av_set_string3(ctx, opt_names[i], str, 1, NULL);
296
+        /* We need to use a differnt system to pass options to the private context because
297
+           it is not known which codec and thus context kind that will be when parsing options
298
+           we thus use opt_values directly instead of opts_ctx */
299
+        if(!str && priv_ctx && av_get_string(priv_ctx, opt_names[i], &opt, buf, sizeof(buf))){
300
+            av_set_string3(priv_ctx, opt_names[i], opt_values[i], 1, NULL);
301
+        }
296 302
     }
297 303
 }
298 304
 
... ...
@@ -138,7 +138,7 @@ void show_help_options(const OptionDef *options, const char *msg, int mask, int
138 138
 void parse_options(int argc, char **argv, const OptionDef *options,
139 139
                    void (* parse_arg_function)(const char*));
140 140
 
141
-void set_context_opts(void *ctx, void *opts_ctx, int flags);
141
+void set_context_opts(void *ctx, void *opts_ctx, int flags, AVCodec *codec);
142 142
 
143 143
 /**
144 144
  * Print an error message to stderr, indicating filename and a human
... ...
@@ -3155,7 +3155,7 @@ static void opt_input_file(const char *filename)
3155 3155
     ap->channel = video_channel;
3156 3156
     ap->standard = video_standard;
3157 3157
 
3158
-    set_context_opts(ic, avformat_opts, AV_OPT_FLAG_DECODING_PARAM);
3158
+    set_context_opts(ic, avformat_opts, AV_OPT_FLAG_DECODING_PARAM, NULL);
3159 3159
 
3160 3160
     ic->video_codec_id   =
3161 3161
         find_codec_or_die(video_codec_name   , AVMEDIA_TYPE_VIDEO   , 0,
... ...
@@ -3235,13 +3235,13 @@ static void opt_input_file(const char *filename)
3235 3235
         avcodec_thread_init(dec, thread_count);
3236 3236
         switch (dec->codec_type) {
3237 3237
         case AVMEDIA_TYPE_AUDIO:
3238
-            set_context_opts(dec, avcodec_opts[AVMEDIA_TYPE_AUDIO], AV_OPT_FLAG_AUDIO_PARAM | AV_OPT_FLAG_DECODING_PARAM);
3238
+            input_codecs[nb_icodecs++] = avcodec_find_decoder_by_name(audio_codec_name);
3239
+            set_context_opts(dec, avcodec_opts[AVMEDIA_TYPE_AUDIO], AV_OPT_FLAG_AUDIO_PARAM | AV_OPT_FLAG_DECODING_PARAM, input_codecs[nb_icodecs-1]);
3239 3240
             //fprintf(stderr, "\nInput Audio channels: %d", dec->channels);
3240 3241
             channel_layout    = dec->channel_layout;
3241 3242
             audio_channels    = dec->channels;
3242 3243
             audio_sample_rate = dec->sample_rate;
3243 3244
             audio_sample_fmt  = dec->sample_fmt;
3244
-            input_codecs[nb_icodecs++] = avcodec_find_decoder_by_name(audio_codec_name);
3245 3245
             if(audio_disable)
3246 3246
                 st->discard= AVDISCARD_ALL;
3247 3247
             /* Note that av_find_stream_info can add more streams, and we
... ...
@@ -3251,7 +3251,8 @@ static void opt_input_file(const char *filename)
3251 3251
                 audio_sample_rate >>= dec->lowres;
3252 3252
             break;
3253 3253
         case AVMEDIA_TYPE_VIDEO:
3254
-            set_context_opts(dec, avcodec_opts[AVMEDIA_TYPE_VIDEO], AV_OPT_FLAG_VIDEO_PARAM | AV_OPT_FLAG_DECODING_PARAM);
3254
+            input_codecs[nb_icodecs++] = avcodec_find_decoder_by_name(video_codec_name);
3255
+            set_context_opts(dec, avcodec_opts[AVMEDIA_TYPE_VIDEO], AV_OPT_FLAG_VIDEO_PARAM | AV_OPT_FLAG_DECODING_PARAM, input_codecs[nb_icodecs-1]);
3255 3256
             frame_height = dec->height;
3256 3257
             frame_width  = dec->width;
3257 3258
             if(ic->streams[i]->sample_aspect_ratio.num)
... ...
@@ -3282,7 +3283,6 @@ static void opt_input_file(const char *filename)
3282 3282
             frame_rate.num = rfps;
3283 3283
             frame_rate.den = rfps_base;
3284 3284
 
3285
-            input_codecs[nb_icodecs++] = avcodec_find_decoder_by_name(video_codec_name);
3286 3285
             if(video_disable)
3287 3286
                 st->discard= AVDISCARD_ALL;
3288 3287
             else if(video_discard)
... ...
@@ -3361,13 +3361,27 @@ static void new_video_stream(AVFormatContext *oc)
3361 3361
     AVStream *st;
3362 3362
     AVCodecContext *video_enc;
3363 3363
     enum CodecID codec_id;
3364
+    AVCodec *codec= NULL;
3364 3365
 
3365 3366
     st = av_new_stream(oc, streamid_map[oc->nb_streams]);
3366 3367
     if (!st) {
3367 3368
         fprintf(stderr, "Could not alloc stream\n");
3368 3369
         ffmpeg_exit(1);
3369 3370
     }
3370
-    avcodec_get_context_defaults2(st->codec, AVMEDIA_TYPE_VIDEO);
3371
+
3372
+    if(!video_stream_copy){
3373
+        if (video_codec_name) {
3374
+            codec_id = find_codec_or_die(video_codec_name, AVMEDIA_TYPE_VIDEO, 1,
3375
+                                         avcodec_opts[AVMEDIA_TYPE_VIDEO]->strict_std_compliance);
3376
+            codec = avcodec_find_encoder_by_name(video_codec_name);
3377
+            output_codecs[nb_ocodecs] = codec;
3378
+        } else {
3379
+            codec_id = av_guess_codec(oc->oformat, NULL, oc->filename, NULL, AVMEDIA_TYPE_VIDEO);
3380
+            codec = avcodec_find_encoder(codec_id);
3381
+        }
3382
+    }
3383
+
3384
+    avcodec_get_context_defaults3(st->codec, codec);
3371 3385
     bitstream_filters[nb_output_files][oc->nb_streams - 1]= video_bitstream_filters;
3372 3386
     video_bitstream_filters= NULL;
3373 3387
 
... ...
@@ -3396,22 +3410,10 @@ static void new_video_stream(AVFormatContext *oc)
3396 3396
     } else {
3397 3397
         const char *p;
3398 3398
         int i;
3399
-        AVCodec *codec;
3400 3399
         AVRational fps= frame_rate.num ? frame_rate : (AVRational){25,1};
3401 3400
 
3402
-        if (video_codec_name) {
3403
-            codec_id = find_codec_or_die(video_codec_name, AVMEDIA_TYPE_VIDEO, 1,
3404
-                                         avcodec_opts[AVMEDIA_TYPE_VIDEO]->strict_std_compliance);
3405
-            codec = avcodec_find_encoder_by_name(video_codec_name);
3406
-            output_codecs[nb_ocodecs] = codec;
3407
-        } else {
3408
-            codec_id = av_guess_codec(oc->oformat, NULL, oc->filename, NULL, AVMEDIA_TYPE_VIDEO);
3409
-            codec = avcodec_find_encoder(codec_id);
3410
-        }
3411
-
3412 3401
         video_enc->codec_id = codec_id;
3413
-
3414
-        set_context_opts(video_enc, avcodec_opts[AVMEDIA_TYPE_VIDEO], AV_OPT_FLAG_VIDEO_PARAM | AV_OPT_FLAG_ENCODING_PARAM);
3402
+        set_context_opts(video_enc, avcodec_opts[AVMEDIA_TYPE_VIDEO], AV_OPT_FLAG_VIDEO_PARAM | AV_OPT_FLAG_ENCODING_PARAM, codec);
3415 3403
 
3416 3404
         if (codec && codec->supported_framerates && !force_fps)
3417 3405
             fps = codec->supported_framerates[av_find_nearest_q_idx(fps, codec->supported_framerates)];
... ...
@@ -3497,6 +3499,7 @@ static void new_video_stream(AVFormatContext *oc)
3497 3497
 static void new_audio_stream(AVFormatContext *oc)
3498 3498
 {
3499 3499
     AVStream *st;
3500
+    AVCodec *codec= NULL;
3500 3501
     AVCodecContext *audio_enc;
3501 3502
     enum CodecID codec_id;
3502 3503
 
... ...
@@ -3505,7 +3508,20 @@ static void new_audio_stream(AVFormatContext *oc)
3505 3505
         fprintf(stderr, "Could not alloc stream\n");
3506 3506
         ffmpeg_exit(1);
3507 3507
     }
3508
-    avcodec_get_context_defaults2(st->codec, AVMEDIA_TYPE_AUDIO);
3508
+
3509
+    if(!audio_stream_copy){
3510
+        if (audio_codec_name) {
3511
+            codec_id = find_codec_or_die(audio_codec_name, AVMEDIA_TYPE_AUDIO, 1,
3512
+                                         avcodec_opts[AVMEDIA_TYPE_AUDIO]->strict_std_compliance);
3513
+            codec = avcodec_find_encoder_by_name(audio_codec_name);
3514
+            output_codecs[nb_ocodecs] = codec;
3515
+        } else {
3516
+            codec_id = av_guess_codec(oc->oformat, NULL, oc->filename, NULL, AVMEDIA_TYPE_AUDIO);
3517
+            codec = avcodec_find_encoder(codec_id);
3518
+        }
3519
+    }
3520
+
3521
+    avcodec_get_context_defaults3(st->codec, codec);
3509 3522
 
3510 3523
     bitstream_filters[nb_output_files][oc->nb_streams - 1]= audio_bitstream_filters;
3511 3524
     audio_bitstream_filters= NULL;
... ...
@@ -3527,20 +3543,8 @@ static void new_audio_stream(AVFormatContext *oc)
3527 3527
         audio_enc->channels = audio_channels;
3528 3528
         audio_enc->sample_rate = audio_sample_rate;
3529 3529
     } else {
3530
-        AVCodec *codec;
3531
-
3532
-        set_context_opts(audio_enc, avcodec_opts[AVMEDIA_TYPE_AUDIO], AV_OPT_FLAG_AUDIO_PARAM | AV_OPT_FLAG_ENCODING_PARAM);
3533
-
3534
-        if (audio_codec_name) {
3535
-            codec_id = find_codec_or_die(audio_codec_name, AVMEDIA_TYPE_AUDIO, 1,
3536
-                                         avcodec_opts[AVMEDIA_TYPE_AUDIO]->strict_std_compliance);
3537
-            codec = avcodec_find_encoder_by_name(audio_codec_name);
3538
-            output_codecs[nb_ocodecs] = codec;
3539
-        } else {
3540
-            codec_id = av_guess_codec(oc->oformat, NULL, oc->filename, NULL, AVMEDIA_TYPE_AUDIO);
3541
-            codec = avcodec_find_encoder(codec_id);
3542
-        }
3543 3530
         audio_enc->codec_id = codec_id;
3531
+        set_context_opts(audio_enc, avcodec_opts[AVMEDIA_TYPE_AUDIO], AV_OPT_FLAG_AUDIO_PARAM | AV_OPT_FLAG_ENCODING_PARAM, codec);
3544 3532
 
3545 3533
         if (audio_qscale > QSCALE_NONE) {
3546 3534
             audio_enc->flags |= CODEC_FLAG_QSCALE;
... ...
@@ -3571,6 +3575,7 @@ static void new_audio_stream(AVFormatContext *oc)
3571 3571
 static void new_subtitle_stream(AVFormatContext *oc)
3572 3572
 {
3573 3573
     AVStream *st;
3574
+    AVCodec *codec=NULL;
3574 3575
     AVCodecContext *subtitle_enc;
3575 3576
 
3576 3577
     st = av_new_stream(oc, streamid_map[oc->nb_streams]);
... ...
@@ -3578,12 +3583,17 @@ static void new_subtitle_stream(AVFormatContext *oc)
3578 3578
         fprintf(stderr, "Could not alloc stream\n");
3579 3579
         ffmpeg_exit(1);
3580 3580
     }
3581
-    avcodec_get_context_defaults2(st->codec, AVMEDIA_TYPE_SUBTITLE);
3581
+    subtitle_enc = st->codec;
3582
+    if(!subtitle_stream_copy){
3583
+        subtitle_enc->codec_id = find_codec_or_die(subtitle_codec_name, AVMEDIA_TYPE_SUBTITLE, 1,
3584
+                                                   avcodec_opts[AVMEDIA_TYPE_SUBTITLE]->strict_std_compliance);
3585
+        codec= output_codecs[nb_ocodecs] = avcodec_find_encoder_by_name(subtitle_codec_name);
3586
+    }
3587
+    avcodec_get_context_defaults3(st->codec, codec);
3582 3588
 
3583 3589
     bitstream_filters[nb_output_files][oc->nb_streams - 1]= subtitle_bitstream_filters;
3584 3590
     subtitle_bitstream_filters= NULL;
3585 3591
 
3586
-    subtitle_enc = st->codec;
3587 3592
     subtitle_enc->codec_type = AVMEDIA_TYPE_SUBTITLE;
3588 3593
 
3589 3594
     if(subtitle_codec_tag)
... ...
@@ -3592,10 +3602,7 @@ static void new_subtitle_stream(AVFormatContext *oc)
3592 3592
     if (subtitle_stream_copy) {
3593 3593
         st->stream_copy = 1;
3594 3594
     } else {
3595
-        set_context_opts(avcodec_opts[AVMEDIA_TYPE_SUBTITLE], subtitle_enc, AV_OPT_FLAG_SUBTITLE_PARAM | AV_OPT_FLAG_ENCODING_PARAM);
3596
-        subtitle_enc->codec_id = find_codec_or_die(subtitle_codec_name, AVMEDIA_TYPE_SUBTITLE, 1,
3597
-                                                   avcodec_opts[AVMEDIA_TYPE_SUBTITLE]->strict_std_compliance);
3598
-        output_codecs[nb_ocodecs] = avcodec_find_encoder_by_name(subtitle_codec_name);
3595
+        set_context_opts(avcodec_opts[AVMEDIA_TYPE_SUBTITLE], subtitle_enc, AV_OPT_FLAG_SUBTITLE_PARAM | AV_OPT_FLAG_ENCODING_PARAM, codec);
3599 3596
     }
3600 3597
     nb_ocodecs++;
3601 3598
 
... ...
@@ -3791,7 +3798,7 @@ static void opt_output_file(const char *filename)
3791 3791
     oc->loop_output = loop_output;
3792 3792
     oc->flags |= AVFMT_FLAG_NONBLOCK;
3793 3793
 
3794
-    set_context_opts(oc, avformat_opts, AV_OPT_FLAG_ENCODING_PARAM);
3794
+    set_context_opts(oc, avformat_opts, AV_OPT_FLAG_ENCODING_PARAM, NULL);
3795 3795
 
3796 3796
     memset(streamid_map, 0, sizeof(streamid_map));
3797 3797
 }
... ...
@@ -2280,7 +2280,7 @@ static int stream_component_open(VideoState *is, int stream_index)
2280 2280
     avctx->error_concealment= error_concealment;
2281 2281
     avcodec_thread_init(avctx, thread_count);
2282 2282
 
2283
-    set_context_opts(avctx, avcodec_opts[avctx->codec_type], 0);
2283
+    set_context_opts(avctx, avcodec_opts[avctx->codec_type], 0, codec);
2284 2284
 
2285 2285
     if (!codec ||
2286 2286
         avcodec_open(avctx, codec) < 0)
... ...
@@ -2458,7 +2458,7 @@ static int decode_thread(void *arg)
2458 2458
     ap->time_base= (AVRational){1, 25};
2459 2459
     ap->pix_fmt = frame_pix_fmt;
2460 2460
 
2461
-    set_context_opts(ic, avformat_opts, AV_OPT_FLAG_DECODING_PARAM);
2461
+    set_context_opts(ic, avformat_opts, AV_OPT_FLAG_DECODING_PARAM, NULL);
2462 2462
 
2463 2463
     err = av_open_input_file(&ic, is->filename, is->iformat, 0, ap);
2464 2464
     if (err < 0) {
... ...
@@ -269,7 +269,7 @@ static int open_input_file(AVFormatContext **fmt_ctx_ptr, const char *filename)
269 269
     AVFormatContext *fmt_ctx;
270 270
 
271 271
     fmt_ctx = avformat_alloc_context();
272
-    set_context_opts(fmt_ctx, avformat_opts, AV_OPT_FLAG_DECODING_PARAM);
272
+    set_context_opts(fmt_ctx, avformat_opts, AV_OPT_FLAG_DECODING_PARAM, NULL);
273 273
 
274 274
     if ((err = av_open_input_file(&fmt_ctx, filename, iformat, 0, NULL)) < 0) {
275 275
         print_error(filename, err);