[x265] [PATCH] Add temporal-layer support

Anusuya Kumarasamy anusuya.kumarasamy at multicorewareinc.com
Mon Sep 9 08:34:52 UTC 2024


>From 4a2c8338c0b9e1523d1dd25a4f04aea069fe3883 Mon Sep 17 00:00:00 2001
From: AnusuyaKumarasamy <anusuya.kumarasamy at multicorewareinc.com>
Date: Thu, 29 Aug 2024 11:51:38 +0530
Subject: [PATCH 4/7] Add temporal-layer support

---
 source/common/slice.h      |  1 +
 source/encoder/encoder.cpp | 13 +++++++--
 source/encoder/entropy.cpp | 58 +++++++++++++++++++++++++++-----------
 3 files changed, 53 insertions(+), 19 deletions(-)

diff --git a/source/common/slice.h b/source/common/slice.h
index d23479778..3745e7b2f 100644
--- a/source/common/slice.h
+++ b/source/common/slice.h
@@ -178,6 +178,7 @@ struct VPS
     uint8_t          m_layerIdInVps[MAX_VPS_LAYER_ID_PLUS1];
     int              m_viewIdLen;
     int              m_vpsNumLayerSetsMinus1;
+    int              m_numLayersInIdList[1023];
 #endif

 #if ENABLE_MULTIVIEW
diff --git a/source/encoder/encoder.cpp b/source/encoder/encoder.cpp
index 4c2865953..1d75ca258 100644
--- a/source/encoder/encoder.cpp
+++ b/source/encoder/encoder.cpp
@@ -2224,6 +2224,7 @@ int Encoder::encode(const x265_picture* pic_in,
x265_picture** pic_out)
                 else if(m_param->numViews > 1)
                     frameEnc[layer]->m_lowres.sliceType =
IS_X265_TYPE_I(baseViewType) ? X265_TYPE_P : baseViewType;
                 frameEnc[layer]->m_lowres.bKeyframe =
frameEnc[0]->m_lowres.bKeyframe;
+                frameEnc[layer]->m_tempLayer = frameEnc[0]->m_tempLayer;
             }
 #endif

@@ -2416,9 +2417,12 @@ int Encoder::encode(const x265_picture* pic_in,
x265_picture** pic_out)
             if (m_param->bEnableTemporalSubLayers > 2)
             {
                 //Re-assign temporalid if the current frame is at the end
of encode or when I slice is encountered
-                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))
+                for (int layer = 0; layer < m_param->numLayers; layer++)
                 {
-                    frameEnc[0]->m_tempLayer = (int8_t)0;
+                    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))
+                    {
+                        frameEnc[layer]->m_tempLayer = (int8_t)0;
+                    }
                 }
             }
             /* determine references, setup RPS, etc */
@@ -3521,6 +3525,8 @@ void Encoder::initVPS(VPS *vps)
         vps->m_nuhLayerIdPresentFlag = 1;
         vps->m_viewIdLen = 0;
         vps->m_vpsNumLayerSetsMinus1 = 1;
+        vps->m_numLayersInIdList[0] = 1;
+        vps->m_numLayersInIdList[1] = 2;
     }
 #endif

@@ -3568,6 +3574,8 @@ void Encoder::initVPS(VPS *vps)
         vps->m_viewId[1] = 0;

         vps->m_vpsNumLayerSetsMinus1 = 1;
+        vps->m_numLayersInIdList[0] = 1;
+        vps->m_numLayersInIdList[1] = 2;
     }
 #endif
 }
@@ -3656,6 +3664,7 @@ void Encoder::initSPS(SPS *sps)
     sps->sps_extension_flag = false;

 #if ENABLE_MULTIVIEW
