@@ -20,6 +20,8 @@
#include <stdint.h>
+#include "config_components.h"
+
#include "ffmpeg.h"
#include "libavfilter/avfilter.h"
@@ -171,6 +173,9 @@ typedef struct OutputFilterPriv {
AVChannelLayout ch_layout;
enum AVColorSpace csp;
enum AVColorRange color_range;
+ enum AVChromaLocation chroma_loc;
+ enum AVColorPrimaries prim;
+ enum AVColorTransferCharacteristic trc;
// time base in which the output is sent to our downstream
// does not need to match the filtersink's timebase
@@ -188,6 +193,9 @@ typedef struct OutputFilterPriv {
const int *sample_rates;
const enum AVColorSpace *csps;
const enum AVColorRange *color_ranges;
+ const enum AVChromaLocation *chroma_locs;
+ const enum AVColorPrimaries *prims;
+ const enum AVColorTransferCharacteristic *trcs;
AVRational enc_timebase;
// offset for output timestamps, in AV_TIME_BASE_Q
@@ -378,6 +386,17 @@ DEF_CHOOSE_FORMAT(out_color_matrix, enum AVColorSpace, csp, csps,
DEF_CHOOSE_FORMAT(out_range, enum AVColorRange, color_range, color_ranges,
AVCOL_RANGE_UNSPECIFIED, "%s", av_color_range_name);
+#if CONFIG_ZSCALE_FILTER
+DEF_CHOOSE_FORMAT(chromal, enum AVChromaLocation, chroma_loc, chroma_locs,
+ AVCHROMA_LOC_UNSPECIFIED, "%s", av_chroma_location_name);
+
+DEF_CHOOSE_FORMAT(primaries, enum AVColorPrimaries, prim, prims,
+ AVCOL_PRI_UNSPECIFIED, "%s", av_color_primaries_name);
+
+DEF_CHOOSE_FORMAT(transfer, enum AVColorTransferCharacteristic, trc, trcs,
+ AVCOL_TRC_UNSPECIFIED, "%s", av_color_transfer_name);
+#endif
+
static void choose_channel_layouts(OutputFilterPriv *ofp, AVBPrint *bprint)
{
if (av_channel_layout_check(&ofp->ch_layout)) {
@@ -724,6 +743,21 @@ int ofilter_bind_ost(OutputFilter *ofilter, OutputStream *ost)
ofp->color_ranges = mjpeg_ranges;
}
}
+ if (ost->enc_ctx->chroma_sample_location) {
+ ofp->chroma_loc = ost->enc_ctx->chroma_sample_location;
+ } else {
+ ofp->chroma_locs = c->chroma_locs;
+ }
+ if (ost->enc_ctx->color_primaries) {
+ ofp->prim = ost->enc_ctx->color_primaries;
+ } else {
+ ofp->prims = c->primaries;
+ }
+ if (ost->enc_ctx->color_trc) {
+ ofp->trc = ost->enc_ctx->color_trc;
+ } else {
+ ofp->trcs = c->trcs;
+ }
if (ost->enc_ctx->pix_fmt != AV_PIX_FMT_NONE) {
ofp->format = ost->enc_ctx->pix_fmt;
} else {
@@ -1280,6 +1314,34 @@ static int configure_output_video_filter(FilterGraph *fg, OutputFilter *ofilter,
last_filter = filter;
pad_idx = 0;
}
+
+#if CONFIG_ZSCALE_FILTER
+ av_bprint_init(&bprint, 0, AV_BPRINT_SIZE_UNLIMITED);
+ choose_chromal(ofp, &bprint);
+ choose_primaries(ofp, &bprint);
+ choose_transfer(ofp, &bprint);
+ if (bprint.len) {
+ /* Colorspace format conversion needed */
+ AVFilterContext *filter;
+
+ if (!av_bprint_is_complete(&bprint))
+ return AVERROR(ENOMEM);
+
+ snprintf(name, sizeof(name), "color_out_%d_%d",
+ ost->file_index, ost->index);
+ ret = avfilter_graph_create_filter(&filter,
+ avfilter_get_by_name("zscale"),
+ name, bprint.str, NULL, fg->graph);
+ av_bprint_finalize(&bprint, NULL);
+ if (ret < 0)
+ return ret;
+ if ((ret = avfilter_link(last_filter, pad_idx, filter, 0)) < 0)
+ return ret;
+
+ last_filter = filter;
+ pad_idx = 0;
+ }
+#endif
}
snprintf(name, sizeof(name), "trim_out_%d_%d",
From: Niklas Haas <git@haasn.dev> Since swscale currently can't handle conversion between different colorimetry sets, supplement the missing bits and pieces using zscale. Subject to change in the future, if libswscale ever gets the capability to convert between colorspaces natively. --- fftools/ffmpeg_filter.c | 62 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 62 insertions(+)