[x265] [PATCH] Store most frequently used list in ref list in PPS
Weixuan Wang
weixuan at multicorewareinc.com
Sat Oct 8 05:06:01 CEST 2016
# HG changeset patch
# User weixuan
# Date 1475895706 -28800
# Sat Oct 08 11:01:46 2016 +0800
# Node ID 6f244c89eb2d8b8415e04f4464a18a773b55b5b8
# Parent a3d4e3b13c6c70061bc74a0a052bdf5cd408eeb2
Store most frequently used list in ref list in PPS
diff -r a3d4e3b13c6c -r 6f244c89eb2d source/common/slice.h
--- a/source/common/slice.h Wed Sep 28 15:09:58 2016 +0800
+++ b/source/common/slice.h Sat Oct 08 11:01:46 2016 +0800
@@ -282,6 +282,9 @@
bool bDeblockingFilterControlPresent;
bool bPicDisableDeblockingFilter;
+
+ int ppsId;
+ int numRefIdxDefault[2];
};
struct WeightParam
@@ -348,7 +351,8 @@
bool m_colFromL0Flag; // collocated picture from List0 or
List1 flag
int m_iPPSQpMinus26;
-
+ int numRefIdxDefault[2];
+
Slice()
{
m_lastIDR = 0;
@@ -359,6 +363,8 @@
memset(m_refPOCList, 0, sizeof(m_refPOCList));
disableWeights();
m_iPPSQpMinus26 = 0;
+ numRefIdxDefault[0] = 1;
+ numRefIdxDefault[1] = 1;
}
void disableWeights();
diff -r a3d4e3b13c6c -r 6f244c89eb2d source/encoder/encoder.cpp
--- a/source/encoder/encoder.cpp Wed Sep 28 15:09:58 2016 +0800
+++ b/source/encoder/encoder.cpp Sat Oct 08 11:01:46 2016 +0800
@@ -320,6 +320,14 @@
if (!m_lookahead->create())
m_aborted = true;
+ m_refIdxPPS = X265_MALLOC(RefIdxPPS, 1);
+ if (!m_refIdxPPS)
+ {
+ x265_log(m_param, X265_LOG_ERROR, "Ref Idx for PPS cannot be
allocated\n");
+ m_aborted = true;
+ }
+ initRefIdx();
+
if (m_param->analysisMode)
{
const char* name = m_param->analysisFileName;
@@ -406,6 +414,7 @@
}
X265_FREE(m_offsetEmergency);
+ X265_FREE(m_refIdxPPS);
if (m_analysisFile)
fclose(m_analysisFile);
@@ -900,6 +909,8 @@
}
frameEnc->m_encData->m_slice->m_iPPSQpMinus26 =
m_iPPSQpMinus26;
+ frameEnc->m_encData->m_slice->numRefIdxDefault[0] =
m_pps.numRefIdxDefault[0];
+ frameEnc->m_encData->m_slice->numRefIdxDefault[1] =
m_pps.numRefIdxDefault[1];
curEncoder->m_rce.encodeOrder = frameEnc->m_encodeOrder =
m_encodedFrameNum++;
if (m_bframeDelay)
@@ -1446,6 +1457,67 @@
#pragma warning(disable: 4127) // conditional expression is constant
#endif
+void Encoder::initRefIdx()
+{
+ int j = 0;
+
+ for (j = 0; j < MAX_NUM_REF_IDX; j++)
+ {
+ m_refIdxPPS[0].numRefIdxl0[j] = 0;
+ m_refIdxPPS[0].numRefIdxl1[j] = 0;
+ }
+
+ return;
+}
+
+void Encoder::analyseRefIdx(int *numRefIdx)
+{
+ int i_l0 = 0;
+ int i_l1 = 0;
+
+ i_l0 = numRefIdx[0];
+ i_l1 = numRefIdx[1];
+
+ if ((0 < i_l0) && (MAX_NUM_REF_IDX > i_l0))
+ m_refIdxPPS[0].numRefIdxl0[i_l0]++;
+ if ((0 < i_l1) && (MAX_NUM_REF_IDX > i_l1))
+ m_refIdxPPS[0].numRefIdxl1[i_l1]++;
+
+ return;
+}
+
+void Encoder::updateRefIdx()
+{
+ int i_max_l0 = 0;
+ int i_max_l1 = 0;
+ int j = 0;
+
+ i_max_l0 = 0;
+ i_max_l1 = 0;
+ m_refIdxPPS[0].numRefIdxDefault[0] = 1;
+ m_refIdxPPS[0].numRefIdxDefault[1] = 1;
+ for (j = 0; j < MAX_NUM_REF_IDX; j++)
+ {
+ if (i_max_l0 < m_refIdxPPS[0].numRefIdxl0[j])
+ {
+ i_max_l0 = m_refIdxPPS[0].numRefIdxl0[j];
+ m_refIdxPPS[0].numRefIdxDefault[0] = j;
+ }
+ if (i_max_l1 < m_refIdxPPS[0].numRefIdxl1[j])
+ {
+ i_max_l1 = m_refIdxPPS[0].numRefIdxl1[j];
+ m_refIdxPPS[0].numRefIdxDefault[1] = j;
+ }
+ }
+
+ m_pps.ppsId++;
+ m_pps.numRefIdxDefault[0] = m_refIdxPPS[0].numRefIdxDefault[0];
+ m_pps.numRefIdxDefault[1] = m_refIdxPPS[0].numRefIdxDefault[1];
+ initRefIdx();
+
+ return;
+}
+
void Encoder::getStreamHeaders(NALList& list, Entropy& sbacCoder,
Bitstream& bs)
{
sbacCoder.setBitstream(&bs);
@@ -1654,6 +1726,10 @@
pps->deblockingFilterTcOffsetDiv2 = m_param->deblockingFilterTCOffset;
pps->bEntropyCodingSyncEnabled = m_param->bEnableWavefront;
+
+ pps->ppsId = 0;
+ pps->numRefIdxDefault[0] = 1;
+ pps->numRefIdxDefault[1] = 1;
}
void Encoder::configure(x265_param *p)
diff -r a3d4e3b13c6c -r 6f244c89eb2d source/encoder/encoder.h
--- a/source/encoder/encoder.h Wed Sep 28 15:09:58 2016 +0800
+++ b/source/encoder/encoder.h Sat Oct 08 11:01:46 2016 +0800
@@ -70,6 +70,16 @@
void addSsim(double ssim);
};
+#define MAX_NUM_REF_IDX 64
+
+struct RefIdxPPS
+{
+ int ppsId;
+ int numRefIdxDefault[2];
+ int numRefIdxl0[MAX_NUM_REF_IDX];
+ int numRefIdxl1[MAX_NUM_REF_IDX];
+};
+
class FrameEncoder;
class DPB;
class Lookahead;
@@ -143,6 +153,9 @@
int64_t m_iBitsCostSum[QP_MAX_MAX + 1];
int m_iPPSQpMinus26;
+ Lock m_sliceRefIdxLock;
+ RefIdxPPS* m_refIdxPPS;
+
Encoder();
~Encoder() {}
@@ -180,6 +193,10 @@
void calcRefreshInterval(Frame* frameEnc);
+ void initRefIdx();
+ void analyseRefIdx(int *numRefIdx);
+ void updateRefIdx();
+
protected:
void initVPS(VPS *vps);
diff -r a3d4e3b13c6c -r 6f244c89eb2d source/encoder/entropy.cpp
--- a/source/encoder/entropy.cpp Wed Sep 28 15:09:58 2016 +0800
+++ b/source/encoder/entropy.cpp Sat Oct 08 11:01:46 2016 +0800
@@ -333,8 +333,8 @@
WRITE_CODE(0, 3, "num_extra_slice_header_bits");
WRITE_FLAG(pps.bSignHideEnabled, "sign_data_hiding_flag");
WRITE_FLAG(0, "cabac_init_present_flag");
- WRITE_UVLC(0,
"num_ref_idx_l0_default_active_minus1");
- WRITE_UVLC(0,
"num_ref_idx_l1_default_active_minus1");
+ WRITE_UVLC(pps.numRefIdxDefault[0] - 1,
"num_ref_idx_l0_default_active_minus1");
+ WRITE_UVLC(pps.numRefIdxDefault[1] - 1,
"num_ref_idx_l1_default_active_minus1");
WRITE_SVLC(iPPSInitQpMinus26, "init_qp_minus26");
WRITE_FLAG(pps.bConstrainedIntraPred, "constrained_intra_pred_flag");
@@ -633,7 +633,7 @@
if (!slice.isIntra())
{
- bool overrideFlag = (slice.m_numRefIdx[0] != 1 ||
(slice.isInterB() && slice.m_numRefIdx[1] != 1));
+ bool overrideFlag = (slice.m_numRefIdx[0] !=
slice.numRefIdxDefault[0] || (slice.isInterB() && slice.m_numRefIdx[1] !=
slice.numRefIdxDefault[1]));
WRITE_FLAG(overrideFlag, "num_ref_idx_active_override_flag");
if (overrideFlag)
{
diff -r a3d4e3b13c6c -r 6f244c89eb2d source/encoder/frameencoder.cpp
--- a/source/encoder/frameencoder.cpp Wed Sep 28 15:09:58 2016 +0800
+++ b/source/encoder/frameencoder.cpp Sat Oct 08 11:01:46 2016 +0800
@@ -353,7 +353,11 @@
m_nalList.serialize(NAL_UNIT_ACCESS_UNIT_DELIMITER, m_bs);
}
if (m_frame->m_lowres.bKeyframe && m_param->bRepeatHeaders)
+ {
+ ScopedLock refIdxLock(m_top->m_sliceRefIdxLock);
+ m_top->updateRefIdx();
m_top->getStreamHeaders(m_nalList, m_entropyCoder, m_bs);
+ }
// Weighted Prediction parameters estimation.
bool bUseWeightP = slice->m_sliceType == P_SLICE &&
slice->m_pps->bUseWeightPred;
@@ -857,8 +861,9 @@
const uint32_t sliceAddr = nextSliceRow * m_numCols;
//CUData* ctu = m_frame->m_encData->getPicCTU(sliceAddr);
//const int sliceQp = ctu->m_qp[0];
+ ScopedLock refIdxLock(m_top->m_sliceRefIdxLock);
+ m_top->analyseRefIdx(slice->m_numRefIdx);
m_entropyCoder.codeSliceHeader(*slice, *m_frame->m_encData,
sliceAddr, m_sliceAddrBits, slice->m_sliceQp);
-
// Find rows of current slice
const uint32_t prevSliceRow = nextSliceRow;
while(nextSliceRow < m_numRows && m_rows[nextSliceRow].sliceId
== sliceId)
@@ -880,6 +885,8 @@
}
else
{
+ ScopedLock refIdxLock(m_top->m_sliceRefIdxLock);
+ m_top->analyseRefIdx(slice->m_numRefIdx);
m_entropyCoder.codeSliceHeader(*slice, *m_frame->m_encData, 0, 0,
slice->m_sliceQp);
// serialize each row, record final lengths in slice header
--
Thanks,
weixuan
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mailman.videolan.org/pipermail/x265-devel/attachments/20161008/ac6bf3a2/attachment.html>
More information about the x265-devel
mailing list