[FFmpeg-devel] [PATCH 05/25] avfilter/buffersrc: add color_space/range parameters
Niklas Haas
ffmpeg at haasn.xyz
Thu Nov 9 14:19:37 EET 2023
From: Niklas Haas <git at haasn.dev>
To allow adding proper negotiation, in particular, to fftools.
These values will simply be negotiated downstream for YUV formats, and
ignored otherwise.
---
doc/filters.texi | 10 +++++++
libavfilter/buffersrc.c | 62 ++++++++++++++++++++++++++++++++++++-----
libavfilter/buffersrc.h | 6 ++++
3 files changed, 71 insertions(+), 7 deletions(-)
diff --git a/doc/filters.texi b/doc/filters.texi
index 12113d7802..55a333680c 100644
--- a/doc/filters.texi
+++ b/doc/filters.texi
@@ -27939,6 +27939,16 @@ Specify the timebase assumed by the timestamps of the buffered frames.
@item frame_rate
Specify the frame rate expected for the video stream.
+ at item colorspace
+A string representing the color space of the buffered video frames.
+It may be a number corresponding to a color space, or a color space
+name.
+
+ at item range
+A string representing the color range of the buffered video frames.
+It may be a number corresponding to a color range, or a color range
+name.
+
@item pixel_aspect, sar
The sample (pixel) aspect ratio of the input video.
diff --git a/libavfilter/buffersrc.c b/libavfilter/buffersrc.c
index 453fc0fd5c..76f3f1d7a5 100644
--- a/libavfilter/buffersrc.c
+++ b/libavfilter/buffersrc.c
@@ -49,6 +49,8 @@ typedef struct BufferSourceContext {
/* video only */
int w, h;
enum AVPixelFormat pix_fmt;
+ enum AVColorSpace color_space;
+ enum AVColorRange color_range;
AVRational pixel_aspect;
AVBufferRef *hw_frames_ctx;
@@ -64,10 +66,13 @@ typedef struct BufferSourceContext {
int64_t last_pts;
} BufferSourceContext;
-#define CHECK_VIDEO_PARAM_CHANGE(s, c, width, height, format, pts)\
- if (c->w != width || c->h != height || c->pix_fmt != format) {\
- av_log(s, AV_LOG_INFO, "filter context - w: %d h: %d fmt: %d, incoming frame - w: %d h: %d fmt: %d pts_time: %s\n",\
- c->w, c->h, c->pix_fmt, width, height, format, av_ts2timestr(pts, &s->outputs[0]->time_base));\
+#define CHECK_VIDEO_PARAM_CHANGE(s, c, width, height, format, csp, range, pts)\
+ if (c->w != width || c->h != height || c->pix_fmt != format ||\
+ c->color_space != csp || c->color_range != range) {\
+ av_log(s, AV_LOG_INFO, "filter context - w: %d h: %d fmt: %d csp: %s range: %s, incoming frame - w: %d h: %d fmt: %d csp: %s range: %s pts_time: %s\n",\
+ c->w, c->h, c->pix_fmt, av_color_space_name(c->color_space), av_color_range_name(c->color_range),\
+ width, height, format, av_color_space_name(csp), av_color_range_name(range),\
+ av_ts2timestr(pts, &s->outputs[0]->time_base));\
av_log(s, AV_LOG_WARNING, "Changing video frame properties on the fly is not supported by all filters.\n");\
}
@@ -88,6 +93,8 @@ AVBufferSrcParameters *av_buffersrc_parameters_alloc(void)
return NULL;
par->format = -1;
+ par->color_range = AVCOL_RANGE_UNSPECIFIED;
+ par->color_space = AVCOL_SPC_UNSPECIFIED;
return par;
}
@@ -118,6 +125,10 @@ int av_buffersrc_parameters_set(AVFilterContext *ctx, AVBufferSrcParameters *par
if (!s->hw_frames_ctx)
return AVERROR(ENOMEM);
}
+ if (param->color_space != AVCOL_SPC_UNSPECIFIED)
+ s->color_space = param->color_space;
+ if (param->color_range != AVCOL_RANGE_UNSPECIFIED)
+ s->color_range = param->color_range;
break;
case AVMEDIA_TYPE_AUDIO:
if (param->format != AV_SAMPLE_FMT_NONE) {
@@ -205,7 +216,8 @@ FF_ENABLE_DEPRECATION_WARNINGS
switch (ctx->outputs[0]->type) {
case AVMEDIA_TYPE_VIDEO:
CHECK_VIDEO_PARAM_CHANGE(ctx, s, frame->width, frame->height,
- frame->format, frame->pts);
+ frame->format, frame->colorspace,
+ frame->color_range, frame->pts);
break;
case AVMEDIA_TYPE_AUDIO:
/* For layouts unknown on input but known on link after negotiation. */
@@ -302,10 +314,11 @@ static av_cold int init_video(AVFilterContext *ctx)
return AVERROR(EINVAL);
}
- av_log(ctx, AV_LOG_VERBOSE, "w:%d h:%d pixfmt:%s tb:%d/%d fr:%d/%d sar:%d/%d\n",
+ av_log(ctx, AV_LOG_VERBOSE, "w:%d h:%d pixfmt:%s tb:%d/%d fr:%d/%d sar:%d/%d csp:%s range:%s\n",
c->w, c->h, av_get_pix_fmt_name(c->pix_fmt),
c->time_base.num, c->time_base.den, c->frame_rate.num, c->frame_rate.den,
- c->pixel_aspect.num, c->pixel_aspect.den);
+ c->pixel_aspect.num, c->pixel_aspect.den,
+ av_color_space_name(c->color_space), av_color_range_name(c->color_range));
return 0;
}
@@ -328,6 +341,30 @@ static const AVOption buffer_options[] = {
{ "pixel_aspect", "sample aspect ratio", OFFSET(pixel_aspect), AV_OPT_TYPE_RATIONAL, { .dbl = 0 }, 0, DBL_MAX, V },
{ "time_base", NULL, OFFSET(time_base), AV_OPT_TYPE_RATIONAL, { .dbl = 0 }, 0, DBL_MAX, V },
{ "frame_rate", NULL, OFFSET(frame_rate), AV_OPT_TYPE_RATIONAL, { .dbl = 0 }, 0, DBL_MAX, V },
+ { "colorspace", "select colorspace", OFFSET(color_space), AV_OPT_TYPE_INT, {.i64=AVCOL_SPC_UNSPECIFIED}, 0, AVCOL_SPC_NB-1, V, "colorspace"},
+ { "gbr", NULL, 0, AV_OPT_TYPE_CONST, {.i64=AVCOL_SPC_RGB}, INT_MIN, INT_MAX, V, "colorspace"},
+ { "bt709", NULL, 0, AV_OPT_TYPE_CONST, {.i64=AVCOL_SPC_BT709}, INT_MIN, INT_MAX, V, "colorspace"},
+ { "unknown", NULL, 0, AV_OPT_TYPE_CONST, {.i64=AVCOL_SPC_UNSPECIFIED}, INT_MIN, INT_MAX, V, "colorspace"},
+ { "fcc", NULL, 0, AV_OPT_TYPE_CONST, {.i64=AVCOL_SPC_FCC}, INT_MIN, INT_MAX, V, "colorspace"},
+ { "bt470bg", NULL, 0, AV_OPT_TYPE_CONST, {.i64=AVCOL_SPC_BT470BG}, INT_MIN, INT_MAX, V, "colorspace"},
+ { "smpte170m", NULL, 0, AV_OPT_TYPE_CONST, {.i64=AVCOL_SPC_SMPTE170M}, INT_MIN, INT_MAX, V, "colorspace"},
+ { "smpte240m", NULL, 0, AV_OPT_TYPE_CONST, {.i64=AVCOL_SPC_SMPTE240M}, INT_MIN, INT_MAX, V, "colorspace"},
+ { "ycgco", NULL, 0, AV_OPT_TYPE_CONST, {.i64=AVCOL_SPC_YCGCO}, INT_MIN, INT_MAX, V, "colorspace"},
+ { "bt2020nc", NULL, 0, AV_OPT_TYPE_CONST, {.i64=AVCOL_SPC_BT2020_NCL}, INT_MIN, INT_MAX, V, "colorspace"},
+ { "bt2020c", NULL, 0, AV_OPT_TYPE_CONST, {.i64=AVCOL_SPC_BT2020_CL}, INT_MIN, INT_MAX, V, "colorspace"},
+ { "smpte2085", NULL, 0, AV_OPT_TYPE_CONST, {.i64=AVCOL_SPC_SMPTE2085}, INT_MIN, INT_MAX, V, "colorspace"},
+ { "chroma-derived-nc", NULL, 0, AV_OPT_TYPE_CONST, {.i64=AVCOL_SPC_CHROMA_DERIVED_NCL},INT_MIN, INT_MAX, V, "colorspace"},
+ { "chroma-derived-c", NULL, 0, AV_OPT_TYPE_CONST, {.i64=AVCOL_SPC_CHROMA_DERIVED_CL}, INT_MIN, INT_MAX, V, "colorspace"},
+ { "ictcp", NULL, 0, AV_OPT_TYPE_CONST, {.i64=AVCOL_SPC_ICTCP}, INT_MIN, INT_MAX, V, "colorspace"},
+ { "range", "select color range", OFFSET(color_range), AV_OPT_TYPE_INT, {.i64=AVCOL_RANGE_UNSPECIFIED}, 0, AVCOL_RANGE_NB-1, V, "range"},
+ { "unspecified", NULL, 0, AV_OPT_TYPE_CONST, {.i64=AVCOL_RANGE_UNSPECIFIED}, 0, 0, V, "range"},
+ { "unknown", NULL, 0, AV_OPT_TYPE_CONST, {.i64=AVCOL_RANGE_UNSPECIFIED}, 0, 0, V, "range"},
+ { "limited", NULL, 0, AV_OPT_TYPE_CONST, {.i64=AVCOL_RANGE_MPEG}, 0, 0, V, "range"},
+ { "tv", NULL, 0, AV_OPT_TYPE_CONST, {.i64=AVCOL_RANGE_MPEG}, 0, 0, V, "range"},
+ { "mpeg", NULL, 0, AV_OPT_TYPE_CONST, {.i64=AVCOL_RANGE_MPEG}, 0, 0, V, "range"},
+ { "full", NULL, 0, AV_OPT_TYPE_CONST, {.i64=AVCOL_RANGE_JPEG}, 0, 0, V, "range"},
+ { "pc", NULL, 0, AV_OPT_TYPE_CONST, {.i64=AVCOL_RANGE_JPEG}, 0, 0, V, "range"},
+ { "jpeg", NULL, 0, AV_OPT_TYPE_CONST, {.i64=AVCOL_RANGE_JPEG}, 0, 0, V, "range"},
{ NULL },
};
@@ -425,6 +462,8 @@ static int query_formats(AVFilterContext *ctx)
AVFilterChannelLayouts *channel_layouts = NULL;
AVFilterFormats *formats = NULL;
AVFilterFormats *samplerates = NULL;
+ AVFilterFormats *color_spaces = NULL;
+ AVFilterFormats *color_ranges = NULL;
int ret;
switch (ctx->outputs[0]->type) {
@@ -432,6 +471,15 @@ static int query_formats(AVFilterContext *ctx)
if ((ret = ff_add_format (&formats, c->pix_fmt)) < 0 ||
(ret = ff_set_common_formats (ctx , formats )) < 0)
return ret;
+ /* force specific colorspace/range downstream only for ordinary YUV */
+ if (ff_fmt_is_regular_yuv(c->pix_fmt)) {
+ if ((ret = ff_add_format(&color_spaces, c->color_space)) < 0 ||
+ (ret = ff_set_common_color_spaces(ctx, color_spaces)) < 0)
+ return ret;
+ if ((ret = ff_add_format(&color_ranges, c->color_range)) < 0 ||
+ (ret = ff_set_common_color_ranges(ctx, color_ranges)) < 0)
+ return ret;
+ }
break;
case AVMEDIA_TYPE_AUDIO:
if ((ret = ff_add_format (&formats , c->sample_fmt )) < 0 ||
diff --git a/libavfilter/buffersrc.h b/libavfilter/buffersrc.h
index 3b248b37cd..4357a7bbfb 100644
--- a/libavfilter/buffersrc.h
+++ b/libavfilter/buffersrc.h
@@ -105,6 +105,12 @@ typedef struct AVBufferSrcParameters {
*/
AVBufferRef *hw_frames_ctx;
+ /**
+ * Video only, the YUV colorspace and range
+ */
+ enum AVColorSpace color_space;
+ enum AVColorRange color_range;
+
/**
* Audio only, the audio sampling rate in samples per second.
*/
--
2.42.0
More information about the ffmpeg-devel
mailing list