[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