[vlc-devel] [PATCHv3 04/12] resource: handle vlc_renderer

Thomas Guillem thomas at gllm.fr
Tue Mar 29 15:06:35 CEST 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.
---
 src/input/resource.c | 112 +++++++++++++++++++++++++++++++++++++++++++++++++++
 src/input/resource.h |  12 ++++++
 2 files changed, 124 insertions(+)

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..a185eba 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 );
@@ -65,4 +70,11 @@ void input_resource_Terminate( input_resource_t * );
  */
 input_resource_t *input_resource_Hold( 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
-- 
2.8.0.rc3



More information about the vlc-devel mailing list