[x265] [PATCH 6 of 8] multi-level refinement: support new level 5 to recode without any refinement

kavitha at multicorewareinc.com kavitha at multicorewareinc.com
Mon Feb 27 15:05:22 CET 2017


# HG changeset patch
# User Kavitha Sampath
# Date 1486226542 -19800
#      Sat Feb 04 22:12:22 2017 +0530
# Node ID fec542968fecc4cda76264fe9b746952718a64f7
# Parent  685b95d9bb93cc82448b85182b20643bd6f8a3ba
multi-level refinement: support new level 5 to recode without any refinement

All CU member data required to recode CU as coded in first pass are stored
in this level. Optimizations like the use of recursion skip doesnot permit the
second pass to be coded as first pass leading to output mismatch between the
2 passes when enabled. The speed of encoding in 2nd pass is maximum in this level
TODO: allow refinement level 5 to support rd level 1

diff -r 685b95d9bb93 -r fec542968fec source/common/framedata.h
--- a/source/common/framedata.h	Fri Feb 03 15:32:14 2017 +0530
+++ b/source/common/framedata.h	Sat Feb 04 22:12:22 2017 +0530
@@ -181,6 +181,10 @@
     uint8_t*    modes;
     uint8_t*    partSize;
     uint8_t*    mergeFlag;
+    uint8_t*    interDir;
+    uint8_t*    mvpIdx[2];
+    int8_t*     refIdx[2];
+    MV*         mv[2];
 };
 
 struct analysis2PassFrameData
diff -r 685b95d9bb93 -r fec542968fec source/encoder/analysis.cpp
--- a/source/encoder/analysis.cpp	Fri Feb 03 15:32:14 2017 +0530
+++ b/source/encoder/analysis.cpp	Sat Feb 04 22:12:22 2017 +0530
@@ -167,7 +167,7 @@
         }
     }
 
-    if (m_param->analysisMode && m_slice->m_sliceType != I_SLICE && m_param->analysisRefineLevel > 1)
+    if (m_param->analysisMode && m_slice->m_sliceType != I_SLICE && m_param->analysisRefineLevel > 1 && m_param->analysisRefineLevel < 5)
     {
         int numPredDir = m_slice->isInterP() ? 1 : 2;
         m_reuseInterDataCTU = (analysis_inter_data*)m_frame->m_analysisData.interData;
@@ -214,6 +214,26 @@
             /* generate residual for entire CTU at once and copy to reconPic */
             encodeResidue(ctu, cuGeom);
         }
+        else if (m_param->analysisMode == X265_ANALYSIS_LOAD && m_param->analysisRefineLevel == 5)
+        {
+            analysis_inter_data* interDataCTU = (analysis_inter_data*)m_frame->m_analysisData.interData;
+            int posCTU = ctu.m_cuAddr * numPartition;
+            memcpy(ctu.m_cuDepth, &interDataCTU->depth[posCTU], sizeof(uint8_t) * numPartition);
+            memcpy(ctu.m_predMode, &interDataCTU->modes[posCTU], sizeof(uint8_t) * numPartition);
+            memcpy(ctu.m_partSize, &interDataCTU->partSize[posCTU], sizeof(uint8_t) * numPartition);
+            if (m_slice->m_sliceType == P_SLICE || m_param->bIntraInBFrames)
+            {
+                analysis_intra_data* intraDataCTU = (analysis_intra_data*)m_frame->m_analysisData.intraData;
+                memcpy(ctu.m_lumaIntraDir, &intraDataCTU->modes[posCTU], sizeof(uint8_t) * numPartition);
+                memcpy(ctu.m_chromaIntraDir, &intraDataCTU->chromaModes[posCTU], sizeof(uint8_t) * numPartition);
+            }
+            //Calculate log2CUSize from depth
+            for (uint32_t i = 0; i < cuGeom.numPartitions; i++)
+                ctu.m_log2CUSize[i] = (uint8_t)g_maxLog2CUSize - ctu.m_cuDepth[i];
+
+            qprdRefine (ctu, cuGeom, qp, qp);
+            return *m_modeDepth[0].bestMode;
+        }
         else if (m_param->bDistributeModeAnalysis && m_param->rdLevel >= 2)
             compressInterCU_dist(ctu, cuGeom, qp);
         else if (m_param->rdLevel <= 4)
