[vlc-commits] [Git][videolan/vlc][master] 4 commits: vpx_alpha: add reference-counting to picture context

Felix Paul Kühne (@fkuehne) gitlab at videolan.org
Fri Sep 13 05:03:45 UTC 2024



Felix Paul Kühne pushed to branch master at VideoLAN / VLC


Commits:
85a28e9a by Alexandre Janniaux at 2024-09-13T04:41:03+00:00
vpx_alpha: add reference-counting to picture context

The context is read-only and was currently copied for every picture, so
switch to reference counting to avoid this. It will also help when
moving planes stored in p_sys into the context, to determine when the
allocated plane should be released, and to copy/share the pointer
automatically.

- - - - -
a3054e86 by Alexandre Janniaux at 2024-09-13T04:41:03+00:00
vpx_alpha: use picture context to forward plane

p_sys is used by the pool to forward the picture pool context. Pictures
that are supporting copying should be using picture context instead,
which the vpx_alpha decoder was already doing.

This fixes a huge memory leak of picture data when playing VP9 videos.

    STACK OF 1242 INSTANCES OF 'ROOT LEAK: malloc[2097152]':
    9   libsystem_pthread.dylib               0x185e89d34 thread_start + 8
    8   libsystem_pthread.dylib               0x185e8ef94 _pthread_start + 136
    7   libvlccore.9.dylib                    0x1032606cc DecoderThread + 348  decoder.c:1869
    6   libvlccore.9.dylib                    0x103262c04 DecoderThread_DecodeBlock + 256  decoder.c:1627
    5   ???                                   0x107066034 0x7fffffffffffffff + 9223372041267601461
    4   ???                                   0x12a809674 0x7fffffffffffffff + 9223372041862813301
    3   ???                                   0x107065c70 0x7fffffffffffffff + 9223372041267600497
    2   ???                                   0x107066644 0x7fffffffffffffff + 9223372041267603013
    1   ???                                   0x1070662ec 0x7fffffffffffffff + 9223372041267602157
    0   libsystem_malloc.dylib                0x185cc8a68 _malloc_zone_malloc_instrumented_or_legacy + 148 

Instruments correctly indicates the following trace:

    CombinePicturesCPU	
    SendMergedLocked	
    QueuePic	
    ecoder_QueueVideo	
    ecodeBlock	
    DecodeVideo	
    Decode	
    DecoderThread_DecodeBlock	
    DecoderThread	
    _pthread_start	
    thread_start

See ticket for details of the trace.

Fixes #28792

- - - - -
e3cad491 by Alexandre Janniaux at 2024-09-13T04:41:03+00:00
vpx_alpha: early-return during merging

Early return to avoid mixing the allocation path and the re-use path,
making two level of indentation useless.

Indentation is changed in the follow-up commit.

- - - - -
b132d095 by Alexandre Janniaux at 2024-09-13T04:41:03+00:00
vpx_alpha: reindent after last changes

- - - - -


1 changed file:

- modules/codec/vpx_alpha.c


Changes:

=====================================
modules/codec/vpx_alpha.c
=====================================
@@ -4,6 +4,7 @@
 // Copyright © 2023 VideoLabs, VLC authors and VideoLAN
 
 // Authors: Steve Lhomme <robux4 at videolabs.io>
+//          Alexandre Janniaux <ajanni at videolabs.io>
 
 #ifdef HAVE_CONFIG_H
 # include "config.h"
