mirror of
https://github.com/mpv-player/mpv
synced 2025-03-21 18:57:35 +00:00
vo_opengl: implement the Panasonic V-Log function
User request and not that hard. Closes #3157. Note that FFmpeg doesn't support this and there's no signalling in HEVC etc., so the only way users can access it is by using vf_format manually. Mind: This encoding uses full range values, not TV range.
This commit is contained in:
parent
740fdc139f
commit
f3b6966d14
@ -314,6 +314,7 @@ Available filters are:
|
|||||||
:prophoto: ProPhoto RGB (ROMM) curve
|
:prophoto: ProPhoto RGB (ROMM) curve
|
||||||
:st2084: SMPTE ST2084 (HDR) curve
|
:st2084: SMPTE ST2084 (HDR) curve
|
||||||
:std-b67: ARIB STD-B67 (Hybrid Log-gamma) curve
|
:std-b67: ARIB STD-B67 (Hybrid Log-gamma) curve
|
||||||
|
:v-log: Panasonic V-Log transfer curve
|
||||||
|
|
||||||
``<peak>``
|
``<peak>``
|
||||||
Reference peak illumination for the video file. This is mostly
|
Reference peak illumination for the video file. This is mostly
|
||||||
|
@ -1007,6 +1007,8 @@ Available video output drivers are:
|
|||||||
SMPTE ST2084 (HDR) curve, PQ OETF
|
SMPTE ST2084 (HDR) curve, PQ OETF
|
||||||
std-b67
|
std-b67
|
||||||
ARIB STD-B67 (Hybrid Log-gamma) curve, also known as BBC/NHK HDR
|
ARIB STD-B67 (Hybrid Log-gamma) curve, also known as BBC/NHK HDR
|
||||||
|
v-log
|
||||||
|
Panasonic V-Log (VARICAM) curve
|
||||||
|
|
||||||
NOTE: When using HDR output formats, mpv will encode to the specified
|
NOTE: When using HDR output formats, mpv will encode to the specified
|
||||||
curve but it will not set any HDMI flags or other signalling that
|
curve but it will not set any HDMI flags or other signalling that
|
||||||
|
@ -80,6 +80,7 @@ const struct m_opt_choice_alternatives mp_csp_trc_names[] = {
|
|||||||
{"prophoto", MP_CSP_TRC_PRO_PHOTO},
|
{"prophoto", MP_CSP_TRC_PRO_PHOTO},
|
||||||
{"st2084", MP_CSP_TRC_SMPTE_ST2084},
|
{"st2084", MP_CSP_TRC_SMPTE_ST2084},
|
||||||
{"std-b67", MP_CSP_TRC_ARIB_STD_B67},
|
{"std-b67", MP_CSP_TRC_ARIB_STD_B67},
|
||||||
|
{"v-log", MP_CSP_TRC_V_LOG},
|
||||||
{0}
|
{0}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -81,6 +81,7 @@ enum mp_csp_trc {
|
|||||||
MP_CSP_TRC_PRO_PHOTO,
|
MP_CSP_TRC_PRO_PHOTO,
|
||||||
MP_CSP_TRC_SMPTE_ST2084,
|
MP_CSP_TRC_SMPTE_ST2084,
|
||||||
MP_CSP_TRC_ARIB_STD_B67,
|
MP_CSP_TRC_ARIB_STD_B67,
|
||||||
|
MP_CSP_TRC_V_LOG,
|
||||||
MP_CSP_TRC_COUNT
|
MP_CSP_TRC_COUNT
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -611,8 +611,13 @@ void mp_image_params_guess_csp(struct mp_image_params *params)
|
|||||||
}
|
}
|
||||||
if (params->colorspace == MP_CSP_AUTO)
|
if (params->colorspace == MP_CSP_AUTO)
|
||||||
params->colorspace = mp_csp_guess_colorspace(params->w, params->h);
|
params->colorspace = mp_csp_guess_colorspace(params->w, params->h);
|
||||||
if (params->colorlevels == MP_CSP_LEVELS_AUTO)
|
if (params->colorlevels == MP_CSP_LEVELS_AUTO) {
|
||||||
params->colorlevels = MP_CSP_LEVELS_TV;
|
if (params->gamma == MP_CSP_TRC_V_LOG) {
|
||||||
|
params->colorlevels = MP_CSP_LEVELS_PC;
|
||||||
|
} else {
|
||||||
|
params->colorlevels = MP_CSP_LEVELS_TV;
|
||||||
|
}
|
||||||
|
}
|
||||||
if (params->primaries == MP_CSP_PRIM_AUTO) {
|
if (params->primaries == MP_CSP_PRIM_AUTO) {
|
||||||
// Guess based on the colormatrix as a first priority
|
// Guess based on the colormatrix as a first priority
|
||||||
if (params->colorspace == MP_CSP_BT_2020_NC ||
|
if (params->colorspace == MP_CSP_BT_2020_NC ||
|
||||||
|
@ -2177,7 +2177,8 @@ static void pass_colormanage(struct gl_video *p, float peak_src,
|
|||||||
// We could pick any value we want here, the difference is just coding
|
// We could pick any value we want here, the difference is just coding
|
||||||
// efficiency.
|
// efficiency.
|
||||||
if (trc_orig == MP_CSP_TRC_SMPTE_ST2084 ||
|
if (trc_orig == MP_CSP_TRC_SMPTE_ST2084 ||
|
||||||
trc_orig == MP_CSP_TRC_ARIB_STD_B67)
|
trc_orig == MP_CSP_TRC_ARIB_STD_B67 ||
|
||||||
|
trc_orig == MP_CSP_TRC_V_LOG)
|
||||||
{
|
{
|
||||||
trc_orig = MP_CSP_TRC_GAMMA22;
|
trc_orig = MP_CSP_TRC_GAMMA22;
|
||||||
}
|
}
|
||||||
@ -2224,6 +2225,10 @@ static void pass_colormanage(struct gl_video *p, float peak_src,
|
|||||||
// target's reference peak
|
// target's reference peak
|
||||||
if (trc_src == MP_CSP_TRC_ARIB_STD_B67)
|
if (trc_src == MP_CSP_TRC_ARIB_STD_B67)
|
||||||
peak_src = 12 * peak_dst;
|
peak_src = 12 * peak_dst;
|
||||||
|
|
||||||
|
// Similar deal for V-Log
|
||||||
|
if (trc_src == MP_CSP_TRC_V_LOG)
|
||||||
|
peak_src = 46.0855 * peak_dst;
|
||||||
}
|
}
|
||||||
|
|
||||||
// All operations from here on require linear light as a starting point,
|
// All operations from here on require linear light as a starting point,
|
||||||
|
@ -232,6 +232,12 @@ static const float B67_A = 0.17883277,
|
|||||||
B67_B = 0.28466892,
|
B67_B = 0.28466892,
|
||||||
B67_C = 0.55991073;
|
B67_C = 0.55991073;
|
||||||
|
|
||||||
|
// Common constants for Panasonic V-Log
|
||||||
|
static const float VLOG_B = 0.00873,
|
||||||
|
VLOG_C = 0.241514,
|
||||||
|
VLOG_D = 0.598206,
|
||||||
|
VLOG_R = 46.085527; // nominal peak
|
||||||
|
|
||||||
// Linearize (expand), given a TRC as input
|
// Linearize (expand), given a TRC as input
|
||||||
void pass_linearize(struct gl_shader_cache *sc, enum mp_csp_trc trc)
|
void pass_linearize(struct gl_shader_cache *sc, enum mp_csp_trc trc)
|
||||||
{
|
{
|
||||||
@ -281,6 +287,16 @@ void pass_linearize(struct gl_shader_cache *sc, enum mp_csp_trc trc)
|
|||||||
// assume 1.0 is the maximum brightness, not the reference peak)
|
// assume 1.0 is the maximum brightness, not the reference peak)
|
||||||
GLSL(color.rgb /= vec3(12.0);)
|
GLSL(color.rgb /= vec3(12.0);)
|
||||||
break;
|
break;
|
||||||
|
case MP_CSP_TRC_V_LOG:
|
||||||
|
GLSLF("color.rgb = mix((color.rgb - vec3(0.125)) / vec3(5.6), \n"
|
||||||
|
" pow(vec3(10.0), (color.rgb - vec3(%f)) / vec3(%f)) \n"
|
||||||
|
" - vec3(%f), \n"
|
||||||
|
" lessThanEqual(vec3(0.181), color.rgb)); \n",
|
||||||
|
VLOG_D, VLOG_C, VLOG_B);
|
||||||
|
// Same deal as with the B67 function, renormalize to texture range
|
||||||
|
GLSLF("color.rgb /= vec3(%f);\n", VLOG_R);
|
||||||
|
GLSL(color.rgb = clamp(color.rgb, 0.0, 1.0);)
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
abort();
|
abort();
|
||||||
}
|
}
|
||||||
@ -331,6 +347,14 @@ void pass_delinearize(struct gl_shader_cache *sc, enum mp_csp_trc trc)
|
|||||||
" lessThan(vec3(1.0), color.rgb));\n",
|
" lessThan(vec3(1.0), color.rgb));\n",
|
||||||
B67_A, B67_B, B67_C);
|
B67_A, B67_B, B67_C);
|
||||||
break;
|
break;
|
||||||
|
case MP_CSP_TRC_V_LOG:
|
||||||
|
GLSLF("color.rgb *= vec3(%f);\n", VLOG_R);
|
||||||
|
GLSLF("color.rgb = mix(vec3(5.6) * color.rgb + vec3(0.125), \n"
|
||||||
|
" vec3(%f) * log(color.rgb + vec3(%f)) \n"
|
||||||
|
" + vec3(%f), \n"
|
||||||
|
" lessThanEqual(vec3(0.01), color.rgb)); \n",
|
||||||
|
VLOG_C / M_LN10, VLOG_B, VLOG_D);
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
abort();
|
abort();
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user