[vlc-commits] vout: decklink: fix restart handling

Francois Cartegnie git at videolan.org
Tue Nov 29 16:16:46 CET 2016


vlc | branch: master | Francois Cartegnie <fcvlcdev at free.fr> | Tue Nov 29 14:23:33 2016 +0100| [89c7023526acc60e3078dd5315d24c7621ce55d9] | committer: Francois Cartegnie

vout: decklink: fix restart handling

now can properly handle multiple items

> http://git.videolan.org/gitweb.cgi/vlc.git/?a=commit;h=89c7023526acc60e3078dd5315d24c7621ce55d9
---

 modules/video_output/decklink.cpp | 127 +++++++++++++++++++++++---------------
 1 file changed, 77 insertions(+), 50 deletions(-)

diff --git a/modules/video_output/decklink.cpp b/modules/video_output/decklink.cpp
index 20a440f..17fff71 100644
--- a/modules/video_output/decklink.cpp
+++ b/modules/video_output/decklink.cpp
@@ -192,6 +192,8 @@ typedef struct decklink_sys_t
     vlc_mutex_t lock;
     vlc_cond_t cond;
     uint8_t users;
+    bool    b_videomodule;
+    bool    b_recycling;
 
     //int i_channels;
     int i_rate;
@@ -207,6 +209,7 @@ typedef struct decklink_sys_t
     /* single video module exclusive */
     struct
     {
+        video_format_t currentfmt;
         picture_pool_t *pool;
         bool tenbits;
         uint8_t afd, ar;
@@ -280,21 +283,38 @@ vlc_module_end ()
 /* Protects decklink_sys_t creation/deletion */
 static vlc_mutex_t sys_lock = VLC_STATIC_MUTEX;
 
-static struct decklink_sys_t *GetDLSys(vlc_object_t *obj, bool b_hold = false)
+static decklink_sys_t *HoldDLSys(vlc_object_t *obj, int i_cat)
 {
     vlc_object_t *libvlc = VLC_OBJECT(obj->obj.libvlc);
-    struct decklink_sys_t *sys;
+    decklink_sys_t *sys;
 
     vlc_mutex_lock(&sys_lock);
 
     if (var_Type(libvlc, "decklink-sys") == VLC_VAR_ADDRESS)
-        sys = (struct decklink_sys_t*)var_GetAddress(libvlc, "decklink-sys");
-    else {
-        sys = (struct decklink_sys_t*)malloc(sizeof(*sys));
+    {
+        sys = (decklink_sys_t*)var_GetAddress(libvlc, "decklink-sys");
+        sys->users++;
+
+        if(i_cat == VIDEO_ES)
+        {
+            while(sys->b_videomodule)
+            {
+                vlc_mutex_unlock(&sys_lock);
+                msg_Info(obj, "Waiting for previous vout module to exit");
+                msleep(CLOCK_FREQ / 10);
+                vlc_mutex_lock(&sys_lock);
+            }
+        }
+    }
+    else
+    {
+        sys = (decklink_sys_t*)malloc(sizeof(*sys));
         if (sys) {
             sys->p_output = NULL;
             sys->offset = 0;
-            sys->users = 0;
+            sys->users = 1;
+            sys->b_videomodule = (i_cat == VIDEO_ES);
+            sys->b_recycling = false;
             sys->i_rate = var_InheritInteger(obj, AUDIO_CFG_PREFIX "audio-rate");
             if(sys->i_rate > 0)
                 sys->i_rate = -1;
@@ -305,14 +325,11 @@ static struct decklink_sys_t *GetDLSys(vlc_object_t *obj, bool b_hold = false)
         }
     }
 
-    if(sys && b_hold)
-        sys->users++;
-
     vlc_mutex_unlock(&sys_lock);
     return sys;
 }
 
-static void ReleaseDLSys(vlc_object_t *obj)
+static void ReleaseDLSys(vlc_object_t *obj, int i_cat)
 {
     vlc_object_t *libvlc = VLC_OBJECT(obj->obj.libvlc);
 
@@ -332,9 +349,21 @@ static void ReleaseDLSys(vlc_object_t *obj)
             sys->p_output->Release();
         }
 
+        /* Clean video specific */
+        if (sys->video.pool)
+            picture_pool_Release(sys->video.pool);
+        if (sys->video.pic_nosignal)
+            picture_Release(sys->video.pic_nosignal);
+        video_format_Clean(&sys->video.currentfmt);
+
         free(sys);
         var_Destroy(libvlc, "decklink-sys");
     }
+    else if (i_cat == VIDEO_ES)
+    {
+        sys->b_videomodule = false;
+        sys->b_recycling = true;
+    }
 
     vlc_mutex_unlock(&sys_lock);
 }