@@ -316,6 +336,8 @@
     int lambdaQP = lqp;
 
     bool doQPRefine = (bDecidedDepth && depth <= m_slice->m_pps->maxCuDQPDepth) || (!bDecidedDepth && depth == m_slice->m_pps->maxCuDQPDepth);
+    if (m_param->analysisRefineLevel == 5)
+        doQPRefine = false;
 
     if (doQPRefine)
     {
@@ -2007,10 +2029,39 @@
         else
         {
             mode.cu.copyFromPic(parentCTU, cuGeom, m_csp, false);
-            for (int part = 0; part < (int)parentCTU.getNumPartInter(cuGeom.absPartIdx); part++)
+            uint32_t numPU = parentCTU.getNumPartInter(cuGeom.absPartIdx);
+            for (uint32_t part = 0; part < numPU; part++)
             {
                 PredictionUnit pu(mode.cu, cuGeom, part);
-                motionCompensation(mode.cu, pu, mode.predYuv, true, true);
+                if (m_param->analysisRefineLevel == 5)
+                {
+                    analysis_inter_data* interDataCTU = (analysis_inter_data*)m_frame->m_analysisData.interData;
+                    int cuIdx = (mode.cu.m_cuAddr * parentCTU.m_numPartitions) + cuGeom.absPartIdx;
+                    mode.cu.m_mergeFlag[pu.puAbsPartIdx] = interDataCTU->mergeFlag[cuIdx + part];
+                    mode.cu.setPUInterDir(interDataCTU->interDir[cuIdx + part], pu.puAbsPartIdx, part);
+                    for (int dir = 0; dir < m_slice->isInterB() + 1; dir++)
+                    {
+                        mode.cu.setPUMv(dir, interDataCTU->mv[dir][cuIdx + part], pu.puAbsPartIdx, part);
+                        mode.cu.setPURefIdx(dir, interDataCTU->refIdx[dir][cuIdx + part], pu.puAbsPartIdx, part);
+                        mode.cu.m_mvpIdx[dir][pu.puAbsPartIdx] = interDataCTU->mvpIdx[dir][cuIdx + part];
+                    }
+                    if (!mode.cu.m_mergeFlag[pu.puAbsPartIdx])
+                    {
+                        //AMVP
+                        MV mvc[(MD_ABOVE_LEFT + 1) * 2 + 2];
+                        mode.cu.getNeighbourMV(part, pu.puAbsPartIdx, mode.interNeighbours);
+                        for (int list = 0; list < m_slice->isInterB() + 1; list++)
+                        {
+                            int ref = mode.cu.m_refIdx[list][pu.puAbsPartIdx];
+                            if (ref == -1)
+                                continue;
+                            mode.cu.getPMV(mode.interNeighbours, list, ref, mode.amvpCand[list][ref], mvc);
+                            MV mvp = mode.amvpCand[list][ref][mode.cu.m_mvpIdx[list][pu.puAbsPartIdx]];
+                            mode.cu.m_mvd[list][pu.puAbsPartIdx] = mode.cu.m_mv[list][pu.puAbsPartIdx] - mvp;
+                        }
+                    }
+                }
+                motionCompensation(mode.cu, pu, mode.predYuv, true, (m_csp != X265_CSP_I400 && m_frame->m_fencPic->m_picCsp != X265_CSP_I400));
             }
 
             if (parentCTU.isSkipped(cuGeom.absPartIdx))
@@ -2019,7 +2070,7 @@
                 encodeResAndCalcRdInterCU(mode, cuGeom);
 
             /* checkMerge2Nx2N function performs checkDQP after encoding residual, do the same */
-            bool mergeInter2Nx2N = size == SIZE_2Nx2N && parentCTU.m_mergeFlag[cuGeom.absPartIdx];
+            bool mergeInter2Nx2N = size == SIZE_2Nx2N && mode.cu.m_mergeFlag[0];
             if (parentCTU.isSkipped(cuGeom.absPartIdx) || mergeInter2Nx2N)
                 checkDQP(mode, cuGeom);
         }
@@ -2029,6 +2080,9 @@
 
         if (mightSplit)
             addSplitFlagCost(*md.bestMode, cuGeom.depth);
+
+        if (mightSplit && m_param->rdLevel < 5)
+            checkDQPForSplitPred(*md.bestMode, cuGeom);
     }
     else
     {
@@ -2055,7 +2109,8 @@
                 if (m_slice->m_pps->bUseDQP && nextDepth <= m_slice->m_pps->maxCuDQPDepth)
                     nextQP = setLambdaFromQP(parentCTU, calculateQpforCuSize(parentCTU, childGeom));
 
-                qprdRefine(parentCTU, childGeom, nextQP, lqp);
+                int lamdaQP = m_param->analysisRefineLevel == 5 ? nextQP : lqp;
+                qprdRefine(parentCTU, childGeom, nextQP, lamdaQP);
 
                 // Save best CU and pred data for this sub CU
                 splitCU->copyPartFrom(nd.bestMode->cu, childGeom, subPartIdx);
diff -r 685b95d9bb93 -r fec542968fec source/encoder/encoder.cpp
--- a/source/encoder/encoder.cpp	Fri Feb 03 15:32:14 2017 +0530
+++ b/source/encoder/encoder.cpp	Sat Feb 04 22:12:22 2017 +0530
@@ -2344,7 +2344,6 @@
 
         analysis_inter_data *interData = (analysis_inter_data*)analysis->interData;
         CHECKED_MALLOC_ZERO(interData, analysis_inter_data, 1);
-        CHECKED_MALLOC_ZERO(interData->ref, int32_t, analysis->numCUsInFrame * X265_MAX_PRED_MODE_PER_CTU * numDir);
         CHECKED_MALLOC(interData->depth, uint8_t, analysis->numPartitions * analysis->numCUsInFrame);
         CHECKED_MALLOC(interData->modes, uint8_t, analysis->numPartitions * analysis->numCUsInFrame);
         if (m_param->analysisRefineLevel > 2)
@@ -2352,6 +2351,30 @@
             CHECKED_MALLOC(interData->partSize, uint8_t, analysis->numPartitions * analysis->numCUsInFrame);
             CHECKED_MALLOC(interData->mergeFlag, uint8_t, analysis->numPartitions * analysis->numCUsInFrame);
         }
