<div dir="ltr">From 4a2c8338c0b9e1523d1dd25a4f04aea069fe3883 Mon Sep 17 00:00:00 2001<br>From: AnusuyaKumarasamy <<a href="mailto:anusuya.kumarasamy@multicorewareinc.com">anusuya.kumarasamy@multicorewareinc.com</a>><br>Date: Thu, 29 Aug 2024 11:51:38 +0530<br>Subject: [PATCH 4/7] Add temporal-layer support<br><br>---<br> source/common/slice.h      |  1 +<br> source/encoder/encoder.cpp | 13 +++++++--<br> source/encoder/entropy.cpp | 58 +++++++++++++++++++++++++++-----------<br> 3 files changed, 53 insertions(+), 19 deletions(-)<br><br>diff --git a/source/common/slice.h b/source/common/slice.h<br>index d23479778..3745e7b2f 100644<br>--- a/source/common/slice.h<br>+++ b/source/common/slice.h<br>@@ -178,6 +178,7 @@ struct VPS<br>     uint8_t          m_layerIdInVps[MAX_VPS_LAYER_ID_PLUS1];<br>     int              m_viewIdLen;<br>     int              m_vpsNumLayerSetsMinus1;<br>+    int              m_numLayersInIdList[1023];<br> #endif<br> <br> #if ENABLE_MULTIVIEW<br>diff --git a/source/encoder/encoder.cpp b/source/encoder/encoder.cpp<br>index 4c2865953..1d75ca258 100644<br>--- a/source/encoder/encoder.cpp<br>+++ b/source/encoder/encoder.cpp<br>@@ -2224,6 +2224,7 @@ int Encoder::encode(const x265_picture* pic_in, x265_picture** pic_out)<br>                 else if(m_param->numViews > 1)<br>                     frameEnc[layer]->m_lowres.sliceType = IS_X265_TYPE_I(baseViewType) ? X265_TYPE_P : baseViewType;<br>                 frameEnc[layer]->m_lowres.bKeyframe = frameEnc[0]->m_lowres.bKeyframe;<br>+                frameEnc[layer]->m_tempLayer = frameEnc[0]->m_tempLayer;<br>             }<br> #endif<br> <br>@@ -2416,9 +2417,12 @@ int Encoder::encode(const x265_picture* pic_in, x265_picture** pic_out)<br>             if (m_param->bEnableTemporalSubLayers > 2)<br>             {<br>                 //Re-assign temporalid if the current frame is at the end of encode or when I slice is encountered<br>-                if ((frameEnc[0]->m_poc == (m_param->totalFrames - 1)) || (frameEnc[0]->m_lowres.sliceType == X265_TYPE_I) || (frameEnc[0]->m_lowres.sliceType == X265_TYPE_IDR))<br>+                for (int layer = 0; layer < m_param->numLayers; layer++)<br>                 {<br>-                    frameEnc[0]->m_tempLayer = (int8_t)0;<br>+                    if ((frameEnc[layer]->m_poc == (m_param->totalFrames - 1)) || (frameEnc[layer]->m_lowres.sliceType == X265_TYPE_I) || (frameEnc[layer]->m_lowres.sliceType == X265_TYPE_IDR))<br>+                    {<br>+                        frameEnc[layer]->m_tempLayer = (int8_t)0;<br>+                    }<br>                 }<br>             }<br>             /* determine references, setup RPS, etc */<br>@@ -3521,6 +3525,8 @@ void Encoder::initVPS(VPS *vps)<br>         vps->m_nuhLayerIdPresentFlag = 1;<br>         vps->m_viewIdLen = 0;<br>         vps->m_vpsNumLayerSetsMinus1 = 1;<br>+        vps->m_numLayersInIdList[0] = 1;<br>+        vps->m_numLayersInIdList[1] = 2;<br>     }<br> #endif<br> <br>@@ -3568,6 +3574,8 @@ void Encoder::initVPS(VPS *vps)<br>         vps->m_viewId[1] = 0;<br> <br>         vps->m_vpsNumLayerSetsMinus1 = 1;<br>+        vps->m_numLayersInIdList[0] = 1;<br>+        vps->m_numLayersInIdList[1] = 2;<br>     }<br> #endif<br> }<br>@@ -3656,6 +3664,7 @@ void Encoder::initSPS(SPS *sps)<br>     sps->sps_extension_flag = false;<br> <br> #if ENABLE_MULTIVIEW<br>+    sps->setSpsExtOrMaxSubLayersMinus1 = sps->maxTempSubLayers - 1;<br>     sps->maxViews = m_param->numViews;<br>     if (m_param->numViews > 1)<br>     {<br>diff --git a/source/encoder/entropy.cpp b/source/encoder/entropy.cpp<br>index 12cfc3ef7..a90ab4415 100644<br>--- a/source/encoder/entropy.cpp<br>+++ b/source/encoder/entropy.cpp<br>@@ -255,7 +255,7 @@ void Entropy::codeVPS(const VPS& vps, const SPS& sps)<br>     if (vps.m_numLayers > 1 || vps.m_numViews > 1)<br>     {<br>         WRITE_CODE(maxLayers - 1, 6, "vps_max_nuh_reserved_zero_layer_id");<br>-        WRITE_UVLC(vps.m_vpsNumLayerSetsMinus1, "vps_max_op_sets_minus1");<br>+        WRITE_UVLC(vps.m_vpsNumLayerSetsMinus1, "vps_num_layer_sets_minus1");<br>         for (int i = 1; i <= vps.m_vpsNumLayerSetsMinus1; i++)<br>         {<br> #if ENABLE_MULTIVIEW<br>@@ -293,6 +293,8 @@ void Entropy::codeVPS(const VPS& vps, const SPS& sps)<br> #if ENABLE_ALPHA || ENABLE_MULTIVIEW<br>     if (vps.m_numLayers > 1 || vps.m_numViews > 1)<br>     {<br>+        WRITE_FLAG(vps.vps_extension_flag, "vps_extension_flag");<br>+<br>         if (vps.vps_extension_flag)<br>         {<br>             while (m_bitIf->getNumberOfWrittenBits() % X265_BYTE != 0)<br>@@ -301,6 +303,16 @@ void Entropy::codeVPS(const VPS& vps, const SPS& sps)<br>             }<br> <br>             WRITE_CODE(vps.ptl.levelIdc, 8, "general_level_idc");<br>+            if (vps.maxTempSubLayers > 1)<br>+            {<br>+                for (int i = 0; i < vps.maxTempSubLayers - 1; i++)<br>+                {<br>+                    WRITE_FLAG(0, "sub_layer_profile_present_flag[i]");<br>+                    WRITE_FLAG(0, "sub_layer_level_present_flag[i]");<br>+                }<br>+                for (int i = vps.maxTempSubLayers - 1; i < 8; i++)<br>+                    WRITE_CODE(0, 2, "reserved_zero_2bits");<br>+            }<br> <br>             WRITE_FLAG(vps.splitting_flag, "splitting flag");<br>             for (int i = 0; i < MAX_VPS_NUM_SCALABILITY_TYPES; i++)<br>@@ -373,19 +385,23 @@ void Entropy::codeVPS(const VPS& vps, const SPS& sps)<br>                 WRITE_FLAG(1, "max_one_active_ref_layer_flag");<br>                 WRITE_FLAG(0, "vps_poc_lsb_aligned_flag");<br>                 WRITE_FLAG(1, "poc_lsb_not_present_flag[");<br>-                WRITE_FLAG(0, "sub_layer_flag_info_present_flag");<br> <br>-                for (int i = 1; i <= 1; i++)<br>+                for (int i = 1; i < vps.m_vpsNumLayerSetsMinus1 + 1; i++)<br>                 {<br>-                    for (int j = 0; j < vps.m_numLayers; j++)<br>+                    WRITE_FLAG(vps.maxTempSubLayers > 1, "sub_layer_flag_info_present_flag");<br>+                    for (int j = 0; j < vps.maxTempSubLayers ; j++)<br>                     {<br>-                        WRITE_UVLC(vps.maxDecPicBuffering[0] - 1, "vps_max_dec_pic_buffering_minus1[i]");<br>+                        if(j > 0)<br>+                        WRITE_FLAG(vps.maxTempSubLayers > 1, "sub_layer_dpb_info_present_flag");<br>+<br>+                        for(int k = 0; k < vps.m_numLayersInIdList[i]; k++)<br>+                            WRITE_UVLC(vps.maxDecPicBuffering[j] - 1, "vps_max_dec_pic_buffering_minus1[i]");<br>+<br>+                        WRITE_UVLC(vps.numReorderPics[0], "vps_num_reorder_pics[i]");<br>+                        WRITE_UVLC(vps.maxLatencyIncrease[0] + 1, "vps_max_latency_increase_plus1[i]");<br>                     }<br>                 }<br> <br>-                WRITE_UVLC(vps.numReorderPics[0], "vps_num_reorder_pics[i]");<br>-                WRITE_UVLC(vps.maxLatencyIncrease[0] + 1, "vps_max_latency_increase_plus1[i]");<br>-<br>                 WRITE_UVLC(0, "direct_dep_type_len_minus2");<br> <br>                 WRITE_FLAG(0, "default_direct_dependency_flag");<br>@@ -454,17 +470,22 @@ void Entropy::codeVPS(const VPS& vps, const SPS& sps)<br> <br>                 WRITE_FLAG(1, "max_one_active_ref_layer_flag");<br>                 WRITE_FLAG(0, "vps_poc_lsb_aligned_flag");<br>-                WRITE_FLAG(0, "sub_layer_flag_info_present_flag");<br> <br>-                for (int i = 1; i <= vps.m_vpsNumLayerSetsMinus1; i++)<br>+                for (int i = 1; i < vps.m_vpsNumLayerSetsMinus1 + 1; i++)<br>                 {<br>-                    for (int j = 0; j < vps.m_numViews; j++)<br>+                    WRITE_FLAG(vps.maxTempSubLayers > 1, "sub_layer_flag_info_present_flag");<br>+                    for (int j = 0; j < vps.maxTempSubLayers; j++)<br>                     {<br>-                        WRITE_UVLC(vps.maxDecPicBuffering[0] - 1, "vps_max_dec_pic_buffering_minus1[i]");<br>+                        if (j > 0)<br>+                            WRITE_FLAG(vps.maxTempSubLayers > 1, "sub_layer_dpb_info_present_flag");<br>+<br>+                        for (int k = 0; k < vps.m_numLayersInIdList[i]; k++)<br>+                            WRITE_UVLC(vps.maxDecPicBuffering[j] - 1, "vps_max_dec_pic_buffering_minus1[i]");<br>+<br>+                        WRITE_UVLC(vps.numReorderPics[0], "vps_num_reorder_pics[i]");<br>+                        WRITE_UVLC(vps.maxLatencyIncrease[0] + 1, "vps_max_latency_increase_plus1[i]");<br>                     }<br>                 }<br>-                WRITE_UVLC(vps.numReorderPics[0], "vps_num_reorder_pics[i]");<br>-                WRITE_UVLC(vps.maxLatencyIncrease[0] + 1, "vps_max_latency_increase_plus1[i]");<br> <br>                 WRITE_UVLC(0, "direct_dep_type_len_minus2");<br> <br>@@ -488,14 +509,17 @@ void Entropy::codeSPS(const SPS& sps, const ScalingList& scalingList, const Prof<br> {<br>     WRITE_CODE(0, 4, "sps_video_parameter_set_id");<br> #if ENABLE_MULTIVIEW<br>-    if(layer != 0 && sps.setSpsExtOrMaxSubLayersMinus1 == 7)<br>+    if(layer != 0)<br>         WRITE_CODE(sps.setSpsExtOrMaxSubLayersMinus1, 3, "sps_ext_or_max_sub_layers_minus1");<br>+    else<br>+        WRITE_CODE(sps.maxTempSubLayers - 1, 3, "sps_max_sub_layers_minus1");<br>     if (!(layer != 0 && sps.setSpsExtOrMaxSubLayersMinus1 == 7))<br>+#else<br>+    WRITE_CODE(sps.maxTempSubLayers - 1, 3, "sps_max_sub_layers_minus1");<br> #endif<br>     {<br>-        WRITE_CODE(sps.maxTempSubLayers - 1, 3, "sps_max_sub_layers_minus1");<br>         WRITE_FLAG(sps.maxTempSubLayers == 1, "sps_temporal_id_nesting_flag");<br>-        codeProfileTier(ptl, sps.maxTempSubLayers, layer);<br>+        codeProfileTier(ptl, sps.maxTempSubLayers);<br>     }<br> <br>     WRITE_UVLC(layer, "sps_seq_parameter_set_id");<br>-- <br>2.36.0.windows.1<br><br></div>