From 39f1065dc6e6c85780c42123033391233f7104af Mon Sep 17 00:00:00 2001
From: Damiano Galassi <damiog@gmail.com>
Date: Fri, 22 Nov 2024 10:49:10 +0100
Subject: [PATCH 4/5] Implement ambient viewing environment sei

Defined in ISO/IEC 23008-2:2017, D.2.39.
---
 source/common/param.cpp    |  6 ++++++
 source/encoder/encoder.cpp |  9 +++++++++
 source/encoder/sei.h       | 19 +++++++++++++++++++
 source/x265.h              |  9 +++++++++
 4 files changed, 43 insertions(+)

diff --git a/source/common/param.cpp b/source/common/param.cpp
index a35b06339..92f70b6bf 100755
--- a/source/common/param.cpp
+++ b/source/common/param.cpp
@@ -408,6 +408,7 @@ void x265_param_default(x265_param* param)
     param->preferredTransferCharacteristics = -1;
     param->pictureStructure = -1;
     param->bEmitCLL = 1;
+    param->bEmitAmbientViewingEnvironment = 0;
 
     param->bEnableFrameDuplication = 0;
     param->dupThreshold = 70;
@@ -1963,6 +1964,7 @@ int x265_check_params(x265_param* param)
                      || param->bEmitIDRRecoverySEI
                    || !!param->interlaceMode
                      || param->preferredTransferCharacteristics > 1
+                     || param->bEmitAmbientViewingEnvironment
                      || strlen(param->toneMapFile)
                      || strlen(param->naluFile));
 
@@ -2910,6 +2912,10 @@ void x265_copy_params(x265_param* dst, x265_param* src)
     dst->bEmitCLL = src->bEmitCLL;
     dst->maxCLL = src->maxCLL;
     dst->maxFALL = src->maxFALL;
+    dst->ambientIlluminance = src->ambientIlluminance;
+    dst->ambientLightX = src->ambientLightX;
+    dst->ambientLightY = src->ambientLightY;
+    dst->bEmitAmbientViewingEnvironment = src->bEmitAmbientViewingEnvironment;
     dst->log2MaxPocLsb = src->log2MaxPocLsb;
     dst->bEmitVUIHRDInfo = src->bEmitVUIHRDInfo;
     dst->bEmitVUITimingInfo = src->bEmitVUITimingInfo;
diff --git a/source/encoder/encoder.cpp b/source/encoder/encoder.cpp
index 6670c814d..752e41a8a 100644
--- a/source/encoder/encoder.cpp
+++ b/source/encoder/encoder.cpp
@@ -3367,6 +3367,15 @@ void Encoder::getStreamHeaders(NALList& list, Entropy& sbacCoder, Bitstream& bs)
         }
     }
 
+    if (m_param->bEmitAmbientViewingEnvironment)
+    {
+        SEIAmbientViewingEnvironment ambientsei;
+        ambientsei.ambientIlluminance = m_param->ambientIlluminance;
+        ambientsei.ambientLightX = m_param->ambientLightX;
+        ambientsei.ambientLightY = m_param->ambientLightY;
+        ambientsei.writeSEImessages(bs, m_sps, NAL_UNIT_PREFIX_SEI, list, m_param->bSingleSeiNal);
+    }
+
     if (m_param->bEmitInfoSEI)
     {
         char *opts = x265_param2string(m_param, m_sps.conformanceWindow.rightOffset, m_sps.conformanceWindow.bottomOffset);
diff --git a/source/encoder/sei.h b/source/encoder/sei.h
index 3ed957058..9d3e74c63 100644
--- a/source/encoder/sei.h
+++ b/source/encoder/sei.h
@@ -638,6 +638,25 @@ public:
     }
 };
 
+class SEIAmbientViewingEnvironment : public SEI
+{
+public:
+    SEIAmbientViewingEnvironment()
+    {
+        m_payloadType = AMBIENT_VIEWING_ENVIRONMENT;
+        m_payloadSize = 8;
+    }
+    uint32_t ambientIlluminance;
+    uint16_t ambientLightX;
+    uint16_t ambientLightY;
+    void writeSEI(const SPS&)
+    {
+        WRITE_CODE(ambientIlluminance, 32, "ambient_illuminance");
+        WRITE_CODE(ambientLightX,      16, "ambient_light_x");
+        WRITE_CODE(ambientLightY,      16, "ambient_light_y");
+    }
+};
+
 class SEIDecodedPictureHash : public SEI
 {
 public:
diff --git a/source/x265.h b/source/x265.h
index 7241beda2..c9fd99984 100644
--- a/source/x265.h
+++ b/source/x265.h
@@ -376,6 +376,7 @@ typedef enum
     MASTERING_DISPLAY_INFO               = 137,
     CONTENT_LIGHT_LEVEL_INFO             = 144,
     ALTERNATIVE_TRANSFER_CHARACTERISTICS = 147,
+    AMBIENT_VIEWING_ENVIRONMENT          = 148,
     ALPHA_CHANNEL_INFO                   = 165,
     THREE_DIMENSIONAL_REFERENCE_DISPLAYS_INFO = 176,
     MULTIVIEW_SCENE_INFO                 = 178,
@@ -1962,6 +1963,11 @@ typedef struct x265_param
      * value to that value. */
     uint16_t maxLuma;
 
+    /* ISO/IEC 23008-2:2017, D.2.39 ambient viewing environment SEI message */
+    uint32_t ambientIlluminance;
+    uint16_t ambientLightX;
+    uint16_t ambientLightY;
+
     /* Maximum of the picture order count */
     int log2MaxPocLsb;
 
@@ -2173,6 +2179,9 @@ typedef struct x265_param
     /*Emit content light level info SEI*/
     int         bEmitCLL;
 
+    /* Emit ambient viewing environment SEI */
+    int         bEmitAmbientViewingEnvironment;
+
     /*
     * Signals picture structure SEI timing message for every frame
     * picture structure 7 is signalled for frame doubling
-- 
2.39.5 (Apple Git-154)

