Originally committed as revision 25266 to svn://svn.ffmpeg.org/ffmpeg/trunk
Michael Niedermayer authored on 2010/09/30 08:06:51... | ... |
@@ -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); |