+
+        if (m_param->analysisRefineLevel == 5)
+        {
+            CHECKED_MALLOC(interData->interDir, uint8_t, analysis->numPartitions * analysis->numCUsInFrame);
+            for (int dir = 0; dir < numDir; dir++)
+            {
+                CHECKED_MALLOC(interData->mvpIdx[dir], uint8_t, analysis->numPartitions * analysis->numCUsInFrame);
+                CHECKED_MALLOC(interData->refIdx[dir], int8_t, analysis->numPartitions * analysis->numCUsInFrame);
+               CHECKED_MALLOC(interData->mv[dir], MV, analysis->numPartitions * analysis->numCUsInFrame);
+            }
+
+            /* Allocate intra in inter */
+            if (analysis->sliceType == X265_TYPE_P || m_param->bIntraInBFrames)
+            {
+                analysis_intra_data *intraData = (analysis_intra_data*)analysis->intraData;
+                CHECKED_MALLOC_ZERO(intraData, analysis_intra_data, 1);
+                CHECKED_MALLOC(intraData->modes, uint8_t, analysis->numPartitions * analysis->numCUsInFrame);
+                CHECKED_MALLOC(intraData->chromaModes, uint8_t, analysis->numPartitions * analysis->numCUsInFrame);
+                analysis->intraData = intraData;
+            }
+        }
+        else
+            CHECKED_MALLOC_ZERO(interData->ref, int32_t, analysis->numCUsInFrame * X265_MAX_PRED_MODE_PER_CTU * numDir);
+
         analysis->interData = interData;
     }
     return;
