[vlc-devel] [V3 03/13] input: Refcount attachments

Hugo Beauzée-Luyssen hugo at beauzee.fr
Wed Nov 18 15:23:49 CET 2020


Instead of performing a deep copy every time they are fetched
---
 include/vlc_demux.h                       |  8 ++++++--
 include/vlc_input.h                       |  4 ++--
 modules/access/bluray.c                   |  6 ++----
 modules/codec/libass.c                    |  2 +-
 modules/codec/subsusf.c                   |  2 +-
 modules/demux/avformat/demux.c            |  6 ++----
 modules/demux/avi/avi.c                   |  4 ++--
 modules/demux/flac.c                      |  4 ++--
 modules/demux/mpeg/ts.c                   |  4 ++--
 modules/demux/ogg.c                       |  4 ++--
 modules/text_renderer/freetype/freetype.c |  8 ++++----
 src/input/access.c                        |  2 +-
 src/input/attachment.c                    | 19 +++++++++++++------
 src/input/input.c                         | 12 ++++++------
 src/input/meta.c                          |  2 +-
 src/input/stream_memory.c                 |  2 +-
 src/libvlccore.sym                        |  4 ++--
 17 files changed, 50 insertions(+), 43 deletions(-)

diff --git a/include/vlc_demux.h b/include/vlc_demux.h
index 92fa9618bb..6d6befa01b 100644
--- a/include/vlc_demux.h
+++ b/include/vlc_demux.h
@@ -223,8 +223,12 @@ enum demux_query_e
     /* Meta data */
     DEMUX_HAS_UNSUPPORTED_META, /* arg1= bool *   res can fail    */
 
