summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNiklas Haas <git@haasn.dev>2024-04-08 13:58:19 +0200
committerAnton Khirnov <anton@khirnov.net>2024-04-09 15:43:25 +0200
commit60ea572a742e875f1fce85faeed2a68362fb8c40 (patch)
treeb63a14fe1993b73cfa61e9f5eb14eeba909908a9
parent67ae6dee915f4a851d8ff6dfe86d7de142575a4f (diff)
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>
-rw-r--r--fftools/ffmpeg.h4
-rw-r--r--fftools/ffmpeg_filter.c26
-rw-r--r--fftools/ffmpeg_mux_init.c12
3 files changed, 42 insertions, 0 deletions
diff --git a/fftools/ffmpeg.h b/fftools/ffmpeg.h
index abd48547e0..7b36ec6798 100644
--- a/fftools/ffmpeg.h
+++ b/fftools/ffmpeg.h
@@ -297,6 +297,8 @@ typedef struct OutputFilterOptions {
int format;
int width;
int height;
+ enum AVColorSpace color_space;
+ enum AVColorRange color_range;
enum VideoSyncMethod vsync_method;
@@ -307,6 +309,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 {
diff --git a/fftools/ffmpeg_filter.c b/fftools/ffmpeg_filter.c
index f9bd894bec..7746d36999 100644
--- a/fftools/ffmpeg_filter.c
+++ b/fftools/ffmpeg_filter.c
@@ -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();
@@ -1484,6 +1506,8 @@ static int configure_output_video_filter(FilterGraph *fg, AVFilterGraph *graph,
(!ofp->format && !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);
@@ -1895,6 +1919,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
diff --git a/fftools/ffmpeg_mux_init.c b/fftools/ffmpeg_mux_init.c
index 0d3d80dfb9..9dde953fc0 100644
--- a/fftools/ffmpeg_mux_init.c
+++ b/fftools/ffmpeg_mux_init.c
@@ -935,6 +935,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,
@@ -968,6 +970,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);
+ if (ret < 0)
+ return ret;
+ ret = avcodec_get_supported_config(enc_ctx, NULL,
+ AV_CODEC_CONFIG_COLOR_RANGE, 0,
+ (const void **) &opts.color_ranges);
+ if (ret < 0)
+ return ret;
} else {
ret = avcodec_get_supported_config(enc_ctx, NULL,
AV_CODEC_CONFIG_SAMPLE_FORMAT, 0,