fftools/ffmpeg_filter: propagate codec yuv metadata to filters

To convert between color spaces/ranges, if needed by the codec
properties.

Signed-off-by: Anton Khirnov <anton@khirnov.net>
This commit is contained in:
Niklas Haas 2024-04-08 13:58:19 +02:00
parent 33d5a4ec4e
commit a850f80e2c
3 changed files with 42 additions and 0 deletions

View File

@ -304,6 +304,8 @@ typedef struct OutputFilterOptions {
int format;
int width;
int height;
enum AVColorSpace color_space;
enum AVColorRange color_range;
enum VideoSyncMethod vsync_method;
@ -314,6 +316,8 @@ typedef struct OutputFilterOptions {
const int *sample_rates;
const AVChannelLayout *ch_layouts;
const AVRational *frame_rates;
const enum AVColorSpace *color_spaces;
const enum AVColorRange *color_ranges;
} OutputFilterOptions;
typedef struct InputFilter {

View File

@ -202,6 +202,8 @@ typedef struct OutputFilterPriv {
int width, height;
int sample_rate;
AVChannelLayout ch_layout;
enum AVColorSpace color_space;
enum AVColorRange color_range;
// time base in which the output is sent to our downstream
// does not need to match the filtersink's timebase
@ -220,6 +222,8 @@ typedef struct OutputFilterPriv {
const int *formats;
const AVChannelLayout *ch_layouts;
const int *sample_rates;
const enum AVColorSpace *color_spaces;
const enum AVColorRange *color_ranges;
AVRational enc_timebase;
int64_t trim_start_us;
@ -395,6 +399,12 @@ DEF_CHOOSE_FORMAT(sample_fmts, enum AVSampleFormat, format, formats,
DEF_CHOOSE_FORMAT(sample_rates, int, sample_rate, sample_rates, 0,
"%d", )
DEF_CHOOSE_FORMAT(color_spaces, enum AVColorSpace, color_space, color_spaces,
AVCOL_SPC_UNSPECIFIED, "%s", av_color_space_name);
DEF_CHOOSE_FORMAT(color_ranges, enum AVColorRange, color_range, color_ranges,
AVCOL_RANGE_UNSPECIFIED, "%s", av_color_range_name);
static void choose_channel_layouts(OutputFilterPriv *ofp, AVBPrint *bprint)
{
if (av_channel_layout_check(&ofp->ch_layout)) {
@ -639,6 +649,8 @@ static OutputFilter *ofilter_alloc(FilterGraph *fg, enum AVMediaType type)
ofilter->graph = fg;
ofilter->type = type;
ofp->format = -1;
ofp->color_space = AVCOL_SPC_UNSPECIFIED;
ofp->color_range = AVCOL_RANGE_UNSPECIFIED;
ofp->index = fg->nb_outputs - 1;
snprintf(ofp->log_name, sizeof(ofp->log_name), "%co%d",
@ -822,6 +834,16 @@ int ofilter_bind_ost(OutputFilter *ofilter, OutputStream *ost,
} else
ofp->formats = opts->formats;
if (opts->color_space != AVCOL_SPC_UNSPECIFIED)
ofp->color_space = opts->color_space;
else
ofp->color_spaces = opts->color_spaces;
if (opts->color_range != AVCOL_RANGE_UNSPECIFIED)
ofp->color_range = opts->color_range;
else
ofp->color_ranges = opts->color_ranges;
fgp->disable_conversions |= !!(ofp->flags & OFILTER_FLAG_DISABLE_CONVERT);
ofp->fps.last_frame = av_frame_alloc();
@ -1485,6 +1507,8 @@ static int configure_output_video_filter(FilterGraph *fg, AVFilterGraph *graph,
ofp->format != AV_PIX_FMT_NONE || !ofp->formats);
av_bprint_init(&bprint, 0, AV_BPRINT_SIZE_UNLIMITED);
choose_pix_fmts(ofp, &bprint);
choose_color_spaces(ofp, &bprint);
choose_color_ranges(ofp, &bprint);
if (!av_bprint_is_complete(&bprint))
return AVERROR(ENOMEM);
@ -1907,6 +1931,8 @@ static int configure_filtergraph(FilterGraph *fg, FilterGraphThread *fgt)
ofp->width = av_buffersink_get_w(sink);
ofp->height = av_buffersink_get_h(sink);
ofp->color_space = av_buffersink_get_colorspace(sink);
ofp->color_range = av_buffersink_get_color_range(sink);
// If the timing parameters are not locked yet, get the tentative values
// here but don't lock them. They will only be used if no output frames

View File

@ -934,6 +934,8 @@ ost_bind_filter(const Muxer *mux, MuxStream *ms, OutputFilter *ofilter,
enc_ctx->pix_fmt : enc_ctx->sample_fmt,
.width = enc_ctx->width,
.height = enc_ctx->height,
.color_space = enc_ctx->colorspace,
.color_range = enc_ctx->color_range,
.vsync_method = vsync_method,
.sample_rate = enc_ctx->sample_rate,
.ch_layout = enc_ctx->ch_layout,
@ -967,6 +969,16 @@ ost_bind_filter(const Muxer *mux, MuxStream *ms, OutputFilter *ofilter,
if (ret < 0)
return ret;
}
ret = avcodec_get_supported_config(enc_ctx, NULL,
AV_CODEC_CONFIG_COLOR_SPACE, 0,
(const void **) &opts.color_spaces, NULL);
if (ret < 0)
return ret;
ret = avcodec_get_supported_config(enc_ctx, NULL,
AV_CODEC_CONFIG_COLOR_RANGE, 0,
(const void **) &opts.color_ranges, NULL);
if (ret < 0)
return ret;
} else {
ret = avcodec_get_supported_config(enc_ctx, NULL,
AV_CODEC_CONFIG_SAMPLE_FORMAT, 0,