[vlc-devel] [RFC PATCHv2 3/6] resource: handle vlc_renderer

Thomas Guillem thomas at gllm.fr
Wed Mar 2 15:58:21 CET 2016


Like sout instance, a vlc_renderer instance is owned by input_resource and
requested from the input thread.

When requested with the "renderer" option, a previous renderer can be re-used
if the option is the same. Then, the vlc_renderer will be configured with the
input_thread of the input_resource.
---
 include/vlc_input.h  |   7 ++++
 src/input/resource.c | 112 +++++++++++++++++++++++++++++++++++++++++++++++++++
 src/input/resource.h |   5 +++
 src/libvlccore.sym   |   1 +
 4 files changed, 125 insertions(+)

diff --git a/include/vlc_input.h b/include/vlc_input.h
index 0bda6d4..daf7025 100644
--- a/include/vlc_input.h
+++ b/include/vlc_input.h
@@ -699,5 +699,12 @@ VLC_API void input_resource_PutAout( input_resource_t *, audio_output_t * );
  */
 VLC_API void input_resource_ResetAout( input_resource_t * );
 
+/**
+ * \return the current renderer if any.
+ *
+ * Use vlc_object_release() to drop the reference.
+ */
+vlc_renderer *input_resource_HoldRenderer( input_resource_t *p_resource );
+
 /** @} */
 #endif
diff --git a/src/input/resource.c b/src/input/resource.c
index 0021cec..675e445 100644
--- a/src/input/resource.c
+++ b/src/input/resource.c
@@ -36,6 +36,7 @@
 #include <vlc_spu.h>
 #include <vlc_aout.h>
 #include <vlc_sout.h>
+#include <vlc_renderer.h>
 #include "../libvlc.h"
 #include "../stream_output/stream_output.h"
 #include "../audio_output/aout_internal.h"
@@ -57,6 +58,8 @@ struct input_resource_t
     input_thread_t *p_input;
 
     sout_instance_t *p_sout;
+    vlc_renderer    *p_renderer;
+    vlc_renderer    *p_renderer_free;
     vout_thread_t   *p_vout_free;
 
     /* This lock is used to protect vout resources access (for hold)
@@ -137,6 +140,79 @@ static sout_instance_t *RequestSout( input_resource_t *p_resource,
 #endif
 }
 
+static void DestroyRenderer( input_resource_t *p_resource )
+{
+    if( p_resource->p_renderer_free )
+        vlc_object_release( p_resource->p_renderer_free );
+    p_resource->p_renderer_free = NULL;
+}
+
+static vlc_renderer *RequestRenderer( input_resource_t *p_resource,
+                                      vlc_renderer *p_renderer,
+                                      const char *psz_renderer )
+{
+    if( !p_renderer && !psz_renderer )
+    {
+        if( p_resource->p_renderer_free )
+            msg_Dbg( p_resource->p_renderer_free, "destroying useless renderer" );
+        DestroyRenderer( p_resource );
+        return NULL;
+    }
+
+    assert( !p_renderer || ( !p_resource->p_renderer_free && !psz_renderer ) );
+
+    /* Check the validity of the renderer */
+    if( p_resource->p_renderer_free &&
+        !vlc_renderer_equals( p_resource->p_renderer_free, psz_renderer ) )
+    {
+        msg_Dbg( p_resource->p_parent, "destroying unusable renderer" );
+        DestroyRenderer( p_resource );
+    }
+
+    if( psz_renderer )
+    {
+        if( p_resource->p_renderer_free )
+        {
+            /* Reuse it */
+            msg_Dbg( p_resource->p_parent, "reusing renderer" );
+
+            p_renderer = p_resource->p_renderer_free;
+            p_resource->p_renderer_free = NULL;
+        }
+        else
+        {
+            /* Create a new one */
+            p_renderer = vlc_renderer_new( p_resource->p_parent, psz_renderer );
+            if( !p_renderer )
+                return NULL;
+        }
+        if( p_resource->p_input
+         && vlc_renderer_set_input( p_renderer, p_resource->p_input ) )
+        {
+            msg_Warn( p_resource->p_parent, "vlc_renderer_set_input failed" );
+            vlc_object_release( p_renderer );
+            return NULL;
+        }
+        vlc_mutex_lock( &p_resource->lock_hold );
+        p_resource->p_renderer = p_renderer;
+        vlc_mutex_unlock( &p_resource->lock_hold );
+        return p_renderer;
+    }
+    else
+    {
+        if( p_resource->p_input
+         && vlc_renderer_set_input( p_renderer, NULL ) )
+            msg_Warn( p_resource->p_parent, "vlc_renderer_set_input failed");
+
+        p_resource->p_renderer_free = p_renderer;
+
+        vlc_mutex_lock( &p_resource->lock_hold );
+        p_resource->p_renderer = NULL;
+        vlc_mutex_unlock( &p_resource->lock_hold );
+        return NULL;
+    }
+}
+
 /* */
 static void DestroyVout( input_resource_t *p_resource )
 {
@@ -428,6 +504,7 @@ void input_resource_Release( input_resource_t *p_resource )
         return;
 
     DestroySout( p_resource );
+    DestroyRenderer( p_resource );
     DestroyVout( p_resource );
     if( p_resource->p_aout != NULL )
         aout_Destroy( p_resource->p_aout );
@@ -448,7 +525,11 @@ 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 );
+        /* renderer must be released before */
+        assert( p_resource->p_renderer == NULL );
+    }
 
     /* */
     p_resource->p_input = p_input;
