[vlc-devel] [PATCH 03/15] input: Refcount attachments
Hugo Beauzée-Luyssen
hugo at beauzee.fr
Tue Nov 10 18:40:13 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 eb521ec19b..520379ccb3 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.28.0
More information about the vlc-devel
mailing list