[x265] [PATCH MV-HEVC 10/10] Decouple mv-hevc code from alpha and latest-tip
Anusuya Kumarasamy
anusuya.kumarasamy at multicorewareinc.com
Tue Aug 6 10:50:25 UTC 2024
>From 6990541ee2e5b63c818b813a0b766192dbd21f53 Mon Sep 17 00:00:00 2001
From: AnusuyaKumarasamy <anusuya.kumarasamy at multicorewareinc.com>
Date: Mon, 15 Jul 2024 23:11:51 +0530
Subject: [PATCH] Decouple mv-hevc code from alpha and latest-tip
---
source/abrEncApp.cpp | 5 +++--
source/abrEncApp.h | 1 +
source/common/cudata.cpp | 5 +++--
source/common/param.cpp | 5 ++++-
source/common/slice.h | 7 ++-----
source/encoder/dpb.cpp | 8 ++++++--
source/encoder/encoder.cpp | 30 +++++++++++++++++-------------
source/encoder/entropy.cpp | 14 ++++----------
source/encoder/frameencoder.cpp | 4 +++-
source/x265.h | 2 ++
source/x265cli.cpp | 2 +-
11 files changed, 46 insertions(+), 37 deletions(-)
diff --git a/source/abrEncApp.cpp b/source/abrEncApp.cpp
index 3460dfe78..0ae7e5800 100644
--- a/source/abrEncApp.cpp
+++ b/source/abrEncApp.cpp
@@ -63,6 +63,7 @@ namespace X265_NS {
m_passEnc[i]->init(ret);
}
+ m_numInputViews = m_passEnc[0]->m_param->numViews;
if (!allocBuffers())
{
x265_log(NULL, X265_LOG_ERROR, "Unable to allocate memory for
buffers\n");
@@ -96,7 +97,7 @@ namespace X265_NS {
#if ENABLE_MULTIVIEW
if (m_passEnc[0]->m_param->numViews > 1)
{
- for (uint8_t pass = 0; pass < m_passEnc[0]->m_param->numViews;
pass++)
+ for (uint8_t pass = 0; pass < m_numInputViews; pass++)
{
m_inputPicBuffer[pass] = X265_MALLOC(x265_picture*,
m_queueSize);
for (uint32_t idx = 0; idx < m_queueSize; idx++)
@@ -144,7 +145,7 @@ namespace X265_NS {
{
x265_cleanup(); /* Free library singletons */
#if ENABLE_MULTIVIEW
- for (uint8_t pass = 0; pass < MAX_VIEWS; pass++)
+ for (uint8_t pass = 0; pass < m_numInputViews; pass++)
{
for (uint32_t index = 0; index < m_queueSize; index++)
{
diff --git a/source/abrEncApp.h b/source/abrEncApp.h
index 43b202cc5..fab694656 100644
--- a/source/abrEncApp.h
+++ b/source/abrEncApp.h
@@ -42,6 +42,7 @@ namespace X265_NS {
{
public:
uint8_t m_numEncodes;
+ uint8_t m_numInputViews; // Number of inputs for
multiview-extension
PassEncoder **m_passEnc;
uint32_t m_queueSize;
ThreadSafeInteger m_numActiveEncodes;
diff --git a/source/common/cudata.cpp b/source/common/cudata.cpp
index baa9be476..c0d68bc5f 100644
--- a/source/common/cudata.cpp
+++ b/source/common/cudata.cpp
@@ -2053,11 +2053,12 @@ bool CUData::getIndirectPMV(MV& outMV,
InterNeighbourMV *neighbours, uint32_t pi
outMV = mvp;
if (!(curRefPOC == curPOC))
outMV = scaleMvByPOCDist(mvp, curPOC, curRefPOC,
neibPOC, neibRefPOC);
+ return true;
+ }
#else
outMV = scaleMvByPOCDist(mvp, curPOC, curRefPOC, neibPOC,
neibRefPOC);
-#endif
return true;
- }
+#endif
}
}
return false;
diff --git a/source/common/param.cpp b/source/common/param.cpp
index c310a7b4c..084743ee9 100755
--- a/source/common/param.cpp
+++ b/source/common/param.cpp
@@ -406,7 +406,7 @@ void x265_param_default(x265_param* param)
/* Multi-View Encoding*/
param->numViews = 1;
- param->format = 1;
+ param->format = 0;
param->numLayers = 1;
}
@@ -1461,6 +1461,7 @@ int x265_param_parse(x265_param* p, const char* name,
const char* value)
{
p->bEnableAlpha = 1;
p->numScalableLayers = 2;
+ p->numLayers = 2;
}
}
#endif
@@ -1952,6 +1953,8 @@ int x265_check_params(x265_param* param)
#endif
#if ENABLE_MULTIVIEW
CHECK((param->numViews > 2), "Multi-View Encoding currently support
only 2 views");
+ CHECK((param->numViews > 1) && (param->internalBitDepth != 8),
"BitDepthConstraint must be 8 for Multiview main profile");
+ CHECK((param->numViews > 1 && param->rc.rateControlMode !=
X265_RC_CQP), "Multiview encode supported only with CQP mode");
#endif
return check_failed;
}
diff --git a/source/common/slice.h b/source/common/slice.h
index 90009ae7f..0d6807952 100644
--- a/source/common/slice.h
+++ b/source/common/slice.h
@@ -164,6 +164,7 @@ struct VPS
uint32_t maxLatencyIncrease[MAX_T_LAYERS];
int m_numLayers;
int m_numViews;
+ bool vps_extension_flag;
#if (ENABLE_ALPHA || ENABLE_MULTIVIEW)
bool splitting_flag;
@@ -176,7 +177,6 @@ struct VPS
uint8_t m_layerIdInVps[MAX_VPS_LAYER_ID_PLUS1];
int m_viewIdLen;
int m_vpsNumLayerSetsMinus1;
- bool vps_extension_flag;
#endif
#if ENABLE_MULTIVIEW
@@ -276,9 +276,9 @@ struct SPS
Window conformanceWindow;
VUI vuiParameters;
+ bool sps_extension_flag;
#if ENABLE_MULTIVIEW
- bool sps_extension_flag;
int setSpsExtOrMaxSubLayersMinus1;
int maxViews;
bool vui_parameters_present_flag;
@@ -322,11 +322,8 @@ struct PPS
int numRefIdxDefault[2];
bool pps_slice_chroma_qp_offsets_present_flag;
-#if ENABLE_MULTIVIEW
bool pps_extension_flag;
int maxViews;
-#endif
-
};
struct WeightParam
diff --git a/source/encoder/dpb.cpp b/source/encoder/dpb.cpp
index a187e6657..eafc9c91e 100644
--- a/source/encoder/dpb.cpp
+++ b/source/encoder/dpb.cpp
@@ -95,10 +95,12 @@ void DPB::recycleUnreferenced()
// iterator is invalidated by remove, restart scan
m_picList.remove(*curFrame);
- if (!curFrame->m_viewId && m_picList.getPOC(curFrame->m_poc,
1) && curFrame == m_picList.getPOC(curFrame->m_poc,
1)->refPicSetInterLayer0.getPOC(curFrame->m_poc, curFrame->m_viewId))
+#if ENABLE_MULTIVIEW
+ if (curFrame->m_param->numViews > 1 && !curFrame->m_viewId &&
m_picList.getPOC(curFrame->m_poc, 1) && curFrame ==
m_picList.getPOC(curFrame->m_poc,
1)->refPicSetInterLayer0.getPOC(curFrame->m_poc, curFrame->m_viewId))
{
m_picList.getPOC(curFrame->m_poc,
1)->refPicSetInterLayer0.removeSubDPB(*curFrame);
}
+#endif
iterFrame = m_picList.first();
m_freeList.pushBack(*curFrame);
@@ -271,8 +273,10 @@ void DPB::prepareEncode(Frame *newFrame)
}
}
+#if ENABLE_MULTIVIEW
if (newFrame->m_viewId)
slice->createInterLayerReferencePictureSet(m_picList,
newFrame->refPicSetInterLayer0, newFrame->refPicSetInterLayer1);
+#endif
if (slice->m_sliceType != I_SLICE)
slice->m_numRefIdx[0] = x265_clip3(1,
newFrame->m_param->maxNumReferences, slice->m_rps.numberOfNegativePictures
+ newFrame->refPicSetInterLayer0.size() +
newFrame->refPicSetInterLayer1.size());
else
@@ -349,7 +353,7 @@ void DPB::computeRPS(int curPoc, int tempId, bool
isRAP, RPS * rps, unsigned int
if ((!m_bTemporalSublayer || (iterPic->m_tempLayer <= tempId))
&& ((m_lastIDR >= curPoc) || (m_lastIDR <= iterPic->m_poc)))
{
#if ENABLE_MULTIVIEW
- if (layer && numNeg ==
iterPic->m_param->maxNumReferences - 1 && (iterPic->m_poc - curPoc) < 0)
+ if (iterPic->m_param->numViews > 1 && layer && numNeg
== iterPic->m_param->maxNumReferences - 1 && (iterPic->m_poc - curPoc) < 0)
{
iterPic = iterPic->m_next;
continue;
diff --git a/source/encoder/encoder.cpp b/source/encoder/encoder.cpp
index 5fb822c8a..ff8f53883 100644
--- a/source/encoder/encoder.cpp
+++ b/source/encoder/encoder.cpp
@@ -1595,12 +1595,13 @@ int Encoder::encode(const x265_picture* pic_in,
x265_picture** pic_out)
inFrame[layer] = new Frame;
inFrame[layer]->m_encodeStartTime = x265_mdate();
#if ENABLE_MULTIVIEW
- inFrame[layer]->m_viewId = layer;
-#else
- inFrame[layer]->m_sLayerId = layer;
+ inFrame[layer]->m_viewId = m_param->numViews > 1 ? layer :
0;
+#endif
+#if ENABLE_ALPHA
+ inFrame[layer]->m_sLayerId = m_param->numScalableLayers >
1 ? layer : 0;
#endif
inFrame[layer]->m_valid = false;
- if (inFrame[layer]->create(p,
inputPic[layer]->quantOffsets))
+ if (inFrame[layer]->create(p, inputPic[!m_param->format ?
(m_param->numScalableLayers > 1) ? 0 : layer : 0]->quantOffsets))
{
/* the first PicYuv created is asked to generate the
CU and block unit offset
* arrays which are then shared with all subsequent
PicYuv (orig and recon)
@@ -1663,9 +1664,10 @@ int Encoder::encode(const x265_picture* pic_in,
x265_picture** pic_out)
inFrame[layer]->m_tempLayer = 0;
inFrame[layer]->m_sameLayerRefPic = 0;
#if ENABLE_MULTIVIEW
- inFrame[layer]->m_viewId = layer;
-#else
- inFrame[layer]->m_sLayerId = layer;
+ inFrame[layer]->m_viewId = m_param->numViews > 1 ? layer :
0;
+#endif
+#if ENABLE_ALPHA
+ inFrame[layer]->m_sLayerId = m_param->numScalableLayers >
1 ? layer : 0;
#endif
inFrame[layer]->m_valid = false;
inFrame[layer]->m_lowres.bKeyframe = false;
@@ -1701,7 +1703,7 @@ int Encoder::encode(const x265_picture* pic_in,
x265_picture** pic_out)
}
/* Copy input picture into a Frame and PicYuv, send to
lookahead */
-
inFrame[layer]->m_fencPic->copyFromPicture(*inputPic[!m_param->format ?
layer : 0], *m_param, m_sps.conformanceWindow.rightOffset,
m_sps.conformanceWindow.bottomOffset, !layer);
+
inFrame[layer]->m_fencPic->copyFromPicture(*inputPic[!m_param->format ?
(m_param->numScalableLayers > 1) ? 0 : layer : 0], *m_param,
m_sps.conformanceWindow.rightOffset, m_sps.conformanceWindow.bottomOffset,
!layer);
inFrame[layer]->m_poc = (!layer) ? (++m_pocLast) : m_pocLast;
inFrame[layer]->m_userData = inputPic[0]->userData;
@@ -2211,12 +2213,11 @@ int Encoder::encode(const x265_picture* pic_in,
x265_picture** pic_out)
{
Frame* currentFrame =
m_dpb->m_picList.getPOC(frameEnc[0]->m_poc, layer);
frameEnc[layer] =
m_dpb->m_picList.removeFrame(*currentFrame);
-#if ENABLE_ALPHA
- frameEnc[layer]->m_lowres.sliceType =
frameEnc[0]->m_lowres.sliceType;
-#else
int baseViewType = frameEnc[0]->m_lowres.sliceType;
- frameEnc[layer]->m_lowres.sliceType =
IS_X265_TYPE_I(baseViewType) ? X265_TYPE_P : baseViewType;
-#endif
+ if (m_param->numScalableLayers > 1)
+ frameEnc[layer]->m_lowres.sliceType = baseViewType;
+ else if(m_param->numViews > 1)
+ frameEnc[layer]->m_lowres.sliceType =
IS_X265_TYPE_I(baseViewType) ? X265_TYPE_P : baseViewType;
}
#endif
@@ -3644,6 +3645,7 @@ void Encoder::initSPS(SPS *sps)
vui.timingInfo.numUnitsInTick = m_param->fpsDenom;
vui.timingInfo.timeScale = m_param->fpsNum;
+ sps->sps_extension_flag = false;
#if ENABLE_MULTIVIEW
if (m_param->numViews > 1)
@@ -3698,6 +3700,8 @@ void Encoder::initPPS(PPS *pps)
pps->numRefIdxDefault[0] = 1;
pps->numRefIdxDefault[1] = 1;
+ pps->pps_extension_flag = false;
+ pps->maxViews = 1;
#if ENABLE_MULTIVIEW
if (m_param->numViews > 1)
diff --git a/source/encoder/entropy.cpp b/source/encoder/entropy.cpp
index 1fe3d5895..0e45b4976 100644
--- a/source/encoder/entropy.cpp
+++ b/source/encoder/entropy.cpp
@@ -487,11 +487,13 @@ void Entropy::codeVPS(const VPS& vps, const SPS& sps)
void Entropy::codeSPS(const SPS& sps, const ScalingList& scalingList,
const ProfileTierLevel& ptl, int layer)
{
WRITE_CODE(0, 4, "sps_video_parameter_set_id");
- WRITE_CODE(!layer ? sps.maxTempSubLayers - 1 :
sps.setSpsExtOrMaxSubLayersMinus1, 3, "sps_ext_or_max_sub_layers_minus1");
#if ENABLE_MULTIVIEW
+ if(layer != 0 && sps.setSpsExtOrMaxSubLayersMinus1 == 7)
+ WRITE_CODE(sps.setSpsExtOrMaxSubLayersMinus1, 3,
"sps_ext_or_max_sub_layers_minus1");
if (!(layer != 0 && sps.setSpsExtOrMaxSubLayersMinus1 == 7))
#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);
}
@@ -924,21 +926,13 @@ void Entropy::codeSliceHeader(const Slice& slice,
FrameData& encData, uint32_t s
WRITE_UVLC(slice.m_sliceType, "slice_type");
- if (layer > 0 || !slice.getIdrPicFlag())
+ if ((slice.m_param->numViews > 1 && layer > 0) ||
!slice.getIdrPicFlag())
{
int picOrderCntLSB = (slice.m_poc - slice.m_lastIDR + (1 <<
slice.m_sps->log2MaxPocLsb)) % (1 << slice.m_sps->log2MaxPocLsb);
WRITE_CODE(picOrderCntLSB, slice.m_sps->log2MaxPocLsb,
"pic_order_cnt_lsb");
}
if (!slice.getIdrPicFlag())
{
-#if ENABLE_MULTIVIEW
- if (!(slice.m_param->numViews > 1))
-#endif
- {
- int picOrderCntLSB = (slice.m_poc - slice.m_lastIDR + (1 <<
slice.m_sps->log2MaxPocLsb)) % (1 << slice.m_sps->log2MaxPocLsb);
- WRITE_CODE(picOrderCntLSB, slice.m_sps->log2MaxPocLsb,
"pic_order_cnt_lsb");
- }
-
#if _DEBUG || CHECKED_BUILD
// check for bitstream restriction stating that:
// If the current picture is a BLA or CRA picture, the value of
NumPocTotalCurr shall be equal to 0.
diff --git a/source/encoder/frameencoder.cpp
b/source/encoder/frameencoder.cpp
index 19d61ec35..c5175f538 100644
--- a/source/encoder/frameencoder.cpp
+++ b/source/encoder/frameencoder.cpp
@@ -1159,8 +1159,10 @@ void FrameEncoder::compressFrame(int layer)
/* rateControlEnd may also block for earlier frames to call
rateControlUpdateStats */
if (!layer && m_top->m_rateControl->rateControlEnd(m_frame[layer],
m_accessUnitBits[layer], &m_rce, &filler) < 0)
m_top->m_aborted = true;
- if (!layer)
+#if ENABLE_ALPHA || ENABLE_MULTIVIEW
+ if (!layer && m_frame[layer+1])
m_frame[1]->m_encData->m_avgQpAq =
m_frame[layer]->m_encData->m_avgQpAq;
+#endif
if (filler > 0)
{
diff --git a/source/x265.h b/source/x265.h
index fb06372af..7b5144ec2 100644
--- a/source/x265.h
+++ b/source/x265.h
@@ -650,6 +650,8 @@ typedef enum
#if ENABLE_ALPHA || ENABLE_MULTIVIEW
#define MAX_LAYERS 2
+#else
+#define MAX_LAYERS 1
#endif
#define X265_IPRATIO_STRENGTH 1.43
diff --git a/source/x265cli.cpp b/source/x265cli.cpp
index c0c70b78b..a4ce6d272 100755
--- a/source/x265cli.cpp
+++ b/source/x265cli.cpp
@@ -983,7 +983,7 @@ namespace X265_NS {
}
}
#endif
- for (int i = 0; i < param->numLayers - !!param->format; i++)
+ for (int i = 0; i < param->numLayers; i++)
{
this->recon[i] = ReconFile::open(reconfn[i],
param->sourceWidth, param->sourceHeight, reconFileBitDepth,
param->fpsNum, param->fpsDenom, param->internalCsp,
param->sourceBitDepth);
--
2.36.0.windows.1
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mailman.videolan.org/pipermail/x265-devel/attachments/20240806/cb64483d/attachment-0001.htm>
-------------- next part --------------
A non-text attachment was scrubbed...
Name: 0010-Decouple-mv-hevc-code-from-alpha-and-latest-tip.patch
Type: application/x-patch
Size: 15357 bytes
Desc: not available
URL: <http://mailman.videolan.org/pipermail/x265-devel/attachments/20240806/cb64483d/attachment-0001.bin>
More information about the x265-devel
mailing list