@@ -506,9 +587,40 @@ void input_resource_TerminateSout( input_resource_t *p_resource )
     input_resource_RequestSout( p_resource, NULL, NULL );
 }
 
+/* */
+vlc_renderer *input_resource_RequestRenderer( input_resource_t *p_resource,
+                                              vlc_renderer *p_renderer,
+                                              const char *psz_renderer )
+{
+    vlc_mutex_lock( &p_resource->lock );
+    vlc_renderer *p_ret = RequestRenderer( p_resource, p_renderer, psz_renderer );
+    vlc_mutex_unlock( &p_resource->lock );
+
+    return p_ret;
+}
+
+vlc_renderer *input_resource_HoldRenderer( input_resource_t *p_resource )
+{
+    vlc_renderer *p_renderer;
+
+    vlc_mutex_lock( &p_resource->lock_hold );
+    p_renderer = p_resource->p_renderer;
+    if( p_renderer != NULL )
+        vlc_object_hold( p_renderer );
+    vlc_mutex_unlock( &p_resource->lock_hold );
+
+    return p_renderer;
+}
+
+static void input_resource_TerminateRenderer( input_resource_t *p_resource )
+{
+    input_resource_RequestRenderer( p_resource, NULL, NULL );
+}
+
 void input_resource_Terminate( input_resource_t *p_resource )
 {
     input_resource_TerminateSout( p_resource );
+    input_resource_TerminateRenderer( p_resource );
     input_resource_ResetAout( p_resource );
     input_resource_TerminateVout( p_resource );
 }
diff --git a/src/input/resource.h b/src/input/resource.h
index 4c24c74..1f0b871 100644
--- a/src/input/resource.h
+++ b/src/input/resource.h
@@ -37,6 +37,11 @@ void input_resource_SetInput( input_resource_t *, input_thread_t * );
 sout_instance_t *input_resource_RequestSout( input_resource_t *, sout_instance_t *, const char *psz_sout );
 
 /**
+ * This function handles renderer request.
+ */
+vlc_renderer *input_resource_RequestRenderer( input_resource_t *, vlc_renderer *, const char *psz_renderer );
+
+/**
  * This function handles vout request.
  */
 vout_thread_t *input_resource_RequestVout( input_resource_t *, vout_thread_t *, video_format_t *, unsigned dpb_size, bool b_recycle );
diff --git a/src/libvlccore.sym b/src/libvlccore.sym
index 572e293..412b09b 100644
--- a/src/libvlccore.sym
+++ b/src/libvlccore.sym
@@ -216,6 +216,7 @@ input_resource_GetAout
 input_resource_HoldAout
 input_resource_PutAout
 input_resource_ResetAout
+input_resource_HoldRenderer
 input_Start
 input_Stop
 input_vaControl
-- 
2.7.0



More information about the vlc-devel mailing list