@@ -521,7 +550,6 @@ static IDeckLinkDisplayMode * MatchDisplayMode(vout_display_t *vd,
 
 static int OpenDecklink(vout_display_t *vd, decklink_sys_t *sys)
 {
-    video_format_t *fmt = &vd->fmt;
 #define CHECK(message) do { \
     if (result != S_OK) \
     { \
@@ -624,7 +652,7 @@ static int OpenDecklink(vout_display_t *vd, decklink_sys_t *sys)
     CHECK("Could not set video output connection");
 
     p_display_mode = MatchDisplayMode(vd, sys->p_output,
-                                          fmt, wanted_mode_id);
+                                          &vd->fmt, wanted_mode_id);
     if(p_display_mode == NULL)
     {
         msg_Err(vd, "Could not negociate a compatible display mode");
@@ -670,6 +698,8 @@ static int OpenDecklink(vout_display_t *vd, decklink_sys_t *sys)
         result = sys->p_output->EnableVideoOutput(mode_id, flags);
         CHECK("Could not enable video output");
 
+        video_format_t *fmt = &sys->video.currentfmt;
+        video_format_Copy(fmt, &vd->fmt);
         fmt->i_width = fmt->i_visible_width = p_display_mode->GetWidth();
         fmt->i_height = fmt->i_visible_height = p_display_mode->GetHeight();
         fmt->i_x_offset = 0;
@@ -869,8 +899,6 @@ static void PrepareVideo(vout_display_t *vd, picture_t *picture, subpicture_t *)
     if (!picture)
         return;
 
-    picture_t *orig_picture = picture;
-
     if (now - picture->date > sys->video.nosignal_delay * CLOCK_FREQ) {
         msg_Dbg(vd, "no signal");
         if (sys->video.pic_nosignal) {
@@ -998,33 +1026,47 @@ static int ControlVideo(vout_display_t *vd, int query, va_list args)
 static int OpenVideo(vlc_object_t *p_this)
 {
     vout_display_t *vd = (vout_display_t *)p_this;
-    decklink_sys_t *sys = GetDLSys(p_this, true);
+    decklink_sys_t *sys = HoldDLSys(p_this, VIDEO_ES);
     if(!sys)
         return VLC_ENOMEM;
 
     vd->sys = (vout_display_sys_t*) sys;
 
-    sys->video.tenbits = var_InheritBool(p_this, VIDEO_CFG_PREFIX "tenbits");
-    sys->video.nosignal_delay = var_InheritInteger(p_this, VIDEO_CFG_PREFIX "nosignal-delay");
-    sys->video.afd = var_InheritInteger(p_this, VIDEO_CFG_PREFIX "afd");
-    sys->video.ar = var_InheritInteger(p_this, VIDEO_CFG_PREFIX "ar");
-    sys->video.pic_nosignal = NULL;
-    sys->video.pool = NULL;
+    bool b_init;
+    vlc_mutex_lock(&sys->lock);
+    b_init = !sys->b_recycling;
+    vlc_mutex_unlock(&sys->lock);
 
-    if (OpenDecklink(vd, sys) != VLC_SUCCESS)
+    if( b_init )
     {
-        CloseVideo(p_this);
-        return VLC_EGENERIC;
-    }
+        sys->video.tenbits = var_InheritBool(p_this, VIDEO_CFG_PREFIX "tenbits");
+        sys->video.nosignal_delay = var_InheritInteger(p_this, VIDEO_CFG_PREFIX "nosignal-delay");
+        sys->video.afd = var_InheritInteger(p_this, VIDEO_CFG_PREFIX "afd");
+        sys->video.ar = var_InheritInteger(p_this, VIDEO_CFG_PREFIX "ar");
+        sys->video.pic_nosignal = NULL;
+        sys->video.pool = NULL;
+        video_format_Init( &sys->video.currentfmt, 0 );
 
-    char *pic_file = var_InheritString(p_this, VIDEO_CFG_PREFIX "nosignal-image");
-    if (pic_file)
-    {
-        sys->video.pic_nosignal = CreateNoSignalPicture(p_this, &vd->fmt, pic_file);
-        if (!sys->video.pic_nosignal)
-            msg_Err(p_this, "Could not create no signal picture");
-        free(pic_file);
+        if (OpenDecklink(vd, sys) != VLC_SUCCESS)
+        {
+            CloseVideo(p_this);
+            return VLC_EGENERIC;
+        }
+
+        char *pic_file = var_InheritString(p_this, VIDEO_CFG_PREFIX "nosignal-image");
+        if (pic_file)
+        {
+            sys->video.pic_nosignal = CreateNoSignalPicture(p_this, &vd->fmt, pic_file);
+            if (!sys->video.pic_nosignal)
+                msg_Err(p_this, "Could not create no signal picture");
+            free(pic_file);
+        }
     }
+
+    /* vout must adapt */
+    video_format_Clean( &vd->fmt );
+    video_format_Copy( &vd->fmt, &sys->video.currentfmt );
+
     vd->info.has_hide_mouse = true;
     vd->pool    = PoolVideo;
     vd->prepare = PrepareVideo;
@@ -1038,22 +1080,7 @@ static int OpenVideo(vlc_object_t *p_this)
 
 static void CloseVideo(vlc_object_t *p_this)
 {
-    vout_display_t *vd = (vout_display_t *)p_this;
-    decklink_sys_t *sys = (decklink_sys_t *) vd->sys;
-
-    if (sys->video.pool)
-    {
-        picture_pool_Release(sys->video.pool);
-        sys->video.pool = NULL;
-    }
-
-    if (sys->video.pic_nosignal)
-    {
-        picture_Release(sys->video.pic_nosignal);
-        sys->video.pic_nosignal = NULL;
-    }
-
-    ReleaseDLSys(p_this);
+    ReleaseDLSys(p_this, VIDEO_ES);
 }
 
 /*****************************************************************************
@@ -1129,7 +1156,7 @@ static void PlayAudio(audio_output_t *aout, block_t *audio)
 static int OpenAudio(vlc_object_t *p_this)
 {
     audio_output_t *aout = (audio_output_t *)p_this;
-    decklink_sys_t *sys = GetDLSys(p_this, true);
+    decklink_sys_t *sys = HoldDLSys(p_this, AUDIO_ES);
     if(!sys)
         return VLC_ENOMEM;
 
@@ -1159,5 +1186,5 @@ static void CloseAudio(vlc_object_t *p_this)
     decklink_sys_t *sys = (decklink_sys_t *) ((audio_output_t *)p_this)->sys;
     vlc_mutex_lock(&sys->lock);
     vlc_mutex_unlock(&sys->lock);
-    ReleaseDLSys(p_this);
+    ReleaseDLSys(p_this, AUDIO_ES);
 }



More information about the vlc-commits mailing list