@@ -63,14 +64,21 @@ static vlc_decoder_device *GetDevice( decoder_t *dec )
 
 struct cpu_alpha_context
 {
+    vlc_atomic_rc_t    rc;
     picture_context_t  ctx;
     picture_t          *opaque;
     picture_t          *alpha; // may be NULL if the alpha layer was missing
+    struct pic_alpha_plane *plane;
 };
 
 static void cpu_alpha_destroy(picture_context_t *ctx)
 {
     struct cpu_alpha_context *pctx = container_of(ctx, struct cpu_alpha_context, ctx);
+
+    if (!vlc_atomic_rc_dec(&pctx->rc))
+        return;
+
+    free(pctx->plane);
     picture_Release(pctx->opaque);
     if (pctx->alpha)
         picture_Release(pctx->alpha);
@@ -80,13 +88,9 @@ static void cpu_alpha_destroy(picture_context_t *ctx)
 static picture_context_t *cpu_alpha_copy(picture_context_t *src)
 {
     struct cpu_alpha_context *pctx = container_of(src, struct cpu_alpha_context, ctx);
-    struct cpu_alpha_context *alpha_ctx = calloc(1, sizeof(*alpha_ctx));
-    if (unlikely(alpha_ctx == NULL))
-        return NULL;
-    alpha_ctx->ctx = *src;
-    alpha_ctx->opaque = picture_Hold(pctx->opaque);
-    alpha_ctx->alpha  = alpha_ctx->alpha ? picture_Hold(pctx->alpha) : NULL;
-    return &alpha_ctx->ctx;
+
+    vlc_atomic_rc_inc(&pctx->rc);
+    return &pctx->ctx;
 }
 
 struct pic_alpha_plane
@@ -114,6 +118,7 @@ static picture_t *CombinePicturesCPU(decoder_t *bdec, picture_t *opaque, picture
         picture_Release(out);
         return NULL;
     }
+    vlc_atomic_rc_init(&alpha_ctx->rc);
     alpha_ctx->ctx = (picture_context_t) {
         cpu_alpha_destroy, cpu_alpha_copy, NULL
     };
@@ -123,37 +128,37 @@ static picture_t *CombinePicturesCPU(decoder_t *bdec, picture_t *opaque, picture
 
     for (int i=0; i<opaque->i_planes; i++)
         out->p[i] = opaque->p[i];
+
     if (alpha)
-        out->p[opaque->i_planes] = alpha->p[0];
-    else
     {
-        // use the dummy opaque plane attached in the picture p_sys
-        struct pic_alpha_plane *p = out->p_sys;
-        if (out->p_sys == NULL)
-        {
-            int plane_size = bdec->fmt_out.video.i_width * bdec->fmt_out.video.i_height;
-            p = malloc(sizeof(*p) + plane_size);
-            if (likely(p != NULL))
-            {
-                p->p.i_lines = bdec->fmt_out.video.i_height;
-                p->p.i_visible_lines = bdec->fmt_out.video.i_y_offset + bdec->fmt_out.video.i_visible_height;
-
-                p->p.i_pitch = bdec->fmt_out.video.i_width;
-                p->p.i_visible_pitch = bdec->fmt_out.video.i_x_offset + bdec->fmt_out.video.i_visible_width;
-                p->p.i_pixel_pitch = 1;
-                p->p.p_pixels = p->buffer;
-                memset(p->p.p_pixels, 0xFF, plane_size);
+        out->p[opaque->i_planes] = alpha->p[0];
+        return out;
+    }
 
-                out->p_sys = p;
-            }
-        }
+    // use the dummy opaque plane attached in the picture context
+    struct pic_alpha_plane *p = alpha_ctx->plane;
+    if (p == NULL)
+    {
+        int plane_size = bdec->fmt_out.video.i_width * bdec->fmt_out.video.i_height;
+        p = malloc(sizeof(*p) + plane_size);
         if (unlikely(p == NULL))
         {
             picture_Release(out);
             return NULL;
         }
-        out->p[opaque->i_planes] = p->p;
+
+        p->p.i_lines = bdec->fmt_out.video.i_height;
+        p->p.i_visible_lines = bdec->fmt_out.video.i_y_offset + bdec->fmt_out.video.i_visible_height;
+
+        p->p.i_pitch = bdec->fmt_out.video.i_width;
+        p->p.i_visible_pitch = bdec->fmt_out.video.i_x_offset + bdec->fmt_out.video.i_visible_width;
+        p->p.i_pixel_pitch = 1;
+        p->p.p_pixels = p->buffer;
+        memset(p->p.p_pixels, 0xFF, plane_size);
+
+        alpha_ctx->plane = p;
     }
+    out->p[opaque->i_planes] = p->p;
     return out;
 }
 



View it on GitLab: https://code.videolan.org/videolan/vlc/-/compare/02921db96886fd82f94efa72fbbe4c1b7f32e5c4...b132d09580a85907e52a52624bd8d2a90da9629d

-- 
View it on GitLab: https://code.videolan.org/videolan/vlc/-/compare/02921db96886fd82f94efa72fbbe4c1b7f32e5c4...b132d09580a85907e52a52624bd8d2a90da9629d
You're receiving this email because of your account on code.videolan.org.


VideoLAN code repository instance


More information about the vlc-commits mailing list