GL: v210 shader: use Rec. 709 coeffs

This commit is contained in:
Martin Pulec
2022-05-06 16:21:45 +02:00
parent 4db63a3431
commit a51ded322b
3 changed files with 34 additions and 49 deletions

View File

@@ -71,6 +71,35 @@ static const comp_type_t cr_b = (-0.0722/1.5748*224/255) * (1<<COMP_BASE);
#define RGB_TO_CR_709_SCALED(r, g, b) ((r) * cr_r + (g) * cr_g + (b) * cr_b)
#define CLAMP_LIMITED_Y(val, depth) MIN(MAX(val, 1<<(depth-4)), 235 * (1<<(depth-8)));
#define CLAMP_LIMITED_CBCR(val, depth) MIN(MAX(val, 1<<(depth-4)), 240 * (1<<(depth-8)));
#define Y_709 1.164383
#define R_CB_709 0.0
#define R_CR_709 1.792741
#define G_CB_709 -0.213249
#define G_CR_709 -0.532909
#define B_CB_709 2.112402
#define B_CR_709 0.0
// matrix Y1^-1 = inv(Y)
static const comp_type_t y_scale = Y_709 * (1<<COMP_BASE); // precomputed value, Y multiplier is same for all channels
//static const comp_type_t r_y = 1; // during computation already contained in y_scale
//static const comp_type_t r_cb = 0;
static const comp_type_t r_cr = R_CR_709 * (1<<COMP_BASE);
//static const comp_type_t g_y = 1;
static const comp_type_t g_cb = G_CB_709 * (1<<COMP_BASE);
static const comp_type_t g_cr = G_CR_709 * (1<<COMP_BASE);
//static const comp_type_t b_y = 1;
static const comp_type_t b_cb = B_CB_709 * (1<<COMP_BASE);
//static const comp_type_t b_cr = 0;
#define YCBCR_TO_R_709_SCALED(y, cb, cr) ((y) /* * r_y */ /* + (cb) * r_cb */ + (cr) * r_cr)
#define YCBCR_TO_G_709_SCALED(y, cb, cr) ((y) /* * g_y */ + (cb) * g_cb + (cr) * g_cr)
#define YCBCR_TO_B_709_SCALED(y, cb, cr) ((y) /* * b_y */ + (cb) * b_cb /* + (cr) * b_cr */)
#define FULL_FOOT(depth) (1<<((depth)-8))
#define FULL_HEAD(depth) ((255<<((depth)-8))-1)
#define CLAMP_FULL(val, depth) MIN(FULL_HEAD(depth), MAX((val), FULL_FOOT(depth)))
#define FORMAT_RGBA(r, g, b, depth) (~(0xFFU << (rgb_shift[R]) | 0xFFU << (rgb_shift[G]) | 0xFFU << (rgb_shift[B])) | \
(CLAMP_FULL((r), (depth)) << rgb_shift[R] | CLAMP_FULL((g), (depth)) << rgb_shift[G] | CLAMP_FULL((b), (depth)) << rgb_shift[B]))
/// @}
#endif // !defined COLOR_H_CD26B745_C30E_4DA3_8280_C9492B6BFF25

View File