-    /* Attachments */
-    DEMUX_GET_ATTACHMENTS,      /* arg1=input_attachment_t***, int* res=can fail */
+    /*
+     * Fetches attachment from the demux.
+     * The returned attachments are owned by the demuxer and must not be modified
+     * arg1=input_attachment_t***, int* res=can fail
+     */
+    DEMUX_GET_ATTACHMENTS,
 
     /* RECORD you are ensured that it is never called twice with the same state
      * you should accept it only if the stream can be recorded without
diff --git a/include/vlc_input.h b/include/vlc_input.h
index 2c0c4b1718..b0bb237b89 100644
--- a/include/vlc_input.h
+++ b/include/vlc_input.h
@@ -165,7 +165,7 @@ struct input_attachment_t
     void *p_data;
 };
 
-VLC_API void vlc_input_attachment_Delete( input_attachment_t *a );
+VLC_API void vlc_input_attachment_Release( input_attachment_t *a );
 
 VLC_API input_attachment_t *vlc_input_attachment_New( const char *psz_name,
                                                       const char *psz_mime,
@@ -173,7 +173,7 @@ VLC_API input_attachment_t *vlc_input_attachment_New( const char *psz_name,
                                                       const void *p_data,
                                                       size_t i_data );
 
-VLC_API input_attachment_t *vlc_input_attachment_Duplicate( const input_attachment_t *a );
+VLC_API input_attachment_t *vlc_input_attachment_Hold( input_attachment_t *a );
 
 /**
  * Input rate.
diff --git a/modules/access/bluray.c b/modules/access/bluray.c
index 5d23b3893c..d6278d1331 100644
--- a/modules/access/bluray.c
+++ b/modules/access/bluray.c
@@ -1128,7 +1128,7 @@ static void blurayClose(vlc_object_t *object)
     TAB_CLEAN(p_sys->i_title, p_sys->pp_title);
 
     for (int i = 0; i < p_sys->i_attachments; i++)
-      vlc_input_attachment_Delete(p_sys->attachments[i]);
+      vlc_input_attachment_Release(p_sys->attachments[i]);
     TAB_CLEAN(p_sys->i_attachments, p_sys->attachments);
 
     ARRAY_RESET(p_sys->events_delayed);
@@ -2629,9 +2629,7 @@ static int blurayControl(demux_t *p_demux, int query, va_list args)
             return VLC_EGENERIC;
         for (int i = 0; i < p_sys->i_attachments; i++)
         {
-            input_attachment_t *p_dup = vlc_input_attachment_Duplicate(p_sys->attachments[i]);
-            if(p_dup)
-                (*ppp_attach)[(*pi_int)++] = p_dup;
+            (*ppp_attach)[(*pi_int)++] = vlc_input_attachment_Hold(p_sys->attachments[i]);
         }
         return VLC_SUCCESS;
     }
diff --git a/modules/codec/libass.c b/modules/codec/libass.c
index dbaa5f5c4c..9d3ce5c1d2 100644
--- a/modules/codec/libass.c
+++ b/modules/codec/libass.c
@@ -192,7 +192,7 @@ static int Create( vlc_object_t *p_this )
 
             ass_add_font( p_sys->p_library, p_attach->psz_name, p_attach->p_data, p_attach->i_data );
         }
-        vlc_input_attachment_Delete( p_attach );
+        vlc_input_attachment_Release( p_attach );
     }
     free( pp_attachments );
 
diff --git a/modules/codec/subsusf.c b/modules/codec/subsusf.c
index 9b9b42a0bb..04ea674a35 100644
--- a/modules/codec/subsusf.c
+++ b/modules/codec/subsusf.c
@@ -537,7 +537,7 @@ static int ParseImageAttachments( decoder_t *p_dec )
                 }
             }
         }
-        vlc_input_attachment_Delete( pp_attachments[ k ] );
+        vlc_input_attachment_Release( pp_attachments[ k ] );
     }
     free( pp_attachments );
 
diff --git a/modules/demux/avformat/demux.c b/modules/demux/avformat/demux.c
index 11c15dad24..91c4e005f4 100644
--- a/modules/demux/avformat/demux.c
+++ b/modules/demux/avformat/demux.c
@@ -780,7 +780,7 @@ void avformat_CloseDemux( vlc_object_t *p_this )
     }
 
     for( int i = 0; i < p_sys->i_attachments; i++ )
-        vlc_input_attachment_Delete( p_sys->attachments[i] );
+        vlc_input_attachment_Release( p_sys->attachments[i] );
     TAB_CLEAN( p_sys->i_attachments, p_sys->attachments);
 
     if( p_sys->p_title )
@@ -1185,9 +1185,7 @@ static int Control( demux_t *p_demux, int i_query, va_list args )
 
             for( i = 0; i < p_sys->i_attachments; i++ )
             {
-                (*ppp_attach)[i] = vlc_input_attachment_Duplicate( p_sys->attachments[i] );
-                if((*ppp_attach)[i] == NULL)
-                    break;
+                (*ppp_attach)[i] = vlc_input_attachment_Hold( p_sys->attachments[i] );
             }
             *pi_int = i;
             return VLC_SUCCESS;
diff --git a/modules/demux/avi/avi.c b/modules/demux/avi/avi.c
index 7bae686ca1..6159e5e4e8 100644
--- a/modules/demux/avi/avi.c
+++ b/modules/demux/avi/avi.c
@@ -288,7 +288,7 @@ static void Close ( vlc_object_t * p_this )
         vlc_meta_Delete( p_sys->meta );
 
     for( unsigned i = 0; i < p_sys->i_attachment; i++)
-        vlc_input_attachment_Delete(p_sys->attachment[i]);
+        vlc_input_attachment_Release(p_sys->attachment[i]);
     free(p_sys->attachment);
 
     free( p_sys );
@@ -1703,7 +1703,7 @@ static int Control( demux_t *p_demux, int i_query, va_list args )
             {
                 *pi_int = p_sys->i_attachment;
                 for( unsigned i = 0; i < p_sys->i_attachment; i++ )
-                    (*ppp_attach)[i] = vlc_input_attachment_Duplicate( p_sys->attachment[i] );
+                    (*ppp_attach)[i] = vlc_input_attachment_Hold( p_sys->attachment[i] );
                 return VLC_SUCCESS;
             }
             return VLC_EGENERIC;
diff --git a/modules/demux/flac.c b/modules/demux/flac.c
index defb7d39bc..52850562f5 100644
--- a/modules/demux/flac.c
+++ b/modules/demux/flac.c
@@ -203,7 +203,7 @@ static void Close( vlc_object_t * p_this )
     TAB_CLEAN( p_sys->i_seekpoint, p_sys->seekpoint );
 
     for( int i = 0; i < p_sys->i_attachments; i++ )
-        vlc_input_attachment_Delete( p_sys->attachments[i] );
+        vlc_input_attachment_Release( p_sys->attachments[i] );
     TAB_CLEAN( p_sys->i_attachments, p_sys->attachments);
 
     for( int i = 0; i < p_sys->i_title_seekpoints; i++ )
@@ -585,7 +585,7 @@ static int Control( demux_t *p_demux, int i_query, va_list args )
             return VLC_EGENERIC;
         *pi_int = p_sys->i_attachments;
         for( int i = 0; i < p_sys->i_attachments; i++ )
-            (*ppp_attach)[i] = vlc_input_attachment_Duplicate( p_sys->attachments[i] );
+            (*ppp_attach)[i] = vlc_input_attachment_Hold( p_sys->attachments[i] );
         return VLC_SUCCESS;
     }
     else if( i_query == DEMUX_GET_TITLE_INFO )
diff --git a/modules/demux/mpeg/ts.c b/modules/demux/mpeg/ts.c
index cfeccd6a34..54edd253ab 100644
--- a/modules/demux/mpeg/ts.c
+++ b/modules/demux/mpeg/ts.c
@@ -550,7 +550,7 @@ static int Open( vlc_object_t *p_this )
 static void FreeDictAttachment( void *p_value, void *p_obj )
 {
     VLC_UNUSED(p_obj);
-    vlc_input_attachment_Delete( (input_attachment_t *) p_value );
+    vlc_input_attachment_Release( (input_attachment_t *) p_value );
 }
 
 static void Close( vlc_object_t *p_this )
@@ -1196,7 +1196,7 @@ static int Control( demux_t *p_demux, int i_query, va_list args )
                                          p_entry; p_entry = p_entry->p_next )
             {
                 msg_Err(p_demux, "GET ATTACHMENT %s", p_entry->psz_key);
-                (*ppp_attach)[*pi_int] = vlc_input_attachment_Duplicate(
+                (*ppp_attach)[*pi_int] = vlc_input_attachment_Hold(
                                                 (input_attachment_t *) p_entry->p_value );
                 if( (*ppp_attach)[*pi_int] )
                     (*pi_int)++;
diff --git a/modules/demux/ogg.c b/modules/demux/ogg.c
index 90edf1cb7e..b31bdc4aac 100644
--- a/modules/demux/ogg.c
+++ b/modules/demux/ogg.c
@@ -751,7 +751,7 @@ static int Control( demux_t *p_demux, int i_query, va_list args )
                 return VLC_ENOMEM;
             *pi_int = p_sys->i_attachments;
             for( int i = 0; i < p_sys->i_attachments; i++ )
-                (*ppp_attach)[i] = vlc_input_attachment_Duplicate( p_sys->attachments[i] );
+                (*ppp_attach)[i] = vlc_input_attachment_Hold( p_sys->attachments[i] );
             return VLC_SUCCESS;
         }
 
@@ -2258,7 +2258,7 @@ static void Ogg_EndOfStream( demux_t *p_demux )
     p_ogg->p_meta = NULL;
 
     for(int i=0; i<p_ogg->i_attachments; i++)
-        vlc_input_attachment_Delete( p_ogg->attachments[i] );
+        vlc_input_attachment_Release( p_ogg->attachments[i] );
     TAB_CLEAN(p_ogg->i_attachments, p_ogg->attachments);
 
     for ( int i=0; i < p_ogg->i_seekpoints; i++ )
diff --git a/modules/text_renderer/freetype/freetype.c b/modules/text_renderer/freetype/freetype.c
index d9044ca54c..3303e46000 100644
--- a/modules/text_renderer/freetype/freetype.c
+++ b/modules/text_renderer/freetype/freetype.c
@@ -272,7 +272,7 @@ static int LoadFontsFromAttachments( filter_t *p_filter )
     if( !p_sys->pp_font_attachments )
     {
         for( int i = 0; i < i_attachments_cnt; ++i )
-            vlc_input_attachment_Delete( pp_attachments[ i ] );
+            vlc_input_attachment_Release( pp_attachments[ i ] );
         free( pp_attachments );
         return VLC_ENOMEM;
     }
@@ -322,7 +322,7 @@ static int LoadFontsFromAttachments( filter_t *p_filter )
         }
         else
         {
-            vlc_input_attachment_Delete( p_attach );
+            vlc_input_attachment_Release( p_attach );
         }
     }
 
@@ -335,7 +335,7 @@ error:
         FT_Done_Face( p_face );
 
     for( int i = k + 1; i < i_attachments_cnt; ++i )
-        vlc_input_attachment_Delete( pp_attachments[ i ] );
+        vlc_input_attachment_Release( pp_attachments[ i ] );
 
     free( pp_attachments );
     return VLC_ENOMEM;
@@ -1279,7 +1279,7 @@ static void Destroy( filter_t *p_filter )
     if( p_sys->pp_font_attachments )
     {
         for( int k = 0; k < p_sys->i_font_attachments; k++ )
-            vlc_input_attachment_Delete( p_sys->pp_font_attachments[k] );
+            vlc_input_attachment_Release( p_sys->pp_font_attachments[k] );
 
         free( p_sys->pp_font_attachments );
     }
diff --git a/src/input/access.c b/src/input/access.c
index eab763f020..b5a5ae010d 100644
--- a/src/input/access.c
+++ b/src/input/access.c
@@ -86,7 +86,7 @@ static stream_t *accessNewAttachment(vlc_object_t *parent,
     stream_t *stream = vlc_stream_AttachmentNew(parent, attachment);
     if (!stream)
     {
-        vlc_input_attachment_Delete(attachment);
+        vlc_input_attachment_Release(attachment);
         return NULL;
     }
     stream->psz_url = strdup(mrl);
diff --git a/src/input/attachment.c b/src/input/attachment.c
index 0b4bb99ab9..35064ca47c 100644
--- a/src/input/attachment.c
+++ b/src/input/attachment.c
@@ -24,10 +24,12 @@
 
 #include <vlc_common.h>
 #include <vlc_input.h>
+#include <vlc_atomic.h>
 
 struct input_attachment_priv
 {
     input_attachment_t a;
+    vlc_atomic_rc_t rc;
 };
 
 static struct input_attachment_priv* input_attachment_priv( input_attachment_t* a )
@@ -35,13 +37,16 @@ static struct input_attachment_priv* input_attachment_priv( input_attachment_t*
     return container_of( a, struct input_attachment_priv, a );
 }
 
-void vlc_input_attachment_Delete( input_attachment_t *a )
+void vlc_input_attachment_Release( input_attachment_t *a )
 {
     if( !a )
         return;
 
     struct input_attachment_priv* p = input_attachment_priv( a );
 
+    if( !vlc_atomic_rc_dec( &p->rc ) )
+        return;
+
     free( a->p_data );
     free( a->psz_description );
     free( a->psz_mime );
@@ -59,6 +64,7 @@ input_attachment_t *vlc_input_attachment_New( const char *psz_name,
     if( unlikely(a == NULL) )
         return NULL;
 
+    vlc_atomic_rc_init( &a->rc );
     a->a.psz_name = strdup( psz_name ? psz_name : "" );
     a->a.psz_mime = strdup( psz_mime ? psz_mime : "" );
     a->a.psz_description = strdup( psz_description ? psz_description : "" );
@@ -70,14 +76,15 @@ input_attachment_t *vlc_input_attachment_New( const char *psz_name,
     if( unlikely(a->a.psz_name == NULL || a->a.psz_mime == NULL
               || a->a.psz_description == NULL || (i_data > 0 && a->a.p_data == NULL)) )
     {
-        vlc_input_attachment_Delete( &a->a );
-        a = NULL;
+        vlc_input_attachment_Release( &a->a );
+        return NULL;
     }
     return &a->a;
 }
 
-input_attachment_t *vlc_input_attachment_Duplicate( const input_attachment_t *a )
+input_attachment_t *vlc_input_attachment_Hold( input_attachment_t *a )
 {
-    return vlc_input_attachment_New( a->psz_name, a->psz_mime, a->psz_description,
-                                     a->p_data, a->i_data );
+    struct input_attachment_priv* p = input_attachment_priv( a );
+    vlc_atomic_rc_inc( &p->rc );
+    return a;
 }
diff --git a/src/input/input.c b/src/input/input.c
index 4be4d304f6..8a37f814f5 100644
--- a/src/input/input.c
+++ b/src/input/input.c
@@ -1151,7 +1151,7 @@ static void LoadSlaves( input_thread_t *p_input )
             free( psz_mrl );
             /* Don't update item slaves for attachements */
         }