@@ -2363,6 +2386,7 @@
 
 void Encoder::freeAnalysis(x265_analysis_data* analysis)
 {
+    /* Early exit freeing weights alone if level is 1 (when there is no analysis inter/intra) */
     if (analysis->sliceType > X265_TYPE_I && analysis->wt)
         X265_FREE(analysis->wt);
     if (m_param->analysisRefineLevel < 2)
@@ -2389,6 +2413,25 @@
             X265_FREE(((analysis_inter_data*)analysis->interData)->mergeFlag);
             X265_FREE(((analysis_inter_data*)analysis->interData)->partSize);
         }
+
+        if (m_param->analysisRefineLevel == 5)
+        {
+            X265_FREE(((analysis_inter_data*)analysis->interData)->interDir);
+            int numDir = analysis->sliceType == X265_TYPE_P ? 1 : 2;
+            for (int dir = 0; dir < numDir; dir++)
+            {
+                X265_FREE(((analysis_inter_data*)analysis->interData)->mvpIdx[dir]);
+                X265_FREE(((analysis_inter_data*)analysis->interData)->refIdx[dir]);
+                X265_FREE(((analysis_inter_data*)analysis->interData)->mv[dir]);
+            }
+            if (analysis->sliceType == P_SLICE || m_param->bIntraInBFrames)
+            {
+                X265_FREE(((analysis_intra_data*)analysis->intraData)->modes);
+                X265_FREE(((analysis_intra_data*)analysis->intraData)->chromaModes);
+                X265_FREE(analysis->intraData);
+            }
+        }
+
         X265_FREE(analysis->interData);
     }
 }
@@ -2513,6 +2556,7 @@
 
     if (analysis->sliceType == X265_TYPE_IDR || analysis->sliceType == X265_TYPE_I)
     {
+        analysis->sliceType = X265_TYPE_I;
         if (m_param->analysisRefineLevel < 2)
             return;
 
@@ -2536,7 +2580,6 @@
         }
         X265_FREAD(((analysis_intra_data *)analysis->intraData)->modes, sizeof(uint8_t), analysis->numCUsInFrame * analysis->numPartitions, m_analysisFile);
         X265_FREE(tempBuf);
-        analysis->sliceType = X265_TYPE_I;
         consumedBytes += frameRecordSize;
     }
 
@@ -2549,8 +2592,19 @@
             return;
 
         uint8_t *tempBuf = NULL, *depthBuf = NULL, *modeBuf = NULL, *partSize = NULL, *mergeFlag = NULL;
+        uint8_t *interDir = NULL, *chromaDir = NULL, *mvpIdx[2];
+        MV* mv[2];
+        int8_t* refIdx[2];
 
         int numBuf = m_param->analysisRefineLevel > 2 ? 4 : 2;
+        bool bIntraInInter = false;
+        if (m_param->analysisRefineLevel == 5)
+        {
+            numBuf++;
+            bIntraInInter = (analysis->sliceType == X265_TYPE_P || m_param->bIntraInBFrames);
+            if (bIntraInInter) numBuf++;
+        }
+
         tempBuf = X265_MALLOC(uint8_t, depthBytes * numBuf);
         X265_FREAD(tempBuf, sizeof(uint8_t), depthBytes * numBuf, m_analysisFile);
 
@@ -2560,6 +2614,20 @@
         {
             partSize = modeBuf + depthBytes;
             mergeFlag = partSize + depthBytes;
+            if (m_param->analysisRefineLevel == 5)
+            {
+                interDir = mergeFlag + depthBytes;
+                if (bIntraInInter) chromaDir = interDir + depthBytes;
+                for (uint32_t i = 0; i < numDir; i++)
+                {
+                    mvpIdx[i] = X265_MALLOC(uint8_t, depthBytes * 3);
+                    X265_FREAD(mvpIdx[i], sizeof(uint8_t), depthBytes, m_analysisFile);
+                    refIdx[i] = X265_MALLOC(int8_t, depthBytes);
+                    X265_FREAD(refIdx[i], sizeof(int8_t), depthBytes, m_analysisFile);
+                    mv[i] = X265_MALLOC(MV, depthBytes);
+                    X265_FREAD(mv[i], sizeof(MV), depthBytes, m_analysisFile);
+                }
+            }
         }
 
         size_t count = 0;
