changeset 12396:b0d31e2bc0df draft

Create API function for allocating and freeing x265_analysis_data. 1. Merge the two overloaded functions existed for allocAnalysis and moved as API function - x265_alloc_analysis_data 2. Merge the two overloaded functions existed for freeAnalysis and moved as API function - x265_free_analysis_data 3. Bump up the build number as new API functions are added 4. Update the document
author Aasaipriya Chandran <aasaipriya@multicorewareinc.com>
date Fri, 20 Jul 2018 14:20:22 +0530
parents e2759ae31c36
children 5d34bbf671f7
files doc/reST/api.rst source/CMakeLists.txt source/encoder/api.cpp source/encoder/encoder.cpp source/encoder/encoder.h source/x265.h
diffstat 6 files changed, 211 insertions(+-), 255 deletions(-) [+]
line wrap: on
line diff
--- a/doc/reST/api.rst	Thu Jul 19 12:25:26 2018 +0530
+++ b/doc/reST/api.rst	Fri Jul 20 14:20:22 2018 +0530
@@ -223,6 +223,18 @@ changes made to the parameters for auto-
      *     returns negative on error, 0 access unit were output.*/
      int x265_set_analysis_data(x265_encoder *encoder, x265_analysis_data *analysis_data, int poc, uint32_t cuBytes);
 
+**x265_alloc_analysis_data()** may be used to allocate memory for the x265_analysis_data::
+
+    /* x265_alloc_analysis_data:
+     *     Allocate memory for the x265_analysis_data object's internal structures. */
+     void x265_alloc_analysis_data(x265_param *param, x265_analysis_data* analysis);
+
+**x265_free_analysis_data()** may be used to free memory for the x265_analysis_data::
+
+    /* x265_free_analysis_data:
+     *    Free the allocated memory for x265_analysis_data object's internal structures. */
+     void x265_free_analysis_data(x265_param *param, x265_analysis_data* analysis);
+
 Pictures
 ========
 