-        vlc_input_attachment_Delete( a );
+        vlc_input_attachment_Release( a );
     }
     free( pp_attachment );
     if( i_attachment > 0 )
@@ -1416,7 +1416,7 @@ static void End( input_thread_t * p_input )
     if( priv->i_attachment > 0 )
     {
         for( int i = 0; i < priv->i_attachment; i++ )
-            vlc_input_attachment_Delete( priv->attachment[i] );
+            vlc_input_attachment_Release( priv->attachment[i] );
         TAB_CLEAN( priv->i_attachment, priv->attachment );
         free( priv->attachment_demux);
         priv->attachment_demux = NULL;
@@ -3069,7 +3069,7 @@ static void AppendAttachment( int *pi_attachment, input_attachment_t ***ppp_atta
 
     /* on alloc errors */
     for( i = 0; i < i_new; i++ )
-        vlc_input_attachment_Delete( pp_new[i] );
+        vlc_input_attachment_Release( pp_new[i] );
     free( pp_new );
 }
 
@@ -3100,7 +3100,7 @@ static void InputUpdateMeta( input_thread_t *p_input, demux_t *p_demux )
             for( int i = 0; i < input_priv(p_input)->i_attachment; i++ )
             {
                 if( input_priv(p_input)->attachment_demux[i] == p_demux )
-                    vlc_input_attachment_Delete( input_priv(p_input)->attachment[i] );
+                    vlc_input_attachment_Release( input_priv(p_input)->attachment[i] );
                 else
                 {
                     input_priv(p_input)->attachment[j] = input_priv(p_input)->attachment[i];
@@ -3490,7 +3490,7 @@ int input_GetAttachments(input_thread_t *input,
         return -1;
 
     for (int i = 0; i < attachments_count; i++)
-        (*attachments)[i] = vlc_input_attachment_Duplicate(priv->attachment[i]);
+        (*attachments)[i] = vlc_input_attachment_Hold(priv->attachment[i]);
 
     vlc_mutex_unlock(&priv->p_item->lock);
     return attachments_count;
@@ -3506,7 +3506,7 @@ input_attachment_t *input_GetAttachment(input_thread_t *input, const char *name)
         if (!strcmp( priv->attachment[i]->psz_name, name))
         {
             input_attachment_t *attachment =
-                vlc_input_attachment_Duplicate(priv->attachment[i] );
+                vlc_input_attachment_Hold(priv->attachment[i] );
             vlc_mutex_unlock( &priv->p_item->lock );
             return attachment;
         }
diff --git a/src/input/meta.c b/src/input/meta.c
index e5d829222f..9ef43cad83 100644
--- a/src/input/meta.c
+++ b/src/input/meta.c
@@ -234,7 +234,7 @@ void input_ExtractAttachmentAndCacheArt( input_thread_t *p_input,
 
     input_SaveArt( VLC_OBJECT(p_input), p_item,
                    p_attachment->p_data, p_attachment->i_data, psz_type );
-    vlc_input_attachment_Delete( p_attachment );
+    vlc_input_attachment_Release( p_attachment );
 }
 
 int input_item_WriteMeta( vlc_object_t *obj, input_item_t *p_item )
diff --git a/src/input/stream_memory.c b/src/input/stream_memory.c
index 381d4250df..8b03502ddb 100644
--- a/src/input/stream_memory.c
+++ b/src/input/stream_memory.c
@@ -60,7 +60,7 @@ static void stream_AttachmentDelete(stream_t *s)
 {
     struct vlc_stream_attachment_private *sys = vlc_stream_Private(s);
 
-    vlc_input_attachment_Delete(sys->attachment);
+    vlc_input_attachment_Release(sys->attachment);
     free(s->psz_name);
 }
 
diff --git a/src/libvlccore.sym b/src/libvlccore.sym
index 5bda357ef0..e3a2de9f6d 100644
--- a/src/libvlccore.sym
+++ b/src/libvlccore.sym
@@ -981,6 +981,6 @@ vlc_executor_Delete
 vlc_executor_Submit
 vlc_executor_Cancel
 vlc_executor_WaitIdle
-vlc_input_attachment_Delete
+vlc_input_attachment_Release
 vlc_input_attachment_New
-vlc_input_attachment_Duplicate
+vlc_input_attachment_Hold
-- 
2.29.2



More information about the vlc-devel mailing list