@@ -2571,14 +2639,44 @@
             if (m_param->analysisRefineLevel > 2)
             {
                 memset(&((analysis_inter_data *)analysis->interData)->partSize[count], partSize[d], bytes);
-                memset(&((analysis_inter_data *)analysis->interData)->mergeFlag[count], mergeFlag[d], bytes);
+                int numPU = nbPartsTable[(int)partSize[d]];
+                for (int pu = 0; pu < numPU; pu++)
+                {
+                    if (pu) d++;
+                    ((analysis_inter_data *)analysis->interData)->mergeFlag[count + pu] = mergeFlag[d];
+                    if (m_param->analysisRefineLevel == 5)
+                    {
+                        ((analysis_inter_data *)analysis->interData)->interDir[count + pu] = interDir[d];
+                        for (uint32_t i = 0; i < numDir; i++)
+                        {
+                            ((analysis_inter_data *)analysis->interData)->mvpIdx[i][count + pu] = mvpIdx[i][d];
+                            ((analysis_inter_data *)analysis->interData)->refIdx[i][count + pu] = refIdx[i][d];
+                            memcpy(&((analysis_inter_data *)analysis->interData)->mv[i][count + pu], &mv[i][d], sizeof(MV));
+                        }
+                    }
+                }
+                if (m_param->analysisRefineLevel == 5 && bIntraInInter)
+                    memset(&((analysis_intra_data *)analysis->intraData)->chromaModes[count], chromaDir[d], bytes);
             }
             count += bytes;
         }
 
         X265_FREE(tempBuf);
 
-        X265_FREAD(((analysis_inter_data *)analysis->interData)->ref, sizeof(int32_t), analysis->numCUsInFrame * X265_MAX_PRED_MODE_PER_CTU * numDir, m_analysisFile);
+        if (m_param->analysisRefineLevel == 5)
+        {
+            for (uint32_t i = 0; i < numDir; i++)
+            {
+                X265_FREE(mvpIdx[i]);
+                X265_FREE(refIdx[i]);
+                X265_FREE(mv[i]);
+            }
+            if (bIntraInInter)
+                X265_FREAD(((analysis_intra_data *)analysis->intraData)->modes, sizeof(uint8_t), analysis->numCUsInFrame * analysis->numPartitions, m_analysisFile);
+        }
+        else
+            X265_FREAD(((analysis_inter_data *)analysis->interData)->ref, sizeof(int32_t), analysis->numCUsInFrame * X265_MAX_PRED_MODE_PER_CTU * numDir, m_analysisFile);
+
         consumedBytes += frameRecordSize;
         if (numDir == 1)
             totalConsumedBytes = consumedBytes;
@@ -2724,12 +2822,18 @@
     }\
 
     uint32_t depthBytes = 0;
-    int numDir = (analysis->sliceType == X265_TYPE_P) ? 1 : 2;
+    int numDir, numPlanes;
+    bool bIntraInInter = false;
+
     /* calculate frameRecordSize */
     analysis->frameRecordSize = sizeof(analysis->frameRecordSize) + sizeof(depthBytes) + sizeof(analysis->poc) + sizeof(analysis->sliceType) +
                       sizeof(analysis->numCUsInFrame) + sizeof(analysis->numPartitions) + sizeof(analysis->bScenecut) + sizeof(analysis->satdCost);
     if (analysis->sliceType > X265_TYPE_I)
