<div dir="ltr"><div class="gmail_extra"><br><div class="gmail_quote">On Fri, Nov 17, 2017 at 7:23 PM, <span dir="ltr"><<a href="mailto:praveen@multicorewareinc.com" target="_blank">praveen@multicorewareinc.com</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex"># HG changeset patch<br>
# User Praveen Tiwari <<a href="mailto:praveen@multicorewareinc.com">praveen@multicorewareinc.com</a>><br>
# Date 1510926794 -19800<br>
# Fri Nov 17 19:23:14 2017 +0530<br>
# Node ID 6b248ccb14169d2b0d5b84d50d94a1<wbr>53bd8f3b4f<br>
# Parent 9723e8812e63ce51e38ede41f7d5ed<wbr>f73cad0849<br>
analysis: use AVC CU analysis-info for HEVC mode analysis<br></blockquote><div><br></div><div>Pushed to default. Thanks!</div><div> </div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">
<br>
This patch work implements the functionality for anlysis-reuselevel 7, here we want<br>
to use AVC analysis-info for HEVC mode decision and use the depth from offload<br>
for AVC sizes<br>
<br>
diff -r 9723e8812e63 -r 6b248ccb1416 source/common/cudata.cpp<br>
--- a/source/common/cudata.cpp Fri Nov 17 14:16:31 2017 +0530<br>
+++ b/source/common/cudata.cpp Fri Nov 17 19:23:14 2017 +0530<br>
@@ -201,6 +201,8 @@<br>
m_cuDepth = charBuf; charBuf += m_numPartitions;<br>
m_predMode = charBuf; charBuf += m_numPartitions; /* the order up to here is important in initCTU() and initSubCU() */<br>
m_partSize = charBuf; charBuf += m_numPartitions;<br>
+ m_skipFlag[0] = charBuf; charBuf += m_numPartitions;<br>
+ m_skipFlag[1] = charBuf; charBuf += m_numPartitions;<br>
m_mergeFlag = charBuf; charBuf += m_numPartitions;<br>
m_interDir = charBuf; charBuf += m_numPartitions;<br>
m_mvpIdx[0] = charBuf; charBuf += m_numPartitions;<br>
@@ -239,6 +241,8 @@<br>
m_cuDepth = charBuf; charBuf += m_numPartitions;<br>
m_predMode = charBuf; charBuf += m_numPartitions; /* the order up to here is important in initCTU() and initSubCU() */<br>
m_partSize = charBuf; charBuf += m_numPartitions;<br>
+ m_skipFlag[0] = charBuf; charBuf += m_numPartitions;<br>
+ m_skipFlag[1] = charBuf; charBuf += m_numPartitions;<br>
m_mergeFlag = charBuf; charBuf += m_numPartitions;<br>
m_interDir = charBuf; charBuf += m_numPartitions;<br>
m_mvpIdx[0] = charBuf; charBuf += m_numPartitions;<br>
diff -r 9723e8812e63 -r 6b248ccb1416 source/common/cudata.h<br>
--- a/source/common/cudata.h Fri Nov 17 14:16:31 2017 +0530<br>
+++ b/source/common/cudata.h Fri Nov 17 19:23:14 2017 +0530<br>
@@ -199,13 +199,14 @@<br>
uint8_t* m_predMode; // array of prediction modes<br>
uint8_t* m_partSize; // array of partition sizes<br>
uint8_t* m_mergeFlag; // array of merge flags<br>
+ uint8_t* m_skipFlag[2];<br>
uint8_t* m_interDir; // array of inter directions<br>
uint8_t* m_mvpIdx[2]; // array of motion vector predictor candidates or merge candidate indices [0]<br>
uint8_t* m_tuDepth; // array of transform indices<br>
uint8_t* m_transformSkip[3]; // array of transform skipping flags per plane<br>
uint8_t* m_cbf[3]; // array of coded block flags (CBF) per plane<br>
uint8_t* m_chromaIntraDir; // array of intra directions (chroma)<br>
- enum { BytesPerPartition = 21 }; // combined sizeof() of all per-part data<br>
+ enum { BytesPerPartition = 23 }; // combined sizeof() of all per-part data<br>
<br>
sse_t* m_distortion;<br>
coeff_t* m_trCoeff[3]; // transformed coefficient buffer per plane<br>
diff -r 9723e8812e63 -r 6b248ccb1416 source/common/framedata.h<br>
--- a/source/common/framedata.h Fri Nov 17 14:16:31 2017 +0530<br>
+++ b/source/common/framedata.h Fri Nov 17 19:23:14 2017 +0530<br>
@@ -195,6 +195,7 @@<br>
uint8_t* mvpIdx[2];<br>
int8_t* refIdx[2];<br>
MV* mv[2];<br>
+ int64_t* sadCost;<br>
};<br>
<br>
struct analysis2PassFrameData<br>
diff -r 9723e8812e63 -r 6b248ccb1416 source/encoder/analysis.cpp<br>
--- a/source/encoder/analysis.cpp Fri Nov 17 14:16:31 2017 +0530<br>
+++ b/source/encoder/analysis.cpp Fri Nov 17 19:23:14 2017 +0530<br>
@@ -75,6 +75,10 @@<br>
m_reuseInterDataCTU = NULL;<br>
m_reuseRef = NULL;<br>
m_bHD = false;<br>
+ m_modeFlag[0] = false;<br>
+ m_modeFlag[1] = false;<br>
+ m_checkMergeAndSkipOnly[0] = false;<br>
+ m_checkMergeAndSkipOnly[1] = false;<br>
m_evaluateInter = 0;<br>
}<br>
<br>
@@ -247,6 +251,9 @@<br>
memcpy(ctu.m_cuDepth, &interDataCTU->depth[posCTU], sizeof(uint8_t) * numPartition);<br>
memcpy(ctu.m_predMode, &interDataCTU->modes[posCTU], sizeof(uint8_t) * numPartition);<br>
memcpy(ctu.m_partSize, &interDataCTU->partSize[<wbr>posCTU], sizeof(uint8_t) * numPartition);<br>
+ for (int list = 0; list < m_slice->isInterB() + 1; list++)<br>
+ memcpy(ctu.m_skipFlag[list], &m_frame->m_analysisData.<wbr>modeFlag[list][posCTU], sizeof(uint8_t) * numPartition);<br>
+<br>
if ((m_slice->m_sliceType == P_SLICE || m_param->bIntraInBFrames) && !m_param->bMVType)<br>
{<br>
analysis_intra_data* intraDataCTU = (analysis_intra_data*)m_frame-<wbr>>m_analysisData.intraData;<br>
@@ -1162,7 +1169,11 @@<br>
PicYuv& reconPic = *m_frame->m_reconPic;<br>
SplitData splitCUData;<br>
<br>
- if ((m_param->bMVType && cuGeom.numPartitions > 16) || !m_param->bMVType)<br>
+ bool bHEVCBlockAnalysis = (m_param->bMVType && cuGeom.numPartitions > 16);<br>
+ bool bRefineAVCAnalysis = (m_param->analysisReuseLevel == 7 && (m_modeFlag[0] || m_modeFlag[1]));<br>
+ bool bNooffloading = !m_param->bMVType;<br>
+<br>
+ if (bHEVCBlockAnalysis || bRefineAVCAnalysis || bNooffloading)<br>
{<br>
md.bestMode = NULL;<br>
bool mightSplit = !(cuGeom.flags & CUGeom::LEAF);<br>
@@ -1296,7 +1307,7 @@<br>
}<br>
<br>
/* Step 1. Evaluate Merge/Skip candidates for likely early-outs, if skip mode was not set above */<br>
- if (mightNotSplit && depth >= minDepth && !md.bestMode && !bCtuInfoCheck) /* TODO: Re-evaluate if analysis load/save still works */<br>
+ if ((mightNotSplit && depth >= minDepth && !md.bestMode && !bCtuInfoCheck) || (m_param->bMVType && (m_modeFlag[0] || m_modeFlag[1]))) /* TODO: Re-evaluate if analysis load/save still works */<br>
{<br>
/* Compute Merge Cost */<br>
md.pred[PRED_MERGE].cu.<wbr>initSubCU(parentCTU, cuGeom, qp);<br>
@@ -1307,7 +1318,7 @@<br>
&& md.bestMode && md.bestMode->cu.isSkipped(0); // TODO: sa8d threshold per depth<br>
}<br>
<br>
- if (md.bestMode && m_param->bEnableRecursionSkip && !bCtuInfoCheck)<br>
+ if (md.bestMode && m_param->bEnableRecursionSkip && !bCtuInfoCheck && !(m_param->bMVType && (m_modeFlag[0] || m_modeFlag[1])))<br>
{<br>
skipRecursion = md.bestMode->cu.isSkipped(0);<br>
if (mightSplit && depth >= minDepth && !skipRecursion)<br>
@@ -1319,6 +1330,9 @@<br>
}<br>
}<br>
<br>
+ if (m_param->bMVType && md.bestMode && cuGeom.numPartitions <= 16)<br>
+ skipRecursion = true;<br>
+<br>
/* Step 2. Evaluate each of the 4 split sub-blocks in series */<br>
if (mightSplit && !skipRecursion)<br>
{<br>
@@ -1374,6 +1388,10 @@<br>
splitPred->sa8dCost = m_rdCost.calcRdSADCost((<wbr>uint32_t)splitPred-><wbr>distortion, splitPred->sa8dBits);<br>
}<br>
<br>
+ /* If analysis mode is simple do not Evaluate other modes */<br>
+ if ((m_param->bMVType && cuGeom.numPartitions <= 16) && (m_slice->m_sliceType == P_SLICE || m_slice->m_sliceType == B_SLICE))<br>
+ mightNotSplit = !(m_checkMergeAndSkipOnly[0] || (m_checkMergeAndSkipOnly[0] && m_checkMergeAndSkipOnly[1]));<br>
+<br>
/* Split CUs<br>
* 0 1<br>
* 2 3 */<br>
@@ -1838,7 +1856,12 @@<br>
}<br>
<br>
SplitData splitCUData;<br>
- if ((m_param->bMVType && cuGeom.numPartitions > 16) || !m_param->bMVType)<br>
+<br>
+ bool bHEVCBlockAnalysis = (m_param->bMVType && cuGeom.numPartitions > 16);<br>
+ bool bRefineAVCAnalysis = (m_param->analysisReuseLevel == 7 && (m_modeFlag[0] || m_modeFlag[1]));<br>
+ bool bNooffloading = !m_param->bMVType;<br>
+<br>
+ if (bHEVCBlockAnalysis || bRefineAVCAnalysis || bNooffloading)<br>
{<br>
bool mightSplit = !(cuGeom.flags & CUGeom::LEAF);<br>
bool mightNotSplit = !(cuGeom.flags & CUGeom::SPLIT_MANDATORY);<br>
@@ -1977,7 +2000,7 @@<br>
}<br>
<br>
/* Step 1. Evaluate Merge/Skip candidates for likely early-outs */<br>
- if (mightNotSplit && !md.bestMode && !bCtuInfoCheck)<br>
+ if (mightNotSplit && !md.bestMode && !bCtuInfoCheck || (m_param->bMVType && (m_modeFlag[0] || m_modeFlag[1])))<br>
{<br>
md.pred[PRED_SKIP].cu.<wbr>initSubCU(parentCTU, cuGeom, qp);<br>
md.pred[PRED_MERGE].cu.<wbr>initSubCU(parentCTU, cuGeom, qp);<br>
@@ -1993,6 +2016,9 @@<br>
skipRecursion = md.bestMode && !md.bestMode->cu.getQtRootCbf(<wbr>0);<br>
}<br>
<br>
+ if (m_param->bMVType && md.bestMode && cuGeom.numPartitions <= 16)<br>
+ skipRecursion = true;<br>
+<br>
// estimate split cost<br>
/* Step 2. Evaluate each of the 4 split sub-blocks in series */<br>
if (mightSplit && !skipRecursion)<br>
@@ -2045,6 +2071,10 @@<br>
checkDQPForSplitPred(*<wbr>splitPred, cuGeom);<br>
}<br>
<br>
+ /* If analysis mode is simple do not Evaluate other modes */<br>
+ if ((m_param->bMVType && cuGeom.numPartitions <= 16) && (m_slice->m_sliceType == P_SLICE || m_slice->m_sliceType == B_SLICE))<br>
+ mightNotSplit = !(m_checkMergeAndSkipOnly[0] || (m_checkMergeAndSkipOnly[0] && m_checkMergeAndSkipOnly[1]));<br>
+<br>
/* Split CUs<br>
* 0 1<br>
* 2 3 */<br>
@@ -2479,6 +2509,22 @@<br>
checkDQPForSplitPred(*md.<wbr>bestMode, cuGeom);<br>
}<br>
<br>
+ if (m_param->bMVType && m_param->analysisReuseLevel == 7)<br>
+ {<br>
+ for (int list = 0; list < m_slice->isInterB() + 1; list++)<br>
+ {<br>
+ m_modeFlag[list] = true;<br>
+ if (parentCTU.m_skipFlag[list][<wbr>cuGeom.absPartIdx] == 1 && cuGeom.numPartitions <= 16)<br>
+ m_checkMergeAndSkipOnly[list] = true;<br>
+ }<br>
+ m_param->rdLevel > 4 ? compressInterCU_rd5_6(<wbr>parentCTU, cuGeom, qp) : compressInterCU_rd0_4(<wbr>parentCTU, cuGeom, qp);<br>
+ for (int list = 0; list < m_slice->isInterB() + 1; list++)<br>
+ {<br>
+ m_modeFlag[list] = false;<br>
+ m_checkMergeAndSkipOnly[list] = false;<br>
+ }<br>
+ }<br>
+<br>
if (m_param->interRefine > 1 || (m_param->interRefine && parentCTU.m_predMode[cuGeom.<wbr>absPartIdx] == MODE_SKIP && !mode.cu.isSkipped(0)))<br>
{<br>
m_evaluateInter = 1;<br>
diff -r 9723e8812e63 -r 6b248ccb1416 source/encoder/analysis.h<br>
--- a/source/encoder/analysis.h Fri Nov 17 14:16:31 2017 +0530<br>
+++ b/source/encoder/analysis.h Fri Nov 17 19:23:14 2017 +0530<br>
@@ -110,6 +110,9 @@<br>
bool m_bChromaSa8d;<br>
bool m_bHD;<br>
<br>
+ bool m_modeFlag[2];<br>
+ bool m_checkMergeAndSkipOnly[2];<br>
+<br>
Analysis();<br>
<br>
bool create(ThreadLocalData* tld);<br>
diff -r 9723e8812e63 -r 6b248ccb1416 source/encoder/encoder.cpp<br>
--- a/source/encoder/encoder.cpp Fri Nov 17 14:16:31 2017 +0530<br>
+++ b/source/encoder/encoder.cpp Fri Nov 17 19:23:14 2017 +0530<br>
@@ -48,6 +48,12 @@<br>
const char g_sliceTypeToChar[] = {'B', 'P', 'I'};<br>
}<br>
<br>
+/* Threshold for motion vection, based on expermental result.<br>
+ * TODO: come up an algorithm for adoptive threshold */<br>
+<br>
+#define MVTHRESHOLD 10<br>
+#define PU_2Nx2N 1<br>
+<br>
static const char* defaultAnalysisFileName = "x265_analysis.dat";<br>
<br>
using namespace X265_NS;<br>
@@ -565,6 +571,14 @@<br>
(interData)->mvpIdx[k][cuPos + cuOffset] = (srcInterData)->mvpIdx[k][(<wbr>mbIndex * 16) + cuOffset];<br>
(interData)->refIdx[k][cuPos + cuOffset] = (srcInterData)->refIdx[k][(<wbr>mbIndex * 16) + cuOffset];<br>
memcpy(&(interData)->mv[k][<wbr>cuPos + cuOffset], &(srcInterData)->mv[k][(<wbr>mbIndex * 16) + cuOffset], sizeof(MV));<br>
+ if (m_param->analysisReuseLevel == 7)<br>
+ {<br>
+ int mv_x = ((analysis_inter_data *)curFrame->m_analysisData.<wbr>interData)->mv[k][(mbIndex * 16) + cuOffset].x;<br>
+ int mv_y = ((analysis_inter_data *)curFrame->m_analysisData.<wbr>interData)->mv[k][(mbIndex * 16) + cuOffset].y;<br>
+ double mv = sqrt(mv_x*mv_x + mv_y*mv_y);<br>
+ if (numPU == PU_2Nx2N && ((srcInterData)->depth[cuPos + cuOffset] == (m_param->maxCUSize >> 5)) && mv <= MVTHRESHOLD)<br>
+ memset(&curFrame->m_<wbr>analysisData.modeFlag[k][cuPos + cuOffset], 1, bytes);<br>
+ }<br>
}<br>
}<br>
}<br>
@@ -624,6 +638,7 @@<br>
int bytes = curFrame->m_analysisData.<wbr>numPartitions >> ((interData)->depth[d] * 2);<br>
memset(&(currInterData)-><wbr>depth[count], (interData)->depth[d], bytes);<br>
memset(&(currInterData)-><wbr>modes[count], (interData)->modes[d], bytes);<br>
+ memcpy(&(currInterData)-><wbr>sadCost[count], &((analysis_inter_data*)<wbr>analysis_data->interData)-><wbr>sadCost[d], bytes);<br>
if (m_param->analysisReuseLevel > 4)<br>
{<br>
memset(&(currInterData)-><wbr>partSize[count], (interData)->partSize[d], bytes);<br>
@@ -639,6 +654,14 @@<br>
(currInterData)->mvpIdx[i][<wbr>count + pu] = (interData)->mvpIdx[i][d];<br>
(currInterData)->refIdx[i][<wbr>count + pu] = (interData)->refIdx[i][d];<br>
memcpy(&(currInterData)->mv[i]<wbr>[count + pu], &(interData)->mv[i][d], sizeof(MV));<br>
+ if (m_param->analysisReuseLevel == 7)<br>
+ {<br>
+ int mv_x = ((analysis_inter_data *)curFrame->m_analysisData.<wbr>interData)->mv[i][count + pu].x;<br>
+ int mv_y = ((analysis_inter_data *)curFrame->m_analysisData.<wbr>interData)->mv[i][count + pu].y;<br>
+ double mv = sqrt(mv_x*mv_x + mv_y*mv_y);<br>
+ if (numPU == PU_2Nx2N && m_param->num4x4Partitions <= 16 && mv <= MVTHRESHOLD)<br>
+ memset(&curFrame->m_<wbr>analysisData.modeFlag[i][count + pu], 1, bytes);<br>
+ }<br>
}<br>
}<br>
}<br>
@@ -3116,12 +3139,14 @@<br>
if (m_param->analysisReuseLevel >= 7)<br>
{<br>
X265_FREE(((analysis_inter_<wbr>data*)analysis->interData)-><wbr>interDir);<br>
+ X265_FREE(((analysis_inter_<wbr>data*)analysis->interData)-><wbr>sadCost);<br>
int numDir = analysis->sliceType == X265_TYPE_P ? 1 : 2;<br>
for (int dir = 0; dir < numDir; dir++)<br>
{<br>
X265_FREE(((analysis_inter_<wbr>data*)analysis->interData)-><wbr>mvpIdx[dir]);<br>
X265_FREE(((analysis_inter_<wbr>data*)analysis->interData)-><wbr>refIdx[dir]);<br>
X265_FREE(((analysis_inter_<wbr>data*)analysis->interData)-><wbr>mv[dir]);<br>
+ X265_FREE(analysis->modeFlag[<wbr>dir]);<br>
}<br>
}<br>
else<br>
diff -r 9723e8812e63 -r 6b248ccb1416 source/x265.h<br>
--- a/source/x265.h Fri Nov 17 14:16:31 2017 +0530<br>
+++ b/source/x265.h Fri Nov 17 19:23:14 2017 +0530<br>
@@ -123,6 +123,7 @@<br>
void* intraData;<br>
uint32_t numCuInHeight;<br>
x265_lookahead_data lookahead;<br>
+ uint8_t* modeFlag[2];<br>
} x265_analysis_data;<br>
<br>
/* cu statistics */<br>
______________________________<wbr>_________________<br>
x265-devel mailing list<br>
<a href="mailto:x265-devel@videolan.org">x265-devel@videolan.org</a><br>
<a href="https://mailman.videolan.org/listinfo/x265-devel" rel="noreferrer" target="_blank">https://mailman.videolan.org/<wbr>listinfo/x265-devel</a><br>
</blockquote></div><br></div></div>