mirror of
https://github.com/FFmpeg/FFmpeg.git
synced 2026-11-06 05:17:42 +00:00
avutil/csp: apply only the transfer in the ST 428-1 EOTF
The EOTF scaled X and Z by the X/Y and Z/Y of the DCI white, the
reference projector of RP 431-2, which ST 428-1 does not define: it
fixes the transfer alone, 52.37/48 above the 48 cd/m2 white. Treat the
three channels alike, L = (Lw - Lb) * 52.37/48 * V^2.6 + Lb, through the
wrappers of the other SDR curves. Equal in each channel, the black is
neutral in RGB only. The black of X'Y'Z' has the white of its content,
which only the RGB it is decoded into knows, so the documentation asks
for Lb = 0 on X'Y'Z' samples and their black after that conversion. A
gray of the reference projector came out at the chromaticity (0.298,
0.366) instead of its own. Broken since 06f084468e.
Signed-off-by: Kacper Michajłow <kasper93@gmail.com>
This commit is contained in:
1 parent
61ae1901c7
commit
89ca1261d0
3 files changed
+15
-40
No files matched your search
+2
-28
@@ -537,6 +537,7 @@ static void oetf_##name##_inv(double E[3]) \
|
||||
WRAP_SDR_OETF(gamma22)
|
||||
WRAP_SDR_OETF(gamma28)
|
||||
WRAP_SDR_OETF(iec61966_2_1)
|
||||
WRAP_SDR_OETF(smpte_st428_1)
|
||||
|
||||
#define WRAP_SDR_EOTF(name) \
|
||||
static void eotf_##name(double Lw, double Lb, double E[3]) \
|
||||
@@ -554,6 +555,7 @@ static void eotf_##name##_inv(double Lw, double Lb, double L[3]) \
|
||||
WRAP_SDR_EOTF(gamma22)
|
||||
WRAP_SDR_EOTF(gamma28)
|
||||
WRAP_SDR_EOTF(iec61966_2_1)
|
||||
WRAP_SDR_EOTF(smpte_st428_1)
|
||||
|
||||
static void eotf_bt1886(const double Lw, const double Lb, double E[3])
|
||||
{
|
||||
@@ -589,34 +591,6 @@ static void eotf_smpte_st2084_inv(const double Lw, const double Lb, double L[3])
|
||||
L[i] = trc_smpte_st2084(L[i]);
|
||||
}
|
||||
|
||||
/* This implementation assumes an SMPTE RP 431-2 reference projector (DCI) */
|
||||
#define DCI_L 48.00
|
||||
#define DCI_P 52.37
|
||||
#define DCI_X (42.94 / DCI_L)
|
||||
#define DCI_Z (45.82 / DCI_L)
|
||||
|
||||
static void eotf_smpte_st428_1(const double Lw_Y, const double Lb_Y, double E[3])
|
||||
{
|
||||
const double Lw[3] = { DCI_X * Lw_Y, Lw_Y, DCI_Z * Lw_Y };
|
||||
const double Lb[3] = { DCI_X * Lb_Y, Lb_Y, DCI_Z * Lb_Y };
|
||||
|
||||
for (int i = 0; i < 3; i++) {
|
||||
E[i] = (0.0 > E[i]) ? 0.0 : pow(E[i], 2.6) * DCI_P / DCI_L;
|
||||
E[i] = E[i] * (Lw[i] - Lb[i]) + Lb[i];
|
||||
}
|
||||
}
|
||||
|
||||
static void eotf_smpte_st428_1_inv(const double Lw_Y, const double Lb_Y, double L[3])
|
||||
{
|
||||
const double Lw[3] = { DCI_X * Lw_Y, Lw_Y, DCI_Z * Lw_Y };
|
||||
const double Lb[3] = { DCI_X * Lb_Y, Lb_Y, DCI_Z * Lb_Y };
|
||||
|
||||
for (int i = 0; i < 3; i++) {
|
||||
L[i] = (L[i] - Lb[i]) / (Lw[i] - Lb[i]);
|
||||
L[i] = (0.0 > L[i]) ? 0.0 : pow(L[i] * DCI_L / DCI_P, 1.0 / 2.6);
|
||||
}
|
||||
}
|
||||
|
||||
static void eotf_arib_std_b67(const double Lw, const double Lb, double E[3])
|
||||
{
|
||||
const double gamma = fmax(1.2 + 0.42 * log10(Lw / 1000.0), 1.0);
|
||||
|
||||
+3
-2
@@ -180,8 +180,9 @@ typedef void (*av_csp_eotf_function)(double Lw, double Lb, double c[3]);
|
||||
/**
|
||||
* Returns the ITU EOTF corresponding to a given TRC. This converts from the
|
||||
* signal level [0,1] to the raw output display luminance in nits (cd/m^2).
|
||||
* This is done per channel in RGB space, except for AVCOL_TRC_SMPTE428, which
|
||||
* assumes CIE XYZ in- and output.
|
||||
* This is done per channel in RGB space. For X'Y'Z' with AVCOL_TRC_SMPTE428,
|
||||
* pass Lb = 0 and apply the black level after the conversion to RGB for correct
|
||||
* white point scaling.
|
||||
*
|
||||
* @return A pointer to the function implementing the given TRC, or NULL if no
|
||||
* such function is defined.
|
||||
|
||||
+10
-10
@@ -2741,16 +2741,16 @@ trc=bt2020-12 EOTF(10000, 1.5, {0.7}) = {4360.83}
|
||||
trc=bt2020-12 EOTF(10000, 1.5, {0.8}) = {5943.5}
|
||||
trc=bt2020-12 EOTF(10000, 1.5, {0.9}) = {7818.66}
|
||||
trc=bt2020-12 EOTF(10000, 1.5, {1}) = {10000}
|
||||
trc=smpte428 EOTF(48.024, 0.024012, {0.0925519, 0.0967033, 0.0949939}) = {0.11771, 0.144579 0.132798}, expected Y=0.140000
|
||||
trc=smpte428 EOTF(48.024, 0.024012, {0.185348, 0.193407, 0.189988}) = {0.606907, 0.754996 0.689089}, expected Y=0.750000
|
||||
trc=smpte428 EOTF(48.024, 0.024012, {0.2779, 0.29011, 0.284982}) = {1.69956, 2.12172 1.93462}, expected Y=2.120000
|
||||
trc=smpte428 EOTF(48.024, 0.024012, {0.370696, 0.386813, 0.379976}) = {3.57084, 4.45587 4.0618}, expected Y=4.450000
|
||||
trc=smpte428 EOTF(48.024, 0.024012, {0.463248, 0.483516, 0.474969}) = {6.35753, 7.94085 7.23777}, expected Y=7.940000
|
||||
trc=smpte428 EOTF(48.024, 0.024012, {0.5558, 0.58022, 0.569963}) = {10.1955, 12.7421 11.6133}, expected Y=12.740000
|
||||
trc=smpte428 EOTF(48.024, 0.024012, {0.648596, 0.676923, 0.664957}) = {15.2212, 19.0123 17.3275}, expected Y=19.010000
|
||||
trc=smpte428 EOTF(48.024, 0.024012, {0.741148, 0.773626, 0.759951}) = {21.5223, 26.8938 24.5101}, expected Y=26.890000
|
||||
trc=smpte428 EOTF(48.024, 0.024012, {0.833944, 0.87033, 0.854945}) = {29.2401, 36.5213 33.284}, expected Y=36.520000
|
||||
trc=smpte428 EOTF(48.024, 0.024012, {0.926496, 0.967033, 0.949939}) = {38.4361, 48.0228 43.7656}, expected Y=48.020000
|
||||
trc=smpte428 EOTF(48.024, 0.024012, {0.0925519, 0.0967033, 0.0949939}) = {0.13158, 0.144579 0.139116}, expected Y=0.140000
|
||||
trc=smpte428 EOTF(48.024, 0.024012, {0.185348, 0.193407, 0.189988}) = {0.678424, 0.754996 0.721874}, expected Y=0.750000
|
||||
trc=smpte428 EOTF(48.024, 0.024012, {0.2779, 0.29011, 0.284982}) = {1.89984, 2.12172 2.02667}, expected Y=2.120000
|
||||
trc=smpte428 EOTF(48.024, 0.024012, {0.370696, 0.386813, 0.379976}) = {3.99162, 4.45587 4.25505}, expected Y=4.450000
|
||||
trc=smpte428 EOTF(48.024, 0.024012, {0.463248, 0.483516, 0.474969}) = {7.10669, 7.94085 7.58213}, expected Y=7.940000
|
||||
trc=smpte428 EOTF(48.024, 0.024012, {0.5558, 0.58022, 0.569963}) = {11.3969, 12.7421 12.1659}, expected Y=12.740000
|
||||
trc=smpte428 EOTF(48.024, 0.024012, {0.648596, 0.676923, 0.664957}) = {17.0149, 19.0123 18.1519}, expected Y=19.010000
|
||||
trc=smpte428 EOTF(48.024, 0.024012, {0.741148, 0.773626, 0.759951}) = {24.0585, 26.8938 25.6763}, expected Y=26.890000
|
||||
trc=smpte428 EOTF(48.024, 0.024012, {0.833944, 0.87033, 0.854945}) = {32.6857, 36.5213 34.8675}, expected Y=36.520000
|
||||
trc=smpte428 EOTF(48.024, 0.024012, {0.926496, 0.967033, 0.949939}) = {42.9653, 48.0228 45.8478}, expected Y=48.020000
|
||||
trc=arib-std-b67 EOTF(50, 0, {0}) = {0}
|
||||
trc=arib-std-b67 EOTF(50, 0, {0.1}) = {0.166667}
|
||||
trc=arib-std-b67 EOTF(50, 0, {0.2}) = {0.666667}
|
||||
|
||||
Reference in new issue
Block a user