+    sps->setSpsExtOrMaxSubLayersMinus1 = sps->maxTempSubLayers - 1;
     sps->maxViews = m_param->numViews;
     if (m_param->numViews > 1)
     {
diff --git a/source/encoder/entropy.cpp b/source/encoder/entropy.cpp
index 12cfc3ef7..a90ab4415 100644
--- a/source/encoder/entropy.cpp
+++ b/source/encoder/entropy.cpp
@@ -255,7 +255,7 @@ void Entropy::codeVPS(const VPS& vps, const SPS& sps)
     if (vps.m_numLayers > 1 || vps.m_numViews > 1)
     {
         WRITE_CODE(maxLayers - 1, 6, "vps_max_nuh_reserved_zero_layer_id");
-        WRITE_UVLC(vps.m_vpsNumLayerSetsMinus1, "vps_max_op_sets_minus1");
+        WRITE_UVLC(vps.m_vpsNumLayerSetsMinus1,
"vps_num_layer_sets_minus1");
         for (int i = 1; i <= vps.m_vpsNumLayerSetsMinus1; i++)
         {
 #if ENABLE_MULTIVIEW
@@ -293,6 +293,8 @@ void Entropy::codeVPS(const VPS& vps, const SPS& sps)
 #if ENABLE_ALPHA || ENABLE_MULTIVIEW
     if (vps.m_numLayers > 1 || vps.m_numViews > 1)
     {
+        WRITE_FLAG(vps.vps_extension_flag, "vps_extension_flag");
+
         if (vps.vps_extension_flag)
         {
             while (m_bitIf->getNumberOfWrittenBits() % X265_BYTE != 0)
@@ -301,6 +303,16 @@ void Entropy::codeVPS(const VPS& vps, const SPS& sps)
             }

             WRITE_CODE(vps.ptl.levelIdc, 8, "general_level_idc");
+            if (vps.maxTempSubLayers > 1)
+            {
+                for (int i = 0; i < vps.maxTempSubLayers - 1; i++)
+                {
+                    WRITE_FLAG(0, "sub_layer_profile_present_flag[i]");
+                    WRITE_FLAG(0, "sub_layer_level_present_flag[i]");
+                }
+                for (int i = vps.maxTempSubLayers - 1; i < 8; i++)
+                    WRITE_CODE(0, 2, "reserved_zero_2bits");
+            }

             WRITE_FLAG(vps.splitting_flag, "splitting flag");
             for (int i = 0; i < MAX_VPS_NUM_SCALABILITY_TYPES; i++)
@@ -373,19 +385,23 @@ void Entropy::codeVPS(const VPS& vps, const SPS& sps)
                 WRITE_FLAG(1, "max_one_active_ref_layer_flag");
                 WRITE_FLAG(0, "vps_poc_lsb_aligned_flag");
                 WRITE_FLAG(1, "poc_lsb_not_present_flag[");
-                WRITE_FLAG(0, "sub_layer_flag_info_present_flag");

-                for (int i = 1; i <= 1; i++)
+                for (int i = 1; i < vps.m_vpsNumLayerSetsMinus1 + 1; i++)
                 {
-                    for (int j = 0; j < vps.m_numLayers; j++)
+                    WRITE_FLAG(vps.maxTempSubLayers > 1,
"sub_layer_flag_info_present_flag");
+                    for (int j = 0; j < vps.maxTempSubLayers ; j++)
                     {
-                        WRITE_UVLC(vps.maxDecPicBuffering[0] - 1,
"vps_max_dec_pic_buffering_minus1[i]");
+                        if(j > 0)
+                        WRITE_FLAG(vps.maxTempSubLayers > 1,
"sub_layer_dpb_info_present_flag");
+
+                        for(int k = 0; k < vps.m_numLayersInIdList[i]; k++)
+                            WRITE_UVLC(vps.maxDecPicBuffering[j] - 1,
"vps_max_dec_pic_buffering_minus1[i]");
+
+                        WRITE_UVLC(vps.numReorderPics[0],
"vps_num_reorder_pics[i]");
+                        WRITE_UVLC(vps.maxLatencyIncrease[0] + 1,
"vps_max_latency_increase_plus1[i]");
                     }
                 }

-                WRITE_UVLC(vps.numReorderPics[0],
"vps_num_reorder_pics[i]");
-                WRITE_UVLC(vps.maxLatencyIncrease[0] + 1,
"vps_max_latency_increase_plus1[i]");
-
                 WRITE_UVLC(0, "direct_dep_type_len_minus2");

                 WRITE_FLAG(0, "default_direct_dependency_flag");
@@ -454,17 +470,22 @@ void Entropy::codeVPS(const VPS& vps, const SPS& sps)

                 WRITE_FLAG(1, "max_one_active_ref_layer_flag");
                 WRITE_FLAG(0, "vps_poc_lsb_aligned_flag");
-                WRITE_FLAG(0, "sub_layer_flag_info_present_flag");

-                for (int i = 1; i <= vps.m_vpsNumLayerSetsMinus1; i++)
+                for (int i = 1; i < vps.m_vpsNumLayerSetsMinus1 + 1; i++)
                 {
-                    for (int j = 0; j < vps.m_numViews; j++)
+                    WRITE_FLAG(vps.maxTempSubLayers > 1,
"sub_layer_flag_info_present_flag");
+                    for (int j = 0; j < vps.maxTempSubLayers; j++)
                     {
-                        WRITE_UVLC(vps.maxDecPicBuffering[0] - 1,
"vps_max_dec_pic_buffering_minus1[i]");
+                        if (j > 0)
+                            WRITE_FLAG(vps.maxTempSubLayers > 1,
"sub_layer_dpb_info_present_flag");
+
+                        for (int k = 0; k < vps.m_numLayersInIdList[i];
k++)
+                            WRITE_UVLC(vps.maxDecPicBuffering[j] - 1,
"vps_max_dec_pic_buffering_minus1[i]");
+
+                        WRITE_UVLC(vps.numReorderPics[0],
"vps_num_reorder_pics[i]");
+                        WRITE_UVLC(vps.maxLatencyIncrease[0] + 1,
"vps_max_latency_increase_plus1[i]");
                     }
                 }
-                WRITE_UVLC(vps.numReorderPics[0],
"vps_num_reorder_pics[i]");
-                WRITE_UVLC(vps.maxLatencyIncrease[0] + 1,
"vps_max_latency_increase_plus1[i]");

                 WRITE_UVLC(0, "direct_dep_type_len_minus2");

@@ -488,14 +509,17 @@ void Entropy::codeSPS(const SPS& sps, const
ScalingList& scalingList, const Prof
 {
     WRITE_CODE(0, 4, "sps_video_parameter_set_id");
 #if ENABLE_MULTIVIEW
-    if(layer != 0 && sps.setSpsExtOrMaxSubLayersMinus1 == 7)
+    if(layer != 0)
         WRITE_CODE(sps.setSpsExtOrMaxSubLayersMinus1, 3,
"sps_ext_or_max_sub_layers_minus1");
+    else
+        WRITE_CODE(sps.maxTempSubLayers - 1, 3,
"sps_max_sub_layers_minus1");
     if (!(layer != 0 && sps.setSpsExtOrMaxSubLayersMinus1 == 7))
+#else
+    WRITE_CODE(sps.maxTempSubLayers - 1, 3, "sps_max_sub_layers_minus1");
 #endif
     {
-        WRITE_CODE(sps.maxTempSubLayers - 1, 3,
"sps_max_sub_layers_minus1");
         WRITE_FLAG(sps.maxTempSubLayers == 1,
"sps_temporal_id_nesting_flag");
-        codeProfileTier(ptl, sps.maxTempSubLayers, layer);
+        codeProfileTier(ptl, sps.maxTempSubLayers);
     }

     WRITE_UVLC(layer, "sps_seq_parameter_set_id");
-- 
2.36.0.windows.1
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mailman.videolan.org/pipermail/x265-devel/attachments/20240909/f70568da/attachment-0001.htm>
-------------- next part --------------
A non-text attachment was scrubbed...
Name: 0004-Add-temporal-layer-support.patch
Type: application/octet-stream
Size: 9232 bytes
Desc: not available
URL: <http://mailman.videolan.org/pipermail/x265-devel/attachments/20240909/f70568da/attachment-0001.obj>


More information about the x265-devel mailing list