[x265] [PATCH] Fix zone duplicated memory free bug

Pavan Tarun Chakka Venkata pavan.tarun at multicorewareinc.com
Thu Nov 21 10:12:18 UTC 2024


>From c8d6c92867f1823d71965c9fa04ae14a656e5089 Mon Sep 17 00:00:00 2001
From: Min Chen <chenm003 at 163.com>
Date: Thu, 14 Nov 2024 00:09:11 -0800
Subject: [PATCH] Fix zone duplicated memory free bug

---
 source/encoder/api.cpp     | 23 +++++++++++------------
 source/encoder/encoder.cpp | 20 ++++++--------------
 source/encoder/encoder.h   |  2 +-
 source/x265cli.cpp         |  3 +--
 4 files changed, 19 insertions(+), 29 deletions(-)

diff --git a/source/encoder/api.cpp b/source/encoder/api.cpp
index 40a325334..3ea67168d 100644
--- a/source/encoder/api.cpp
+++ b/source/encoder/api.cpp
@@ -91,10 +91,14 @@ x265_encoder *x265_encoder_open(x265_param *p)
         return NULL;
     }

-    Encoder* encoder = NULL;
-    x265_param* param = PARAM_NS::x265_param_alloc();
-    x265_param* latestParam = PARAM_NS::x265_param_alloc();
-    x265_param* zoneParam = PARAM_NS::x265_param_alloc();
+    Encoder* encoder = new Encoder;
+    encoder->m_paramBase[0] = PARAM_NS::x265_param_alloc();
+    encoder->m_paramBase[1] = PARAM_NS::x265_param_alloc();
+    encoder->m_paramBase[2] = PARAM_NS::x265_param_alloc();
+
+    x265_param* param = encoder->m_paramBase[0];
+    x265_param* latestParam = encoder->m_paramBase[1];
+    x265_param* zoneParam = encoder->m_paramBase[2];

     if(param) PARAM_NS::x265_param_default(param);
     if(latestParam) PARAM_NS::x265_param_default(latestParam);
@@ -116,8 +120,6 @@ x265_encoder *x265_encoder_open(x265_param *p)
     x265_log(param, X265_LOG_INFO, "HEVC encoder version %s\n",
PFX(version_str));
     x265_log(param, X265_LOG_INFO, "build info %s\n", PFX(build_info_str));

-    encoder = new Encoder;
-
 #ifdef SVT_HEVC

     if (param->bEnableSvtHevc)
@@ -195,18 +197,16 @@ x265_encoder *x265_encoder_open(x265_param *p)

     if (!param->bResetZoneConfig)
     {
-        param->rc.zones = X265_MALLOC(x265_zone, param->rc.zonefileCount);
+        // TODO: Memory pointer broken if both (p->rc.zoneCount ||
p->rc.zonefileCount) and (!param->bResetZoneConfig)
+        param->rc.zones = x265_zone_alloc(param->rc.zonefileCount, 1);
         for (int i = 0; i < param->rc.zonefileCount; i++)
         {
-            param->rc.zones[i].zoneParam = X265_MALLOC(x265_param, 1);
             memcpy(param->rc.zones[i].zoneParam, param,
sizeof(x265_param));
             param->rc.zones[i].relativeComplexity = X265_MALLOC(double,
param->reconfigWindowSize);
         }
     }

-    // Need free zone because follow up Memcpy will broken all of pointer
-    x265_zone_free(zoneParam);
-    memcpy(zoneParam, param, sizeof(x265_param));
+    x265_copy_params(zoneParam, param);
     for (int i = 0; i < param->rc.zonefileCount; i++)
     {
         encoder->configureZone(zoneParam, param->rc.zones[i].zoneParam);
@@ -223,7 +223,6 @@ x265_encoder *x265_encoder_open(x265_param *p)
         }
     }

-    encoder->m_templateParam = param;
     encoder->m_latestParam = latestParam;
     encoder->m_zoneParam = zoneParam;
     x265_copy_params(latestParam, param);
diff --git a/source/encoder/encoder.cpp b/source/encoder/encoder.cpp
index ce33e8f9b..609264067 100644
--- a/source/encoder/encoder.cpp
+++ b/source/encoder/encoder.cpp
@@ -138,7 +138,6 @@ Encoder::Encoder()
     m_outputCount = 0;
     m_param = NULL;
     m_latestParam = NULL;
