static const char *const opt_name_audio_channels[] = {"ac", NULL};
static const char *const opt_name_audio_sample_rate[] = {"ar", NULL};
static const char *const opt_name_frame_rates[] = {"r", NULL};
+static const char *const opt_name_max_frame_rates[] = {"fpsmax", NULL};
static const char *const opt_name_frame_sizes[] = {"s", NULL};
static const char *const opt_name_frame_pix_fmts[] = {"pix_fmt", NULL};
static const char *const opt_name_ts_scale[] = {"itsscale", NULL};
return codec;
}
-static AVCodec *choose_decoder(OptionsContext *o, AVFormatContext *s, AVStream *st)
+static const AVCodec *choose_decoder(OptionsContext *o, AVFormatContext *s, AVStream *st)
{
char *codec_name = NULL;
MATCH_PER_STREAM_OPT(codec_names, str, codec_name, s, st);
if (codec_name) {
- AVCodec *codec = find_codec_or_die(codec_name, st->codecpar->codec_type, 0);
+ const AVCodec *codec = find_codec_or_die(codec_name, st->codecpar->codec_type, 0);
st->codecpar->codec_id = codec->id;
return codec;
} else
case AVMEDIA_TYPE_VIDEO:
if(!ist->dec)
ist->dec = avcodec_find_decoder(par->codec_id);
-#if FF_API_LOWRES
- if (st->codec->lowres) {
- ist->dec_ctx->lowres = st->codec->lowres;
- ist->dec_ctx->width = st->codec->width;
- ist->dec_ctx->height = st->codec->height;
- ist->dec_ctx->coded_width = st->codec->coded_width;
- ist->dec_ctx->coded_height = st->codec->coded_height;
- }
-#endif
// avformat_find_stream_info() doesn't set this for us anymore.
ist->dec_ctx->framerate = st->avg_frame_rate;
{
InputFile *f;
AVFormatContext *ic;
- AVInputFormat *file_iformat = NULL;
+ const AVInputFormat *file_iformat = NULL;
int err, i, ret;
int64_t timestamp;
AVDictionary *unused_opts = NULL;
av_dict_set_int(&o->g->format_opts, "sample_rate", o->audio_sample_rate[o->nb_audio_sample_rate - 1].u.i, 0);
}
if (o->nb_audio_channels) {
+ const AVClass *priv_class;
/* because we set audio_channels based on both the "ac" and
* "channel_layout" options, we need to check that the specified
* demuxer actually has the "channels" option before setting it */
- if (file_iformat && file_iformat->priv_class &&
- av_opt_find(&file_iformat->priv_class, "channels", NULL, 0,
+ if (file_iformat && (priv_class = file_iformat->priv_class) &&
+ av_opt_find(&priv_class, "channels", NULL, 0,
AV_OPT_SEARCH_FAKE_OBJ)) {
av_dict_set_int(&o->g->format_opts, "channels", o->audio_channels[o->nb_audio_channels - 1].u.i, 0);
}
}
if (o->nb_frame_rates) {
+ const AVClass *priv_class;
/* set the format-level framerate option;
* this is important for video grabbers, e.g. x11 */
- if (file_iformat && file_iformat->priv_class &&
- av_opt_find(&file_iformat->priv_class, "framerate", NULL, 0,
+ if (file_iformat && (priv_class = file_iformat->priv_class) &&
+ av_opt_find(&priv_class, "framerate", NULL, 0,
AV_OPT_SEARCH_FAKE_OBJ)) {
av_dict_set(&o->g->format_opts, "framerate",
o->frame_rates[o->nb_frame_rates - 1].u.str, 0);
f->loop = o->loop;
f->duration = 0;
f->time_base = (AVRational){ 1, 1 };
+ f->pkt = av_packet_alloc();
+ if (!f->pkt)
+ exit_program(1);
#if HAVE_THREADS
f->thread_queue_size = o->thread_queue_size;
#endif
ost->max_muxing_queue_size = 128;
MATCH_PER_STREAM_OPT(max_muxing_queue_size, i, ost->max_muxing_queue_size, oc, st);
- ost->max_muxing_queue_size *= sizeof(AVPacket);
+ ost->max_muxing_queue_size *= sizeof(ost->pkt);
ost->muxing_queue_data_size = 0;
AVStream *st;
OutputStream *ost;
AVCodecContext *video_enc;
- char *frame_rate = NULL, *frame_aspect_ratio = NULL;
+ char *frame_rate = NULL, *max_frame_rate = NULL, *frame_aspect_ratio = NULL;
ost = new_output_stream(o, oc, AVMEDIA_TYPE_VIDEO, source_index);
st = ost->st;
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(max_frame_rates, str, max_frame_rate, oc, st);
+ if (max_frame_rate && av_parse_video_rate(&ost->max_frame_rate, max_frame_rate) < 0) {
+ av_log(NULL, AV_LOG_FATAL, "Invalid maximum framerate value: %s\n", max_frame_rate);
+ exit_program(1);
+ }
+
+ if (frame_rate && max_frame_rate) {
+ av_log(NULL, AV_LOG_ERROR, "Only one of -fpsmax and -r can be set for a stream.\n");
+ exit_program(1);
+ }
+
+ if ((frame_rate || max_frame_rate) &&
+ video_sync_method == VSYNC_PASSTHROUGH)
+ av_log(NULL, AV_LOG_ERROR, "Using -vsync 0 and -r/-fpsmax can produce invalid output files\n");
MATCH_PER_STREAM_OPT(frame_aspect_ratios, str, frame_aspect_ratio, oc, st);
if (frame_aspect_ratio) {
if(o->recording_time != INT64_MAX)
av_dict_set(&oc->metadata, "duration", NULL, 0);
av_dict_set(&oc->metadata, "creation_time", NULL, 0);
+ av_dict_set(&oc->metadata, "company_name", NULL, 0);
+ av_dict_set(&oc->metadata, "product_name", NULL, 0);
+ av_dict_set(&oc->metadata, "product_version", NULL, 0);
}
if (!o->metadata_streams_manual)
for (i = of->ost_index; i < nb_output_streams; i++) {
{ "debug_ts", OPT_BOOL | OPT_EXPERT, { &debug_ts },
"print timestamp debugging info" },
{ "max_error_rate", HAS_ARG | OPT_FLOAT, { &max_error_rate },
- "ratio of errors (0.0: no errors, 1.0: 100% errors) above which ffmpeg returns an error instead of success.", "maximum error rate" },
+ "ratio of decoding errors (0.0: no errors, 1.0: 100% errors) above which ffmpeg returns an error instead of success.", "maximum error rate" },
{ "discard", OPT_STRING | HAS_ARG | OPT_SPEC |
OPT_INPUT, { .off = OFFSET(discard) },
"discard", "" },
{ "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" },
+ { "fpsmax", OPT_VIDEO | HAS_ARG | OPT_STRING | OPT_SPEC |
+ OPT_OUTPUT, { .off = OFFSET(max_frame_rates) },
+ "set max frame rate (Hz value, fraction or abbreviation)", "rate" },
{ "s", OPT_VIDEO | HAS_ARG | OPT_SUBTITLE | OPT_STRING | OPT_SPEC |
OPT_INPUT | OPT_OUTPUT, { .off = OFFSET(frame_sizes) },
"set frame size (WxH or abbreviation)", "size" },