-        analysis->frameRecordSize += sizeof(WeightParam)* 3 * numDir;
+    {
+        numDir = (analysis->sliceType == X265_TYPE_P) ? 1 : 2;
+        numPlanes = m_param->internalCsp == X265_CSP_I400 ? 1 : 3;
+        analysis->frameRecordSize += sizeof(WeightParam) * numPlanes * numDir;
+    }
 
     if (m_param->analysisRefineLevel > 1)
     {
@@ -2762,15 +2866,16 @@
         }
         else
         {
+            bIntraInInter = (analysis->sliceType == X265_TYPE_P || m_param->bIntraInBFrames);
             for (uint32_t cuAddr = 0; cuAddr < analysis->numCUsInFrame; cuAddr++)
             {
                 uint8_t depth = 0;
                 uint8_t predMode = 0;
                 uint8_t partSize = 0;
-                uint8_t mergeFlag = 0;
 
                 CUData* ctu = curEncData.getPicCTU(cuAddr);
                 analysis_inter_data* interDataCTU = (analysis_inter_data*)analysis->interData;
+                analysis_intra_data* intraDataCTU = (analysis_intra_data*)analysis->intraData;
 
                 for (uint32_t absPartIdx = 0; absPartIdx < ctu->m_numPartitions; depthBytes++)
                 {
@@ -2778,7 +2883,7 @@
                     interDataCTU->depth[depthBytes] = depth;
 
                     predMode = ctu->m_predMode[absPartIdx];
-                    if (ctu->m_refIdx[1][absPartIdx] != -1)
+                    if (m_param->analysisRefineLevel != 5 && ctu->m_refIdx[1][absPartIdx] != -1)
                         predMode = 4; // used as indiacator if the block is coded as bidir
 
                     interDataCTU->modes[depthBytes] = predMode;
@@ -2788,12 +2893,32 @@
                         partSize = ctu->m_partSize[absPartIdx];
                         interDataCTU->partSize[depthBytes] = partSize;
 
-                        mergeFlag = ctu->m_mergeFlag[absPartIdx];
-                        interDataCTU->mergeFlag[depthBytes] = mergeFlag;
+                        /* Store per PU data */
+                        uint32_t numPU = nbPartsTable[(int)partSize];
+                        for (uint32_t puIdx = 0; puIdx < numPU; puIdx++)
+                        {
+                            uint32_t puabsPartIdx = ctu->getPUOffset(puIdx, absPartIdx) + absPartIdx;
+                            if (puIdx) depthBytes++;
+                            interDataCTU->mergeFlag[depthBytes] = ctu->m_mergeFlag[puabsPartIdx];
+
+                            if (m_param->analysisRefineLevel == 5)
+                            {
+                                interDataCTU->interDir[depthBytes] = ctu->m_interDir[puabsPartIdx];
+                                for (int dir = 0; dir < numDir; dir++)
+                                {
+                                    interDataCTU->mvpIdx[dir][depthBytes] = ctu->m_mvpIdx[dir][puabsPartIdx];
+                                    interDataCTU->refIdx[dir][depthBytes] = ctu->m_refIdx[dir][puabsPartIdx];
+                                    interDataCTU->mv[dir][depthBytes] = ctu->m_mv[dir][puabsPartIdx];
+                                }
+                            }
+                        }
+                        if (m_param->analysisRefineLevel == 5 && bIntraInInter)
+                            intraDataCTU->chromaModes[depthBytes] = ctu->m_chromaIntraDir[absPartIdx];
                     }
-
                     absPartIdx += ctu->m_numPartitions >> (depth * 2);
                 }
+                if (m_param->analysisRefineLevel == 5 && bIntraInInter)
+                    memcpy(&intraDataCTU->modes[ctu->m_cuAddr * ctu->m_numPartitions], ctu->m_lumaIntraDir, sizeof(uint8_t)* ctu->m_numPartitions);
             }
         }
 
@@ -2801,9 +2926,23 @@
             analysis->frameRecordSize += sizeof(uint8_t)* analysis->numCUsInFrame * analysis->numPartitions + depthBytes * 3;
         else
         {
-            int numBuf = m_param->analysisRefineLevel > 2 ? 4 : 2;
-            analysis->frameRecordSize += depthBytes * numBuf;
-            analysis->frameRecordSize += sizeof(int32_t)* analysis->numCUsInFrame * X265_MAX_PRED_MODE_PER_CTU * numDir;
+            /* Add sizeof depth, modes, partSize, mergeFlag */
+            analysis->frameRecordSize += depthBytes * 2;
+            if (m_param->analysisRefineLevel > 2)
+                analysis->frameRecordSize += (depthBytes * 2);
+
+            if (m_param->analysisRefineLevel == 5)
+            {
+                /* Add Size of interDir, mvpIdx, refIdx, mv, luma and chroma modes */
+                analysis->frameRecordSize += depthBytes;
+                analysis->frameRecordSize += sizeof(uint8_t)* depthBytes * numDir;
+                analysis->frameRecordSize += sizeof(int8_t)* depthBytes * numDir;
+                analysis->frameRecordSize += sizeof(MV)* depthBytes * numDir;
+                if (bIntraInInter)
+                    analysis->frameRecordSize += sizeof(uint8_t)* analysis->numCUsInFrame * analysis->numPartitions + depthBytes;
+            }
+            else
+                analysis->frameRecordSize += sizeof(int32_t)* analysis->numCUsInFrame * X265_MAX_PRED_MODE_PER_CTU * numDir;
         }
     }
     X265_FWRITE(&analysis->frameRecordSize, sizeof(uint32_t), 1, m_analysisFile);
