You've already forked FFmpeg
							
							
				mirror of
				https://github.com/FFmpeg/FFmpeg.git
				synced 2025-10-30 23:18:11 +02:00 
			
		
		
		
	lavu: add support for Panasonic V-Log
This commit is contained in:
		| @@ -50,7 +50,7 @@ void ff_icc_context_uninit(FFIccContext *s) | ||||
| static int get_curve(FFIccContext *s, enum AVColorTransferCharacteristic trc, | ||||
|                      cmsToneCurve **out_curve) | ||||
| { | ||||
|     if (trc >= AVCOL_TRC_NB) | ||||
|     if ((trc >= AVCOL_TRC_NB && trc < AVCOL_TRC_EXT_BASE) || trc >= AVCOL_TRC_EXT_NB) | ||||
|         return AVERROR_INVALIDDATA; | ||||
|  | ||||
|     if (s->curves[trc]) | ||||
| @@ -128,6 +128,7 @@ static int get_curve(FFIccContext *s, enum AVColorTransferCharacteristic trc, | ||||
|     case AVCOL_TRC_BT1361_ECG: | ||||
|     case AVCOL_TRC_SMPTE2084: | ||||
|     case AVCOL_TRC_ARIB_STD_B67: | ||||
|     case AVCOL_TRC_V_LOG: | ||||
|         return AVERROR_PATCHWELCOME; | ||||
|  | ||||
|     default: | ||||
|   | ||||
| @@ -1682,6 +1682,7 @@ static const AVOption libplacebo_options[] = { | ||||
|     {"bt2020-12",                      NULL,  0, AV_OPT_TYPE_CONST, {.i64=AVCOL_TRC_BT2020_12},    INT_MIN, INT_MAX, STATIC, .unit = "color_trc"}, | ||||
|     {"smpte2084",                      NULL,  0, AV_OPT_TYPE_CONST, {.i64=AVCOL_TRC_SMPTE2084},    INT_MIN, INT_MAX, STATIC, .unit = "color_trc"}, | ||||
|     {"arib-std-b67",                   NULL,  0, AV_OPT_TYPE_CONST, {.i64=AVCOL_TRC_ARIB_STD_B67}, INT_MIN, INT_MAX, STATIC, .unit = "color_trc"}, | ||||
|     {"vlog",                           NULL,  0, AV_OPT_TYPE_CONST, {.i64=AVCOL_TRC_V_LOG},        INT_MIN, INT_MAX, STATIC, .unit = "color_trc"}, | ||||
|  | ||||
|     {"rotate", "rotate the input clockwise", OFFSET(rotation), AV_OPT_TYPE_INT, {.i64=PL_ROTATION_0}, PL_ROTATION_0, PL_ROTATION_360, DYNAMIC, .unit = "rotation"}, | ||||
|     {"0",                              NULL,  0, AV_OPT_TYPE_CONST, {.i64=PL_ROTATION_0},   .flags = STATIC, .unit = "rotation"}, | ||||
|   | ||||
| @@ -82,7 +82,7 @@ static const AVOption setparams_options[] = { | ||||
|     {"jedec-p22",                       NULL,  0, AV_OPT_TYPE_CONST, {.i64=AVCOL_PRI_JEDEC_P22},    0, 0, FLAGS, .unit = "color_primaries"}, | ||||
|     {"ebu3213",                         NULL,  0, AV_OPT_TYPE_CONST, {.i64=AVCOL_PRI_EBU3213},      0, 0, FLAGS, .unit = "color_primaries"}, | ||||
|  | ||||
|     {"color_trc", "select color transfer", OFFSET(color_trc), AV_OPT_TYPE_INT, {.i64=-1}, -1, AVCOL_TRC_NB-1, FLAGS, .unit = "color_trc"}, | ||||
|     {"color_trc", "select color transfer", OFFSET(color_trc), AV_OPT_TYPE_INT, {.i64=-1}, -1, AVCOL_TRC_EXT_NB-1, FLAGS, .unit = "color_trc"}, | ||||
|     {"auto", "keep the same color transfer",  0, AV_OPT_TYPE_CONST, {.i64=-1},                     0, 0, FLAGS, .unit = "color_trc"}, | ||||
|     {"bt709",                          NULL,  0, AV_OPT_TYPE_CONST, {.i64=AVCOL_TRC_BT709},        0, 0, FLAGS, .unit = "color_trc"}, | ||||
|     {"unknown",                        NULL,  0, AV_OPT_TYPE_CONST, {.i64=AVCOL_TRC_UNSPECIFIED},  0, 0, FLAGS, .unit = "color_trc"}, | ||||
| @@ -101,6 +101,7 @@ static const AVOption setparams_options[] = { | ||||
|     {"smpte2084",                      NULL,  0, AV_OPT_TYPE_CONST, {.i64=AVCOL_TRC_SMPTE2084},    0, 0, FLAGS, .unit = "color_trc"}, | ||||
|     {"smpte428",                       NULL,  0, AV_OPT_TYPE_CONST, {.i64=AVCOL_TRC_SMPTE428},     0, 0, FLAGS, .unit = "color_trc"}, | ||||
|     {"arib-std-b67",                   NULL,  0, AV_OPT_TYPE_CONST, {.i64=AVCOL_TRC_ARIB_STD_B67}, 0, 0, FLAGS, .unit = "color_trc"}, | ||||
|     {"vlog",                           NULL,  0, AV_OPT_TYPE_CONST, {.i64=AVCOL_TRC_V_LOG},        0, 0, FLAGS, .unit = "color_trc"}, | ||||
|  | ||||
|     {"colorspace", "select colorspace", OFFSET(colorspace), AV_OPT_TYPE_INT, {.i64=-1}, -1, AVCOL_SPC_NB-1, FLAGS, .unit = "colorspace"}, | ||||
|     {"auto", "keep the same colorspace",  0, AV_OPT_TYPE_CONST, {.i64=-1},                          0, 0, FLAGS, .unit = "colorspace"}, | ||||
|   | ||||
| @@ -146,14 +146,17 @@ static const double approximate_gamma[AVCOL_TRC_NB] = { | ||||
|     [AVCOL_TRC_SMPTE428] = 2.6, | ||||
| }; | ||||
|  | ||||
| static const double approximate_gamma_ext[AVCOL_TRC_EXT_NB - | ||||
|                                           AVCOL_TRC_EXT_BASE] = { | ||||
|     [AVCOL_TRC_V_LOG - AVCOL_TRC_EXT_BASE] = 2.2, | ||||
| }; | ||||
|  | ||||
| double av_csp_approximate_trc_gamma(enum AVColorTransferCharacteristic trc) | ||||
| { | ||||
|     double gamma; | ||||
|     if ((unsigned)trc >= AVCOL_TRC_NB) | ||||
|         return 0.0; | ||||
|     gamma = approximate_gamma[trc]; | ||||
|     if (gamma > 0) | ||||
|         return gamma; | ||||
|     if (trc < AVCOL_TRC_NB) | ||||
|         return approximate_gamma[trc]; | ||||
|     else if ((trc >= AVCOL_TRC_EXT_BASE) && (trc < AVCOL_TRC_EXT_NB)) | ||||
|         return approximate_gamma_ext[trc - AVCOL_TRC_EXT_BASE]; | ||||
|     return 0.0; | ||||
| } | ||||
|  | ||||
| @@ -171,11 +174,19 @@ static const double approximate_eotf_gamma[AVCOL_TRC_NB] = { | ||||
|     [AVCOL_TRC_SMPTE428] = 2.6, | ||||
| }; | ||||
|  | ||||
| static const double approximate_eotf_gamma_ext[AVCOL_TRC_EXT_NB - | ||||
|                                                AVCOL_TRC_EXT_BASE] = { | ||||
|     [AVCOL_TRC_V_LOG - AVCOL_TRC_EXT_BASE] = 2.2, | ||||
| }; | ||||
|  | ||||
| double av_csp_approximate_eotf_gamma(enum AVColorTransferCharacteristic trc) | ||||
| { | ||||
|     if ((unsigned)trc >= AVCOL_TRC_NB) | ||||
|         return 0.0; | ||||
|     return approximate_eotf_gamma[trc]; | ||||
|     if ((unsigned)trc < AVCOL_TRC_NB) | ||||
|         return approximate_eotf_gamma[trc]; | ||||
|     else if (((unsigned)trc >= AVCOL_TRC_EXT_BASE) && | ||||
|              ((unsigned)trc < AVCOL_TRC_EXT_NB)) | ||||
|         return approximate_eotf_gamma_ext[trc - AVCOL_TRC_EXT_BASE]; | ||||
|     return 0.0; | ||||
| } | ||||
|  | ||||
| #define BT709_alpha 1.099296826809442 | ||||
| @@ -399,6 +410,32 @@ static double trc_arib_std_b67_inv(double E) | ||||
|         (E <= 0.5 ? E * E / 3.0 : (exp((E - c) / a) + b) / 12.0); | ||||
| } | ||||
|  | ||||
| #define VLOG_c1 0.01 | ||||
| #define VLOG_c2 0.181 | ||||
| #define VLOG_b  0.00873 | ||||
| #define VLOG_c  0.241514 | ||||
| #define VLOG_d  0.598206 | ||||
|  | ||||
| static double trc_v_log(double E) | ||||
| { | ||||
|     const double c1 = VLOG_c1; | ||||
|     const double b = VLOG_b; | ||||
|     const double c = VLOG_c; | ||||
|     const double d = VLOG_d; | ||||
|     return (E < c1) ? (5.6 * E + 0.125) : | ||||
|         (c * log10(E + b) + d); | ||||
| } | ||||
|  | ||||
| static double trc_v_log_inv(double E) | ||||
| { | ||||
|     const double c2 = VLOG_c2; | ||||
|     const double b = VLOG_b; | ||||
|     const double c = VLOG_c; | ||||
|     const double d = VLOG_d; | ||||
|     return (E < c2) ? (E - 0.125) / 5.6 : | ||||
|         (pow(10.0, ((E - d) / c)) - b); | ||||
| } | ||||
|  | ||||
| static const av_csp_trc_function trc_funcs[AVCOL_TRC_NB] = { | ||||
|     [AVCOL_TRC_BT709] = trc_bt709, | ||||
|     [AVCOL_TRC_GAMMA22] = trc_gamma22, | ||||
| @@ -418,11 +455,19 @@ static const av_csp_trc_function trc_funcs[AVCOL_TRC_NB] = { | ||||
|     [AVCOL_TRC_ARIB_STD_B67] = trc_arib_std_b67, | ||||
| }; | ||||
|  | ||||
| static const av_csp_trc_function trc_funcs_ext[AVCOL_TRC_EXT_NB - | ||||
|                                                AVCOL_TRC_EXT_BASE] = { | ||||
|     [AVCOL_TRC_V_LOG - AVCOL_TRC_EXT_BASE] = trc_v_log, | ||||
| }; | ||||
|  | ||||
| av_csp_trc_function av_csp_trc_func_from_id(enum AVColorTransferCharacteristic trc) | ||||
| { | ||||
|     if ((unsigned)trc >= AVCOL_TRC_NB) | ||||
|         return NULL; | ||||
|     return trc_funcs[trc]; | ||||
|     if ((unsigned)trc < AVCOL_TRC_NB) | ||||
|         return trc_funcs[trc]; | ||||
|     else if (((unsigned)trc >= AVCOL_TRC_EXT_BASE) && | ||||
|              ((unsigned)trc < AVCOL_TRC_EXT_NB)) | ||||
|         return trc_funcs_ext[trc - AVCOL_TRC_EXT_BASE]; | ||||
|     return NULL; | ||||
| } | ||||
|  | ||||
| static const av_csp_trc_function trc_inv_funcs[AVCOL_TRC_NB] = { | ||||
| @@ -444,11 +489,19 @@ static const av_csp_trc_function trc_inv_funcs[AVCOL_TRC_NB] = { | ||||
|     [AVCOL_TRC_ARIB_STD_B67] = trc_arib_std_b67_inv, | ||||
| }; | ||||
|  | ||||
| static const av_csp_trc_function trc_inv_funcs_ext[AVCOL_TRC_EXT_NB - | ||||
|                                                    AVCOL_TRC_EXT_BASE] = { | ||||
|     [AVCOL_TRC_V_LOG - AVCOL_TRC_EXT_BASE] = trc_v_log_inv, | ||||
| }; | ||||
|  | ||||
| av_csp_trc_function av_csp_trc_func_inv_from_id(enum AVColorTransferCharacteristic trc) | ||||
| { | ||||
|     if ((unsigned)trc >= AVCOL_TRC_NB) | ||||
|         return NULL; | ||||
|     return trc_inv_funcs[trc]; | ||||
|     if ((unsigned)trc < AVCOL_TRC_NB) | ||||
|         return trc_inv_funcs[trc]; | ||||
|     else if (((unsigned)trc >= AVCOL_TRC_EXT_BASE) && | ||||
|              ((unsigned)trc < AVCOL_TRC_EXT_NB)) | ||||
|         return trc_inv_funcs_ext[trc - AVCOL_TRC_EXT_BASE]; | ||||
|     return NULL; | ||||
| } | ||||
|  | ||||
| static void eotf_linear(const double Lw, const double Lb, double E[3]) | ||||
|   | ||||
| @@ -3452,6 +3452,10 @@ static const char * const color_transfer_names[] = { | ||||
|     [AVCOL_TRC_ARIB_STD_B67] = "arib-std-b67", | ||||
| }; | ||||
|  | ||||
| static const char * const color_transfer_names_ext[] = { | ||||
|     [AVCOL_TRC_V_LOG - AVCOL_TRC_EXT_BASE] = "vlog", | ||||
| }; | ||||
|  | ||||
| static const char * const color_space_names[] = { | ||||
|     [AVCOL_SPC_RGB] = "gbr", | ||||
|     [AVCOL_SPC_BT709] = "bt709", | ||||
| @@ -3939,8 +3943,12 @@ int av_color_primaries_from_name(const char *name) | ||||
|  | ||||
| const char *av_color_transfer_name(enum AVColorTransferCharacteristic transfer) | ||||
| { | ||||
|     return (unsigned) transfer < AVCOL_TRC_NB ? | ||||
|         color_transfer_names[transfer] : NULL; | ||||
|     if ((unsigned)transfer < AVCOL_TRC_NB) | ||||
|         return color_transfer_names[transfer]; | ||||
|     else if (((unsigned)transfer >= AVCOL_TRC_EXT_BASE) && | ||||
|              ((unsigned)transfer < AVCOL_TRC_EXT_NB)) | ||||
|         return color_transfer_names_ext[transfer - AVCOL_TRC_EXT_BASE]; | ||||
|     return NULL; | ||||
| } | ||||
|  | ||||
| int av_color_transfer_from_name(const char *name) | ||||
| @@ -3955,6 +3963,14 @@ int av_color_transfer_from_name(const char *name) | ||||
|             return i; | ||||
|     } | ||||
|  | ||||
|     for (i = 0; i < FF_ARRAY_ELEMS(color_transfer_names_ext); i++) { | ||||
|         if (!color_transfer_names_ext[i]) | ||||
|             continue; | ||||
|  | ||||
|         if (av_strstart(name, color_transfer_names_ext[i], NULL)) | ||||
|             return AVCOL_TRC_EXT_BASE + i; | ||||
|     } | ||||
|  | ||||
|     return AVERROR(EINVAL); | ||||
| } | ||||
|  | ||||
|   | ||||
| @@ -699,7 +699,12 @@ enum AVColorTransferCharacteristic { | ||||
|     AVCOL_TRC_SMPTE428     = 17, ///< SMPTE ST 428-1 | ||||
|     AVCOL_TRC_SMPTEST428_1 = AVCOL_TRC_SMPTE428, | ||||
|     AVCOL_TRC_ARIB_STD_B67 = 18, ///< ARIB STD-B67, known as "Hybrid log-gamma" | ||||
|     AVCOL_TRC_NB                 ///< Not part of ABI | ||||
|     AVCOL_TRC_NB,                ///< Not part of ABI | ||||
|  | ||||
|     /* The following entries are not part of H.273, but custom extensions */ | ||||
|     AVCOL_TRC_EXT_BASE     = 256, | ||||
|     AVCOL_TRC_V_LOG        = AVCOL_TRC_EXT_BASE, | ||||
|     AVCOL_TRC_EXT_NB             ///< Not part of ABI | ||||
| }; | ||||
|  | ||||
| /** | ||||
|   | ||||
| @@ -57,7 +57,10 @@ int main(int argc, char *argv[]) | ||||
|         15123.4567, 19845.88923, 98678.4231, 99999.899998 | ||||
|     }; | ||||
|  | ||||
|     for (enum AVColorTransferCharacteristic trc = 0; trc < AVCOL_TRC_NB; trc++) { | ||||
|     for (enum AVColorTransferCharacteristic trc = 0; trc < AVCOL_TRC_EXT_NB; trc++) { | ||||
|         if (trc == AVCOL_TRC_NB) | ||||
|             trc = AVCOL_TRC_EXT_BASE; | ||||
|  | ||||
|         av_csp_trc_function func = av_csp_trc_func_from_id(trc); | ||||
|         av_csp_trc_function func_inv = av_csp_trc_func_inv_from_id(trc); | ||||
|         const char *name = av_color_transfer_name(trc); | ||||
| @@ -77,7 +80,10 @@ int main(int argc, char *argv[]) | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     for (enum AVColorTransferCharacteristic trc = 0; trc < AVCOL_TRC_NB; trc++) { | ||||
|     for (enum AVColorTransferCharacteristic trc = 0; trc < AVCOL_TRC_EXT_NB; trc++) { | ||||
|         if (trc == AVCOL_TRC_NB) | ||||
|             trc = AVCOL_TRC_EXT_BASE; | ||||
|  | ||||
|         av_csp_eotf_function eotf = av_csp_itu_eotf(trc); | ||||
|         av_csp_eotf_function eotf_inv = av_csp_itu_eotf_inv(trc); | ||||
|         const char *trc_name = av_color_transfer_name(trc); | ||||
|   | ||||
| @@ -1295,9 +1295,11 @@ static AVRational *generate_bayer_matrix(const int size_log2) | ||||
| static bool trc_is_hdr(enum AVColorTransferCharacteristic trc) | ||||
| { | ||||
|     static_assert(AVCOL_TRC_NB == 19, "Update this list when adding TRCs"); | ||||
|     static_assert(AVCOL_TRC_EXT_NB == 257, "Update this list when adding TRCs"); | ||||
|     switch (trc) { | ||||
|     case AVCOL_TRC_LOG: | ||||
|     case AVCOL_TRC_LOG_SQRT: | ||||
|     case AVCOL_TRC_V_LOG: | ||||
|     case AVCOL_TRC_SMPTEST2084: | ||||
|     case AVCOL_TRC_ARIB_STD_B67: | ||||
|         return true; | ||||
|   | ||||
| @@ -302,6 +302,25 @@ trc=arib-std-b67 calling func(15123.456700) expected=2.725380 roundtrip=15123.45 | ||||
| trc=arib-std-b67 calling func(19845.889230) expected=2.773978 roundtrip=19845.889230 | ||||
| trc=arib-std-b67 calling func(98678.423100) expected=3.060803 roundtrip=98678.423100 | ||||
| trc=arib-std-b67 calling func(99999.899998) expected=3.063182 roundtrip=99999.899998 | ||||
| trc=vlog calling func(-0.100000) expected=-0.435000 roundtrip=-0.100000 | ||||
| trc=vlog calling func(-0.018054) expected=0.023898 roundtrip=-0.018054 | ||||
| trc=vlog calling func(-0.010000) expected=0.069000 roundtrip=-0.010000 | ||||
| trc=vlog calling func(-0.004490) expected=0.099856 roundtrip=-0.004490 | ||||
| trc=vlog calling func(0.000000) expected=0.125000 roundtrip=0.000000 | ||||
| trc=vlog calling func(0.003162) expected=0.142709 roundtrip=0.003162 | ||||
| trc=vlog calling func(0.005000) expected=0.153000 roundtrip=0.005000 | ||||
| trc=vlog calling func(0.009000) expected=0.175400 roundtrip=0.009000 | ||||
| trc=vlog calling func(0.015000) expected=0.205818 roundtrip=0.015000 | ||||
| trc=vlog calling func(0.100000) expected=0.365471 roundtrip=0.100000 | ||||
| trc=vlog calling func(1.000000) expected=0.599118 roundtrip=1.000000 | ||||
| trc=vlog calling func(52.370000) expected=1.013406 roundtrip=52.370000 | ||||
| trc=vlog calling func(125.098765) expected=1.104729 roundtrip=125.098765 | ||||
| trc=vlog calling func(1999.111230) expected=1.395405 roundtrip=1999.111230 | ||||
| trc=vlog calling func(6945.443000) expected=1.526030 roundtrip=6945.443000 | ||||
| trc=vlog calling func(15123.456700) expected=1.607650 roundtrip=15123.456700 | ||||
| trc=vlog calling func(19845.889230) expected=1.636154 roundtrip=19845.889230 | ||||
| trc=vlog calling func(98678.423100) expected=1.804381 roundtrip=98678.423100 | ||||
| trc=vlog calling func(99999.899998) expected=1.805776 roundtrip=99999.899998 | ||||
| trc=bt709 EOTF(50, 0, {0}) = {0} | ||||
| trc=bt709 EOTF(50, 0, {0.1}) = {0.199054} | ||||
| trc=bt709 EOTF(50, 0, {0.2}) = {1.05061} | ||||
|   | ||||
		Reference in New Issue
	
	Block a user