X-Git-Url: https://git.sesse.net/?a=blobdiff_plain;f=ffmpeg_opt.c;h=8edc98865c7757ec364088d61505099e61036d5a;hb=a0124b89e393812ff273ffc2f7e0f044c66a287c;hp=a8ee1c328e2ad049721f7da95c87a598091c11d9;hpb=0ba65c9f795a1d3ad842f6d3179472e35c73541c;p=ffmpeg diff --git a/ffmpeg_opt.c b/ffmpeg_opt.c index a8ee1c328e2..8edc98865c7 100644 --- a/ffmpeg_opt.c +++ b/ffmpeg_opt.c @@ -111,6 +111,8 @@ static int do_psnr = 0; static int input_sync; static int override_ffserver = 0; static int input_stream_potentially_available = 0; +static int ignore_unknown_streams = 0; +static int copy_unknown_streams = 0; static void uninit_options(OptionsContext *o) { @@ -927,7 +929,20 @@ static int open_input_file(OptionsContext *o, const char *filename) /* if seeking requested, we execute it */ if (o->start_time != AV_NOPTS_VALUE) { - ret = avformat_seek_file(ic, -1, INT64_MIN, timestamp, timestamp, 0); + int64_t seek_timestamp = timestamp; + + if (!(ic->iformat->flags & AVFMT_SEEK_TO_PTS)) { + int dts_heuristic = 0; + for (i=0; inb_streams; i++) { + AVCodecContext *avctx = ic->streams[i]->codec; + if (avctx->has_b_frames) + dts_heuristic = 1; + } + if (dts_heuristic) { + seek_timestamp -= 3*AV_TIME_BASE / 23; + } + } + ret = avformat_seek_file(ic, -1, INT64_MIN, seek_timestamp, seek_timestamp, 0); if (ret < 0) { av_log(NULL, AV_LOG_WARNING, "%s: could not seek to position %0.3f\n", filename, (double)timestamp / AV_TIME_BASE); @@ -1552,6 +1567,19 @@ static OutputStream *new_data_stream(OptionsContext *o, AVFormatContext *oc, int return ost; } +static OutputStream *new_unknown_stream(OptionsContext *o, AVFormatContext *oc, int source_index) +{ + OutputStream *ost; + + ost = new_output_stream(o, oc, AVMEDIA_TYPE_UNKNOWN, source_index); + if (!ost->stream_copy) { + av_log(NULL, AV_LOG_FATAL, "Unknown stream encoding not supported yet (only streamcopy)\n"); + exit_program(1); + } + + return ost; +} + static OutputStream *new_attachment_stream(OptionsContext *o, AVFormatContext *oc, int source_index) { OutputStream *ost = new_output_stream(o, oc, AVMEDIA_TYPE_ATTACHMENT, source_index); @@ -2004,10 +2032,22 @@ loop_end: case AVMEDIA_TYPE_SUBTITLE: ost = new_subtitle_stream (o, oc, src_idx); break; case AVMEDIA_TYPE_DATA: ost = new_data_stream (o, oc, src_idx); break; case AVMEDIA_TYPE_ATTACHMENT: ost = new_attachment_stream(o, oc, src_idx); break; + case AVMEDIA_TYPE_UNKNOWN: + if (copy_unknown_streams) { + ost = new_unknown_stream (o, oc, src_idx); + break; + } default: - av_log(NULL, AV_LOG_FATAL, "Cannot map stream #%d:%d - unsupported type.\n", + av_log(NULL, ignore_unknown_streams ? AV_LOG_WARNING : AV_LOG_FATAL, + "Cannot map stream #%d:%d - unsupported type.\n", map->file_index, map->stream_index); - exit_program(1); + if (!ignore_unknown_streams) { + av_log(NULL, AV_LOG_FATAL, + "If you want unsupported types ignored instead " + "of failing, please use the -ignore_unknown option\n" + "If you want them copied, please use -copy_unknown\n"); + exit_program(1); + } } } } @@ -2209,8 +2249,12 @@ loop_end: parse_meta_type(o->metadata[i].specifier, &type, &index, &stream_spec); if (type == 's') { for (j = 0; j < oc->nb_streams; j++) { + ost = output_streams[nb_output_streams - oc->nb_streams + j]; if ((ret = check_stream_specifier(oc, oc->streams[j], stream_spec)) > 0) { av_dict_set(&oc->streams[j]->metadata, o->metadata[i].u.str, *val ? val : NULL, 0); + if (!strcmp(o->metadata[i].u.str, "rotate")) { + ost->rotate_overridden = 1; + } } else if (ret < 0) exit_program(1); } @@ -2838,6 +2882,10 @@ const OptionDef options[] = { "overwrite output files" }, { "n", OPT_BOOL, { &no_file_overwrite }, "never overwrite output files" }, + { "ignore_unknown", OPT_BOOL, { &ignore_unknown_streams }, + "Ignore unknown stream types" }, + { "copy_unknown", OPT_BOOL | OPT_EXPERT, { ©_unknown_streams }, + "Copy unknown stream types" }, { "c", HAS_ARG | OPT_STRING | OPT_SPEC | OPT_INPUT | OPT_OUTPUT, { .off = OFFSET(codec_names) }, "codec name", "codec" }, @@ -2883,7 +2931,7 @@ const OptionDef options[] = { { "itsscale", HAS_ARG | OPT_DOUBLE | OPT_SPEC | OPT_EXPERT | OPT_INPUT, { .off = OFFSET(ts_scale) }, "set the input ts scale", "scale" }, - { "timestamp", HAS_ARG | OPT_PERFILE, { .func_arg = opt_recording_timestamp }, + { "timestamp", HAS_ARG | OPT_PERFILE | OPT_OUTPUT, { .func_arg = opt_recording_timestamp }, "set the recording timestamp ('now' to set the current time)", "time" }, { "metadata", HAS_ARG | OPT_STRING | OPT_SPEC | OPT_OUTPUT, { .off = OFFSET(metadata) }, "add metadata", "string=string" },