@@ -2815,10 +2954,7 @@
     X265_FWRITE(&analysis->numCUsInFrame, sizeof(int), 1, m_analysisFile);
     X265_FWRITE(&analysis->numPartitions, sizeof(int), 1, m_analysisFile);
     if (analysis->sliceType > X265_TYPE_I)
-    {
-        uint32_t numPlanes = m_param->internalCsp == X265_CSP_I400 ? 1 : 3;
         X265_FWRITE((WeightParam*)analysis->wt, sizeof(WeightParam), numPlanes * numDir, m_analysisFile);
-    }
 
     if (m_param->analysisRefineLevel < 2)
         return;
@@ -2832,18 +2968,33 @@
     }
     else
     {
-        int numDir = analysis->sliceType == X265_TYPE_P ? 1 : 2;
         X265_FWRITE(((analysis_inter_data*)analysis->interData)->depth, sizeof(uint8_t), depthBytes, m_analysisFile);
         X265_FWRITE(((analysis_inter_data*)analysis->interData)->modes, sizeof(uint8_t), depthBytes, m_analysisFile);
         if (m_param->analysisRefineLevel > 2)
         {
             X265_FWRITE(((analysis_inter_data*)analysis->interData)->partSize, sizeof(uint8_t), depthBytes, m_analysisFile);
             X265_FWRITE(((analysis_inter_data*)analysis->interData)->mergeFlag, sizeof(uint8_t), depthBytes, m_analysisFile);
+            if (m_param->analysisRefineLevel == 5)
+            {
+                X265_FWRITE(((analysis_inter_data*)analysis->interData)->interDir, sizeof(uint8_t), depthBytes, m_analysisFile);
+                if (bIntraInInter) X265_FWRITE(((analysis_intra_data*)analysis->intraData)->chromaModes, sizeof(uint8_t), depthBytes, m_analysisFile);
+                for (int dir = 0; dir < numDir; dir++)
+                {
+                    X265_FWRITE(((analysis_inter_data*)analysis->interData)->mvpIdx[dir], sizeof(uint8_t), depthBytes, m_analysisFile);
+                    X265_FWRITE(((analysis_inter_data*)analysis->interData)->refIdx[dir], sizeof(int8_t), depthBytes, m_analysisFile);
+                    X265_FWRITE(((analysis_inter_data*)analysis->interData)->mv[dir], sizeof(MV), depthBytes, m_analysisFile);
+                }
+                if (bIntraInInter)
+                    X265_FWRITE(((analysis_intra_data*)analysis->intraData)->modes, sizeof(uint8_t), analysis->numCUsInFrame * analysis->numPartitions, m_analysisFile);
+            }
         }
-        X265_FWRITE(((analysis_inter_data*)analysis->interData)->ref, sizeof(int32_t), analysis->numCUsInFrame * X265_MAX_PRED_MODE_PER_CTU * numDir, m_analysisFile);
+        if (m_param->analysisRefineLevel != 5)
+            X265_FWRITE(((analysis_inter_data*)analysis->interData)->ref, sizeof(int32_t), analysis->numCUsInFrame * X265_MAX_PRED_MODE_PER_CTU * numDir, m_analysisFile);
+
     }
 #undef X265_FWRITE
 }
+
 void Encoder::writeAnalysis2PassFile(x265_analysis_2Pass* analysis2Pass, FrameData &curEncData, int slicetype)
 {
 #define X265_FWRITE(val, size, writeSize, fileOffset)\


More information about the x265-devel mailing list