@@ -54,6 +54,7 @@
#include <stdbool.h>
#include <stdint.h>
#include "color.h"
#include "host.h"
#include "hwaccel_vdpau.h"
#include "hwaccel_rpi4.h"
@@ -83,51 +84,6 @@
#pragma GCC diagnostic ignored "-Wunknown-pragmas"
#pragma clang diagnostic warning "-Wpass-failed"
//
// uv_to_av_convert conversions
//
//
/* @brief Color space coedfficients - RGB full range to YCbCr bt. 709 limited range
*
* RGB should use SDI full range [1<<(depth-8)..255<<(depth-8)-1], see [limits]
*
* Scaled by 1<<COMP_BASE, footroom 16/255, headroom 235/255 (luma), 240/255 (chroma); limits [2^(depth-8)..255*2^(depth-8)-1]
* matrix Y = [ 0.182586, 0.614231, 0.062007; -0.100643, -0.338572, 0.4392157; 0.4392157, -0.398942, -0.040274 ]
* * [coefficients]: https://gist.github.com/yohhoy/dafa5a47dade85d8b40625261af3776a "Rec. 709 coefficients"
* * [limits]: https://tech.ebu.ch/docs/r/r103.pdf "SDI limits"
*
* @ingroup lavc_video_conversions
*
* @todo
* Use this transformations in all conversions.
* @{
*/
#define FULL_FOOT(depth) (1<<((depth)-8))
#define FULL_HEAD(depth) ((255<<((depth)-8))-1)
#define CLAMP_FULL(val, depth) MIN(FULL_HEAD(depth), MAX((val), FULL_FOOT(depth)))
typedef int32_t comp_type_t; // int32_t provides much better performance than int_fast32_t
#define COMP_BASE (sizeof(comp_type_t) == 4 ? 14 : 18) // computation will be less precise when comp_type_t is 32 bit
static_assert(sizeof(comp_type_t) * 8 >= COMP_BASE + 18, "comp_type_t not wide enough (we are computing in up to 16 bits!)");
// matrix Y1^-1 = inv(Y)
static const comp_type_t y_scale = 1.164383 * (1<<COMP_BASE); // precomputed value, Y multiplier is same for all channels
//static const comp_type_t r_y = 1; // during computation already contained in y_scale
//static const comp_type_t r_cb = 0;
static const comp_type_t r_cr = 1.792741 * (1<<COMP_BASE);
//static const comp_type_t g_y = 1;
static const comp_type_t g_cb = -0.213249 * (1<<COMP_BASE);
static const comp_type_t g_cr = -0.532909 * (1<<COMP_BASE);
//static const comp_type_t b_y = 1;
static const comp_type_t b_cb = 2.112402 * (1<<COMP_BASE);
//static const comp_type_t b_cr = 0;
#define YCBCR_TO_R_709_SCALED(y, cb, cr) ((y) /* * r_y */ /* + (cb) * r_cb */ + (cr) * r_cr)
#define YCBCR_TO_G_709_SCALED(y, cb, cr) ((y) /* * g_y */ + (cb) * g_cb + (cr) * g_cr)
#define YCBCR_TO_B_709_SCALED(y, cb, cr) ((y) /* * b_y */ + (cb) * b_cb /* + (cr) * b_cr */)
#define FORMAT_RGBA(r, g, b, depth) (~(0xFFU << (rgb_shift[R]) | 0xFFU << (rgb_shift[G]) | 0xFFU << (rgb_shift[B])) | \
(CLAMP_FULL((r), (depth)) << rgb_shift[R] | CLAMP_FULL((g), (depth)) << rgb_shift[G] | CLAMP_FULL((b), (depth)) << rgb_shift[B]))
/// @}
static void nv12_to_uyvy(char * __restrict dst_buffer, AVFrame * __restrict in_frame,
int width, int height, int pitch, const int * __restrict rgb_shift)
{

View File

@@ -68,6 +68,7 @@
#include <string>
#include <string_view>
#include "color.h"
#include "debug.h"
#include "gl_context.h"
#include "host.h"
@@ -136,10 +137,9 @@ uniform float imageWidthOrig;
const vec3 yuvOffset = vec3(-0.0625, -0.5, -0.5);
// RGB coefficients
// BT.601 colorspace
const vec3 Rcoeff = vec3(1.1643, 0.000, 1.5958);
const vec3 Gcoeff = vec3(1.1643, -0.39173, -0.81290);
const vec3 Bcoeff = vec3(1.1643, 2.017, 0.000);
const vec3 Rcoeff = vec3()raw" TOSTRING(Y_709) ", " TOSTRING(R_CB_709) ", " TOSTRING(R_CR_709) R"raw();
const vec3 Gcoeff = vec3()raw" TOSTRING(Y_709) ", " TOSTRING(G_CB_709) ", " TOSTRING(G_CR_709) R"raw();
const vec3 Bcoeff = vec3()raw" TOSTRING(Y_709) ", " TOSTRING(B_CB_709) ", " TOSTRING(B_CR_709) R"raw();
// U Y V A | Y U Y A | V Y U A | Y V Y A