Opened 3 years ago
Closed 14 months ago
#10136 closed defect (fixed)
Can't convert color range with sws_scale
| Reported by: | diogo.r | Owned by: | |
|---|---|---|---|
| Priority: | normal | Component: | swscale |
| Version: | git-master | Keywords: | |
| Cc: | Blocked By: | ||
| Blocking: | Reproduced by developer: | no | |
| Analyzed by developer: | no |
Description
Summary of the bug:
I'm trying to convert a frame with sws_scale while selecting the color range of the input and output, but for some input formats it doesn't work, it ignores the color ranges I set. I looked into it and found weird this check in 'libswscale/utils.c:1046':
//The srcBpc check is possibly wrong but we seem to lack a definitive reference to test this
//and what we have in ticket 2939 looks better with this check
if (need_reinit && (c->srcBpc == 8 || !isYUV(c->srcFormat)))
ff_sws_init_range_convert(c);
I looked at ticket 2939, but didn't find reasoning about why the (c->srcBpc == 8 || !isYUV(c->srcFormat) check is necessary.
How to reproduce:
extern "C"
{
#include <libswscale/swscale.h>
}
#include "assert.h"
int main() {
AVPixelFormat in_pix_fmt = AVPixelFormat::AV_PIX_FMT_YUV420P10LE;
AVPixelFormat out_pix_fmt = AVPixelFormat::AV_PIX_FMT_YUV420P;
int width = 32;
int height = 32;
SwsContext *sws_ctx = (struct SwsContext*)sws_getContext(
width,
height,
in_pix_fmt,
width,
height,
out_pix_fmt,
SWS_BILINEAR,
NULL,
NULL,
NULL
);
int *table = NULL;
int *inv_table = NULL;
int srcRange = -1;
int dstRange = -1;
int brightness = -1;
int contrast = -1;
int saturation = -1;
int res = sws_getColorspaceDetails(
sws_ctx,
&inv_table,
&srcRange,
&table,
&dstRange,
&brightness,
&contrast,
&saturation
);
assert(res == 0);
printf(
R"(
srcRange = %d
dstRange = %d
brightness = %d
contrast = %d
saturation = %d
table = [%d, %d, %d, %d]
inv_table = [%d, %d, %d, %d]
)",
srcRange,
dstRange,
brightness,
contrast,
saturation,
table[0],
table[1],
table[2],
table[3],
inv_table[0],
inv_table[1],
inv_table[2],
inv_table[3]
);
srcRange = 1;
res = sws_setColorspaceDetails(
sws_ctx,
inv_table,
srcRange,
table,
dstRange,
brightness,
contrast,
saturation
);
// Do the conversion
// sws_scale(...)
assert(res == 0);
return 0;
}
Change History (6)
comment:2 by , 3 years ago
According with this comment (http://git.videolan.org/?p=ffmpeg.git;a=commitdiff;h=e645a1ddb90a863e129108aad9aa7e2d417f3615) the problem is that when setting color range options after initializing sws_scale, some fast paths might already be chosen and we can't change it anymore.
I'm wondering if it works when I set everything at the beginning, like so:
SwsContext *sws_ctx = (struct SwsContext*)sws_alloc_context(); av_opt_set_int(sws_ctx, "srcw", width, 0); av_opt_set_int(sws_ctx, "srch", height, 0); av_opt_set_int(sws_ctx, "src_format", in_pix_fmt, 0); av_opt_set_int(sws_ctx, "dstw", width, 0); av_opt_set_int(sws_ctx, "dsth", height, 0); av_opt_set_int(sws_ctx, "dst_format", out_pix_fmt, 0); av_opt_set_int(sws_ctx, "sws_flags", SWS_BILINEAR, 0); av_opt_set_int(sws_ctx, "param0", NULL, 0); av_opt_set_int(sws_ctx, "param1", NULL, 0); av_opt_set_int(sws_ctx, "src_range", 1, 0); // av_opt_set_int(sws_ctx, "dst_range", 1, 0); int res = sws_init_context(sws_ctx, NULL, NULL);
It seems to work, is that the proper way to do it? If that's the case, it might be helpful to return an error for my first attempt.
comment:3 by , 3 years ago
comment:4 by , 3 years ago
I read through those issues, but I still don't understand how what you said @Balling relates to this issue, could you please clarify? Also keep in mind I'm not an expert in ffmpeg nor colorspace stuff.
comment:5 by , 3 years ago
The problem with returning an error is to point out where in the code that error should be.
comment:6 by , 14 months ago
| Resolution: | → fixed |
|---|---|
| Status: | new → closed |
This one should be fixed by using the new API (which vf_scale uses). Tentatively closing for now.



That was added in b53bdae11f1eceea1a2e25a98aee81e1d1954e14
It says it is needed for rgb to full range YCbCr convertion.
I was testing #3785.
Without 4959a4fcf76e7c595dbb23c4e3bf59abf2e60ea4 it will not even work at all.