From: Niklas Haas <ffmpeg@haasn.xyz> To: ffmpeg-devel@ffmpeg.org Cc: Niklas Haas <git@haasn.dev> Subject: [FFmpeg-devel] [PATCH 4/6] avfilter/vf_scale: add in/out_chroma_loc Date: Thu, 4 Jul 2024 13:52:00 +0200 Message-ID: <20240704115202.1235954-4-ffmpeg@haasn.xyz> (raw) In-Reply-To: <20240704115202.1235954-1-ffmpeg@haasn.xyz> From: Niklas Haas <git@haasn.dev> Currently, this just functions as a more principled and user-friendly replacement for the (undocumented and hard to use) *_chr_pos fields. However, the goal is to automatically infer these values from the input frames' chroma location, and deprecate the manual use of *_chr_pos altogether. (Indeed, my plans for an swscale replacement will most likely also end up limiting the set of legal chroma locations to those permissible by AVFrame properties) --- doc/filters.texi | 15 +++++++++ libavfilter/vf_scale.c | 75 ++++++++++++++++++++++++++++-------------- 2 files changed, 66 insertions(+), 24 deletions(-) diff --git a/doc/filters.texi b/doc/filters.texi index ca8f6e461a..3cff4eec1c 100644 --- a/doc/filters.texi +++ b/doc/filters.texi @@ -21137,6 +21137,21 @@ Set full range (0-255 in case of 8-bit luma). Set "MPEG" range (16-235 in case of 8-bit luma). @end table +@item in_chroma_loc +@item out_chroma_loc +Set in/output chroma sample location. If not specified, center-sited chroma +is used by default. Possible values: + +@table @samp +@item auto, unknown +@item left +@item center +@item topleft +@item top +@item bottomleft +@item bottom +@end table + @item force_original_aspect_ratio Enable decreasing or increasing output video width or height if necessary to keep the original aspect ratio. Possible values: diff --git a/libavfilter/vf_scale.c b/libavfilter/vf_scale.c index 0b6701673f..f0de0261db 100644 --- a/libavfilter/vf_scale.c +++ b/libavfilter/vf_scale.c @@ -168,6 +168,8 @@ typedef struct ScaleContext { int in_range; int out_range; + int in_chroma_loc; + int out_chroma_loc; int out_h_chr_pos; int out_v_chr_pos; int in_h_chr_pos; @@ -617,6 +619,29 @@ fail: return ret; } +static void calc_chroma_pos(int *h_pos, int *v_pos, int chroma_loc, + int h_pos_default, int v_pos_default, + int h_sub, int v_sub, int index) +{ + *h_pos = h_pos_default; + *v_pos = v_pos_default; + if (chroma_loc != AVCHROMA_LOC_UNSPECIFIED) + av_chroma_location_enum_to_pos(h_pos, v_pos, chroma_loc); + + if (h_sub && index > 0 /* interlaced fields */) { + if (*v_pos == -513) + *v_pos = 128; /* explicitly default missing info */ + *v_pos += 256 * (index == 2); /* offset by one luma row for odd rows */ + *v_pos >>= 1; /* double luma row distance */ + } + + /* Avoid offsetting chroma for progressive content */ + if (!h_sub) + *h_pos = -513; + if (!v_sub) + *v_pos = -513; +} + static int config_props(AVFilterLink *outlink) { AVFilterContext *ctx = outlink->src; @@ -673,15 +698,16 @@ static int config_props(AVFilterLink *outlink) inlink0->h == outlink->h && in_range == outlink->color_range && in_colorspace == outlink->colorspace && - inlink0->format == outlink->format) + inlink0->format == outlink->format && + scale->in_chroma_loc == scale->out_chroma_loc) ; else { struct SwsContext **swscs[3] = {&scale->sws, &scale->isws[0], &scale->isws[1]}; int i; for (i = 0; i < 3; i++) { - int in_v_chr_pos = scale->in_v_chr_pos, out_v_chr_pos = scale->out_v_chr_pos; int in_full, out_full, brightness, contrast, saturation; + int h_chr_pos, v_chr_pos; const int *inv_table, *table; struct SwsContext *const s = sws_alloc_context(); if (!s) @@ -705,28 +731,17 @@ static int config_props(AVFilterLink *outlink) av_opt_set_int(s, "dst_range", outlink->color_range == AVCOL_RANGE_JPEG, 0); - /* Override chroma location default settings to have the correct - * chroma positions. MPEG chroma positions are used by convention. - * Note that this works for both MPEG-1/JPEG and MPEG-2/4 chroma - * locations, since they share a vertical alignment */ - if (desc->log2_chroma_h == 1) { - if (in_v_chr_pos == -513) - in_v_chr_pos = 128; /* explicitly default missing info */ - in_v_chr_pos += 256 * (i == 2); /* offset by one luma row for odd rows */ - in_v_chr_pos >>= i > 0; /* double luma row distance */ - } - - if (outdesc->log2_chroma_h == 1) { - if (out_v_chr_pos == -513) - out_v_chr_pos = 128; - out_v_chr_pos += 256 * (i == 2); - out_v_chr_pos >>= i > 0; - } - - av_opt_set_int(s, "src_h_chr_pos", scale->in_h_chr_pos, 0); - av_opt_set_int(s, "src_v_chr_pos", in_v_chr_pos, 0); - av_opt_set_int(s, "dst_h_chr_pos", scale->out_h_chr_pos, 0); - av_opt_set_int(s, "dst_v_chr_pos", out_v_chr_pos, 0); + calc_chroma_pos(&h_chr_pos, &v_chr_pos, scale->in_chroma_loc, + scale->in_h_chr_pos, scale->in_v_chr_pos, + desc->log2_chroma_w, desc->log2_chroma_h, i); + av_opt_set_int(s, "src_h_chr_pos", h_chr_pos, 0); + av_opt_set_int(s, "src_v_chr_pos", v_chr_pos, 0); + + calc_chroma_pos(&h_chr_pos, &v_chr_pos, scale->out_chroma_loc, + scale->out_h_chr_pos, scale->out_v_chr_pos, + outdesc->log2_chroma_w, outdesc->log2_chroma_h, i); + av_opt_set_int(s, "dst_h_chr_pos", h_chr_pos, 0); + av_opt_set_int(s, "dst_v_chr_pos", v_chr_pos, 0); if ((ret = sws_init_context(s, NULL, NULL)) < 0) return ret; @@ -987,6 +1002,8 @@ scale: out->height = outlink->h; out->color_range = outlink->color_range; out->colorspace = outlink->colorspace; + if (scale->out_chroma_loc != AVCHROMA_LOC_UNSPECIFIED) + out->chroma_location = scale->out_chroma_loc; if (scale->output_is_pal) avpriv_set_systematic_pal2((uint32_t*)out->data[1], outlink->format == AV_PIX_FMT_PAL8 ? AV_PIX_FMT_BGR8 : outlink->format); @@ -1217,6 +1234,16 @@ static const AVOption scale_options[] = { { "mpeg", NULL, 0, AV_OPT_TYPE_CONST, {.i64 = AVCOL_RANGE_MPEG}, 0, 0, FLAGS, .unit = "range" }, { "tv", NULL, 0, AV_OPT_TYPE_CONST, {.i64 = AVCOL_RANGE_MPEG}, 0, 0, FLAGS, .unit = "range" }, { "pc", NULL, 0, AV_OPT_TYPE_CONST, {.i64 = AVCOL_RANGE_JPEG}, 0, 0, FLAGS, .unit = "range" }, + { "in_chroma_loc", "set input chroma sample location", OFFSET(in_chroma_loc), AV_OPT_TYPE_INT, { .i64 = AVCHROMA_LOC_UNSPECIFIED }, 0, AVCHROMA_LOC_NB-1, .flags = FLAGS, .unit = "chroma_loc" }, + { "out_chroma_loc", "set output chroma sample location", OFFSET(out_chroma_loc), AV_OPT_TYPE_INT, { .i64 = AVCHROMA_LOC_UNSPECIFIED }, 0, AVCHROMA_LOC_NB-1, .flags = FLAGS, .unit = "chroma_loc" }, + {"auto", NULL, 0, AV_OPT_TYPE_CONST, {.i64=AVCHROMA_LOC_UNSPECIFIED}, 0, 0, FLAGS, .unit = "chroma_loc"}, + {"unknown", NULL, 0, AV_OPT_TYPE_CONST, {.i64=AVCHROMA_LOC_UNSPECIFIED}, 0, 0, FLAGS, .unit = "chroma_loc"}, + {"left", NULL, 0, AV_OPT_TYPE_CONST, {.i64=AVCHROMA_LOC_LEFT}, 0, 0, FLAGS, .unit = "chroma_loc"}, + {"center", NULL, 0, AV_OPT_TYPE_CONST, {.i64=AVCHROMA_LOC_CENTER}, 0, 0, FLAGS, .unit = "chroma_loc"}, + {"topleft", NULL, 0, AV_OPT_TYPE_CONST, {.i64=AVCHROMA_LOC_TOPLEFT}, 0, 0, FLAGS, .unit = "chroma_loc"}, + {"top", NULL, 0, AV_OPT_TYPE_CONST, {.i64=AVCHROMA_LOC_TOP}, 0, 0, FLAGS, .unit = "chroma_loc"}, + {"bottomleft", NULL, 0, AV_OPT_TYPE_CONST, {.i64=AVCHROMA_LOC_BOTTOMLEFT}, 0, 0, FLAGS, .unit = "chroma_loc"}, + {"bottom", NULL, 0, AV_OPT_TYPE_CONST, {.i64=AVCHROMA_LOC_BOTTOM}, 0, 0, FLAGS, .unit = "chroma_loc"}, { "in_v_chr_pos", "input vertical chroma position in luma grid/256" , OFFSET(in_v_chr_pos), AV_OPT_TYPE_INT, { .i64 = -513}, -513, 512, FLAGS }, { "in_h_chr_pos", "input horizontal chroma position in luma grid/256", OFFSET(in_h_chr_pos), AV_OPT_TYPE_INT, { .i64 = -513}, -513, 512, FLAGS }, { "out_v_chr_pos", "output vertical chroma position in luma grid/256" , OFFSET(out_v_chr_pos), AV_OPT_TYPE_INT, { .i64 = -513}, -513, 512, FLAGS }, -- 2.45.2 _______________________________________________ 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".
next prev parent reply other threads:[~2024-07-04 11:54 UTC|newest] Thread overview: 8+ messages / expand[flat|nested] mbox.gz Atom feed top 2024-07-04 11:51 [FFmpeg-devel] [PATCH 1/6] swscale: document SWS_FULL_CHR_H_* flags Niklas Haas 2024-07-04 11:51 ` [FFmpeg-devel] [PATCH 2/6] avfilter/vf_setparams: allow setting chroma location Niklas Haas 2024-07-04 15:09 ` Paul B Mahol 2024-07-04 11:51 ` [FFmpeg-devel] [PATCH 3/6] avfilter/swscale: always fix interlaced " Niklas Haas 2024-07-04 11:52 ` Niklas Haas [this message] 2024-07-04 12:52 ` [FFmpeg-devel] [PATCH 4/6] avfilter/vf_scale: add in/out_chroma_loc Niklas Haas 2024-07-04 11:52 ` [FFmpeg-devel] [PATCH 5/6] avfilter/vf_zscale: remove unused fields Niklas Haas 2024-07-04 11:52 ` [FFmpeg-devel] [PATCH 6/6] fate/scalechroma: switch to standard chroma location Niklas Haas
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=20240704115202.1235954-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