You've already forked FFmpeg
mirror of
https://github.com/FFmpeg/FFmpeg.git
synced 2025-07-16 22:42:38 +02:00
fftools/ffmpeg_filter: pass sws/swr opts through OutputFilterOptions
Do not read them from OutputStream directly. Will allow decoupling filtering from encoding in future commits.
This commit is contained in:
@ -265,6 +265,8 @@ typedef struct InputFilterOptions {
|
|||||||
|
|
||||||
enum OFilterFlags {
|
enum OFilterFlags {
|
||||||
OFILTER_FLAG_DISABLE_CONVERT = (1 << 0),
|
OFILTER_FLAG_DISABLE_CONVERT = (1 << 0),
|
||||||
|
// produce 24-bit audio
|
||||||
|
OFILTER_FLAG_AUDIO_24BIT = (1 << 1),
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef struct OutputFilterOptions {
|
typedef struct OutputFilterOptions {
|
||||||
@ -283,6 +285,9 @@ typedef struct OutputFilterOptions {
|
|||||||
*/
|
*/
|
||||||
AVRational output_tb;
|
AVRational output_tb;
|
||||||
|
|
||||||
|
AVDictionary *sws_opts;
|
||||||
|
AVDictionary *swr_opts;
|
||||||
|
|
||||||
// A combination of OFilterFlags.
|
// A combination of OFilterFlags.
|
||||||
unsigned flags;
|
unsigned flags;
|
||||||
|
|
||||||
@ -574,8 +579,6 @@ typedef struct OutputStream {
|
|||||||
OutputFilter *filter;
|
OutputFilter *filter;
|
||||||
|
|
||||||
AVDictionary *encoder_opts;
|
AVDictionary *encoder_opts;
|
||||||
AVDictionary *sws_dict;
|
|
||||||
AVDictionary *swr_opts;
|
|
||||||
char *apad;
|
char *apad;
|
||||||
|
|
||||||
char *attachment_filename;
|
char *attachment_filename;
|
||||||
|
@ -210,6 +210,9 @@ typedef struct OutputFilterPriv {
|
|||||||
|
|
||||||
AVRational sample_aspect_ratio;
|
AVRational sample_aspect_ratio;
|
||||||
|
|
||||||
|
AVDictionary *sws_opts;
|
||||||
|
AVDictionary *swr_opts;
|
||||||
|
|
||||||
// those are only set if no format is specified and the encoder gives us multiple options
|
// those are only set if no format is specified and the encoder gives us multiple options
|
||||||
// They point directly to the relevant lists of the encoder.
|
// They point directly to the relevant lists of the encoder.
|
||||||
const int *formats;
|
const int *formats;
|
||||||
@ -813,6 +816,17 @@ int ofilter_bind_ost(OutputFilter *ofilter, OutputStream *ost,
|
|||||||
if (!ofp->name)
|
if (!ofp->name)
|
||||||
return AVERROR(EINVAL);
|
return AVERROR(EINVAL);
|
||||||
|
|
||||||
|
ret = av_dict_copy(&ofp->sws_opts, opts->sws_opts, 0);
|
||||||
|
if (ret < 0)
|
||||||
|
return ret;
|
||||||
|
|
||||||
|
ret = av_dict_copy(&ofp->swr_opts, opts->swr_opts, 0);
|
||||||
|
if (ret < 0)
|
||||||
|
return ret;
|
||||||
|
|
||||||
|
if (opts->flags & OFILTER_FLAG_AUDIO_24BIT)
|
||||||
|
av_dict_set(&ofp->swr_opts, "output_sample_bits", "24", 0);
|
||||||
|
|
||||||
if (fgp->is_simple) {
|
if (fgp->is_simple) {
|
||||||
// for simple filtergraph there is just one output,
|
// for simple filtergraph there is just one output,
|
||||||
// so use only graph-level information for logging
|
// so use only graph-level information for logging
|
||||||
@ -945,6 +959,8 @@ void fg_free(FilterGraph **pfg)
|
|||||||
OutputFilterPriv *ofp = ofp_from_ofilter(ofilter);
|
OutputFilterPriv *ofp = ofp_from_ofilter(ofilter);
|
||||||
|
|
||||||
av_frame_free(&ofp->fps.last_frame);
|
av_frame_free(&ofp->fps.last_frame);
|
||||||
|
av_dict_free(&ofp->sws_opts);
|
||||||
|
av_dict_free(&ofp->swr_opts);
|
||||||
|
|
||||||
av_freep(&ofilter->linklabel);
|
av_freep(&ofilter->linklabel);
|
||||||
av_freep(&ofilter->name);
|
av_freep(&ofilter->name);
|
||||||
@ -1358,7 +1374,7 @@ static int configure_output_video_filter(FilterGraph *fg, AVFilterGraph *graph,
|
|||||||
snprintf(args, sizeof(args), "%d:%d",
|
snprintf(args, sizeof(args), "%d:%d",
|
||||||
ofp->width, ofp->height);
|
ofp->width, ofp->height);
|
||||||
|
|
||||||
while ((e = av_dict_iterate(ost->sws_dict, e))) {
|
while ((e = av_dict_iterate(ofp->sws_opts, e))) {
|
||||||
av_strlcatf(args, sizeof(args), ":%s=%s", e->key, e->value);
|
av_strlcatf(args, sizeof(args), ":%s=%s", e->key, e->value);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1725,6 +1741,7 @@ static int configure_filtergraph(FilterGraph *fg, FilterGraphThread *fgt)
|
|||||||
return AVERROR(ENOMEM);
|
return AVERROR(ENOMEM);
|
||||||
|
|
||||||
if (simple) {
|
if (simple) {
|
||||||
|
OutputFilterPriv *ofp = ofp_from_ofilter(fg->outputs[0]);
|
||||||
OutputStream *ost = fg->outputs[0]->ost;
|
OutputStream *ost = fg->outputs[0]->ost;
|
||||||
|
|
||||||
if (filter_nbthreads) {
|
if (filter_nbthreads) {
|
||||||
@ -1738,17 +1755,17 @@ static int configure_filtergraph(FilterGraph *fg, FilterGraphThread *fgt)
|
|||||||
av_opt_set(fgt->graph, "threads", e->value, 0);
|
av_opt_set(fgt->graph, "threads", e->value, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (av_dict_count(ost->sws_dict)) {
|
if (av_dict_count(ofp->sws_opts)) {
|
||||||
ret = av_dict_get_string(ost->sws_dict,
|
ret = av_dict_get_string(ofp->sws_opts,
|
||||||
&fgt->graph->scale_sws_opts,
|
&fgt->graph->scale_sws_opts,
|
||||||
'=', ':');
|
'=', ':');
|
||||||
if (ret < 0)
|
if (ret < 0)
|
||||||
goto fail;
|
goto fail;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (av_dict_count(ost->swr_opts)) {
|
if (av_dict_count(ofp->swr_opts)) {
|
||||||
char *args;
|
char *args;
|
||||||
ret = av_dict_get_string(ost->swr_opts, &args, '=', ':');
|
ret = av_dict_get_string(ofp->swr_opts, &args, '=', ':');
|
||||||
if (ret < 0)
|
if (ret < 0)
|
||||||
goto fail;
|
goto fail;
|
||||||
av_opt_set(fgt->graph, "aresample_swr_opts", args, 0);
|
av_opt_set(fgt->graph, "aresample_swr_opts", args, 0);
|
||||||
|
@ -819,9 +819,6 @@ static void ost_free(OutputStream **post)
|
|||||||
|
|
||||||
av_freep(&ost->attachment_filename);
|
av_freep(&ost->attachment_filename);
|
||||||
|
|
||||||
av_dict_free(&ost->sws_dict);
|
|
||||||
av_dict_free(&ost->swr_opts);
|
|
||||||
|
|
||||||
if (ost->enc_ctx)
|
if (ost->enc_ctx)
|
||||||
av_freep(&ost->enc_ctx->stats_in);
|
av_freep(&ost->enc_ctx->stats_in);
|
||||||
avcodec_free_context(&ost->enc_ctx);
|
avcodec_free_context(&ost->enc_ctx);
|
||||||
|
@ -1356,12 +1356,6 @@ static int ost_add(Muxer *mux, const OptionsContext *o, enum AVMediaType type,
|
|||||||
if (oc->oformat->flags & AVFMT_GLOBALHEADER && ost->enc_ctx)
|
if (oc->oformat->flags & AVFMT_GLOBALHEADER && ost->enc_ctx)
|
||||||
ost->enc_ctx->flags |= AV_CODEC_FLAG_GLOBAL_HEADER;
|
ost->enc_ctx->flags |= AV_CODEC_FLAG_GLOBAL_HEADER;
|
||||||
|
|
||||||
av_dict_copy(&ost->sws_dict, o->g->sws_dict, 0);
|
|
||||||
|
|
||||||
av_dict_copy(&ost->swr_opts, o->g->swr_opts, 0);
|
|
||||||
if (ost->enc_ctx && av_get_exact_bits_per_sample(ost->enc_ctx->codec_id) == 24)
|
|
||||||
av_dict_set(&ost->swr_opts, "output_sample_bits", "24", 0);
|
|
||||||
|
|
||||||
MATCH_PER_STREAM_OPT(copy_initial_nonkeyframes, i,
|
MATCH_PER_STREAM_OPT(copy_initial_nonkeyframes, i,
|
||||||
ms->copy_initial_nonkeyframes, oc, st);
|
ms->copy_initial_nonkeyframes, oc, st);
|
||||||
|
|
||||||
@ -1392,10 +1386,13 @@ static int ost_add(Muxer *mux, const OptionsContext *o, enum AVMediaType type,
|
|||||||
.vsync_method = vsync_method,
|
.vsync_method = vsync_method,
|
||||||
.sample_rate = ost->enc_ctx->sample_rate,
|
.sample_rate = ost->enc_ctx->sample_rate,
|
||||||
.ch_layout = ost->enc_ctx->ch_layout,
|
.ch_layout = ost->enc_ctx->ch_layout,
|
||||||
|
.sws_opts = o->g->sws_dict,
|
||||||
|
.swr_opts = o->g->swr_opts,
|
||||||
.output_tb = enc_tb,
|
.output_tb = enc_tb,
|
||||||
.ts_offset = mux->of.start_time == AV_NOPTS_VALUE ?
|
.ts_offset = mux->of.start_time == AV_NOPTS_VALUE ?
|
||||||
0 : mux->of.start_time,
|
0 : mux->of.start_time,
|
||||||
.flags = OFILTER_FLAG_DISABLE_CONVERT * !!keep_pix_fmt,
|
.flags = OFILTER_FLAG_DISABLE_CONVERT * !!keep_pix_fmt |
|
||||||
|
OFILTER_FLAG_AUDIO_24BIT * !!(av_get_exact_bits_per_sample(ost->enc_ctx->codec_id) == 24),
|
||||||
};
|
};
|
||||||
|
|
||||||
snprintf(name, sizeof(name), "#%d:%d", mux->of.index, ost->index);
|
snprintf(name, sizeof(name), "#%d:%d", mux->of.index, ost->index);
|
||||||
|
Reference in New Issue
Block a user