Originally committed as revision 25266 to svn://svn.ffmpeg.org/ffmpeg/trunk
| ... | ... |
@@ -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); |