[x265] [PATCH 2 of 2] Reuse CU depth for B frame and allow I, P frame to follow x265 depth decision
jayashri at multicorewareinc.com
jayashri at multicorewareinc.com
Fri Dec 28 10:17:28 CET 2018
# HG changeset patch
# User Jayashri Murugan
# Date 1537464480 25200
# Thu Sep 20 10:28:00 2018 -0700
# Node ID d571bdb0b0ae9894dce12d9d0fc3ea4d639a01a2
# Parent 23a8a7456916d98040b56a09a93ce3b1149613d9
Reuse CU depth for B frame and allow I, P frame to follow x265 depth decision
diff -r 23a8a7456916 -r d571bdb0b0ae source/common/param.cpp
--- a/source/common/param.cpp Wed Sep 19 14:30:48 2018 -0700
+++ b/source/common/param.cpp Thu Sep 20 10:28:00 2018 -0700
@@ -1157,6 +1157,10 @@
{
p->bAnalysisType = AVC_INFO;
}
+ else if (strcmp(strdup(value), "hevc") == 0)
+ {
+ p->bAnalysisType = HEVC_INFO;
+ }
else if (strcmp(strdup(value), "off") == 0)
{
p->bAnalysisType = NO_INFO;
@@ -1714,7 +1718,11 @@
TOOLVAL(param->lookaheadThreads, "lthreads=%d")
TOOLVAL(param->bCTUInfo, "ctu-info=%d");
if (param->bAnalysisType == AVC_INFO)
+ {
TOOLOPT(param->bAnalysisType, "refine-analysis-type=avc");
+ }
+ else if (param->bAnalysisType == HEVC_INFO)
+ TOOLOPT(param->bAnalysisType, "refine-analysis-type=hevc");
TOOLOPT(param->bDynamicRefine, "dynamic-refine");
if (param->maxSlices > 1)
TOOLVAL(param->maxSlices, "slices=%d");
diff -r 23a8a7456916 -r d571bdb0b0ae source/encoder/analysis.cpp
--- a/source/encoder/analysis.cpp Wed Sep 19 14:30:48 2018 -0700
+++ b/source/encoder/analysis.cpp Thu Sep 20 10:28:00 2018 -0700
@@ -275,7 +275,8 @@
/* generate residual for entire CTU at once and copy to reconPic */
encodeResidue(ctu, cuGeom);
}
- else if ((m_param->analysisLoad && m_param->analysisReuseLevel == 10) || ((m_param->bAnalysisType == AVC_INFO) && m_param->analysisReuseLevel >= 7 && ctu.m_numPartitions <= 16))
+ else if ((m_param->analysisLoad && m_param->analysisReuseLevel == 10 && (!(m_param->bAnalysisType == HEVC_INFO) || m_slice->m_sliceType != P_SLICE)) ||
+ ((m_param->bAnalysisType == AVC_INFO) && m_param->analysisReuseLevel >= 7 && ctu.m_numPartitions <= 16))
{
x265_analysis_inter_data* interDataCTU = m_frame->m_analysisData.interData;
int posCTU = ctu.m_cuAddr * numPartition;
@@ -516,7 +517,7 @@
bool mightSplit = !(cuGeom.flags & CUGeom::LEAF);
bool mightNotSplit = !(cuGeom.flags & CUGeom::SPLIT_MANDATORY);
- bool bAlreadyDecided = m_param->intraRefine != 4 && parentCTU.m_lumaIntraDir[cuGeom.absPartIdx] != (uint8_t)ALL_IDX;
+ bool bAlreadyDecided = m_param->intraRefine != 4 && parentCTU.m_lumaIntraDir[cuGeom.absPartIdx] != (uint8_t)ALL_IDX && !(m_param->bAnalysisType == HEVC_INFO);
bool bDecidedDepth = m_param->intraRefine != 4 && parentCTU.m_cuDepth[cuGeom.absPartIdx] == depth;
int split = 0;
if (m_param->intraRefine && m_param->intraRefine != 4)
@@ -2423,7 +2424,7 @@
(m_refineLevel && cuGeom.log2CUSize == (uint32_t)(g_log2Size[m_param->minCUSize] + 1))));
td.split = split;
- if (bDecidedDepth && mightNotSplit)
+ if ((bDecidedDepth && mightNotSplit) || (m_param->bAnalysisType == HEVC_INFO && parentCTU.m_cuDepth[cuGeom.absPartIdx] == 4))
{
setLambdaFromQP(parentCTU, qp, lqp);
@@ -2562,7 +2563,10 @@
if (m_refineLevel > 1 || (m_refineLevel && parentCTU.m_predMode[cuGeom.absPartIdx] == MODE_SKIP && !mode.cu.isSkipped(0)))
{
- m_evaluateInter = 1;
+ if (parentCTU.m_cuDepth[cuGeom.absPartIdx] < 4 && mightNotSplit)
+ m_evaluateInter = 1;
+ else
+ bDecidedDepth = true;
m_param->rdLevel > 4 ? compressInterCU_rd5_6(parentCTU, cuGeom, qp) : compressInterCU_rd0_4(parentCTU, cuGeom, qp);
m_evaluateInter = 0;
}
diff -r 23a8a7456916 -r d571bdb0b0ae source/encoder/api.cpp
--- a/source/encoder/api.cpp Wed Sep 19 14:30:48 2018 -0700
+++ b/source/encoder/api.cpp Thu Sep 20 10:28:00 2018 -0700
@@ -463,20 +463,20 @@
//Allocate memory for intraData pointer
CHECKED_MALLOC_ZERO(intraData, x265_analysis_intra_data, 1);
CHECKED_MALLOC(intraData->depth, uint8_t, analysis->numPartitions * analysis->numCUsInFrame);
- CHECKED_MALLOC(intraData->modes, uint8_t, analysis->numPartitions * analysis->numCUsInFrame);
- CHECKED_MALLOC(intraData->partSizes, char, analysis->numPartitions * analysis->numCUsInFrame);
- CHECKED_MALLOC(intraData->chromaModes, uint8_t, analysis->numPartitions * analysis->numCUsInFrame);
+ CHECKED_MALLOC_ZERO(intraData->modes, uint8_t, analysis->numPartitions * analysis->numCUsInFrame);
+ CHECKED_MALLOC_ZERO(intraData->partSizes, char, analysis->numPartitions * analysis->numCUsInFrame);
+ CHECKED_MALLOC_ZERO(intraData->chromaModes, uint8_t, analysis->numPartitions * analysis->numCUsInFrame);
if (param->rc.cuTree)
- CHECKED_MALLOC(intraData->cuQPOff, int8_t, analysis->numPartitions * analysis->numCUsInFrame);
+ CHECKED_MALLOC_ZERO(intraData->cuQPOff, int8_t, analysis->numPartitions * analysis->numCUsInFrame);
analysis->intraData = intraData;
//Allocate memory for interData pointer based on ReuseLevels
CHECKED_MALLOC_ZERO(interData, x265_analysis_inter_data, 1);
CHECKED_MALLOC(interData->depth, uint8_t, analysis->numPartitions * analysis->numCUsInFrame);
- CHECKED_MALLOC(interData->modes, uint8_t, analysis->numPartitions * analysis->numCUsInFrame);
+ CHECKED_MALLOC_ZERO(interData->modes, uint8_t, analysis->numPartitions * analysis->numCUsInFrame);
if (param->rc.cuTree)
- CHECKED_MALLOC(interData->cuQPOff, int8_t, analysis->numPartitions * analysis->numCUsInFrame);
+ CHECKED_MALLOC_ZERO(interData->cuQPOff, int8_t, analysis->numPartitions * analysis->numCUsInFrame);
CHECKED_MALLOC_ZERO(interData->mvpIdx[0], uint8_t, analysis->numPartitions * analysis->numCUsInFrame);
CHECKED_MALLOC_ZERO(interData->mvpIdx[1], uint8_t, analysis->numPartitions * analysis->numCUsInFrame);
CHECKED_MALLOC_ZERO(interData->mv[0], x265_analysis_MV, analysis->numPartitions * analysis->numCUsInFrame);
@@ -484,16 +484,16 @@
if (param->analysisReuseLevel > 4)
{
- CHECKED_MALLOC(interData->partSize, uint8_t, analysis->numPartitions * analysis->numCUsInFrame);
+ CHECKED_MALLOC_ZERO(interData->partSize, uint8_t, analysis->numPartitions * analysis->numCUsInFrame);
CHECKED_MALLOC_ZERO(interData->mergeFlag, uint8_t, analysis->numPartitions * analysis->numCUsInFrame);
}
if (param->analysisReuseLevel >= 7)
{
- CHECKED_MALLOC(interData->interDir, uint8_t, analysis->numPartitions * analysis->numCUsInFrame);
- CHECKED_MALLOC(interData->sadCost, int64_t, analysis->numPartitions * analysis->numCUsInFrame);
+ CHECKED_MALLOC_ZERO(interData->interDir, uint8_t, analysis->numPartitions * analysis->numCUsInFrame);
+ CHECKED_MALLOC_ZERO(interData->sadCost, int64_t, analysis->numPartitions * analysis->numCUsInFrame);
for (int dir = 0; dir < numDir; dir++)
{
- CHECKED_MALLOC(interData->refIdx[dir], int8_t, analysis->numPartitions * analysis->numCUsInFrame);
+ CHECKED_MALLOC_ZERO(interData->refIdx[dir], int8_t, analysis->numPartitions * analysis->numCUsInFrame);
CHECKED_MALLOC_ZERO(analysis->modeFlag[dir], uint8_t, analysis->numPartitions * analysis->numCUsInFrame);
}
}
diff -r 23a8a7456916 -r d571bdb0b0ae source/encoder/encoder.cpp
--- a/source/encoder/encoder.cpp Wed Sep 19 14:30:48 2018 -0700
+++ b/source/encoder/encoder.cpp Thu Sep 20 10:28:00 2018 -0700
@@ -1145,7 +1145,7 @@
{
/* reads analysis data for the frame and allocates memory based on slicetype */
static int paramBytes = 0;
- if (!inFrame->m_poc)
+ if (!inFrame->m_poc && m_param->bAnalysisType != HEVC_INFO)
{
x265_analysis_data analysisData = pic_in->analysisData;
paramBytes = validateAnalysisData(&analysisData, 0);
@@ -2885,7 +2885,7 @@
p->rc.rfConstantMin = 0;
}
- if ((p->analysisLoad || p->analysisSave) && p->rc.cuTree && p->analysisReuseLevel < 10)
+ if (!(p->bAnalysisType == HEVC_INFO) && (p->analysisLoad || p->analysisSave) && p->rc.cuTree && p->analysisReuseLevel < 10)
{
x265_log(p, X265_LOG_WARNING, "cu-tree works only with analysis reuse level 10, Disabling cu-tree\n");
p->rc.cuTree = 0;
@@ -2954,7 +2954,7 @@
p->interRefine = 1;
}
- if (p->limitTU && (p->interRefine || p->bDynamicRefine))
+ if (!(p->bAnalysisType == HEVC_INFO) && p->limitTU && (p->interRefine || p->bDynamicRefine))
{
x265_log(p, X265_LOG_WARNING, "Inter refinement does not support limitTU. Disabling limitTU.\n");
p->limitTU = 0;
@@ -3465,6 +3465,8 @@
}
if (analysis->sliceType == X265_TYPE_IDR || analysis->sliceType == X265_TYPE_I)
{
+ if (m_param->bAnalysisType == HEVC_INFO)
+ return;
if (m_param->analysisReuseLevel < 2)
return;
@@ -3542,98 +3544,107 @@
bIntraInInter = (analysis->sliceType == X265_TYPE_P || m_param->bIntraInBFrames);
if (bIntraInInter) numBuf++;
}
-
- tempBuf = X265_MALLOC(uint8_t, depthBytes * numBuf);
- depthBuf = tempBuf;
- modeBuf = tempBuf + depthBytes;
- if (m_param->rc.cuTree)
- cuQPBuf = X265_MALLOC(int8_t, depthBytes);
-
- X265_FREAD(depthBuf, sizeof(uint8_t), depthBytes, m_analysisFileIn, interPic->depth);
- X265_FREAD(modeBuf, sizeof(uint8_t), depthBytes, m_analysisFileIn, interPic->modes);
- if (m_param->rc.cuTree) { X265_FREAD(cuQPBuf, sizeof(int8_t), depthBytes, m_analysisFileIn, interPic->cuQPOff); }
-
- if (m_param->analysisReuseLevel > 4)
+ if (m_param->bAnalysisType == HEVC_INFO)
+ {
+ depthBytes = analysis->numCUsInFrame * analysis->numPartitions;
+ memcpy(((x265_analysis_inter_data *)analysis->interData)->depth, interPic->depth, depthBytes);
+ }
+ else
{
- partSize = modeBuf + depthBytes;
- mergeFlag = partSize + depthBytes;
- X265_FREAD(partSize, sizeof(uint8_t), depthBytes, m_analysisFileIn, interPic->partSize);
- X265_FREAD(mergeFlag, sizeof(uint8_t), depthBytes, m_analysisFileIn, interPic->mergeFlag);
-
- if (m_param->analysisReuseLevel == 10)
+ tempBuf = X265_MALLOC(uint8_t, depthBytes * numBuf);
+ depthBuf = tempBuf;
+ modeBuf = tempBuf + depthBytes;
+ if (m_param->rc.cuTree)
+ cuQPBuf = X265_MALLOC(int8_t, depthBytes);
+
+ X265_FREAD(depthBuf, sizeof(uint8_t), depthBytes, m_analysisFileIn, interPic->depth);
+ X265_FREAD(modeBuf, sizeof(uint8_t), depthBytes, m_analysisFileIn, interPic->modes);
+ if (m_param->rc.cuTree) { X265_FREAD(cuQPBuf, sizeof(int8_t), depthBytes, m_analysisFileIn, interPic->cuQPOff); }
+
+ if (m_param->analysisReuseLevel > 4)
{
- interDir = mergeFlag + depthBytes;
- X265_FREAD(interDir, sizeof(uint8_t), depthBytes, m_analysisFileIn, interPic->interDir);
- if (bIntraInInter)
+ partSize = modeBuf + depthBytes;
+ mergeFlag = partSize + depthBytes;
+ X265_FREAD(partSize, sizeof(uint8_t), depthBytes, m_analysisFileIn, interPic->partSize);
+ X265_FREAD(mergeFlag, sizeof(uint8_t), depthBytes, m_analysisFileIn, interPic->mergeFlag);
+
+ if (m_param->analysisReuseLevel == 10)
{
- chromaDir = interDir + depthBytes;
- X265_FREAD(chromaDir, sizeof(uint8_t), depthBytes, m_analysisFileIn, intraPic->chromaModes);
- }
- for (uint32_t i = 0; i < numDir; i++)
- {
- mvpIdx[i] = X265_MALLOC(uint8_t, depthBytes);
- refIdx[i] = X265_MALLOC(int8_t, depthBytes);
- mv[i] = X265_MALLOC(MV, depthBytes);
- X265_FREAD(mvpIdx[i], sizeof(uint8_t), depthBytes, m_analysisFileIn, interPic->mvpIdx[i]);
- X265_FREAD(refIdx[i], sizeof(int8_t), depthBytes, m_analysisFileIn, interPic->refIdx[i]);
- X265_FREAD(mv[i], sizeof(MV), depthBytes, m_analysisFileIn, interPic->mv[i]);
+ interDir = mergeFlag + depthBytes;
+ X265_FREAD(interDir, sizeof(uint8_t), depthBytes, m_analysisFileIn, interPic->interDir);
+ if (bIntraInInter)
+ {
+ chromaDir = interDir + depthBytes;
+ X265_FREAD(chromaDir, sizeof(uint8_t), depthBytes, m_analysisFileIn, intraPic->chromaModes);
+ }
+ for (uint32_t i = 0; i < numDir; i++)
+ {
+ mvpIdx[i] = X265_MALLOC(uint8_t, depthBytes);
+ refIdx[i] = X265_MALLOC(int8_t, depthBytes);
+ mv[i] = X265_MALLOC(MV, depthBytes);
+ X265_FREAD(mvpIdx[i], sizeof(uint8_t), depthBytes, m_analysisFileIn, interPic->mvpIdx[i]);
+ X265_FREAD(refIdx[i], sizeof(int8_t), depthBytes, m_analysisFileIn, interPic->refIdx[i]);
+ X265_FREAD(mv[i], sizeof(MV), depthBytes, m_analysisFileIn, interPic->mv[i]);
+ }
}
}
- }
-
- size_t count = 0;
- for (uint32_t d = 0; d < depthBytes; d++)
- {
- int bytes = analysis->numPartitions >> (depthBuf[d] * 2);
- if (m_param->scaleFactor && modeBuf[d] == MODE_INTRA && depthBuf[d] == 0)
- depthBuf[d] = 1;
- memset(&(analysis->interData)->depth[count], depthBuf[d], bytes);
- memset(&(analysis->interData)->modes[count], modeBuf[d], bytes);
- if (m_param->rc.cuTree)
- memset(&(analysis->interData)->cuQPOff[count], cuQPBuf[d], bytes);
- if (m_param->analysisReuseLevel > 4)
+
+ size_t count = 0;
+ for (uint32_t d = 0; d < depthBytes; d++)
{
- if (m_param->scaleFactor && modeBuf[d] == MODE_INTRA && partSize[d] == SIZE_NxN)
- partSize[d] = SIZE_2Nx2N;
- memset(&(analysis->interData)->partSize[count], partSize[d], bytes);
- int numPU = (modeBuf[d] == MODE_INTRA) ? 1 : nbPartsTable[(int)partSize[d]];
- for (int pu = 0; pu < numPU; pu++)
+ int bytes = analysis->numPartitions >> (depthBuf[d] * 2);
+ if (m_param->scaleFactor && modeBuf[d] == MODE_INTRA && depthBuf[d] == 0)
+ depthBuf[d] = 1;
+ memset(&(analysis->interData)->depth[count], depthBuf[d], bytes);
+ memset(&(analysis->interData)->modes[count], modeBuf[d], bytes);
+ if (m_param->rc.cuTree)
+ memset(&(analysis->interData)->cuQPOff[count], cuQPBuf[d], bytes);
+ if (m_param->analysisReuseLevel > 4)
{
- if (pu) d++;
- (analysis->interData)->mergeFlag[count + pu] = mergeFlag[d];
- if (m_param->analysisReuseLevel == 10)
+ if (m_param->scaleFactor && modeBuf[d] == MODE_INTRA && partSize[d] == SIZE_NxN)
+ partSize[d] = SIZE_2Nx2N;
+ memset(&(analysis->interData)->partSize[count], partSize[d], bytes);
+ int numPU = (modeBuf[d] == MODE_INTRA) ? 1 : nbPartsTable[(int)partSize[d]];
+ for (int pu = 0; pu < numPU; pu++)
{
- (analysis->interData)->interDir[count + pu] = interDir[d];
- for (uint32_t i = 0; i < numDir; i++)
+ if (pu) d++;
+ (analysis->interData)->mergeFlag[count + pu] = mergeFlag[d];
+ if (m_param->analysisReuseLevel == 10)
{
- (analysis->interData)->mvpIdx[i][count + pu] = mvpIdx[i][d];
- (analysis->interData)->refIdx[i][count + pu] = refIdx[i][d];
- if (m_param->scaleFactor)
+ (analysis->interData)->interDir[count + pu] = interDir[d];
+ for (uint32_t i = 0; i < numDir; i++)
{
- mv[i][d].x *= (int16_t)m_param->scaleFactor;
- mv[i][d].y *= (int16_t)m_param->scaleFactor;
+ (analysis->interData)->mvpIdx[i][count + pu] = mvpIdx[i][d];
+ (analysis->interData)->refIdx[i][count + pu] = refIdx[i][d];
+ if (m_param->scaleFactor)
+ {
+ mv[i][d].x *= (int16_t)m_param->scaleFactor;
+ mv[i][d].y *= (int16_t)m_param->scaleFactor;
+ }
+ memcpy(&(analysis->interData)->mv[i][count + pu], &mv[i][d], sizeof(MV));
}
- memcpy(&(analysis->interData)->mv[i][count + pu], &mv[i][d], sizeof(MV));
}
}
+ if (m_param->analysisReuseLevel == 10 && bIntraInInter)
+ memset(&(analysis->intraData)->chromaModes[count], chromaDir[d], bytes);
}
- if (m_param->analysisReuseLevel == 10 && bIntraInInter)
- memset(&(analysis->intraData)->chromaModes[count], chromaDir[d], bytes);
+ count += bytes;
}
- count += bytes;
+
+ if (m_param->rc.cuTree)
+ X265_FREE(cuQPBuf);
+ X265_FREE(tempBuf);
}
-
- if (m_param->rc.cuTree)
- X265_FREE(cuQPBuf);
- X265_FREE(tempBuf);
-
if (m_param->analysisReuseLevel == 10)
{
- for (uint32_t i = 0; i < numDir; i++)
+ if (m_param->bAnalysisType != HEVC_INFO)
{
- X265_FREE(mvpIdx[i]);
- X265_FREE(refIdx[i]);
- X265_FREE(mv[i]);
+ for (uint32_t i = 0; i < numDir; i++)
+ {
+ X265_FREE(mvpIdx[i]);
+ X265_FREE(refIdx[i]);
+ X265_FREE(mv[i]);
+ }
}
if (bIntraInInter)
{
diff -r 23a8a7456916 -r d571bdb0b0ae source/encoder/slicetype.cpp
--- a/source/encoder/slicetype.cpp Wed Sep 19 14:30:48 2018 -0700
+++ b/source/encoder/slicetype.cpp Thu Sep 20 10:28:00 2018 -0700
@@ -1090,7 +1090,7 @@
if (m_param->rc.cuTree && !m_param->rc.bStatRead)
/* update row satds based on cutree offsets */
curFrame->m_lowres.satdCost = frameCostRecalculate(frames, p0, p1, b);
- else if (!m_param->analysisLoad || m_param->scaleFactor)
+ else if (!m_param->analysisLoad || m_param->scaleFactor || m_param->bAnalysisType == HEVC_INFO)
{
if (m_param->rc.aqMode)
curFrame->m_lowres.satdCost = curFrame->m_lowres.costEstAq[b - p0][p1 - b];
@@ -1245,7 +1245,7 @@
}
int bframes, brefs;
- if (!m_param->analysisLoad)
+ if (!m_param->analysisLoad || m_param->bAnalysisType == HEVC_INFO)
{
for (bframes = 0, brefs = 0;; bframes++)
{
diff -r 23a8a7456916 -r d571bdb0b0ae source/x265.h
--- a/source/x265.h Wed Sep 19 14:30:48 2018 -0700
+++ b/source/x265.h Thu Sep 20 10:28:00 2018 -0700
@@ -317,6 +317,7 @@
{
NO_INFO = 0,
AVC_INFO = 1,
+ HEVC_INFO = 2,
}AnalysisRefineType;
/* Arbitrary User SEI
diff -r 23a8a7456916 -r d571bdb0b0ae source/x265cli.h
--- a/source/x265cli.h Wed Sep 19 14:30:48 2018 -0700
+++ b/source/x265cli.h Thu Sep 20 10:28:00 2018 -0700
@@ -501,7 +501,7 @@
H0(" --analysis-load <filename> Load analysis buffers from the file specified. Default Disabled\n");
H0(" --analysis-reuse-file <filename> Specify file name used for either dumping or reading analysis data. Deault x265_analysis.dat\n");
H0(" --analysis-reuse-level <1..10> Level of analysis reuse indicates amount of info stored/reused in save/load mode, 1:least..10:most. Default %d\n", param->analysisReuseLevel);
- H0(" --refine-analysis-type <string> Reuse anlaysis information received through API call. Supported options are avc. Default disabled - %d\n", param->bAnalysisType);
+ H0(" --refine-analysis-type <string> Reuse anlaysis information received through API call. Supported options are avc and hevc. Default disabled - %d\n", param->bAnalysisType);
H0(" --scale-factor <int> Specify factor by which input video is scaled down for analysis save mode. Default %d\n", param->scaleFactor);
H0(" --refine-intra <0..4> Enable intra refinement for encode that uses analysis-load.\n"
" - 0 : Forces both mode and depth from the save encode.\n"
-------------- next part --------------
A non-text attachment was scrubbed...
Name: x265-3-2.patch
Type: text/x-patch
Size: 21450 bytes
Desc: not available
URL: <http://mailman.videolan.org/pipermail/x265-devel/attachments/20181228/1da7b074/attachment-0001.bin>
More information about the x265-devel
mailing list