<div dir="ltr"><div class="gmail_default" style="font-family:tahoma,sans-serif">From c8d6c92867f1823d71965c9fa04ae14a656e5089 Mon Sep 17 00:00:00 2001<br>From: Min Chen <<a href="mailto:chenm003@163.com">chenm003@163.com</a>><br>Date: Thu, 14 Nov 2024 00:09:11 -0800<br>Subject: [PATCH] Fix zone duplicated memory free bug<br><br>---<br> source/encoder/api.cpp     | 23 +++++++++++------------<br> source/encoder/encoder.cpp | 20 ++++++--------------<br> source/encoder/encoder.h   |  2 +-<br> source/x265cli.cpp         |  3 +--<br> 4 files changed, 19 insertions(+), 29 deletions(-)<br><br>diff --git a/source/encoder/api.cpp b/source/encoder/api.cpp<br>index 40a325334..3ea67168d 100644<br>--- a/source/encoder/api.cpp<br>+++ b/source/encoder/api.cpp<br>@@ -91,10 +91,14 @@ x265_encoder *x265_encoder_open(x265_param *p)<br>         return NULL;<br>     }<br> <br>-    Encoder* encoder = NULL;<br>-    x265_param* param = PARAM_NS::x265_param_alloc();<br>-    x265_param* latestParam = PARAM_NS::x265_param_alloc();<br>-    x265_param* zoneParam = PARAM_NS::x265_param_alloc();<br>+    Encoder* encoder = new Encoder;<br>+    encoder->m_paramBase[0] = PARAM_NS::x265_param_alloc();<br>+    encoder->m_paramBase[1] = PARAM_NS::x265_param_alloc();<br>+    encoder->m_paramBase[2] = PARAM_NS::x265_param_alloc();<br>+<br>+    x265_param* param = encoder->m_paramBase[0];<br>+    x265_param* latestParam = encoder->m_paramBase[1];<br>+    x265_param* zoneParam = encoder->m_paramBase[2];<br> <br>     if(param) PARAM_NS::x265_param_default(param);<br>     if(latestParam) PARAM_NS::x265_param_default(latestParam);<br>@@ -116,8 +120,6 @@ x265_encoder *x265_encoder_open(x265_param *p)<br>     x265_log(param, X265_LOG_INFO, "HEVC encoder version %s\n", PFX(version_str));<br>     x265_log(param, X265_LOG_INFO, "build info %s\n", PFX(build_info_str));<br> <br>-    encoder = new Encoder;<br>-<br> #ifdef SVT_HEVC<br> <br>     if (param->bEnableSvtHevc)<br>@@ -195,18 +197,16 @@ x265_encoder *x265_encoder_open(x265_param *p)<br> <br>     if (!param->bResetZoneConfig)<br>     {<br>-        param->rc.zones = X265_MALLOC(x265_zone, param->rc.zonefileCount);<br>+        // TODO: Memory pointer broken if both (p->rc.zoneCount || p->rc.zonefileCount) and (!param->bResetZoneConfig)<br>+        param->rc.zones = x265_zone_alloc(param->rc.zonefileCount, 1);<br>         for (int i = 0; i < param->rc.zonefileCount; i++)<br>         {<br>-            param->rc.zones[i].zoneParam = X265_MALLOC(x265_param, 1);<br>             memcpy(param->rc.zones[i].zoneParam, param, sizeof(x265_param));<br>             param->rc.zones[i].relativeComplexity = X265_MALLOC(double, param->reconfigWindowSize);<br>         }<br>     }<br> <br>-    // Need free zone because follow up Memcpy will broken all of pointer<br>-    x265_zone_free(zoneParam);<br>-    memcpy(zoneParam, param, sizeof(x265_param));<br>+    x265_copy_params(zoneParam, param);<br>     for (int i = 0; i < param->rc.zonefileCount; i++)<br>     {<br>         encoder->configureZone(zoneParam, param->rc.zones[i].zoneParam);<br>@@ -223,7 +223,6 @@ x265_encoder *x265_encoder_open(x265_param *p)<br>         }<br>     }<br> <br>-    encoder->m_templateParam = param;<br>     encoder->m_latestParam = latestParam;<br>     encoder->m_zoneParam = zoneParam;<br>     x265_copy_params(latestParam, param);<br>diff --git a/source/encoder/encoder.cpp b/source/encoder/encoder.cpp<br>index ce33e8f9b..609264067 100644<br>--- a/source/encoder/encoder.cpp<br>+++ b/source/encoder/encoder.cpp<br>@@ -138,7 +138,6 @@ Encoder::Encoder()<br>     m_outputCount = 0;<br>     m_param = NULL;<br>     m_latestParam = NULL;<br>-    m_templateParam = NULL;<br>     m_threadPool = NULL;<br>     m_analysisFileIn = NULL;<br>     m_analysisFileOut = NULL;<br>@@ -943,18 +942,6 @@ void Encoder::destroy()<br> <br>     X265_FREE(m_offsetEmergency);<br> <br>-    if (m_latestParam != NULL && m_latestParam != m_param)<br>-        PARAM_NS::x265_param_free(m_latestParam);<br>-<br>-    if (m_zoneParam != NULL && m_zoneParam != m_param)<br>-        PARAM_NS::x265_param_free(m_zoneParam);<br>-<br>-    if (m_templateParam != NULL && m_templateParam != m_param){<br>-        // TODO: we don't free zone here because it is overwrite into m_zoneParam in x265_encoder_open<br>-        m_templateParam->rc.zonefileCount = m_templateParam->rc.zoneCount = 0;<br>-        PARAM_NS::x265_param_free(m_templateParam);<br>-    }<br>-<br>     if (m_analysisFileIn)<br>         fclose(m_analysisFileIn);<br> <br>@@ -987,12 +974,17 @@ void Encoder::destroy()<br> #ifdef SVT_HEVC<br>     X265_FREE(m_svtAppData);<br> #endif<br>+<br>     if (m_param)<br>     {<br>         if (m_param->csvfpt)<br>             fclose(m_param->csvfpt);<br>-        PARAM_NS::x265_param_free(m_param);<br>     }<br>+<br>+    // Need not check anymore since all pointer is alias to base[]<br>+    PARAM_NS::x265_param_free(m_paramBase[0]);<br>+    PARAM_NS::x265_param_free(m_paramBase[1]);<br>+    PARAM_NS::x265_param_free(m_paramBase[2]);<br> }<br> <br> void Encoder::updateVbvPlan(RateControl* rc)<br>diff --git a/source/encoder/encoder.h b/source/encoder/encoder.h<br>index 134759d70..40af6a50d 100644<br>--- a/source/encoder/encoder.h<br>+++ b/source/encoder/encoder.h<br>@@ -206,10 +206,10 @@ public:<br>     FILE*              m_analysisFileIn;<br>     FILE*              m_analysisFileOut;<br>     FILE*              m_naluFile;<br>+    x265_param*        m_paramBase[3];<br>     x265_param*        m_param;<br>     x265_param*        m_latestParam;     // Holds latest param during a reconfigure<br>     x265_param*        m_zoneParam;<br>-    x265_param*        m_templateParam;<br>     RateControl*       m_rateControl;<br>     Lookahead*         m_lookahead;<br>     AdaptiveFrameDuplication* m_dupBuffer[DUP_BUFFER];      // picture buffer of size 2<br>diff --git a/source/x265cli.cpp b/source/x265cli.cpp<br>index 5f1b1b56a..5bd83a143 100755<br>--- a/source/x265cli.cpp<br>+++ b/source/x265cli.cpp<br>@@ -1132,7 +1132,7 @@ namespace X265_NS {<br> <br>         rewind(zoneFile);<br>         char **args = (char**)alloca(256 * sizeof(char *));<br>-        param->rc.zones = X265_MALLOC(x265_zone, param->rc.zonefileCount);<br>+        param->rc.zones = x265_zone_alloc(param->rc.zonefileCount, 1);;<br>         for (int i = 0; i < param->rc.zonefileCount; i++)<br>         {<br>             param->rc.zones[i].startFrame = -1;<br>@@ -1140,7 +1140,6 @@ namespace X265_NS {<br>             {<br>                 if (*line == '#' || (strcmp(line, "\r\n") == 0))<br>                     continue;<br>-                param->rc.zones[i].zoneParam = X265_MALLOC(x265_param, 1);<br>                 int index = (int)strcspn(line, "\r\n");<br>                 line[index] = '\0';<br>                 argLine = line;<br>-- <br>2.41.0.windows.1<br><br></div></div>