PR #22536 opened by jiangjie
URL: https://code.ffmpeg.org/FFmpeg/FFmpeg/pulls/22536
Patch URL: https://code.ffmpeg.org/FFmpeg/FFmpeg/pulls/22536.patch

Replace fixed-size char arrays in HLSSegment structure with dynamically
allocated pointers to reduce memory footprint per segment.


>From b3bd7a1ecaa3d0920ed1dc794e21a729cf61dc71 Mon Sep 17 00:00:00 2001
From: jiangjie <[email protected]>
Date: Tue, 17 Mar 2026 17:43:19 +0800
Subject: [PATCH] avformat/hlsenc: Replace fixed-size arrays with dynamic
 allocation in HLSSegment structure

Replace fixed-size char arrays in HLSSegment structure with dynamically
allocated pointers to reduce memory footprint per segment.
---
 libavformat/hlsenc.c | 71 ++++++++++++++++++++++++++++----------------
 1 file changed, 46 insertions(+), 25 deletions(-)

diff --git a/libavformat/hlsenc.c b/libavformat/hlsenc.c
index 8eaab37a2c..fcbfd6ed24 100644
--- a/libavformat/hlsenc.c
+++ b/libavformat/hlsenc.c
@@ -74,8 +74,8 @@ typedef enum {
 #define POSTFIX_PATTERN "_%d"
 
 typedef struct HLSSegment {
-    char filename[MAX_URL_SIZE];
-    char sub_filename[MAX_URL_SIZE];
+    char *filename;
+    char *sub_filename;
     double duration; /* in seconds */
     int discont;
     int64_t pos;
@@ -84,7 +84,7 @@ typedef struct HLSSegment {
     int64_t keyframe_size;
     unsigned var_stream_idx;
 
-    char key_uri[LINE_BUFFER_SIZE + 1];
+    char *key_uri;
     char iv_string[KEYSIZE*2 + 1];
 
     struct HLSSegment *next;
@@ -526,6 +526,27 @@ static int hls_delete_file(HLSContext *hls, 
AVFormatContext *avf,
     return 0;
 }
 
+static void hls_free_segment(HLSSegment *en)
+{
+    if (!en)
+        return;
+    av_freep(&en->filename);
+    av_freep(&en->sub_filename);
+    av_freep(&en->key_uri);
+    av_freep(&en);
+}
+
+static void hls_free_segments(HLSSegment *p)
+{
+    HLSSegment *en;
+
+    while (p) {
+        en = p;
+        p = p->next;
+        hls_free_segment(en);
+    }
+}
+
 static int hls_delete_old_segments(AVFormatContext *s, HLSContext *hls,
                                    VariantStream *vs)
 {
@@ -606,7 +627,7 @@ static int hls_delete_old_segments(AVFormatContext *s, 
HLSContext *hls,
         if (ret = hls_delete_file(hls, s, path.str, proto))
             goto fail;
 
-        if ((segment->sub_filename[0] != '\0')) {
+        if (segment->sub_filename) {
             vtt_dirname_r = av_strdup(vs->vtt_avf->url);
             vtt_dirname = av_dirname(vtt_dirname_r);
 
@@ -625,7 +646,7 @@ static int hls_delete_old_segments(AVFormatContext *s, 
HLSContext *hls,
         av_bprint_clear(&path);
         previous_segment = segment;
         segment = previous_segment->next;
-        av_freep(&previous_segment);
+        hls_free_segment(previous_segment);
     }
 
 fail:
@@ -1033,7 +1054,7 @@ static int hls_append_segment(struct AVFormatContext *s, 
HLSContext *hls,
                               VariantStream *vs, double duration, int64_t pos,
                               int64_t size)
 {
-    HLSSegment *en = av_malloc(sizeof(*en));
+    HLSSegment *en = av_mallocz(sizeof(*en));
     const char  *filename;
     int byterange_mode = (hls->flags & HLS_SINGLE_FILE) || (hls->max_seg_size 
> 0);
     int ret;
@@ -1056,7 +1077,7 @@ static int hls_append_segment(struct AVFormatContext *s, 
HLSContext *hls,
     en->var_stream_idx = vs->var_stream_idx;
     ret = sls_flags_filename_process(s, hls, vs, en, duration, pos, size);
     if (ret < 0) {
-        av_freep(&en);
+        hls_free_segment(en);
         return ret;
     }
 
@@ -1069,12 +1090,19 @@ static int hls_append_segment(struct AVFormatContext 
*s, HLSContext *hls,
         && !byterange_mode) {
         av_log(hls, AV_LOG_WARNING, "Duplicated segment filename detected: 
%s\n", filename);
     }
-    av_strlcpy(en->filename, filename, sizeof(en->filename));
+    en->filename = av_strdup(filename);
+    if (!en->filename) {
+        hls_free_segment(en);
+        return AVERROR(ENOMEM);
+    }
 
-    if (vs->has_subtitle)
-        av_strlcpy(en->sub_filename, av_basename(vs->vtt_avf->url), 
sizeof(en->sub_filename));
-    else
-        en->sub_filename[0] = '\0';
+    if (vs->has_subtitle) {
+        en->sub_filename = av_strdup(av_basename(vs->vtt_avf->url));
+        if (!en->sub_filename) {
+            hls_free_segment(en);
+            return AVERROR(ENOMEM);
+        }
+    }
 
     en->duration = duration;
     en->pos      = pos;
@@ -1091,7 +1119,11 @@ static int hls_append_segment(struct AVFormatContext *s, 
HLSContext *hls,
     }
 
     if (hls->key_info_file || hls->encrypt) {
-        av_strlcpy(en->key_uri, vs->key_uri, sizeof(en->key_uri));
+        en->key_uri = av_strdup(vs->key_uri);
+        if (!en->key_uri) {
+            hls_free_segment(en);
+            return AVERROR(ENOMEM);
+        }
         av_strlcpy(en->iv_string, vs->iv_string, sizeof(en->iv_string));
     }
 
@@ -1118,7 +1150,7 @@ static int hls_append_segment(struct AVFormatContext *s, 
HLSContext *hls,
             if ((ret = hls_delete_old_segments(s, hls, vs)) < 0)
                 return ret;
         } else
-            av_freep(&en);
+            hls_free_segment(en);
     } else
         vs->nb_entries++;
 
@@ -1273,17 +1305,6 @@ fail:
     return ret;
 }
 
-static void hls_free_segments(HLSSegment *p)
-{
-    HLSSegment *en;
-
-    while (p) {
-        en = p;
-        p = p->next;
-        av_freep(&en);
-    }
-}
-
 static int hls_rename_temp_file(AVFormatContext *s, AVFormatContext *oc)
 {
     size_t len = strlen(oc->url);
-- 
2.52.0

_______________________________________________
ffmpeg-devel mailing list -- [email protected]
To unsubscribe send an email to [email protected]

Reply via email to