Git Inbox Mirror of the ffmpeg-devel mailing list - see https://ffmpeg.org/mailman/listinfo/ffmpeg-devel
 help / color / mirror / Atom feed
From: Niklas Haas <ffmpeg@haasn.xyz>
To: ffmpeg-devel@ffmpeg.org
Cc: Niklas Haas <git@haasn.dev>
Subject: [FFmpeg-devel] [PATCH v2 03/13] fftools/ffmpeg_filter: auto-convert range if needed
Date: Fri, 13 Oct 2023 16:24:41 +0200
Message-ID: <20231013142706.23971-4-ffmpeg@haasn.xyz> (raw)
In-Reply-To: <20231013142706.23971-1-ffmpeg@haasn.xyz>

From: Niklas Haas <git@haasn.dev>

To convert between color ranges, if needed by the codec properties. We
momentarily duplicate the mjpeg strictness logic to also enfoce full
range. This duplication will be cleaned up in the next commit.

Due to avcodec_open2 being called after ofilter_bind_ost, we need to
look up the eventual encoder options from the options dictionary
directly, following the same design as the "strict" option.
---
 fftools/ffmpeg_filter.c | 61 +++++++++++++++++++++++++++++++++++------
 1 file changed, 52 insertions(+), 9 deletions(-)

