X-Git-Url: https://git.piment-noir.org/?p=deb_ffmpeg.git;a=blobdiff_plain;f=ffmpeg%2Fffmpeg_opt.c;h=1f281f605a1e3e7f026610bfbdd56be6aa882b70;hp=05ab652f1a3dd628f6d7830f7339c6eb50c5fcb9;hb=f6fa7814ccfe3e76514b36cf04f5cd3cb657c8cf;hpb=2ba45a602cbfa7b771effba9b11bb4245c21bc00 diff --git a/ffmpeg/ffmpeg_opt.c b/ffmpeg/ffmpeg_opt.c index 05ab652..1f281f6 100644 --- a/ffmpeg/ffmpeg_opt.c +++ b/ffmpeg/ffmpeg_opt.c @@ -91,6 +91,7 @@ int do_benchmark_all = 0; int do_hex_dump = 0; int do_pkt_dump = 0; int copy_ts = 0; +int start_at_zero = 0; int copy_tb = -1; int debug_ts = 0; int exit_on_error = 0; @@ -508,7 +509,8 @@ static int opt_recording_timestamp(void *optctx, const char *opt, const char *ar char buf[128]; int64_t recording_timestamp = parse_time_or_die(opt, arg, 0) / 1E6; struct tm time = *gmtime((time_t*)&recording_timestamp); - strftime(buf, sizeof(buf), "creation_time=%FT%T%z", &time); + if (!strftime(buf, sizeof(buf), "creation_time=%FT%T%z", &time)) + return -1; parse_option(o, "metadata", buf, options); av_log(NULL, AV_LOG_WARNING, "%s is deprecated, set the 'creation_time' metadata " @@ -702,7 +704,7 @@ static void add_input_streams(OptionsContext *o, AVFormatContext *ic) MATCH_PER_STREAM_OPT(fix_sub_duration, i, ist->fix_sub_duration, ic, st); MATCH_PER_STREAM_OPT(canvas_sizes, str, canvas_size, ic, st); if (canvas_size && - av_parse_video_size(&dec->width, &dec->height, canvas_size) < 0) { + av_parse_video_size(&ist->dec_ctx->width, &ist->dec_ctx->height, canvas_size) < 0) { av_log(NULL, AV_LOG_FATAL, "Invalid canvas size: %s.\n", canvas_size); exit_program(1); } @@ -792,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))) { @@ -862,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); @@ -921,7 +930,7 @@ static int open_input_file(OptionsContext *o, const char *filename) f->start_time = o->start_time; f->recording_time = o->recording_time; f->input_ts_offset = o->input_ts_offset; - f->ts_offset = o->input_ts_offset - (copy_ts ? 0 : timestamp); + f->ts_offset = o->input_ts_offset - (copy_ts ? (start_at_zero && ic->start_time != AV_NOPTS_VALUE ? ic->start_time : 0) : timestamp); f->nb_streams = ic->nb_streams; f->rate_emu = o->rate_emu; f->accurate_seek = o->accurate_seek; @@ -1129,8 +1138,11 @@ static OutputStream *new_output_stream(OptionsContext *o, AVFormatContext *oc, e MATCH_PER_STREAM_OPT(bitstream_filters, str, bsf, oc, st); while (bsf) { + char *arg = NULL; if (next = strchr(bsf, ',')) *next++ = 0; + if (arg = strchr(bsf, '=')) + *arg++ = 0; if (!(bsfc = av_bitstream_filter_init(bsf))) { av_log(NULL, AV_LOG_FATAL, "Unknown bitstream filter %s\n", bsf); exit_program(1); @@ -1139,6 +1151,7 @@ static OutputStream *new_output_stream(OptionsContext *o, AVFormatContext *oc, e bsfc_prev->next = bsfc; else ost->bitstream_filters = bsfc; + av_dict_set(&ost->bsf_args, bsfc->filter->name, arg, 0); bsfc_prev = bsfc; bsf = next; @@ -1276,6 +1289,8 @@ static OutputStream *new_video_stream(OptionsContext *o, AVFormatContext *oc, in av_log(NULL, AV_LOG_FATAL, "Invalid framerate value: %s\n", frame_rate); exit_program(1); } + if (frame_rate && video_sync_method == VSYNC_PASSTHROUGH) + av_log(NULL, AV_LOG_ERROR, "Using -vsync 0 and -r can produce invalid output files\n"); MATCH_PER_STREAM_OPT(frame_aspect_ratios, str, frame_aspect_ratio, oc, st); if (frame_aspect_ratio) { @@ -1620,27 +1635,36 @@ static int read_ffserver_streams(OptionsContext *o, AVFormatContext *s, const ch AVStream *st; OutputStream *ost; AVCodec *codec; - AVCodecContext *avctx; + const char *enc_config; 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); + avcodec_get_context_defaults3(st->codec, codec); + enc_config = av_stream_get_recommended_encoder_configuration(ic->streams[i]); + if (enc_config) { + AVDictionary *opts = NULL; + av_dict_parse_string(&opts, enc_config, "=", ",", 0); + av_opt_set_dict2(st->codec, &opts, AV_OPT_SEARCH_CHILDREN); + av_dict_free(&opts); + } 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 (enc_config) + av_dict_parse_string(&ost->encoder_opts, enc_config, "=", ",", 0); } avformat_close_input(&ic); @@ -1728,8 +1752,8 @@ static int open_output_file(OptionsContext *o, const char *filename) if (o->stop_time != INT64_MAX && o->recording_time == INT64_MAX) { int64_t start_time = o->start_time == AV_NOPTS_VALUE ? 0 : o->start_time; if (o->stop_time <= start_time) { - av_log(NULL, AV_LOG_WARNING, "-to value smaller than -ss; ignoring -to.\n"); - o->stop_time = INT64_MAX; + av_log(NULL, AV_LOG_ERROR, "-to value smaller than -ss; aborting.\n"); + exit_program(1); } else { o->recording_time = o->stop_time - start_time; } @@ -2807,7 +2831,7 @@ const OptionDef options[] = { "add metadata", "string=string" }, { "dframes", HAS_ARG | OPT_PERFILE | OPT_EXPERT | OPT_OUTPUT, { .func_arg = opt_data_frames }, - "set the number of data frames to record", "number" }, + "set the number of data frames to output", "number" }, { "benchmark", OPT_BOOL | OPT_EXPERT, { &do_benchmark }, "add timings for benchmarking" }, { "benchmark_all", OPT_BOOL | OPT_EXPERT, { &do_benchmark_all }, @@ -2836,6 +2860,8 @@ const OptionDef options[] = { "audio drift threshold", "threshold" }, { "copyts", OPT_BOOL | OPT_EXPERT, { ©_ts }, "copy timestamps" }, + { "start_at_zero", OPT_BOOL | OPT_EXPERT, { &start_at_zero }, + "shift input timestamps to start at 0 when using copyts" }, { "copytb", HAS_ARG | OPT_INT | OPT_EXPERT, { ©_tb }, "copy input stream time base when stream copying", "mode" }, { "shortest", OPT_BOOL | OPT_EXPERT | OPT_OFFSET | @@ -2856,7 +2882,7 @@ const OptionDef options[] = { { "copypriorss", OPT_INT | HAS_ARG | OPT_EXPERT | OPT_SPEC | OPT_OUTPUT, { .off = OFFSET(copy_prior_start) }, "copy or discard frames before start time" }, { "frames", OPT_INT64 | HAS_ARG | OPT_SPEC | OPT_OUTPUT, { .off = OFFSET(max_frames) }, - "set the number of frames to record", "number" }, + "set the number of frames to output", "number" }, { "tag", OPT_STRING | HAS_ARG | OPT_SPEC | OPT_EXPERT | OPT_OUTPUT | OPT_INPUT, { .off = OFFSET(codec_tags) }, "force codec tag/fourcc", "fourcc/tag" }, @@ -2898,7 +2924,7 @@ const OptionDef options[] = { /* video options */ { "vframes", OPT_VIDEO | HAS_ARG | OPT_PERFILE | OPT_OUTPUT, { .func_arg = opt_video_frames }, - "set the number of video frames to record", "number" }, + "set the number of video frames to output", "number" }, { "r", OPT_VIDEO | HAS_ARG | OPT_STRING | OPT_SPEC | OPT_INPUT | OPT_OUTPUT, { .off = OFFSET(frame_rates) }, "set frame rate (Hz value, fraction or abbreviation)", "rate" }, @@ -2980,10 +3006,13 @@ const OptionDef options[] = { { "hwaccel_device", OPT_VIDEO | OPT_STRING | HAS_ARG | OPT_EXPERT | OPT_SPEC | OPT_INPUT, { .off = OFFSET(hwaccel_devices) }, "select a device for HW acceleration" "devicename" }, +#if HAVE_VDPAU_X11 + { "vdpau_api_ver", HAS_ARG | OPT_INT | OPT_EXPERT, { &vdpau_api_ver }, "" }, +#endif /* audio options */ { "aframes", OPT_AUDIO | HAS_ARG | OPT_PERFILE | OPT_OUTPUT, { .func_arg = opt_audio_frames }, - "set the number of audio frames to record", "number" }, + "set the number of audio frames to output", "number" }, { "aq", OPT_AUDIO | HAS_ARG | OPT_PERFILE | OPT_OUTPUT, { .func_arg = opt_audio_qscale }, "set audio quality (codec-specific)", "quality", }, { "ar", OPT_AUDIO | HAS_ARG | OPT_INT | OPT_SPEC |