[vlc-devel] [PATCH 02/11] input: resource: move vouts handling from array to list
Thomas Guillem
thomas at gllm.fr
Tue Jun 30 17:27:13 CEST 2020
And create a struct vout_resource, that will hold the input resource vout state.
---
src/input/resource.c | 168 +++++++++++++++++++++++++++++--------------
1 file changed, 113 insertions(+), 55 deletions(-)
diff --git a/src/input/resource.c b/src/input/resource.c
index e145a88342c..e05e20ce449 100644
--- a/src/input/resource.c
+++ b/src/input/resource.c
@@ -44,6 +44,13 @@
#include "event.h"
#include "resource.h"
+struct vout_resource
+{
+ vout_thread_t *vout;
+
+ struct vlc_list node;
+};
+
struct input_resource_t
{
vlc_atomic_rc_t rc;
@@ -58,8 +65,8 @@ struct input_resource_t
input_thread_t *p_input;
sout_instance_t *p_sout;
- vout_thread_t *p_vout_free;
vout_thread_t *p_vout_dummy;
+ struct vout_resource *vout_rsc_free;
/* This lock is used to protect vout resources access (for hold)
* It is a special case because of embed video (possible deadlock
@@ -69,14 +76,55 @@ struct input_resource_t
/* You need lock+lock_hold to write to the following variables and
* only lock or lock_hold to read them */
-
- vout_thread_t **pp_vout;
- int i_vout;
+ struct vlc_list vout_rscs;
bool b_aout_busy;
audio_output_t *p_aout;
};
+#define resource_GetFirstVoutRsc(resource) \
+ vlc_list_first_entry_or_null(&resource->vout_rscs, struct vout_resource, node)
+
+static inline struct vout_resource *
+resource_GetVoutRsc(input_resource_t *resource, vout_thread_t *vout)
+{
+ struct vout_resource *vout_rsc;
+
+ vlc_list_foreach(vout_rsc, &resource->vout_rscs, node)
+ if (vout_rsc->vout == vout)
+ return vout_rsc;
+
+ vlc_assert_unreachable();
+}
+
+static inline struct vout_resource *
+vout_resource_Create(vout_thread_t *vout)
+{
+ struct vout_resource *vout_rsc = malloc(sizeof(*vout_rsc));
+ if (unlikely(vout_rsc == NULL))
+ return NULL;
+
+ vout_rsc->vout = vout;
+ return vout_rsc;
+}
+
+static inline void
+vout_resource_Add(struct vout_resource *vout_rsc, input_resource_t *resource)
+{
+ vlc_list_append(&vout_rsc->node, &resource->vout_rscs);
+}
+
+static inline vout_thread_t *
+vout_resource_Remove(struct vout_resource *vout_rsc)
+{
+ vlc_list_remove(&vout_rsc->node);
+ vout_thread_t *vout = vout_rsc->vout;
+ free(vout_rsc);
+
+ assert(vout);
+ return vout;
+}
+
/* */
static void DestroySout( input_resource_t *p_resource )
{
@@ -144,16 +192,17 @@ static sout_instance_t *RequestSout( input_resource_t *p_resource,
/* */
static void DestroyVout( input_resource_t *p_resource )
{
- assert( p_resource->i_vout == 0 || p_resource->p_vout_free == p_resource->pp_vout[0] );
+ assert( vlc_list_is_empty( &p_resource->vout_rscs )
+ || p_resource->vout_rsc_free == resource_GetFirstVoutRsc( p_resource ) );
- if( p_resource->p_vout_free )
+ if( p_resource->vout_rsc_free )
{
vlc_mutex_lock(&p_resource->lock_hold);
- TAB_REMOVE(p_resource->i_vout, p_resource->pp_vout, p_resource->p_vout_free);
+ vout_thread_t *vout = vout_resource_Remove( p_resource->vout_rsc_free );
vlc_mutex_unlock(&p_resource->lock_hold);
- vout_Close( p_resource->p_vout_free );
- p_resource->p_vout_free = NULL;
+ vout_Close( vout );
+ p_resource->vout_rsc_free = NULL;
}
}
@@ -282,6 +331,8 @@ input_resource_t *input_resource_New( vlc_object_t *p_parent )
return NULL;
}
+ vlc_list_init( &p_resource->vout_rscs );
+
vlc_atomic_rc_init( &p_resource->rc );
p_resource->p_parent = p_parent;
vlc_mutex_init( &p_resource->lock );
@@ -314,7 +365,8 @@ void input_resource_SetInput( input_resource_t *p_resource, input_thread_t *p_in
vlc_mutex_lock( &p_resource->lock );
if( p_resource->p_input && !p_input )
- assert( p_resource->i_vout == 0 || p_resource->p_vout_free == p_resource->pp_vout[0] );
+ assert( vlc_list_is_empty( &p_resource->vout_rscs )
+ || p_resource->vout_rsc_free == resource_GetFirstVoutRsc( p_resource ) );
/* */
p_resource->p_input = p_input;
@@ -326,28 +378,24 @@ static void input_resource_PutVoutLocked(input_resource_t *p_resource,
vout_thread_t *vout)
{
assert(vout != NULL);
- assert( p_resource->i_vout > 0 );
+ struct vout_resource *vout_rsc = resource_GetVoutRsc(p_resource, vout);
+ assert(vout_rsc != NULL);
- if (p_resource->pp_vout[0] == vout)
+ if (vout_rsc == resource_GetFirstVoutRsc(p_resource))
{
- assert(p_resource->p_vout_free == NULL || p_resource->p_vout_free == vout);
+ assert(p_resource->vout_rsc_free == NULL || p_resource->vout_rsc_free == vout_rsc);
+
msg_Dbg(p_resource->p_parent, "saving a free vout");
- p_resource->p_vout_free = vout;
+ p_resource->vout_rsc_free = vout_rsc;
}
else
{
msg_Dbg(p_resource->p_parent, "destroying vout (already one saved or active)");
-#ifndef NDEBUG
- {
- int index;
- TAB_FIND(p_resource->i_vout, p_resource->pp_vout, vout, index);
- assert(index >= 0);
- }
-#endif
vlc_mutex_lock(&p_resource->lock_hold);
- TAB_REMOVE(p_resource->i_vout, p_resource->pp_vout, vout);
+ vout_resource_Remove(vout_rsc);
vlc_mutex_unlock(&p_resource->lock_hold);
+
vout_Stop(vout);
vout_Close(vout);
}
@@ -367,26 +415,39 @@ vout_thread_t *input_resource_GetVoutDecoderDevice(input_resource_t *p_resource,
vlc_decoder_device **pp_dec_dev)
{
vout_thread_t *vout;
+ struct vout_resource *vout_rsc = NULL;
vlc_mutex_lock( &p_resource->lock );
if (cfg_vout == NULL) {
- cfg_vout = p_resource->p_vout_free;
- p_resource->p_vout_free = NULL;
+ if( p_resource->vout_rsc_free != NULL )
+ {
+ cfg_vout = p_resource->vout_rsc_free->vout;
+ p_resource->vout_rsc_free = NULL;
+ }
if (cfg_vout == NULL) {
/* Use the dummy vout as the parent of the future main vout. This
* will allow the future vout to inherit all parameters
* pre-configured on this dummy vout. */
- vlc_object_t *parent = p_resource->i_vout == 0 ?
+ vlc_object_t *parent = vlc_list_is_empty( &p_resource->vout_rscs ) ?
VLC_OBJECT(p_resource->p_vout_dummy) : p_resource->p_parent;
cfg_vout = vout = vout_Create(parent);
if (vout == NULL)
goto out;
+ vout_rsc = vout_resource_Create(vout);
+ if (vout_rsc == NULL)
+ {
+ vout_Close(vout);
+ cfg_vout = vout = NULL;
+ goto out;
+ }
+
+ *order = vlc_list_is_empty( &p_resource->vout_rscs ) ?
+ VLC_VOUT_ORDER_PRIMARY : VLC_VOUT_ORDER_SECONDARY;
+
vlc_mutex_lock(&p_resource->lock_hold);
- *order = p_resource->i_vout == 0 ? VLC_VOUT_ORDER_PRIMARY
- : VLC_VOUT_ORDER_SECONDARY;
- TAB_APPEND(p_resource->i_vout, p_resource->pp_vout, vout);
+ vout_resource_Add(vout_rsc, p_resource);
vlc_mutex_unlock(&p_resource->lock_hold);
} else
{
@@ -397,26 +458,19 @@ vout_thread_t *input_resource_GetVoutDecoderDevice(input_resource_t *p_resource,
}
else
{
- assert(p_resource->i_vout > 0);
- *order = p_resource->pp_vout[0] == cfg_vout ? VLC_VOUT_ORDER_PRIMARY
- : VLC_VOUT_ORDER_SECONDARY;
- /* the caller is going to reuse the free vout, it's not free anymore */
- if (p_resource->p_vout_free == cfg_vout)
- p_resource->p_vout_free = NULL;
- }
+ vout_rsc = resource_GetVoutRsc(p_resource, cfg_vout);
+ assert(vout_rsc != NULL);
-#ifndef NDEBUG
- {
- int index;
- TAB_FIND(p_resource->i_vout, p_resource->pp_vout, cfg_vout, index );
- assert(index >= 0);
+ *order = resource_GetFirstVoutRsc( p_resource ) == vout_rsc ?
+ VLC_VOUT_ORDER_PRIMARY : VLC_VOUT_ORDER_SECONDARY;
+
+ /* the caller is going to reuse the free vout, it's not free anymore */
+ if (p_resource->vout_rsc_free == vout_rsc)
+ p_resource->vout_rsc_free = NULL;
}
-#endif
if (pp_dec_dev)
- {
*pp_dec_dev = vout_GetDevice(cfg_vout);
- }
vout = cfg_vout;
@@ -453,7 +507,8 @@ vout_thread_t *input_resource_HoldVout( input_resource_t *p_resource )
{
vlc_mutex_lock( &p_resource->lock_hold );
- vout_thread_t *p_vout = p_resource->i_vout > 0 ? p_resource->pp_vout[0] : NULL;
+ struct vout_resource *vout_rsc = resource_GetFirstVoutRsc( p_resource );
+ vout_thread_t *p_vout = vout_rsc != NULL ? vout_rsc->vout : NULL;
if( p_vout )
vout_Hold(p_vout);
@@ -477,21 +532,24 @@ void input_resource_HoldVouts( input_resource_t *p_resource, vout_thread_t ***pp
vlc_mutex_lock( &p_resource->lock_hold );
- if( p_resource->i_vout <= 0 )
+ if( vlc_list_is_empty( &p_resource->vout_rscs ) )
goto exit;
- pp_vout = vlc_alloc( p_resource->i_vout, sizeof(*pp_vout) );
+ size_t count = 0;
+ struct vout_resource *vout_rsc;
+ vlc_list_foreach( vout_rsc, &p_resource->vout_rscs, node )
+ count ++;
+
+ pp_vout = vlc_alloc( count, sizeof(*pp_vout) );
if( !pp_vout )
goto exit;
*ppp_vout = pp_vout;
- *pi_vout = p_resource->i_vout;
+ *pi_vout = count;;
- for( int i = 0; i < p_resource->i_vout; i++ )
- {
- pp_vout[i] = p_resource->pp_vout[i];
- vout_Hold(pp_vout[i]);
- }
+ count = 0;
+ vlc_list_foreach( vout_rsc, &p_resource->vout_rscs, node )
+ pp_vout[count++] = vout_Hold( vout_rsc->vout );
exit:
vlc_mutex_unlock( &p_resource->lock_hold );
@@ -500,10 +558,10 @@ exit:
void input_resource_StopFreeVout(input_resource_t *p_resource)
{
vlc_mutex_lock(&p_resource->lock);
- if (p_resource->p_vout_free != NULL)
+ if (p_resource->vout_rsc_free != NULL)
{
- msg_Dbg(p_resource->p_vout_free, "stop free vout");
- vout_Stop(p_resource->p_vout_free);
+ msg_Dbg(p_resource->vout_rsc_free->vout, "stop free vout");
+ vout_Stop(p_resource->vout_rsc_free->vout);
}
vlc_mutex_unlock(&p_resource->lock);
}
--
2.20.1
More information about the vlc-devel
mailing list