From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from ffbox0-bg.ffmpeg.org (ffbox0-bg.ffmpeg.org [79.124.17.100]) by master.gitmailbox.com (Postfix) with ESMTPS id 516D840C50 for ; Sat, 20 Sep 2025 14:50:41 +0000 (UTC) Authentication-Results: ffbox; dkim=fail (body hash mismatch (got b'OII9hX8LS4fCAJhztFxbm5EQvDdsggeQeNKpT5QyJws=', expected b'PQNCrFeKIYkVGnEPef9/jTpoel0tDidqm0TUOysWK4w=')) header.d=ffmpeg.org header.i=@ffmpeg.org header.a=rsa-sha256 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=ffmpeg.org; i=@ffmpeg.org; q=dns/txt; s=mail; t=1758379821; h=mime-version : to : date : message-id : reply-to : subject : list-id : list-archive : list-archive : list-help : list-owner : list-post : list-subscribe : list-unsubscribe : from : cc : content-type : content-transfer-encoding : from; bh=OII9hX8LS4fCAJhztFxbm5EQvDdsggeQeNKpT5QyJws=; b=14BrU2g1gdsh0Ai5qMamoGd347qYYRTELgK4+UaIj5mo7P9qrNfFK0kZwPNqgvWe/6yfb koukcabHLXmljfw0634s43SDxUirKOBay4J52OpM0qPCgK+FHAYrJREYLSkmC/gqlh/zjx+ CAv0ctZgSBHsAOdXSlgEu/WjRLkf2HBW4X+NU5w1fMK8qv0ugtzpRad/gdBD6nthaAWPl59 lyNk/TvBmJRPix/QStO4XUwwsscPC6+2Li26/rjmGkQ7XngIS0xY24cqUtZMvexU/1jrrld K2TdhhhUjz6Qd1LbZfQf+lSq9KF7oBNAa/7IkFiSSHnqocqeG894XioeWypg== Received: from [172.19.0.4] (unknown [172.19.0.4]) by ffbox0-bg.ffmpeg.org (Postfix) with ESMTP id 9E82068E854; Sat, 20 Sep 2025 17:50:21 +0300 (EEST) ARC-Seal: i=1; cv=none; a=rsa-sha256; d=ffmpeg.org; s=arc; t=1758379819; b=uX93+RSdfHxEEGDr6hGEbgiOpkjwbR0762QwJPc2Wps6lbkSK5j5PrD74UNWotS7bbH4c MAbpV6GuSa5TyghTXmSfJggz/ZxOAJpYG9ztmdMgsgKL58dn9+jzB1xmgdzlzHFNdGOfWW6 ZZHwi8JjHUvw6jJk9xV6a+81xwRywej7/zLjXsG2ZzwLlO4Mpk6DGHyJRvNh8Bj6jiIy3xQ zjPttMMiBPjpxi9EGxD9mfToOs2EJkCi8hvzDGtmC5bzQCeMIpaIkvsva19VNjCjRlhVQqU LAa7ZxFYruWKOW2cUFTkyBd0G1dDZj9RYGInyvxKkj9X7u0mIs9GjG0INmDw== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=ffmpeg.org; s=arc; t=1758379819; h=from : sender : reply-to : subject : date : message-id : to : cc : mime-version : content-type : content-transfer-encoding : content-id : content-description : resent-date : resent-from : resent-sender : resent-to : resent-cc : resent-message-id : in-reply-to : references : list-id : list-help : list-unsubscribe : list-subscribe : list-post : list-owner : list-archive; bh=qtCp3oQG0c9EkyHeDuiqrg7A8PFVaayLn21HGw8q9dQ=; b=fGbWOhbj+Hh5R3ykWQVyVfMvAAa09MHzzwZtQBGUkF+lQB8XFkzbQFoG6JKrutj5ucT8N v8B+2IJ40UA1y6hVrDoF9kDn4gv9zn3s2ApIwaoCfaQWBO86RFcOO4jQ7sxC0aCQmCgjG7i B4+e5TR2ZJSMUlcDa8wxfu2uYedHJ6XSwkQDpGdKIWQL3pdyPcxdEZgSnWAanDOwcBq61Nc NTfvYVB1Pv0jD5/bmwxm7ZvJ5clVJWgxksVnhbIA95M5e4izANy43S9rpqqkT1wcCy7rwVz P9N+6AkLB3/2GVkhguoXUiIF/KE1F/aPMcawpjqVDYwYq1S6pTExpBzELOSw== ARC-Authentication-Results: i=1; ffmpeg.org; dkim=pass header.d=ffmpeg.org header.i=@ffmpeg.org; arc=none; dmarc=none Authentication-Results: ffmpeg.org; dkim=pass header.d=ffmpeg.org header.i=@ffmpeg.org; arc=none (Message is not ARC signed); dmarc=none DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=ffmpeg.org; i=@ffmpeg.org; q=dns/txt; s=mail; t=1758379807; h=content-type : mime-version : content-transfer-encoding : from : to : reply-to : subject : date : from; bh=PQNCrFeKIYkVGnEPef9/jTpoel0tDidqm0TUOysWK4w=; b=b8Hy8s/wt2UyzI0kEyO3isZOrQm5ai88P/SAdC8g3E10ErSNEedr9OZTCwXOzmvnlUDZ7 gKnfAjK+Fyb+RMKz3+GpoROLeGMp5VJDTRhGx8seDWKnl1IteKYX6UlG4mYe/Ub8US+5HoH 3K6XuXaj/Qlf8RFpOzTpHh9mqFxw022VahZsUCO0CV4r5/8PfZ0AFN0YsqkN+3gNlVKUyO4 x3JYc/C/bzXuHmKSyEOFfZjseq8F8RI0v2FB/4Zv7WkajqvED0fhj0vhurIrdOncbSwcb/e ZS30Ya67TPZ4OzbW90ndYOQ4EyUqBCJaHeC6T0RSkbbDfS21y5Lpvq3X5D9g== Received: from ed19c606a818 (code.ffmpeg.org [188.245.149.3]) by ffbox0-bg.ffmpeg.org (Postfix) with ESMTPS id 632BC68E80D for ; Sat, 20 Sep 2025 17:50:07 +0300 (EEST) MIME-Version: 1.0 To: ffmpeg-devel@ffmpeg.org Date: Sat, 20 Sep 2025 14:50:07 -0000 Message-ID: <175837980765.25.574033320148429653@463a07221176> Message-ID-Hash: L2GT55OL6CFNADPVNNGN5SLA7P7FLBAK X-Message-ID-Hash: L2GT55OL6CFNADPVNNGN5SLA7P7FLBAK X-MailFrom: code@ffmpeg.org X-Mailman-Rule-Misses: dmarc-mitigation; no-senders; approved; loop; banned-address; header-match-ffmpeg-devel.ffmpeg.org-0; header-match-ffmpeg-devel.ffmpeg.org-1; header-match-ffmpeg-devel.ffmpeg.org-2; header-match-ffmpeg-devel.ffmpeg.org-3; emergency; member-moderation; nonmember-moderation; administrivia; implicit-dest; max-recipients; max-size; news-moderation; no-subject; digests; suspicious-header X-Mailman-Version: 3.3.10 Precedence: list Reply-To: FFmpeg development discussions and patches Subject: [FFmpeg-devel] [PATCH] Add support for Panasonic V-Log transfer function (PR #20561) List-Id: FFmpeg development discussions and patches Archived-At: Archived-At: List-Archive: List-Archive: List-Help: List-Owner: List-Post: List-Subscribe: List-Unsubscribe: From: Lynne via ffmpeg-devel Cc: Lynne Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: 7bit Archived-At: List-Archive: List-Post: PR #20561 opened by Lynne URL: https://code.ffmpeg.org/FFmpeg/FFmpeg/pulls/20561 Patch URL: https://code.ffmpeg.org/FFmpeg/FFmpeg/pulls/20561.patch This PR adds support for the Panasonic V-Log transfer function, used in Panasonic cameras. To avoid bloating structures unnecessarily, the definition uses a value of 37, within the reserved area of H.273. Currently, the last defined H.273 value is 18. As V-Log will very likely never be tagged or supported by H.273, our value may be changed in the future if it looks like the ITU will define 37 to be used for something else. >>From ad8f5e99e8451a0c7c58ce14fdfd40cc340b4a9a Mon Sep 17 00:00:00 2001 From: Lynne Date: Wed, 27 Aug 2025 21:50:32 +0900 Subject: [PATCH 1/4] lavu: add support for Panasonic V-Log transfer function --- libavcodec/fflcms2.c | 1 + libavfilter/vf_libplacebo.c | 1 + libavfilter/vf_setparams.c | 1 + libavutil/csp.c | 28 ++++++++++++++++++++++++++++ libavutil/pixdesc.c | 1 + libavutil/pixfmt.h | 7 +++++++ libswscale/format.c | 3 ++- 7 files changed, 41 insertions(+), 1 deletion(-) diff --git a/libavcodec/fflcms2.c b/libavcodec/fflcms2.c index 3b67e62d3a..3d3241f5a3 100644 --- a/libavcodec/fflcms2.c +++ b/libavcodec/fflcms2.c @@ -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: diff --git a/libavfilter/vf_libplacebo.c b/libavfilter/vf_libplacebo.c index 5e0a678ff2..f5a3c55aa8 100644 --- a/libavfilter/vf_libplacebo.c +++ b/libavfilter/vf_libplacebo.c @@ -1612,6 +1612,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"}, diff --git a/libavfilter/vf_setparams.c b/libavfilter/vf_setparams.c index f32757f940..be0323fd83 100644 --- a/libavfilter/vf_setparams.c +++ b/libavfilter/vf_setparams.c @@ -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"}, diff --git a/libavutil/csp.c b/libavutil/csp.c index 75ac871616..8ea47d6c55 100644 --- a/libavutil/csp.c +++ b/libavutil/csp.c @@ -378,6 +378,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_vlog(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 double trc_vlog_inv(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 const av_csp_trc_function trc_funcs[AVCOL_TRC_NB] = { [AVCOL_TRC_BT709] = trc_bt709, [AVCOL_TRC_GAMMA22] = trc_gamma22, @@ -395,6 +421,7 @@ static const av_csp_trc_function trc_funcs[AVCOL_TRC_NB] = { [AVCOL_TRC_SMPTE2084] = trc_smpte_st2084, [AVCOL_TRC_SMPTE428] = trc_smpte_st428_1, [AVCOL_TRC_ARIB_STD_B67] = trc_arib_std_b67, + [AVCOL_TRC_V_LOG] = trc_vlog, }; av_csp_trc_function av_csp_trc_func_from_id(enum AVColorTransferCharacteristic trc) @@ -421,6 +448,7 @@ static const av_csp_trc_function trc_inv_funcs[AVCOL_TRC_NB] = { [AVCOL_TRC_SMPTE2084] = trc_smpte_st2084_inv, [AVCOL_TRC_SMPTE428] = trc_smpte_st428_1_inv, [AVCOL_TRC_ARIB_STD_B67] = trc_arib_std_b67_inv, + [AVCOL_TRC_V_LOG] = trc_vlog_inv, }; av_csp_trc_function av_csp_trc_func_inv_from_id(enum AVColorTransferCharacteristic trc) diff --git a/libavutil/pixdesc.c b/libavutil/pixdesc.c index 3c31ee2132..0ce12cbc6f 100644 --- a/libavutil/pixdesc.c +++ b/libavutil/pixdesc.c @@ -3312,6 +3312,7 @@ static const char * const color_transfer_names[] = { [AVCOL_TRC_SMPTE2084] = "smpte2084", [AVCOL_TRC_SMPTE428] = "smpte428", [AVCOL_TRC_ARIB_STD_B67] = "arib-std-b67", + [AVCOL_TRC_V_LOG] = "vlog", }; static const char * const color_space_names[] = { diff --git a/libavutil/pixfmt.h b/libavutil/pixfmt.h index 6aa1c94cec..8c4b5aab5d 100644 --- a/libavutil/pixfmt.h +++ b/libavutil/pixfmt.h @@ -680,6 +680,13 @@ 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" + + /** + * NOTE: The following transfer functions are not a part of H.273 and are + * within the "reserved" window. + */ + AVCOL_TRC_V_LOG = 37, ///< Panasonic V-Log + AVCOL_TRC_NB ///< Not part of ABI }; diff --git a/libswscale/format.c b/libswscale/format.c index 9741688e98..5dae9138ae 100644 --- a/libswscale/format.c +++ b/libswscale/format.c @@ -1270,9 +1270,10 @@ 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_NB == 38, "Update this list when adding TRCs"); switch (trc) { case AVCOL_TRC_LOG: + case AVCOL_TRC_V_LOG: case AVCOL_TRC_LOG_SQRT: case AVCOL_TRC_SMPTEST2084: case AVCOL_TRC_ARIB_STD_B67: -- 2.49.1 >>From bbb6037fff08a5c283be148ae5eaff2c75409e87 Mon Sep 17 00:00:00 2001 From: Lynne Date: Thu, 28 Aug 2025 15:10:26 +0900 Subject: [PATCH 2/4] prores_raw: set color_trc based on the vendor tag This is the only identifiable piece of information about the colorspace, apart from the XML embedded in the MOV comments. --- libavcodec/prores_raw.c | 17 ++++++++++++++++- libavcodec/prores_raw_parser.c | 17 ++++++++++++++++- 2 files changed, 32 insertions(+), 2 deletions(-) diff --git a/libavcodec/prores_raw.c b/libavcodec/prores_raw.c index b2aa97ddda..71056014fc 100644 --- a/libavcodec/prores_raw.c +++ b/libavcodec/prores_raw.c @@ -359,7 +359,22 @@ static int decode_frame(AVCodecContext *avctx, } /* Vendor header (e.g. "peac" for Panasonic or "atm0" for Atmos) */ - bytestream2_skip(&gb_hdr, 4); + uint32_t vendor = bytestream2_get_be32(&gb_hdr); + switch (vendor) { + case MKBETAG('p','e','a','c'): + /* Internal recording from a Panasonic camera, V-Log */ + avctx->color_trc = AVCOL_TRC_V_LOG; + break; + case MKBETAG('a','t','m','0'): + /* External recording from an Atomos recorder. Cameras universally + * record in their own native log curve internally, but linearize it + * when outputting RAW externally */ + avctx->color_trc = AVCOL_TRC_LINEAR; + break; + default: + avctx->color_trc = AVCOL_TRC_UNSPECIFIED; + break; + } /* Width and height must always be even */ int w = bytestream2_get_be16(&gb_hdr); diff --git a/libavcodec/prores_raw_parser.c b/libavcodec/prores_raw_parser.c index fca3ec37fb..d0dfdd9e86 100644 --- a/libavcodec/prores_raw_parser.c +++ b/libavcodec/prores_raw_parser.c @@ -61,7 +61,22 @@ static int prores_raw_parse(AVCodecParserContext *s, AVCodecContext *avctx, } /* Vendor header (e.g. "peac" for Panasonic or "atm0" for Atmos) */ - bytestream2_skip(&gb, 4); + uint32_t vendor = bytestream2_get_be32(&gb); + switch (vendor) { + case MKBETAG('p','e','a','c'): + /* Internal recording from a Panasonic camera, V-Log */ + avctx->color_trc = AVCOL_TRC_V_LOG; + break; + case MKBETAG('a','t','m','0'): + /* External recording from an Atomos recorder. Cameras universally + * record in their own native log curve internally, but linearize it + * when outputting RAW externally */ + avctx->color_trc = AVCOL_TRC_LINEAR; + break; + default: + avctx->color_trc = AVCOL_TRC_UNSPECIFIED; + break; + } s->width = bytestream2_get_be16(&gb); s->height = bytestream2_get_be16(&gb); -- 2.49.1 >>From 0aea270cccbb1dc021ca5014556e44c70896343e Mon Sep 17 00:00:00 2001 From: Lynne Date: Thu, 28 Aug 2025 15:12:52 +0900 Subject: [PATCH 3/4] prores_raw: set profile based on the codec tag This is the same as what the parser does. --- libavcodec/prores_raw.c | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/libavcodec/prores_raw.c b/libavcodec/prores_raw.c index 71056014fc..ad47e144bf 100644 --- a/libavcodec/prores_raw.c +++ b/libavcodec/prores_raw.c @@ -334,6 +334,21 @@ static int decode_frame(AVCodecContext *avctx, DECLARE_ALIGNED(32, uint8_t, qmat)[64]; memset(qmat, 1, 64); + switch (avctx->codec_tag) { + case 0: + break; + case MKTAG('a','p','r','n'): + avctx->profile = AV_PROFILE_PRORES_RAW; + break; + case MKTAG('a','p','r','h'): + avctx->profile = AV_PROFILE_PRORES_RAW_HQ; + break; + default: + avpriv_request_sample(avctx, "Profile %d", avctx->codec_tag); + return AVERROR_PATCHWELCOME; + break; + } + GetByteContext gb; bytestream2_init(&gb, avpkt->data, avpkt->size); if (bytestream2_get_be32(&gb) != avpkt->size) -- 2.49.1 >>From baa3f17b66f1ea4c7cdd9c056cf5640568fee913 Mon Sep 17 00:00:00 2001 From: Lynne Date: Thu, 28 Aug 2025 15:14:03 +0900 Subject: [PATCH 4/4] prores_raw: use MKBETAG for the frame header tag Equivalent, but more explicit. All values in the header are big endian. --- libavcodec/prores_raw.c | 2 +- libavcodec/prores_raw_parser.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/libavcodec/prores_raw.c b/libavcodec/prores_raw.c index ad47e144bf..beb11aa23f 100644 --- a/libavcodec/prores_raw.c +++ b/libavcodec/prores_raw.c @@ -355,7 +355,7 @@ static int decode_frame(AVCodecContext *avctx, return AVERROR_INVALIDDATA; /* ProRes RAW frame */ - if (bytestream2_get_le32(&gb) != MKTAG('p','r','r','f')) + if (bytestream2_get_be32(&gb) != MKBETAG('p','r','r','f')) return AVERROR_INVALIDDATA; int header_len = bytestream2_get_be16(&gb); diff --git a/libavcodec/prores_raw_parser.c b/libavcodec/prores_raw_parser.c index d0dfdd9e86..fb690f243d 100644 --- a/libavcodec/prores_raw_parser.c +++ b/libavcodec/prores_raw_parser.c @@ -46,7 +46,7 @@ static int prores_raw_parse(AVCodecParserContext *s, AVCodecContext *avctx, if (bytestream2_get_be32(&gb) != buf_size) /* Packet size */ return buf_size; - if (bytestream2_get_le32(&gb) != MKTAG('p','r','r','f')) /* Frame header */ + if (bytestream2_get_be32(&gb) != MKBETAG('p','r','r','f')) /* Frame header */ return buf_size; int header_size = bytestream2_get_be16(&gb); -- 2.49.1 _______________________________________________ ffmpeg-devel mailing list -- ffmpeg-devel@ffmpeg.org To unsubscribe send an email to ffmpeg-devel-leave@ffmpeg.org