[x265] [PATCH 2 of 4] Reuse analysis info of low resolution for full resolution encoding
Deepthi Nandakumar
deepthipnandakumar at gmail.com
Thu Jun 8 18:20:35 CEST 2017
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/e175580c/attachment-0001.html>
More information about the x265-devel
mailing list