--- a/source/CMakeLists.txt	Thu Jul 19 12:25:26 2018 +0530
+++ b/source/CMakeLists.txt	Fri Jul 20 14:20:22 2018 +0530
@@ -29,7 +29,7 @@ option(NATIVE_BUILD "Target the build CP
 option(STATIC_LINK_CRT "Statically link C runtime for release builds" OFF)
 mark_as_advanced(FPROFILE_USE FPROFILE_GENERATE NATIVE_BUILD)
 # X265_BUILD must be incremented each time the public API is changed
-set(X265_BUILD 162)
+set(X265_BUILD 163)
 configure_file("${PROJECT_SOURCE_DIR}/x265.def.in"
                "${PROJECT_BINARY_DIR}/x265.def")
 configure_file("${PROJECT_SOURCE_DIR}/x265_config.h.in"
--- a/source/encoder/api.cpp	Thu Jul 19 12:25:26 2018 +0530
+++ b/source/encoder/api.cpp	Fri Jul 20 14:20:22 2018 +0530
@@ -403,6 +403,175 @@ int x265_set_analysis_data(x265_encoder 
     return -1;
 }
 
+void x265_alloc_analysis_data(x265_param *param, x265_analysis_data* analysis)
+{
+    X265_CHECK(analysis->sliceType, "invalid slice type\n");
+    analysis->interData = analysis->intraData = analysis->distortionData = NULL;
+    bool isVbv = param->rc.vbvMaxBitrate > 0 && param->rc.vbvBufferSize > 0;
+    int numDir = 2; //irrespective of P or B slices set direction as 2
+    uint32_t numPlanes = param->internalCsp == X265_CSP_I400 ? 1 : 3;
+
+    //Allocate memory for distortionData pointer
+    analysisDistortionData *distortionData = (analysisDistortionData*)analysis->distortionData;
+    CHECKED_MALLOC_ZERO(distortionData, analysisDistortionData, 1);
+    CHECKED_MALLOC_ZERO(distortionData->distortion, sse_t, analysis->numPartitions * analysis->numCUsInFrame);
+    if (param->rc.bStatRead)
+    {
+        CHECKED_MALLOC_ZERO(distortionData->ctuDistortion, sse_t, analysis->numCUsInFrame);
+        CHECKED_MALLOC_ZERO(distortionData->scaledDistortion, double, analysis->numCUsInFrame);
+        CHECKED_MALLOC_ZERO(distortionData->offset, double, analysis->numCUsInFrame);
+        CHECKED_MALLOC_ZERO(distortionData->threshold, double, analysis->numCUsInFrame);
+    }
+    analysis->distortionData = distortionData;
+
+    if (param->bDisableLookahead && isVbv)
+    {
+        CHECKED_MALLOC_ZERO(analysis->lookahead.intraSatdForVbv, uint32_t, analysis->numCuInHeight);
+        CHECKED_MALLOC_ZERO(analysis->lookahead.satdForVbv, uint32_t, analysis->numCuInHeight);
+        CHECKED_MALLOC_ZERO(analysis->lookahead.intraVbvCost, uint32_t, analysis->numCUsInFrame);
+        CHECKED_MALLOC_ZERO(analysis->lookahead.vbvCost, uint32_t, analysis->numCUsInFrame);
+    }
+
+    //Allocate memory for weightParam pointer
+    if (!(param->bMVType == AVC_INFO))
+        CHECKED_MALLOC_ZERO(analysis->wt, WeightParam, numPlanes * numDir);
+
+    if (param->analysisReuseLevel < 2)
+        return;
+
+    //Allocate memory for intraData pointer
+    analysis_intra_data *intraData = (analysis_intra_data*)analysis->intraData;
+    CHECKED_MALLOC_ZERO(intraData, 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);
+    analysis->intraData = intraData;
+
+    //Allocate memory for interData pointer based on ReuseLevels
+    analysis_inter_data *interData = (analysis_inter_data*)analysis->interData;
+    CHECKED_MALLOC_ZERO(interData, 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->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], MV, analysis->numPartitions * analysis->numCUsInFrame);
+    CHECKED_MALLOC_ZERO(interData->mv[1], MV, analysis->numPartitions * analysis->numCUsInFrame);
+
+    if (param->analysisReuseLevel > 4)
+    {
+        CHECKED_MALLOC(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);
+        for (int dir = 0; dir < numDir; dir++)
+        {
+            CHECKED_MALLOC(interData->refIdx[dir], int8_t, analysis->numPartitions * analysis->numCUsInFrame);
+            CHECKED_MALLOC_ZERO(analysis->modeFlag[dir], uint8_t, analysis->numPartitions * analysis->numCUsInFrame);
+        }
+    }
+    else
+    {
+        if (param->analysisMultiPassRefine || param->analysisMultiPassDistortion){
+            CHECKED_MALLOC_ZERO(interData->ref, int32_t, 2 * analysis->numPartitions * analysis->numCUsInFrame);
+        }
+        else
+            CHECKED_MALLOC_ZERO(interData->ref, int32_t, analysis->numCUsInFrame * X265_MAX_PRED_MODE_PER_CTU * numDir);
+    }
+    analysis->interData = interData;
+
+    return;
+
+fail:
+    x265_free_analysis_data(param, analysis);
+}
+
+void x265_free_analysis_data(x265_param *param, x265_analysis_data* analysis)
+{
+    bool isVbv = param->rc.vbvMaxBitrate > 0 && param->rc.vbvBufferSize > 0;
+
+    //Free memory for Lookahead pointers
+    if (param->bDisableLookahead && isVbv)
+    {
+        X265_FREE(analysis->lookahead.satdForVbv);
+        X265_FREE(analysis->lookahead.intraSatdForVbv);
+        X265_FREE(analysis->lookahead.vbvCost);
+        X265_FREE(analysis->lookahead.intraVbvCost);
+    }
+
+    //Free memory for distortionData pointers
+    if (analysis->distortionData)
+    {
+        X265_FREE(((analysisDistortionData*)analysis->distortionData)->distortion);
+        if (param->rc.bStatRead)
+        {
+            X265_FREE(((analysisDistortionData*)analysis->distortionData)->ctuDistortion);
+            X265_FREE(((analysisDistortionData*)analysis->distortionData)->scaledDistortion);
+            X265_FREE(((analysisDistortionData*)analysis->distortionData)->offset);
+            X265_FREE(((analysisDistortionData*)analysis->distortionData)->threshold);
+        }
+        X265_FREE(analysis->distortionData);
+    }
+
+    /* Early exit freeing weights alone if level is 1 (when there is no analysis inter/intra) */
+    if (analysis->wt && !(param->bMVType == AVC_INFO))
+        X265_FREE(analysis->wt);
+
+    if (param->analysisReuseLevel < 2)
+        return;
+
+    //Free memory for intraData pointers
+    if (analysis->intraData)
+    {
+        X265_FREE(((analysis_intra_data*)analysis->intraData)->depth);
+        X265_FREE(((analysis_intra_data*)analysis->intraData)->modes);
+        X265_FREE(((analysis_intra_data*)analysis->intraData)->partSizes);
+        X265_FREE(((analysis_intra_data*)analysis->intraData)->chromaModes);
+        X265_FREE(analysis->intraData);
+        analysis->intraData = NULL;
+    }
+
+    //Free interData pointers
+    if (analysis->interData)
+    {
+        X265_FREE(((analysis_inter_data*)analysis->interData)->depth);
+        X265_FREE(((analysis_inter_data*)analysis->interData)->modes);
+        X265_FREE(((analysis_inter_data*)analysis->interData)->mvpIdx[0]);
+        X265_FREE(((analysis_inter_data*)analysis->interData)->mvpIdx[1]);
+        X265_FREE(((analysis_inter_data*)analysis->interData)->mv[0]);
+        X265_FREE(((analysis_inter_data*)analysis->interData)->mv[1]);
+
+        if (param->analysisReuseLevel > 4)
+        {
+            X265_FREE(((analysis_inter_data*)analysis->interData)->mergeFlag);
+            X265_FREE(((analysis_inter_data*)analysis->interData)->partSize);
+        }
+        if (param->analysisReuseLevel >= 7)
+        {
+            int numDir = 2;
+            X265_FREE(((analysis_inter_data*)analysis->interData)->interDir);
+            X265_FREE(((analysis_inter_data*)analysis->interData)->sadCost);
+            for (int dir = 0; dir < numDir; dir++)
+            {
+                X265_FREE(((analysis_inter_data*)analysis->interData)->refIdx[dir]);
+                if (analysis->modeFlag[dir] != NULL)
+                {
+                    X265_FREE(analysis->modeFlag[dir]);
+                    analysis->modeFlag[dir] = NULL;
+                }
+            }
+        }
+        else
+            X265_FREE(((analysis_inter_data*)analysis->interData)->ref);
+        X265_FREE(analysis->interData);
+        analysis->interData = NULL;
+    }
+}
+
 void x265_cleanup(void)
 {
     BitCost::destroy();
--- a/source/encoder/encoder.cpp	Thu Jul 19 12:25:26 2018 +0530
+++ b/source/encoder/encoder.cpp	Fri Jul 20 14:20:22 2018 +0530
@@ -641,7 +641,7 @@ int Encoder::setAnalysisData(x265_analys
         curFrame->m_analysisData = (*analysis_data);
         curFrame->m_analysisData.numCUsInFrame = widthInCU * heightInCU;
         curFrame->m_analysisData.numPartitions = m_param->num4x4Partitions;
-        allocAnalysis(&curFrame->m_analysisData);
+        x265_alloc_analysis_data(m_param, &curFrame->m_analysisData);
         if (m_param->maxCUSize == 16)
         {
             if (analysis_data->sliceType == X265_TYPE_IDR || analysis_data->sliceType == X265_TYPE_I)
@@ -901,7 +901,7 @@ int Encoder::encode(const x265_picture* 
     if (m_exportedPic)
     {
         if (!m_param->bUseAnalysisFile && m_param->analysisSave)
-            freeAnalysis(&m_exportedPic->m_analysisData);
+            x265_free_analysis_data(m_param, &m_exportedPic->m_analysisData);
         ATOMIC_DEC(&m_exportedPic->m_countRefEncoders);
         m_exportedPic = NULL;
         m_dpb->recycleUnreferenced();
@@ -1209,7 +1209,7 @@ int Encoder::encode(const x265_picture* 
 
             /* Free up pic_in->analysisData since it has already been used */
             if ((m_param->analysisLoad && !m_param->analysisSave) || (m_param->bMVType && slice->m_sliceType != I_SLICE))
-                freeAnalysis(&outFrame->m_analysisData);
+                x265_free_analysis_data(m_param, &outFrame->m_analysisData);
 
             if (pic_out)
             {
@@ -1248,6 +1248,7 @@ int Encoder::encode(const x265_picture* 
                     pic_out->analysisData.intraData = outFrame->m_analysisData.intraData;
                     pic_out->analysisData.modeFlag[0] = outFrame->m_analysisData.modeFlag[0];
                     pic_out->analysisData.modeFlag[1] = outFrame->m_analysisData.modeFlag[1];
+                    pic_out->analysisData.distortionData = outFrame->m_analysisData.distortionData;
                     if (m_param->bDisableLookahead)
                     {
                         int factor = 1;
@@ -1286,7 +1287,7 @@ int Encoder::encode(const x265_picture* 
                     writeAnalysisFile(&pic_out->analysisData, *outFrame->m_encData);
                     pic_out->analysisData.saveParam = pic_out->analysisData.saveParam;
                     if (m_param->bUseAnalysisFile)
-                        freeAnalysis(&pic_out->analysisData);
+                        x265_free_analysis_data(m_param, &pic_out->analysisData);
                 }
             }
             if (m_param->rc.bStatWrite && (m_param->analysisMultiPassRefine || m_param->analysisMultiPassDistortion))
@@ -1298,10 +1299,10 @@ int Encoder::encode(const x265_picture* 
                     pic_out->analysisData.intraData = outFrame->m_analysisData.intraData;
                     pic_out->analysisData.distortionData = outFrame->m_analysisData.distortionData;
                 }
-                writeAnalysisFile(&outFrame->m_analysisData, *outFrame->m_encData, outFrame->m_lowres.sliceType);
+                writeAnalysisFileRefine(&outFrame->m_analysisData, *outFrame->m_encData);
             }
             if (m_param->analysisMultiPassRefine || m_param->analysisMultiPassDistortion)
-                freeAnalysis(&outFrame->m_analysisData, outFrame->m_lowres.sliceType);
+                x265_free_analysis_data(m_param, &outFrame->m_analysisData);
             if (m_param->internalCsp == X265_CSP_I400)
             {
                 if (slice->m_sliceType == P_SLICE)
@@ -1410,7 +1411,7 @@ int Encoder::encode(const x265_picture* 
                 uint32_t heightInCU = (m_param->sourceHeight + m_param->maxCUSize - 1) >> m_param->maxLog2CUSize;
                 frameEnc->m_analysisData.numCUsInFrame = widthInCU * heightInCU;
                 frameEnc->m_analysisData.numPartitions = m_param->num4x4Partitions;
-                allocAnalysis(&frameEnc->m_analysisData, frameEnc->m_lowres.sliceType);
+                x265_alloc_analysis_data(m_param, &frameEnc->m_analysisData);
                 frameEnc->m_analysisData.poc = frameEnc->m_poc;
                 if (m_param->rc.bStatRead)
                     readAnalysisFile(&frameEnc->m_analysisData, frameEnc->m_poc, frameEnc->m_lowres.sliceType);
@@ -1555,7 +1556,7 @@ int Encoder::encode(const x265_picture* 
                 analysis->numCUsInFrame  = numCUsInFrame;
                 analysis->numCuInHeight = heightInCU;
                 analysis->numPartitions  = m_param->num4x4Partitions;
-                allocAnalysis(analysis);
+                x265_alloc_analysis_data(m_param, analysis);
             }
             /* determine references, setup RPS, etc */
             m_dpb->prepareEncode(frameEnc);
@@ -3181,232 +3182,6 @@ void Encoder::configure(x265_param *p)
 
 }
 
-void Encoder::allocAnalysis(x265_analysis_data* analysis)
-{
-    X265_CHECK(analysis->sliceType, "invalid slice type\n");
-    analysis->interData = analysis->intraData = NULL;
-    if (m_param->bDisableLookahead && m_rateControl->m_isVbv)
-    {
-        CHECKED_MALLOC_ZERO(analysis->lookahead.intraSatdForVbv, uint32_t, analysis->numCuInHeight);
-        CHECKED_MALLOC_ZERO(analysis->lookahead.satdForVbv, uint32_t, analysis->numCuInHeight);
-        CHECKED_MALLOC_ZERO(analysis->lookahead.intraVbvCost, uint32_t, analysis->numCUsInFrame);
-        CHECKED_MALLOC_ZERO(analysis->lookahead.vbvCost, uint32_t, analysis->numCUsInFrame);
-    }
-    if (analysis->sliceType == X265_TYPE_IDR || analysis->sliceType == X265_TYPE_I)
-    {
-        if (m_param->analysisReuseLevel < 2)
-            return;
-
-        analysis_intra_data *intraData = (analysis_intra_data*)analysis->intraData;
-        CHECKED_MALLOC_ZERO(intraData, 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);
-        analysis->intraData = intraData;
-    }
-    else
-    {
-        int numDir = analysis->sliceType == X265_TYPE_P ? 1 : 2;
-        uint32_t numPlanes = m_param->internalCsp == X265_CSP_I400 ? 1 : 3;
-        if (!(m_param->bMVType == AVC_INFO))
-            CHECKED_MALLOC_ZERO(analysis->wt, WeightParam, numPlanes * numDir);
-        if (m_param->analysisReuseLevel < 2)
-            return;
-
-        analysis_inter_data *interData = (analysis_inter_data*)analysis->interData;
-        CHECKED_MALLOC_ZERO(interData, analysis_inter_data, 1);
-        CHECKED_MALLOC(interData->depth, uint8_t, analysis->numPartitions * analysis->numCUsInFrame);
-        CHECKED_MALLOC(interData->modes, uint8_t, analysis->numPartitions * analysis->numCUsInFrame);
-        if (m_param->analysisReuseLevel > 4)
-        {
-            CHECKED_MALLOC(interData->partSize, uint8_t, analysis->numPartitions * analysis->numCUsInFrame);
-            CHECKED_MALLOC_ZERO(interData->mergeFlag, uint8_t, analysis->numPartitions * analysis->numCUsInFrame);
-        }
-        if (m_param->analysisReuseLevel >= 7)
-        {
-            CHECKED_MALLOC(interData->interDir, uint8_t, analysis->numPartitions * analysis->numCUsInFrame);
-            CHECKED_MALLOC(interData->sadCost, int64_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);
-                CHECKED_MALLOC_ZERO(analysis->modeFlag[dir], uint8_t, 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;
-
-fail:
-    freeAnalysis(analysis);
-    m_aborted = true;
-}
-void Encoder::freeAnalysis(x265_analysis_data* analysis)
-{
-    if (m_param->bDisableLookahead && m_rateControl->m_isVbv)
-    {
-        X265_FREE(analysis->lookahead.satdForVbv);
-        X265_FREE(analysis->lookahead.intraSatdForVbv);
-        X265_FREE(analysis->lookahead.vbvCost);
-        X265_FREE(analysis->lookahead.intraVbvCost);
-    }
-    /* Early exit freeing weights alone if level is 1 (when there is no analysis inter/intra) */
-    if (analysis->sliceType > X265_TYPE_I && analysis->wt && !(m_param->bMVType == AVC_INFO))
-        X265_FREE(analysis->wt);
-    if (m_param->analysisReuseLevel < 2)
-        return;
-
-    if (analysis->sliceType == X265_TYPE_IDR || analysis->sliceType == X265_TYPE_I)
-    {
-        if (analysis->intraData)
-        {
-            X265_FREE(((analysis_intra_data*)analysis->intraData)->depth);
-            X265_FREE(((analysis_intra_data*)analysis->intraData)->modes);
-            X265_FREE(((analysis_intra_data*)analysis->intraData)->partSizes);
-            X265_FREE(((analysis_intra_data*)analysis->intraData)->chromaModes);
-            X265_FREE(analysis->intraData);
-            analysis->intraData = NULL;
-        }
-    }
-    else
-    {
-        if (analysis->intraData)
-        {
-            X265_FREE(((analysis_intra_data*)analysis->intraData)->modes);
-            X265_FREE(((analysis_intra_data*)analysis->intraData)->chromaModes);
-            X265_FREE(analysis->intraData);
-            analysis->intraData = NULL;
-        }
-        if (analysis->interData)
-        {
-            X265_FREE(((analysis_inter_data*)analysis->interData)->depth);
-            X265_FREE(((analysis_inter_data*)analysis->interData)->modes);
-            if (m_param->analysisReuseLevel > 4)
-            {
-                X265_FREE(((analysis_inter_data*)analysis->interData)->mergeFlag);
-                X265_FREE(((analysis_inter_data*)analysis->interData)->partSize);
-            }
-            if (m_param->analysisReuseLevel >= 7)
-            {
-                X265_FREE(((analysis_inter_data*)analysis->interData)->interDir);
-                X265_FREE(((analysis_inter_data*)analysis->interData)->sadCost);
-                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->modeFlag[dir] != NULL)
-                    {
-                        X265_FREE(analysis->modeFlag[dir]);
-                        analysis->modeFlag[dir] = NULL;
-                    }
-                }
-            }
-            else
-                X265_FREE(((analysis_inter_data*)analysis->interData)->ref);
-
-            X265_FREE(analysis->interData);
-            analysis->interData = NULL;
-        }
-    }
-}
-
-void Encoder::allocAnalysis(x265_analysis_data* analysis, int sliceType)
-{
-    analysis->interData = analysis->intraData = analysis->distortionData = NULL;
-
-    analysisDistortionData *distortionData = (analysisDistortionData*)analysis->distortionData;
-    CHECKED_MALLOC_ZERO(distortionData, analysisDistortionData, 1);
-    CHECKED_MALLOC_ZERO(distortionData->distortion, sse_t, analysis->numPartitions * analysis->numCUsInFrame);
-    if (m_param->rc.bStatRead)
-    {
-        CHECKED_MALLOC_ZERO(distortionData->ctuDistortion, sse_t, analysis->numCUsInFrame);
-        CHECKED_MALLOC_ZERO(distortionData->scaledDistortion, double, analysis->numCUsInFrame);
-        CHECKED_MALLOC_ZERO(distortionData->offset, double, analysis->numCUsInFrame);
-        CHECKED_MALLOC_ZERO(distortionData->threshold, double, analysis->numCUsInFrame);
-    }
-    analysis->distortionData = distortionData;
-
-    if (IS_X265_TYPE_I(sliceType))
-    {
-        analysis_intra_data *intraData = (analysis_intra_data*)analysis->intraData;
-        CHECKED_MALLOC_ZERO(intraData, analysis_intra_data, 1);
-        CHECKED_MALLOC(intraData->depth, uint8_t, analysis->numPartitions * analysis->numCUsInFrame);
-        analysis->intraData = intraData;
-    }
-    else
-    {
-        analysis_inter_data *interData = (analysis_inter_data*)analysis->interData;
-        CHECKED_MALLOC_ZERO(interData, analysis_inter_data, 1);
-        CHECKED_MALLOC_ZERO(interData->depth, uint8_t, analysis->numPartitions * analysis->numCUsInFrame);
-        CHECKED_MALLOC(interData->modes, uint8_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], MV, analysis->numPartitions * analysis->numCUsInFrame);
-        CHECKED_MALLOC_ZERO(interData->mv[1], MV, analysis->numPartitions * analysis->numCUsInFrame);
-        CHECKED_MALLOC_ZERO(interData->ref, int32_t, 2 * analysis->numPartitions * analysis->numCUsInFrame);
-        analysis->interData = interData;
-    }
-    return;
-
-fail:
-    freeAnalysis(analysis, sliceType);
-    m_aborted = true;
-}
-
-void Encoder::freeAnalysis(x265_analysis_data* analysis, int sliceType)
-{
-    if (analysis->distortionData)
-    {
-        X265_FREE(((analysisDistortionData*)analysis->distortionData)->distortion);
-        if (m_param->rc.bStatRead)
-        {
-            X265_FREE(((analysisDistortionData*)analysis->distortionData)->ctuDistortion);
-            X265_FREE(((analysisDistortionData*)analysis->distortionData)->scaledDistortion);
-            X265_FREE(((analysisDistortionData*)analysis->distortionData)->offset);
-            X265_FREE(((analysisDistortionData*)analysis->distortionData)->threshold);
-        }
-        X265_FREE(analysis->distortionData);
-    }
-    if (IS_X265_TYPE_I(sliceType))
-    {
-        if (analysis->intraData)
-        {
-            X265_FREE(((analysis_intra_data*)analysis->intraData)->depth);
-            X265_FREE(analysis->intraData);
-        }
-    }
-    else
-    {
-        if (analysis->interData)
-        {
-            X265_FREE(((analysis_inter_data*)analysis->interData)->mvpIdx[0]);
-            X265_FREE(((analysis_inter_data*)analysis->interData)->mvpIdx[1]);
-            X265_FREE(((analysis_inter_data*)analysis->interData)->mv[0]);
-            X265_FREE(((analysis_inter_data*)analysis->interData)->mv[1]);
-            X265_FREE(((analysis_inter_data*)analysis->interData)->ref);
-            X265_FREE(((analysis_inter_data*)analysis->interData)->depth);
-            X265_FREE(((analysis_inter_data*)analysis->interData)->modes);
-            X265_FREE(analysis->interData);
-        }
-    }
-}
-
 void Encoder::readAnalysisFile(x265_analysis_data* analysis, int curPoc, const x265_picture* picIn, int paramBytes)
 {
 #define X265_FREAD(val, size, readSize, fileOffset, src)\
@@ -3417,7 +3192,7 @@ void Encoder::readAnalysisFile(x265_anal
         else if (fread(val, size, readSize, fileOffset) != readSize)\
     {\
         x265_log(NULL, X265_LOG_ERROR, "Error reading analysis data\n");\
-        freeAnalysis(analysis);\
+        x265_free_analysis_data(m_param, analysis);\
         m_aborted = true;\
         return;\
     }\
@@ -3452,7 +3227,7 @@ void Encoder::readAnalysisFile(x265_anal
         if (poc != curPoc || feof(m_analysisFileIn))
         {
             x265_log(NULL, X265_LOG_WARNING, "Error reading analysis data: Cannot find POC %d\n", curPoc);
-            freeAnalysis(analysis);
+            x265_free_analysis_data(m_param, analysis);
             return;
         }
     }
@@ -3476,7 +3251,7 @@ void Encoder::readAnalysisFile(x265_anal
     if (m_param->scaleFactor)
         analysis->numPartitions *= factor;
     /* Memory is allocated for inter and intra analysis data based on the slicetype */
-    allocAnalysis(analysis);
+    x265_alloc_analysis_data(m_param, analysis);
     if (m_param->bDisableLookahead && m_rateControl->m_isVbv)
     {
         size_t vbvCount = m_param->lookaheadDepth + m_param->bframes + 2;
@@ -3695,7 +3470,7 @@ void Encoder::readAnalysisFile(x265_anal
     else if (fread(val, size, readSize, fileOffset) != readSize)\
     {\
         x265_log(NULL, X265_LOG_ERROR, "Error reading analysis data\n");\
-        freeAnalysis(analysis);\
+        x265_free_analysis_data(m_param, analysis);\
         m_aborted = true;\
         return;\
     }\
@@ -3731,7 +3506,7 @@ void Encoder::readAnalysisFile(x265_anal
         if (poc != curPoc || feof(m_analysisFileIn))
         {
             x265_log(NULL, X265_LOG_WARNING, "Error reading analysis data: Cannot find POC %d\n", curPoc);
-            freeAnalysis(analysis);
+            x265_free_analysis_data(m_param, analysis);
             return;
         }
     }
@@ -3761,7 +3536,7 @@ void Encoder::readAnalysisFile(x265_anal
     analysis->numCuInHeight = cuLoc.heightInCU;
 
     /* Memory is allocated for inter and intra analysis data based on the slicetype */
-    allocAnalysis(analysis);
+    x265_alloc_analysis_data(m_param, analysis);
 
     analysis->numPartitions = numPartitions * factor;
     analysis->numCUsInFrame = numCUsInFrame;
@@ -4275,7 +4050,7 @@ void Encoder::readAnalysisFile(x265_anal
     if (fread(val, size, readSize, fileOffset) != readSize)\
     {\
     x265_log(NULL, X265_LOG_ERROR, "Error reading analysis 2 pass data\n"); \
-    freeAnalysis(analysis, sliceType); \
+    x265_alloc_analysis_data(m_param, analysis); \
     m_aborted = true; \
     return; \
 }\
@@ -4289,7 +4064,7 @@ void Encoder::readAnalysisFile(x265_anal
     if (poc != curPoc || feof(m_analysisFileIn))
     {
         x265_log(NULL, X265_LOG_WARNING, "Error reading analysis 2 pass data: Cannot find POC %d\n", curPoc);
-        freeAnalysis(analysis, sliceType);
+        x265_free_analysis_data(m_param, analysis);
         return;
     }
     /* Now arrived at the right frame, read the record */
@@ -4405,7 +4180,7 @@ void Encoder::writeAnalysisFile(x265_ana
     if (fwrite(val, size, writeSize, fileOffset) < writeSize)\
     {\
         x265_log(NULL, X265_LOG_ERROR, "Error writing analysis data\n");\
-        freeAnalysis(analysis);\
+        x265_free_analysis_data(m_param, analysis);\
         m_aborted = true;\
         return;\
     }\
@@ -4598,13 +4373,13 @@ void Encoder::writeAnalysisFile(x265_ana
 #undef X265_FWRITE
 }
 
-void Encoder::writeAnalysisFile(x265_analysis_data* analysis, FrameData &curEncData, int slicetype)
+void Encoder::writeAnalysisFileRefine(x265_analysis_data* analysis, FrameData &curEncData)
 {
 #define X265_FWRITE(val, size, writeSize, fileOffset)\
     if (fwrite(val, size, writeSize, fileOffset) < writeSize)\
     {\
     x265_log(NULL, X265_LOG_ERROR, "Error writing analysis 2 pass data\n"); \
-    freeAnalysis(analysis, slicetype); \
+    x265_free_analysis_data(m_param, analysis); \
     m_aborted = true; \
     return; \
 }\
--- a/source/encoder/encoder.h	Thu Jul 19 12:25:26 2018 +0530
+++ b/source/encoder/encoder.h	Fri Jul 20 14:20:22 2018 +0530
@@ -275,14 +275,6 @@ public:
 
     void updateVbvPlan(RateControl* rc);
 
-    void allocAnalysis(x265_analysis_data* analysis);
-
-    void allocAnalysis(x265_analysis_data* analysis, int sliceType);
-
-    void freeAnalysis(x265_analysis_data* analysis);
-
-    void freeAnalysis(x265_analysis_data* analysis, int sliceType);
-
     void readAnalysisFile(x265_analysis_data* analysis, int poc, int sliceType);
 
     void readAnalysisFile(x265_analysis_data* analysis, int poc, const x265_picture* picIn, int paramBytes);
@@ -295,7 +287,7 @@ public:
 
     void writeAnalysisFile(x265_analysis_data* analysis, FrameData &curEncData);
 
-    void writeAnalysisFile(x265_analysis_data* analysis, FrameData &curEncData, int slicetype);
+    void writeAnalysisFileRefine(x265_analysis_data* analysis, FrameData &curEncData);
 
     void finishFrameStats(Frame* pic, FrameEncoder *curEncoder, x265_frame_stats* frameStats, int inPoc);
 
--- a/source/x265.h	Thu Jul 19 12:25:26 2018 +0530
+++ b/source/x265.h	Fri Jul 20 14:20:22 2018 +0530
@@ -1757,6 +1757,14 @@ X265_API extern const char *x265_version
  *      A static string describing the compiler and target architecture */
 X265_API extern const char *x265_build_info_str;
 
+/* x265_alloc_analysis_data:
+*     Allocate memory for the x265_analysis_data object's internal structures. */
+void x265_alloc_analysis_data(x265_param *param, x265_analysis_data* analysis);
+
+/*
+*    Free the allocated memory for x265_analysis_data object's internal structures. */
+void x265_free_analysis_data(x265_param *param, x265_analysis_data* analysis);
+
 /* Force a link error in the case of linking against an incompatible API version.
  * Glue #defines exist to force correct macro expansion; the final output of the macro
  * is x265_encoder_open_##X265_BUILD (for purposes of dlopen). */