-    m_templateParam = NULL;
     m_threadPool = NULL;
     m_analysisFileIn = NULL;
     m_analysisFileOut = NULL;
@@ -943,18 +942,6 @@ void Encoder::destroy()

     X265_FREE(m_offsetEmergency);

-    if (m_latestParam != NULL && m_latestParam != m_param)
-        PARAM_NS::x265_param_free(m_latestParam);
-
-    if (m_zoneParam != NULL && m_zoneParam != m_param)
-        PARAM_NS::x265_param_free(m_zoneParam);
-
-    if (m_templateParam != NULL && m_templateParam != m_param){
-        // TODO: we don't free zone here because it is overwrite into
m_zoneParam in x265_encoder_open
-        m_templateParam->rc.zonefileCount = m_templateParam->rc.zoneCount
= 0;
-        PARAM_NS::x265_param_free(m_templateParam);
-    }
-
     if (m_analysisFileIn)
         fclose(m_analysisFileIn);

@@ -987,12 +974,17 @@ void Encoder::destroy()
 #ifdef SVT_HEVC
     X265_FREE(m_svtAppData);
 #endif
+
     if (m_param)
     {
         if (m_param->csvfpt)
             fclose(m_param->csvfpt);
-        PARAM_NS::x265_param_free(m_param);
     }
+
+    // Need not check anymore since all pointer is alias to base[]
+    PARAM_NS::x265_param_free(m_paramBase[0]);
+    PARAM_NS::x265_param_free(m_paramBase[1]);
+    PARAM_NS::x265_param_free(m_paramBase[2]);
 }

 void Encoder::updateVbvPlan(RateControl* rc)
diff --git a/source/encoder/encoder.h b/source/encoder/encoder.h
index 134759d70..40af6a50d 100644
--- a/source/encoder/encoder.h
+++ b/source/encoder/encoder.h
@@ -206,10 +206,10 @@ public:
     FILE*              m_analysisFileIn;
     FILE*              m_analysisFileOut;
     FILE*              m_naluFile;
+    x265_param*        m_paramBase[3];
     x265_param*        m_param;
     x265_param*        m_latestParam;     // Holds latest param during a
reconfigure
     x265_param*        m_zoneParam;
-    x265_param*        m_templateParam;
     RateControl*       m_rateControl;
     Lookahead*         m_lookahead;
     AdaptiveFrameDuplication* m_dupBuffer[DUP_BUFFER];      // picture
buffer of size 2
diff --git a/source/x265cli.cpp b/source/x265cli.cpp
index 5f1b1b56a..5bd83a143 100755
--- a/source/x265cli.cpp
+++ b/source/x265cli.cpp
@@ -1132,7 +1132,7 @@ namespace X265_NS {

         rewind(zoneFile);
         char **args = (char**)alloca(256 * sizeof(char *));
-        param->rc.zones = X265_MALLOC(x265_zone, param->rc.zonefileCount);
+        param->rc.zones = x265_zone_alloc(param->rc.zonefileCount, 1);;
         for (int i = 0; i < param->rc.zonefileCount; i++)
         {
             param->rc.zones[i].startFrame = -1;
@@ -1140,7 +1140,6 @@ namespace X265_NS {
             {
                 if (*line == '#' || (strcmp(line, "\r\n") == 0))
                     continue;
-                param->rc.zones[i].zoneParam = X265_MALLOC(x265_param, 1);
                 int index = (int)strcspn(line, "\r\n");
                 line[index] = '\0';
                 argLine = line;
-- 
2.41.0.windows.1
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mailman.videolan.org/pipermail/x265-devel/attachments/20241121/c7880c0a/attachment-0001.htm>
-------------- next part --------------
A non-text attachment was scrubbed...
Name: 0003-Fix-zone-duplicated-memory-free-bug.patch
Type: application/octet-stream
Size: 6231 bytes
Desc: not available
URL: <http://mailman.videolan.org/pipermail/x265-devel/attachments/20241121/c7880c0a/attachment-0001.obj>


More information about the x265-devel mailing list