From patchwork Tue Oct 6 23:03:16 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: =?utf-8?q?Jan_Ekstr=C3=B6m?= X-Patchwork-Id: 22744 Return-Path: X-Original-To: patchwork@ffaux-bg.ffmpeg.org Delivered-To: patchwork@ffaux-bg.ffmpeg.org Received: from ffbox0-bg.mplayerhq.hu (ffbox0-bg.ffmpeg.org [79.124.17.100]) by ffaux.localdomain (Postfix) with ESMTP id A47D8449516 for ; Wed, 7 Oct 2020 02:11:31 +0300 (EEST) Received: from [127.0.1.1] (localhost [127.0.0.1]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTP id 63C8568B5F8; Wed, 7 Oct 2020 02:11:31 +0300 (EEST) X-Original-To: ffmpeg-devel@ffmpeg.org Delivered-To: ffmpeg-devel@ffmpeg.org Received: from mail-lj1-f180.google.com (mail-lj1-f180.google.com [209.85.208.180]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTPS id 1A2FD68AF30 for ; Wed, 7 Oct 2020 02:11:23 +0300 (EEST) Received: by mail-lj1-f180.google.com with SMTP id a5so34963ljj.11 for ; Tue, 06 Oct 2020 16:11:23 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:subject:date:message-id:mime-version :content-transfer-encoding; bh=PmcdnJQsqTVe8NYAQgfhqex2k+OSI8Z4DaIMmHc/O6o=; b=D8GD4NMVqF2WKnoHWTVWflx4mrZXC5MyVR/EKfVR5LFXyvRRkAW5NoFTmvO/aMbqyC RjEY2RZRNXnfPH6Ib/2IKnoZtq23vqIRxqyChDvoGJarkPUf7Vkl7DjULSXmIwEMd3ra /me4YYST204AufDOlzg1CQQK4yyn7TKHDVH9RYvrZoHcSipHBEcBQJbwi8+TK6K3m0sY 3fNc3l/jyEEp7BXg9rlOjKCU6IuK2ArrnKiztFYfD5kfP9RWjfXRcSDkyEGWKpsUfvva 9FYWzX/j7cjkxBihc18Fwf4Z73Dhr06+hUJYir1Lad/tXUTVmR6EUTSdU8yzIXvVMH6o V8oQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:subject:date:message-id:mime-version :content-transfer-encoding; bh=PmcdnJQsqTVe8NYAQgfhqex2k+OSI8Z4DaIMmHc/O6o=; b=aKFgcnZYGPCJoYfPseMGCa9PiExlJRah7/ltGehL5UYjZBFHQG6rQAjJ8n/gQqKlvr L8IKMpBAqMNSwy/Krd7cb1kyHezde9lSzWd7ZnVX9sXxZ0z2YDef5NsUXWnIuXI4qZiQ h1g+Ks1T8H0upjeqiGgwAj4mwl9CKnZsOai4K8MPsVfW/NHILe84midSnNyIn6dt6PXW Je6sWjej6sFZz5Ky0J0RbrMkKtP97uTGkopsIdJXlnX75PzShOY17AJGfgDyb1z5xQDP NfnSKDifB3sXU6AJTlSwA8ou1sgEbqSZxUNqdutCcLZry/TttEpLg1KSuSy9stZXn+4N 2QlA== X-Gm-Message-State: AOAM532ejpqpsTKL45gyJ0MYgK+O6Hd+OrKFEJA5wMPS8QWmYbDSizuN tXGhqZ2RAT3xPGsUI7BvEAeWfFrc3YI= X-Google-Smtp-Source: ABdhPJyS+FKl4sLTJ2cE7GkMQinAB70FdGDpvBOgoBHwpPC0Eqi3V+Ur89peZqHnnzFwyuHOFGWT1g== X-Received: by 2002:a19:3f55:: with SMTP id m82mr29532lfa.491.1602025399377; Tue, 06 Oct 2020 16:03:19 -0700 (PDT) Received: from localhost.localdomain (91-159-194-103.elisa-laajakaista.fi. [91.159.194.103]) by smtp.gmail.com with ESMTPSA id y184sm52558lfa.245.2020.10.06.16.03.18 for (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 06 Oct 2020 16:03:18 -0700 (PDT) From: =?utf-8?q?Jan_Ekstr=C3=B6m?= To: ffmpeg-devel@ffmpeg.org Date: Wed, 7 Oct 2020 02:03:16 +0300 Message-Id: <20201006230317.15516-1-jeebjp@gmail.com> X-Mailer: git-send-email 2.26.2 MIME-Version: 1.0 Subject: [FFmpeg-devel] [PATCH 1/2] swscale/swscale_internal: interpret RGB paletted pixel formats as RGB X-BeenThere: ffmpeg-devel@ffmpeg.org X-Mailman-Version: 2.1.20 Precedence: list List-Id: FFmpeg development discussions and patches List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Reply-To: FFmpeg development discussions and patches Errors-To: ffmpeg-devel-bounces@ffmpeg.org Sender: "ffmpeg-devel" This makes isAnyRGB return true for AV_PIX_FMT_PAL8 which is currently the only pixel format with this flag. This lets us have a single query for formats where we need to force range as only full range content is supported. --- libswscale/swscale_internal.h | 2 +- tests/ref/fate/sws-pixdesc-query | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/libswscale/swscale_internal.h b/libswscale/swscale_internal.h index d207d3beff..013ad51299 100644 --- a/libswscale/swscale_internal.h +++ b/libswscale/swscale_internal.h @@ -775,7 +775,7 @@ static av_always_inline int isAnyRGB(enum AVPixelFormat pix_fmt) { const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(pix_fmt); av_assert0(desc); - return (desc->flags & AV_PIX_FMT_FLAG_RGB) || + return (desc->flags & (AV_PIX_FMT_FLAG_RGB | AV_PIX_FMT_FLAG_PAL)) || pix_fmt == AV_PIX_FMT_MONOBLACK || pix_fmt == AV_PIX_FMT_MONOWHITE; } diff --git a/tests/ref/fate/sws-pixdesc-query b/tests/ref/fate/sws-pixdesc-query index c3cccfa492..42e82389af 100644 --- a/tests/ref/fate/sws-pixdesc-query +++ b/tests/ref/fate/sws-pixdesc-query @@ -570,6 +570,7 @@ AnyRGB: gbrpf32le monob monow + pal8 rgb0 rgb24 rgb32 From patchwork Tue Oct 6 23:03:17 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: =?utf-8?q?Jan_Ekstr=C3=B6m?= X-Patchwork-Id: 22745 Return-Path: X-Original-To: patchwork@ffaux-bg.ffmpeg.org Delivered-To: patchwork@ffaux-bg.ffmpeg.org Received: from ffbox0-bg.mplayerhq.hu (ffbox0-bg.ffmpeg.org [79.124.17.100]) by ffaux.localdomain (Postfix) with ESMTP id 201BE449516 for ; Wed, 7 Oct 2020 02:11:51 +0300 (EEST) Received: from [127.0.1.1] (localhost [127.0.0.1]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTP id 0B58F68B6C9; Wed, 7 Oct 2020 02:11:51 +0300 (EEST) X-Original-To: ffmpeg-devel@ffmpeg.org Delivered-To: ffmpeg-devel@ffmpeg.org Received: from mail-lj1-f196.google.com (mail-lj1-f196.google.com [209.85.208.196]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTPS id 650F768B6CC for ; Wed, 7 Oct 2020 02:11:44 +0300 (EEST) Received: by mail-lj1-f196.google.com with SMTP id 133so78029ljj.0 for ; Tue, 06 Oct 2020 16:11:44 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:subject:date:message-id:in-reply-to:references:mime-version :content-transfer-encoding; bh=I25AfjXcJcF5EcAbJMRaWSjgtlOkJplSxIeC0M4Den0=; b=gjAg2dhtePlgCOYoF+ovH1etmauk/bjDD0Z8U9vTU3iV+k6nZsTcgdB7cz25L82QSb /AEBlojftpyfTV584XrvHAWEipAC7kxYwb9bSkB8o+r3/pvMPzzIi9zyD+WwLDcZMFLo /JC895Zun6FUUuuDJpJ6OWtW5kTT0lNF/DaNHlRInNBRr2RQiiyrh9FsjbovRErw90dQ i6MzxhLQIrFvGL9OjfR4H7XmliVkhhKYRhqSAJOCrUN8NN36Dg5q4KeDNXupQccvV7vA reaDfbHiKhxpRpBSTIbUAOpHvOvaMHxSqudTWP+Nc2w1qmAzVnHidkf0rhYJ1UPzL5+7 GTKg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=I25AfjXcJcF5EcAbJMRaWSjgtlOkJplSxIeC0M4Den0=; b=OK9E6oJIlkOXait/5EuxkP7Z6LNHcZVFnxIIrBctKg6VRvNB+QGLfhBB4eD2mWDUGN XW4ho2mZMWSyCjNA6VJpeo5WZy+HT8aaY+G85LiRQb8QW91EhyTN+Pqad+DNhaMAvSwD xWTa4Nh32fa3T/02lv0AUSvvO9KgwjsttQMXcUTBFQwC9LHikJBQFqeo4lIHtWr0VQff fSrYW+9bXFZdSX/FIJldj5/puc1f/cprQdpvNMGesyApMUjTPx7085x5/cQaGvo1f+Pg OErRavSwZ6ynajj6m3P2dPUsTRRx9ba7roVIIGwJvSNDu9XbrEXAfmuFAYqIVsGX6zlK 80FA== X-Gm-Message-State: AOAM533GXj0cNdBUUbJ0eqTSjI7eVBX5PEdotmysVEvzj10s/DqMz96h 4uBAwSA0fb5cKaPTg8RW63Ra8r4DjGQ= X-Google-Smtp-Source: ABdhPJw/8WoEO7a6ZXq8H6Kw5rN8HSVg1GTBuD8EOtDSTIdqksdn+0lh81ToAse4Olexk0yu8RYpAA== X-Received: by 2002:a05:651c:1307:: with SMTP id u7mr106920lja.267.1602025400272; Tue, 06 Oct 2020 16:03:20 -0700 (PDT) Received: from localhost.localdomain (91-159-194-103.elisa-laajakaista.fi. [91.159.194.103]) by smtp.gmail.com with ESMTPSA id y184sm52558lfa.245.2020.10.06.16.03.19 for (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 06 Oct 2020 16:03:19 -0700 (PDT) From: =?utf-8?q?Jan_Ekstr=C3=B6m?= To: ffmpeg-devel@ffmpeg.org Date: Wed, 7 Oct 2020 02:03:17 +0300 Message-Id: <20201006230317.15516-2-jeebjp@gmail.com> X-Mailer: git-send-email 2.26.2 In-Reply-To: <20201006230317.15516-1-jeebjp@gmail.com> References: <20201006230317.15516-1-jeebjp@gmail.com> MIME-Version: 1.0 Subject: [FFmpeg-devel] [PATCH 2/2] swscale: separate exported and internal range flags X-BeenThere: ffmpeg-devel@ffmpeg.org X-Mailman-Version: 2.1.20 Precedence: list List-Id: FFmpeg development discussions and patches List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Reply-To: FFmpeg development discussions and patches Errors-To: ffmpeg-devel-bounces@ffmpeg.org Sender: "ffmpeg-devel" Fixes vf_scale outputting RGB AVFrames with limited range in case either input or output specifically sets the range. Keeps the external interfaces the same, but allows us to retrieve and set nonzero value for RGB. Additionally defines the default value of the AVOption as -1 so we can differentiate between attempting to force limited range and requesting the default. --- libswscale/options.c | 4 +- libswscale/swscale_internal.h | 3 + libswscale/utils.c | 154 +++++++++++++++++++++++----------- 3 files changed, 108 insertions(+), 53 deletions(-) diff --git a/libswscale/options.c b/libswscale/options.c index 7eb2752543..48dcfc7634 100644 --- a/libswscale/options.c +++ b/libswscale/options.c @@ -59,8 +59,8 @@ static const AVOption swscale_options[] = { { "dsth", "destination height", OFFSET(dstH), AV_OPT_TYPE_INT, { .i64 = 16 }, 1, INT_MAX, VE }, { "src_format", "source format", OFFSET(srcFormat), AV_OPT_TYPE_PIXEL_FMT,{ .i64 = DEFAULT }, 0, INT_MAX, VE }, { "dst_format", "destination format", OFFSET(dstFormat), AV_OPT_TYPE_PIXEL_FMT,{ .i64 = DEFAULT }, 0, INT_MAX, VE }, - { "src_range", "source is full range", OFFSET(srcRange), AV_OPT_TYPE_BOOL, { .i64 = DEFAULT }, 0, 1, VE }, - { "dst_range", "destination is full range", OFFSET(dstRange), AV_OPT_TYPE_BOOL, { .i64 = DEFAULT }, 0, 1, VE }, + { "src_range", "source is full range", OFFSET(exported_srcRange), AV_OPT_TYPE_BOOL, { .i64 = -1 }, -1, 1, VE }, + { "dst_range", "destination is full range", OFFSET(exported_dstRange), AV_OPT_TYPE_BOOL, { .i64 = -1 }, -1, 1, VE }, { "param0", "scaler param 0", OFFSET(param[0]), AV_OPT_TYPE_DOUBLE, { .dbl = SWS_PARAM_DEFAULT }, INT_MIN, INT_MAX, VE }, { "param1", "scaler param 1", OFFSET(param[1]), AV_OPT_TYPE_DOUBLE, { .dbl = SWS_PARAM_DEFAULT }, INT_MIN, INT_MAX, VE }, diff --git a/libswscale/swscale_internal.h b/libswscale/swscale_internal.h index 013ad51299..7ce475de85 100644 --- a/libswscale/swscale_internal.h +++ b/libswscale/swscale_internal.h @@ -625,6 +625,9 @@ typedef struct SwsContext { SwsDither dither; SwsAlphaBlend alphablend; + + int exported_srcRange; + int exported_dstRange; } SwsContext; //FIXME check init (where 0) diff --git a/libswscale/utils.c b/libswscale/utils.c index 9ca378bd3b..11e0898360 100644 --- a/libswscale/utils.c +++ b/libswscale/utils.c @@ -864,6 +864,69 @@ static void fill_xyztables(struct SwsContext *c) } } +static int handle_jpeg(enum AVPixelFormat *format) +{ + switch (*format) { + case AV_PIX_FMT_YUVJ420P: + *format = AV_PIX_FMT_YUV420P; + return 1; + case AV_PIX_FMT_YUVJ411P: + *format = AV_PIX_FMT_YUV411P; + return 1; + case AV_PIX_FMT_YUVJ422P: + *format = AV_PIX_FMT_YUV422P; + return 1; + case AV_PIX_FMT_YUVJ444P: + *format = AV_PIX_FMT_YUV444P; + return 1; + case AV_PIX_FMT_YUVJ440P: + *format = AV_PIX_FMT_YUV440P; + return 1; + case AV_PIX_FMT_GRAY8: + case AV_PIX_FMT_YA8: + case AV_PIX_FMT_GRAY9LE: + case AV_PIX_FMT_GRAY9BE: + case AV_PIX_FMT_GRAY10LE: + case AV_PIX_FMT_GRAY10BE: + case AV_PIX_FMT_GRAY12LE: + case AV_PIX_FMT_GRAY12BE: + case AV_PIX_FMT_GRAY14LE: + case AV_PIX_FMT_GRAY14BE: + case AV_PIX_FMT_GRAY16LE: + case AV_PIX_FMT_GRAY16BE: + case AV_PIX_FMT_YA16BE: + case AV_PIX_FMT_YA16LE: + return 1; + default: + return 0; + } +} + +static int check_format_range(SwsContext *c, enum AVPixelFormat *format, + int range, const char *descriptor) +{ + const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(*format); + int default_range = handle_jpeg(format); + av_assert0(desc); + + if (isAnyRGB(*format) && !range) { + // first, handle the special case of limited range RGB + av_log(c, AV_LOG_WARNING, + "%s range set to limited for %s, unsupported! " + "Overriding to full range.\n", + descriptor ? descriptor : "Color", desc->name); + + return 1; + } + + + if (range != -1) + // for YCbCr and gray, we return the value if set + return range; + + return isAnyRGB(*format) ? 1 : default_range; +} + int sws_setColorspaceDetails(struct SwsContext *c, const int inv_table[4], int srcRange, const int table[4], int dstRange, int brightness, int contrast, int saturation) @@ -876,10 +939,23 @@ int sws_setColorspaceDetails(struct SwsContext *c, const int inv_table[4], desc_dst = av_pix_fmt_desc_get(c->dstFormat); desc_src = av_pix_fmt_desc_get(c->srcFormat); - if(!isYUV(c->dstFormat) && !isGray(c->dstFormat)) - dstRange = 0; - if(!isYUV(c->srcFormat) && !isGray(c->srcFormat)) - srcRange = 0; + if (dstRange == -1) { + dstRange = c->dstRange; + } else { + c->exported_dstRange = check_format_range(c, &c->dstFormat, + dstRange, + "Destination"); + dstRange = isAnyRGB(c->dstFormat) ? 0 : c->exported_dstRange; + } + + if (srcRange == -1) { + srcRange = c->srcRange; + } else { + c->exported_srcRange = check_format_range(c, &c->srcFormat, + srcRange, + "Source"); + srcRange = isAnyRGB(c->srcFormat) ? 0 : c->exported_srcRange; + } if (c->srcRange != srcRange || c->dstRange != dstRange || @@ -911,7 +987,7 @@ int sws_setColorspaceDetails(struct SwsContext *c, const int inv_table[4], c->srcFormatBpp = av_get_bits_per_pixel(desc_src); if (c->cascaded_context[c->cascaded_mainindex]) - return sws_setColorspaceDetails(c->cascaded_context[c->cascaded_mainindex],inv_table, srcRange,table, dstRange, brightness, contrast, saturation); + return sws_setColorspaceDetails(c->cascaded_context[c->cascaded_mainindex],inv_table, c->exported_srcRange,table, c->exported_dstRange, brightness, contrast, saturation); if (!need_reinit) return 0; @@ -968,7 +1044,8 @@ int sws_setColorspaceDetails(struct SwsContext *c, const int inv_table[4], return ret; //we set both src and dst depending on that the RGB side will be ignored sws_setColorspaceDetails(c->cascaded_context[0], inv_table, - srcRange, table, dstRange, + c->exported_srcRange, table, + c->exported_dstRange, brightness, contrast, saturation); c->cascaded_context[1] = sws_getContext(tmp_width, tmp_height, tmp_format, @@ -977,7 +1054,8 @@ int sws_setColorspaceDetails(struct SwsContext *c, const int inv_table[4], if (!c->cascaded_context[1]) return -1; sws_setColorspaceDetails(c->cascaded_context[1], inv_table, - srcRange, table, dstRange, + c->exported_srcRange, table, + c->exported_dstRange, 0, 1 << 16, 1 << 16); return 0; } @@ -1008,8 +1086,8 @@ int sws_getColorspaceDetails(struct SwsContext *c, int **inv_table, *inv_table = c->srcColorspaceTable; *table = c->dstColorspaceTable; - *srcRange = c->srcRange; - *dstRange = c->dstRange; + *srcRange = c->exported_srcRange; + *dstRange = c->exported_dstRange; *brightness = c->brightness; *contrast = c->contrast; *saturation = c->saturation; @@ -1017,44 +1095,6 @@ int sws_getColorspaceDetails(struct SwsContext *c, int **inv_table, return 0; } -static int handle_jpeg(enum AVPixelFormat *format) -{ - switch (*format) { - case AV_PIX_FMT_YUVJ420P: - *format = AV_PIX_FMT_YUV420P; - return 1; - case AV_PIX_FMT_YUVJ411P: - *format = AV_PIX_FMT_YUV411P; - return 1; - case AV_PIX_FMT_YUVJ422P: - *format = AV_PIX_FMT_YUV422P; - return 1; - case AV_PIX_FMT_YUVJ444P: - *format = AV_PIX_FMT_YUV444P; - return 1; - case AV_PIX_FMT_YUVJ440P: - *format = AV_PIX_FMT_YUV440P; - return 1; - case AV_PIX_FMT_GRAY8: - case AV_PIX_FMT_YA8: - case AV_PIX_FMT_GRAY9LE: - case AV_PIX_FMT_GRAY9BE: - case AV_PIX_FMT_GRAY10LE: - case AV_PIX_FMT_GRAY10BE: - case AV_PIX_FMT_GRAY12LE: - case AV_PIX_FMT_GRAY12BE: - case AV_PIX_FMT_GRAY14LE: - case AV_PIX_FMT_GRAY14BE: - case AV_PIX_FMT_GRAY16LE: - case AV_PIX_FMT_GRAY16BE: - case AV_PIX_FMT_YA16BE: - case AV_PIX_FMT_YA16LE: - return 1; - default: - return 0; - } -} - static int handle_0alpha(enum AVPixelFormat *format) { switch (*format) { @@ -1200,16 +1240,28 @@ av_cold int sws_init_context(SwsContext *c, SwsFilter *srcFilter, unscaled = (srcW == dstW && srcH == dstH); - c->srcRange |= handle_jpeg(&c->srcFormat); - c->dstRange |= handle_jpeg(&c->dstFormat); + av_log(c, AV_LOG_VERBOSE, "Initial configured range values: src: %d, dst: %d\n", + c->exported_srcRange, c->exported_dstRange); + + c->exported_srcRange = check_format_range(c, &c->srcFormat, + c->exported_srcRange, + "Source"); + c->exported_dstRange = check_format_range(c, &c->dstFormat, + c->exported_dstRange, + "Destination"); + + // convert exported range to internal + c->srcRange = isAnyRGB(srcFormat) ? 0 : c->exported_srcRange; + c->dstRange = isAnyRGB(dstFormat) ? 0 : c->exported_dstRange; if(srcFormat!=c->srcFormat || dstFormat!=c->dstFormat) av_log(c, AV_LOG_WARNING, "deprecated pixel format used, make sure you did set range correctly\n"); if (!c->contrast && !c->saturation && !c->dstFormatBpp) - sws_setColorspaceDetails(c, ff_yuv2rgb_coeffs[SWS_CS_DEFAULT], c->srcRange, + sws_setColorspaceDetails(c, ff_yuv2rgb_coeffs[SWS_CS_DEFAULT], + c->exported_srcRange, ff_yuv2rgb_coeffs[SWS_CS_DEFAULT], - c->dstRange, 0, 1 << 16, 1 << 16); + c->exported_dstRange, 0, 1 << 16, 1 << 16); handle_formats(c); srcFormat = c->srcFormat;