[x265] [PATCH 2 of 4] Reuse analysis info of low resolution for full resolution encoding
Tom Vaughan
tom.vaughan at multicorewareinc.com
Fri Jun 9 04:42:05 CEST 2017
Yes. This is an experimental feature, still in development.
*From:* x265-devel [mailto:x265-devel-bounces at videolan.org] *On Behalf
Of *Deepthi
Nandakumar
*Sent:* Thursday, June 8, 2017 9:21 AM
*To:* Development for x265
*Subject:* Re: [x265] [PATCH 2 of 4] Reuse analysis info of low resolution
for full resolution encoding
So, the general idea here is to reuse analysis data from lower resolution
encodes (save mode) for higher resolution encodes (load mode). The
compression efficiency loss here will always be higher, than, if you used
high-res analysis data for low-res encodes.
On Fri, Jun 2, 2017 at 10:58 PM, <kavitha at multicorewareinc.com> wrote:
# HG changeset patch
# User Kavitha Sampath <kavitha at multicorewareinc.com>
# Date 1495615463 -19800
# Wed May 24 14:14:23 2017 +0530
# Node ID 802bb7ead1e0151a604bc293451c735990656162
# Parent 404253434d33e99955aac29480ee16b8e939a64c
Reuse analysis info of low resolution for full resolution encoding.
New CLI option --scale-factor is added. This option should be coupled
with analysis-mode, --refine-level 10. It specifies the factor
by which input video of save mode should be scaled down.
Currently only scale-factor 2 is supported.
diff -r 404253434d33 -r 802bb7ead1e0 source/common/cudata.cpp
--- a/source/common/cudata.cpp Wed May 24 08:39:45 2017 +0530
+++ b/source/common/cudata.cpp Wed May 24 14:14:23 2017 +0530
@@ -28,6 +28,7 @@
#include "picyuv.h"
#include "mv.h"
#include "cudata.h"
+#define MAX_MV 1 << 14
using namespace X265_NS;
@@ -1623,6 +1624,11 @@
dir |= (1 << list);
candMvField[count][list].mv = colmv;
candMvField[count][list].refIdx = refIdx;
+ if (m_encData->m_param->scaleFactor &&
m_encData->m_param->analysisMode == X265_ANALYSIS_SAVE && m_log2CUSize[0] <
4)
+ {
+ MV dist(MAX_MV, MAX_MV);
+ candMvField[count][list].mv = dist;
+ }
}
}
@@ -1783,7 +1789,13 @@
int curRefPOC = m_slice->m_refPOCList[picList][refIdx];
int curPOC = m_slice->m_poc;
- pmv[numMvc++] = amvpCand[num++] =
scaleMvByPOCDist(neighbours[MD_COLLOCATED].mv[picList], curPOC, curRefPOC,
colPOC, colRefPOC);
+ if (m_encData->m_param->scaleFactor &&
m_encData->m_param->analysisMode == X265_ANALYSIS_SAVE && (m_log2CUSize[0]
< 4))
+ {
+ MV dist(MAX_MV, MAX_MV);
+ pmv[numMvc++] = amvpCand[num++] = dist;
+ }
+ else
+ pmv[numMvc++] = amvpCand[num++] =
scaleMvByPOCDist(neighbours[MD_COLLOCATED].mv[picList], curPOC, curRefPOC,
colPOC, colRefPOC);
}
}
diff -r 404253434d33 -r 802bb7ead1e0 source/encoder/analysis.cpp
--- a/source/encoder/analysis.cpp Wed May 24 08:39:45 2017 +0530
+++ b/source/encoder/analysis.cpp Wed May 24 14:14:23 2017 +0530
@@ -2263,6 +2263,19 @@
mode.cu.m_mvd[list][pu.puAbsPartIdx] =
mode.cu.m_mv[list][pu.puAbsPartIdx] - mvp;
}
}
+ else if(m_param->scaleFactor)
+ {
+ MVField candMvField[MRG_MAX_NUM_CANDS][2]; //
double length for mv of both lists
+ uint8_t candDir[MRG_MAX_NUM_CANDS];
+ mode.cu.getInterMergeCandidates(pu.puAbsPartIdx,
part, candMvField, candDir);
+ mode.cu.m_mvpIdx[0][pu.puAbsPartIdx] =
interDataCTU->mvpIdx[0][cuIdx + part];
+ uint8_t mvpIdx =
mode.cu.m_mvpIdx[0][pu.puAbsPartIdx];
+ mode.cu.setPUInterDir(candDir[mvpIdx],
pu.puAbsPartIdx, part);
+ mode.cu.setPUMv(0, candMvField[mvpIdx][0].mv,
pu.puAbsPartIdx, part);
+ mode.cu.setPUMv(1, candMvField[mvpIdx][1].mv,
pu.puAbsPartIdx, part);
+ mode.cu.setPURefIdx(0,
(int8_t)candMvField[mvpIdx][0].refIdx, pu.puAbsPartIdx, part);
+ mode.cu.setPURefIdx(1,
(int8_t)candMvField[mvpIdx][1].refIdx, pu.puAbsPartIdx, part);
+ }
}
motionCompensation(mode.cu, pu, mode.predYuv, true, (m_csp
!= X265_CSP_I400 && m_frame->m_fencPic->m_picCsp != X265_CSP_I400));
}
diff -r 404253434d33 -r 802bb7ead1e0 source/encoder/encoder.cpp
--- a/source/encoder/encoder.cpp Wed May 24 08:39:45 2017 +0530
+++ b/source/encoder/encoder.cpp Wed May 24 14:14:23 2017 +0530
@@ -2839,6 +2839,11 @@
X265_FREAD(&analysis->satdCost, sizeof(int64_t), 1, m_analysisFile);
X265_FREAD(&analysis->numCUsInFrame, sizeof(int), 1, m_analysisFile);
X265_FREAD(&analysis->numPartitions, sizeof(int), 1, m_analysisFile);
+ int scaledNumPartition = analysis->numPartitions;
+ int factor = 1 << m_param->scaleFactor;
+
+ if (m_param->scaleFactor)
+ analysis->numPartitions *= factor;
/* Memory is allocated for inter and intra analysis data based on the
slicetype */
allocAnalysis(analysis);
@@ -2862,12 +2867,31 @@
for (uint32_t d = 0; d < depthBytes; d++)
{
int bytes = analysis->numPartitions >> (depthBuf[d] * 2);
+ if (m_param->scaleFactor)
+ {
+ if (depthBuf[d] == 0)
+ depthBuf[d] = 1;
+ if (partSizes[d] == SIZE_NxN)
+ partSizes[d] = SIZE_2Nx2N;
+ }
memset(&((analysis_intra_data
*)analysis->intraData)->depth[count], depthBuf[d], bytes);
memset(&((analysis_intra_data
*)analysis->intraData)->chromaModes[count], modeBuf[d], bytes);
memset(&((analysis_intra_data
*)analysis->intraData)->partSizes[count], partSizes[d], bytes);
count += bytes;
}
- X265_FREAD(((analysis_intra_data *)analysis->intraData)->modes,
sizeof(uint8_t), analysis->numCUsInFrame * analysis->numPartitions,
m_analysisFile);
+
+ if (!m_param->scaleFactor)
+ {
+ X265_FREAD(((analysis_intra_data
*)analysis->intraData)->modes, sizeof(uint8_t), analysis->numCUsInFrame *
analysis->numPartitions, m_analysisFile);
+ }
+ else
+ {
+ uint8_t *tempLumaBuf = X265_MALLOC(uint8_t,
analysis->numCUsInFrame * scaledNumPartition);
+ X265_FREAD(tempLumaBuf, sizeof(uint8_t),
analysis->numCUsInFrame * scaledNumPartition, m_analysisFile);
+ for (uint32_t ctu32Idx = 0, cnt = 0; ctu32Idx <
analysis->numCUsInFrame * scaledNumPartition; ctu32Idx++, cnt += factor)
+ memset(&((analysis_intra_data
*)analysis->intraData)->modes[cnt], tempLumaBuf[ctu32Idx], factor);
+ X265_FREE(tempLumaBuf);
+ }
X265_FREE(tempBuf);
consumedBytes += frameRecordSize;
}
@@ -2923,12 +2947,16 @@
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_inter_data
*)analysis->interData)->depth[count], depthBuf[d], bytes);
memset(&((analysis_inter_data
*)analysis->interData)->modes[count], modeBuf[d], bytes);
if (m_param->analysisRefineLevel > 4)
{
+ if (m_param->scaleFactor && modeBuf[d] == MODE_INTRA &&
partSize[d] == SIZE_NxN)
+ partSize[d] = SIZE_2Nx2N;
memset(&((analysis_inter_data
*)analysis->interData)->partSize[count], partSize[d], bytes);
- int numPU = nbPartsTable[(int)partSize[d]];
+ int numPU = (modeBuf[d] == MODE_INTRA) ? 1 :
nbPartsTable[(int)partSize[d]];
for (int pu = 0; pu < numPU; pu++)
{
if (pu) d++;
@@ -2940,6 +2968,11 @@
{
((analysis_inter_data
*)analysis->interData)->mvpIdx[i][count + pu] = mvpIdx[i][d];
((analysis_inter_data
*)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_inter_data
*)analysis->interData)->mv[i][count + pu], &mv[i][d], sizeof(MV));
}
}
@@ -2961,7 +2994,20 @@
X265_FREE(mv[i]);
}
if (bIntraInInter)
- X265_FREAD(((analysis_intra_data
*)analysis->intraData)->modes, sizeof(uint8_t), analysis->numCUsInFrame *
analysis->numPartitions, m_analysisFile);
+ {
+ if (!m_param->scaleFactor)
+ {
+ X265_FREAD(((analysis_intra_data
*)analysis->intraData)->modes, sizeof(uint8_t), analysis->numCUsInFrame *
analysis->numPartitions, m_analysisFile);
+ }
+ else
+ {
+ uint8_t *tempLumaBuf = X265_MALLOC(uint8_t,
analysis->numCUsInFrame * scaledNumPartition);
+ X265_FREAD(tempLumaBuf, sizeof(uint8_t),
analysis->numCUsInFrame * scaledNumPartition, m_analysisFile);
+ for (uint32_t ctu32Idx = 0, cnt = 0; ctu32Idx <
analysis->numCUsInFrame * scaledNumPartition; ctu32Idx++, cnt += factor)
+ memset(&((analysis_intra_data
*)analysis->intraData)->modes[cnt], tempLumaBuf[ctu32Idx], factor);
+ X265_FREE(tempLumaBuf);
+ }
+ }
}
else
X265_FREAD(((analysis_inter_data *)analysis->interData)->ref,
sizeof(int32_t), analysis->numCUsInFrame * X265_MAX_PRED_MODE_PER_CTU *
numDir, m_analysisFile);
@@ -3183,7 +3229,7 @@
interDataCTU->partSize[depthBytes] = partSize;
/* Store per PU data */
- uint32_t numPU = nbPartsTable[(int)partSize];
+ uint32_t numPU = (predMode == MODE_INTRA) ? 1 :
nbPartsTable[(int)partSize];
for (uint32_t puIdx = 0; puIdx < numPU; puIdx++)
{
uint32_t puabsPartIdx =
ctu->getPUOffset(puIdx, absPartIdx) + absPartIdx;
diff -r 404253434d33 -r 802bb7ead1e0 source/encoder/slicetype.cpp
--- a/source/encoder/slicetype.cpp Wed May 24 08:39:45 2017 +0530
+++ b/source/encoder/slicetype.cpp Wed May 24 14:14:23 2017 +0530
@@ -893,7 +893,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->analysisMode != X265_ANALYSIS_LOAD)
+ else if (m_param->analysisMode != X265_ANALYSIS_LOAD ||
m_param->scaleFactor)
{
if (m_param->rc.aqMode)
curFrame->m_lowres.satdCost = curFrame->m_lowres.costEstAq[b -
p0][p1 - b];
_______________________________________________
x265-devel mailing list
x265-devel at videolan.org
https://mailman.videolan.org/listinfo/x265-devel
--
Deepthi
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mailman.videolan.org/pipermail/x265-devel/attachments/20170608/0e5da451/attachment-0001.html>
More information about the x265-devel
mailing list