diff --git a/fftools/ffmpeg_filter.c b/fftools/ffmpeg_filter.c
index c738fc3397..acdfa72043 100644
--- a/fftools/ffmpeg_filter.c
+++ b/fftools/ffmpeg_filter.c
@@ -169,6 +169,7 @@ typedef struct OutputFilterPriv {
     int width, height;
     int sample_rate;
     AVChannelLayout ch_layout;
+    enum AVColorRange range;
 
     // time base in which the output is sent to our downstream
     // does not need to match the filtersink's timebase
@@ -184,6 +185,7 @@ typedef struct OutputFilterPriv {
     const int *formats;
     const AVChannelLayout *ch_layouts;
     const int *sample_rates;
+    const enum AVColorRange *ranges;
 
     AVRational enc_timebase;
     // offset for output timestamps, in AV_TIME_BASE_Q
@@ -368,6 +370,9 @@ DEF_CHOOSE_FORMAT(sample_fmts, enum AVSampleFormat, format, formats,
 DEF_CHOOSE_FORMAT(sample_rates, int, sample_rate, sample_rates, 0,
                   "%d", )
 
+DEF_CHOOSE_FORMAT(out_range, enum AVColorRange, range, 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)) {
@@ -662,6 +667,17 @@ static int set_channel_layout(OutputFilterPriv *f, OutputStream *ost)
     return 0;
 }
 
+static int ost_opt_int(OutputStream *ost, const char *name, int defval)
+{
+    const AVDictionaryEntry *e = av_dict_get(ost->encoder_opts, name, NULL, 0);
+    if (e) {
+        const AVOption *o = av_opt_find(ost->enc_ctx, e->key, NULL, 0, 0);
+        av_assert0(o);
+        av_opt_eval_int(ost->enc_ctx, o, e->value, &defval);
+    }
+    return defval;
+}
+
 int ofilter_bind_ost(OutputFilter *ofilter, OutputStream *ost)
 {
     const OutputFile  *of = output_files[ost->file_index];
@@ -669,6 +685,7 @@ int ofilter_bind_ost(OutputFilter *ofilter, OutputStream *ost)
     FilterGraph  *fg = ofilter->graph;
     FilterGraphPriv *fgp = fgp_from_fg(fg);
     const AVCodec *c = ost->enc_ctx->codec;
+    enum AVColorRange color_range;
 
     av_assert0(!ofilter->ost);
 
@@ -682,6 +699,26 @@ int ofilter_bind_ost(OutputFilter *ofilter, OutputStream *ost)
     case AVMEDIA_TYPE_VIDEO:
         ofp->width      = ost->enc_ctx->width;
         ofp->height     = ost->enc_ctx->height;
+        color_range     = ost_opt_int(ost, "color_range", ost->enc_ctx->color_range);
+        if (color_range != AVCOL_RANGE_UNSPECIFIED) {
+            ofp->range = color_range;
+        } else {
+            ofp->ranges = c->color_ranges;
+
+            // MJPEG encoder exports a full list of supported pixel formats,
+            // but the full-range ones are experimental-only.
+            // Restrict the auto-conversion list unless -strict experimental
+            // has been specified.
+            if (!strcmp(c->name, "mjpeg")) {
+                static const enum AVColorRange mjpeg_ranges[] =
+                    { AVCOL_RANGE_JPEG, AVCOL_RANGE_UNSPECIFIED };
+
+                int strict_val = ost->enc_ctx->strict_std_compliance;
+                strict_val = ost_opt_int(ost, "strict", strict_val);
+                if (strict_val > FF_COMPLIANCE_UNOFFICIAL)
+                    ofp->ranges = mjpeg_ranges;
+            }
+        }
         if (ost->enc_ctx->pix_fmt != AV_PIX_FMT_NONE) {
             ofp->format = ost->enc_ctx->pix_fmt;
         } else {
@@ -1149,6 +1186,7 @@ static int configure_output_video_filter(FilterGraph *fg, OutputFilter *ofilter,
     OutputFilterPriv *ofp = ofp_from_ofilter(ofilter);
     OutputStream *ost = ofilter->ost;
     OutputFile    *of = output_files[ost->file_index];
+    FilterGraphPriv *fgp = fgp_from_fg(fg);
     AVFilterContext *last_filter = out->filter_ctx;
     AVBPrint bprint;
     int pad_idx = out->pad_idx;
@@ -1164,22 +1202,27 @@ static int configure_output_video_filter(FilterGraph *fg, OutputFilter *ofilter,
     if (ret < 0)
         return ret;
 
-    if ((ofp->width || ofp->height) && ofilter->ost->autoscale) {
-        char args[255];
+    av_bprint_init(&bprint, 0, AV_BPRINT_SIZE_UNLIMITED);
+    if ((ofp->width || ofp->height) && ofilter->ost->autoscale)
+        av_bprintf(&bprint, "w=%d:h=%d:", ofp->width, ofp->height);
+    if (!fgp->disable_conversions)
+        choose_out_range(ofp, &bprint);
+    if (bprint.len) {
         AVFilterContext *filter;
         const AVDictionaryEntry *e = NULL;
 
-        snprintf(args, sizeof(args), "%d:%d",
-                 ofp->width, ofp->height);
+        while ((e = av_dict_iterate(ost->sws_dict, e)))
+            av_bprintf(&bprint, "%s=%s:", e->key, e->value);
 
-        while ((e = av_dict_iterate(ost->sws_dict, e))) {
-            av_strlcatf(args, sizeof(args), ":%s=%s", e->key, e->value);
-        }
+        if (!av_bprint_is_complete(&bprint))
+            return AVERROR(ENOMEM);
 
         snprintf(name, sizeof(name), "scaler_out_%d_%d",
                  ost->file_index, ost->index);
-        if ((ret = avfilter_graph_create_filter(&filter, avfilter_get_by_name("scale"),
-                                                name, args, NULL, fg->graph)) < 0)
+        ret = avfilter_graph_create_filter(&filter, avfilter_get_by_name("scale"),
+                                           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;
-- 
2.42.0

_______________________________________________
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-devel

To unsubscribe, visit link above, or email
ffmpeg-devel-request@ffmpeg.org with subject "unsubscribe".

  parent reply	other threads:[~2023-10-13 14:27 UTC|newest]

Thread overview: 37+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2023-10-13 14:24 [FFmpeg-devel] [PATCH v2 00/13] YUVJ removal Niklas Haas
2023-10-13 14:24 ` [FFmpeg-devel] [PATCH v2 01/13] avfilter/vf_scale: don't change range by default Niklas Haas
2023-10-13 14:24 ` [FFmpeg-devel] [PATCH v2 02/13] avcodec: add extended AVCodec color metadata Niklas Haas
2023-10-13 17:10   ` Andreas Rheinhardt
2023-10-13 18:52     ` Vittorio Giovara
2023-10-14 10:29     ` Niklas Haas
2023-10-14 11:46     ` Niklas Haas
2023-10-20 13:54       ` Anton Khirnov
2023-10-20 14:11         ` Michael Niedermayer
2023-10-20 14:01     ` Anton Khirnov
2023-10-14 13:31   ` Leo Izen
2023-10-14 13:40     ` Niklas Haas
2023-10-13 14:24 ` Niklas Haas [this message]
2023-10-13 14:24 ` [FFmpeg-devel] [PATCH v2 04/13] lavfi/vf_colorspace: support prim/trc/csp passthrough Niklas Haas
2023-10-13 14:24 ` [FFmpeg-devel] [PATCH v2 05/13] fftools/ffmpeg_filter: auto-insert colorspace filter Niklas Haas
2023-10-13 14:24 ` [FFmpeg-devel] [PATCH v2 06/13] avcodec/encode: enforce AVCodec capabilities at encode time Niklas Haas
2023-10-13 14:24 ` [FFmpeg-devel] [PATCH v2 07/13] tests/fate: force MPEG range for rawvideo tests Niklas Haas
2023-10-13 14:24 ` [FFmpeg-devel] [PATCH v2 08/13] tests/fate: allow conversion filters in jpg-icc test Niklas Haas
2023-10-13 14:24 ` [FFmpeg-devel] [PATCH v2 09/13] lavc: set color_ranges for YUVJ-only codecs Niklas Haas
2023-10-13 14:24 ` [FFmpeg-devel] [PATCH v2 10/13] lavfi/lavu/lavc: remove YUVJ pixel formats Niklas Haas
2023-10-13 14:24 ` [FFmpeg-devel] [PATCH v2 11/13] swscale/utils: simplify JPEG handling function Niklas Haas
2023-10-13 14:24 ` [FFmpeg-devel] [PATCH v2 12/13] tests/fate: remove unused YUVJ ref files Niklas Haas
2023-10-13 14:24 ` [FFmpeg-devel] [PATCH v2 13/13] avutil/pixdesc: remove old yuvj pixel format check Niklas Haas
2023-10-13 18:33 ` [FFmpeg-devel] [PATCH v2 00/13] YUVJ removal Vittorio Giovara
2023-10-13 21:14   ` Lynne
2023-10-13 22:21     ` Vittorio Giovara
2023-10-14 13:11       ` Lynne
2023-10-14 15:15         ` Vittorio Giovara
2023-10-14 15:18           ` Lynne
2023-10-20 12:14           ` Ronald S. Bultje
2023-10-20 16:14             ` Vittorio Giovara
2023-10-20 23:13               ` Ronald S. Bultje
2023-10-21 23:20                 ` Michael Niedermayer
2023-10-24  0:56                   ` Vittorio Giovara
2023-10-25 22:15                     ` Michael Niedermayer
2023-10-20 11:30   ` Niklas Haas
2023-10-20 16:17     ` Vittorio Giovara

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20231013142706.23971-4-ffmpeg@haasn.xyz \
    --to=ffmpeg@haasn.xyz \
    --cc=ffmpeg-devel@ffmpeg.org \
    --cc=git@haasn.dev \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link

Git Inbox Mirror of the ffmpeg-devel mailing list - see https://ffmpeg.org/mailman/listinfo/ffmpeg-devel

This inbox may be cloned and mirrored by anyone:

	git clone --mirror https://master.gitmailbox.com/ffmpegdev/0 ffmpegdev/git/0.git

	# If you have public-inbox 1.1+ installed, you may
	# initialize and index your mirror using the following commands:
	public-inbox-init -V2 ffmpegdev ffmpegdev/ https://master.gitmailbox.com/ffmpegdev \
		ffmpegdev@gitmailbox.com
	public-inbox-index ffmpegdev

Example config snippet for mirrors.


AGPL code for this site: git clone https://public-inbox.org/public-inbox.git