[vlc-commits] vout: decklink: unify sys

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


vlc | branch: master | Francois Cartegnie <fcvlcdev at free.fr> | Tue Nov 29 11:52:23 2016 +0100| [3ef8c0993f3d241ec39f8771e7d6a70f06a6f418] | committer: Francois Cartegnie

vout: decklink: unify sys

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

 modules/video_output/decklink.cpp | 220 ++++++++++++++++++--------------------
 1 file changed, 107 insertions(+), 113 deletions(-)

diff --git a/modules/video_output/decklink.cpp b/modules/video_output/decklink.cpp
index e160cfb..20a440f 100644
--- a/modules/video_output/decklink.cpp
+++ b/modules/video_output/decklink.cpp
@@ -176,20 +176,12 @@ static const char * const rgsz_ar_text[] = {
 };
 static_assert(ARRAY_SIZE(rgi_ar_values) == ARRAY_SIZE(rgsz_ar_text), "afd arrays messed up");
 
-struct vout_display_sys_t
-{
-    picture_pool_t *pool;
-    bool tenbits;
-    uint8_t afd, ar;
-    int nosignal_delay;
-    picture_t *pic_nosignal;
-};
-
 /* Only one audio output module and one video output module
  * can be used per process.
  * We use a static mutex in audio/video submodules entry points.  */
-struct decklink_sys_t
+typedef struct decklink_sys_t
 {
+    /* With LOCK */
     IDeckLinkOutput *p_output;
 
     /*
@@ -209,7 +201,19 @@ struct decklink_sys_t
 
     /* XXX: workaround card clock drift */
     mtime_t offset;
-};
+
+    /* !With LOCK */
+
+    /* single video module exclusive */
+    struct
+    {
+        picture_pool_t *pool;
+        bool tenbits;
+        uint8_t afd, ar;
+        int nosignal_delay;
+        picture_t *pic_nosignal;
+    } video;
+} decklink_sys_t;
 
 /*****************************************************************************
  * Local prototypes.
@@ -515,9 +519,8 @@ static IDeckLinkDisplayMode * MatchDisplayMode(vout_display_t *vd,
     return p_selected;
 }
 
-static int OpenDecklink(vout_display_t *vd, struct decklink_sys_t *decklink_sys)
+static int OpenDecklink(vout_display_t *vd, decklink_sys_t *sys)
 {
-    vout_display_sys_t *sys = vd->sys;
     video_format_t *fmt = &vd->fmt;
 #define CHECK(message) do { \
     if (result != S_OK) \
@@ -539,12 +542,12 @@ static int OpenDecklink(vout_display_t *vd, struct decklink_sys_t *decklink_sys)
     IDeckLink *p_card = NULL;
     BMDDisplayMode wanted_mode_id = bmdDisplayModeNotSupported;
 
-    vlc_mutex_lock(&decklink_sys->lock);
+    vlc_mutex_lock(&sys->lock);
 
     /* wait until aout is ready */
     msg_Info(vd, "Waiting for DeckLink audio input module to start");
-    while (decklink_sys->i_rate == -1)
-        vlc_cond_wait(&decklink_sys->cond, &decklink_sys->lock);
+    while (sys->i_rate == -1)
+        vlc_cond_wait(&sys->cond, &sys->lock);
 
     int i_card_index = var_InheritInteger(vd, CFG_PREFIX "card-index");
     char *mode = var_InheritString(vd, VIDEO_CFG_PREFIX "mode");
@@ -601,7 +604,7 @@ static int OpenDecklink(vout_display_t *vd, struct decklink_sys_t *decklink_sys)
     CHECK("Could not get BMDDeckLinkVideoOutputConnections");
 
     result = p_card->QueryInterface(IID_IDeckLinkOutput,
-        (void**)&decklink_sys->p_output);
+        (void**)&sys->p_output);
     CHECK("No outputs");
 
     result = p_card->QueryInterface(IID_IDeckLinkConfiguration,
@@ -620,7 +623,7 @@ static int OpenDecklink(vout_display_t *vd, struct decklink_sys_t *decklink_sys)
     result = p_config->SetInt(bmdDeckLinkConfigVideoOutputConnection, (BMDVideoConnection) vconn);
     CHECK("Could not set video output connection");
 
-    p_display_mode = MatchDisplayMode(vd, decklink_sys->p_output,
+    p_display_mode = MatchDisplayMode(vd, sys->p_output,
                                           fmt, wanted_mode_id);
     if(p_display_mode == NULL)
     {
@@ -644,8 +647,8 @@ static int OpenDecklink(vout_display_t *vd, struct decklink_sys_t *decklink_sys)
         BMDDisplayModeSupport support;
         IDeckLinkDisplayMode *resultMode;
 
-        result = decklink_sys->p_output->DoesSupportVideoMode(mode_id,
-                                                              sys->tenbits ? bmdFormat10BitYUV : bmdFormat8BitYUV,
+        result = sys->p_output->DoesSupportVideoMode(mode_id,
+                                                              sys->video.tenbits ? bmdFormat10BitYUV : bmdFormat8BitYUV,
                                                               flags, &support, &resultMode);
         CHECK("Does not support video mode");
         if (support == bmdDisplayModeNotSupported)
@@ -660,11 +663,11 @@ static int OpenDecklink(vout_display_t *vd, struct decklink_sys_t *decklink_sys)
              goto error;
         }
 
-        result = p_display_mode->GetFrameRate(&decklink_sys->frameduration,
-                                              &decklink_sys->timescale);
+        result = p_display_mode->GetFrameRate(&sys->frameduration,
+                                              &sys->timescale);
         CHECK("Could not read frame rate");
 
-        result = decklink_sys->p_output->EnableVideoOutput(mode_id, flags);
+        result = sys->p_output->EnableVideoOutput(mode_id, flags);
         CHECK("Could not enable video output");
 
         fmt->i_width = fmt->i_visible_width = p_display_mode->GetWidth();
@@ -673,15 +676,15 @@ static int OpenDecklink(vout_display_t *vd, struct decklink_sys_t *decklink_sys)
         fmt->i_y_offset = 0;
         fmt->i_sar_num = 0;
         fmt->i_sar_den = 0;
-        fmt->i_chroma = !sys->tenbits ? VLC_CODEC_UYVY : VLC_CODEC_I422_10L; /* we will convert to v210 */
-        fmt->i_frame_rate = (unsigned) decklink_sys->frameduration;
-        fmt->i_frame_rate_base = (unsigned) decklink_sys->timescale;
+        fmt->i_chroma = !sys->video.tenbits ? VLC_CODEC_UYVY : VLC_CODEC_I422_10L; /* we will convert to v210 */
+        fmt->i_frame_rate = (unsigned) sys->frameduration;
+        fmt->i_frame_rate_base = (unsigned) sys->timescale;
     }
 
-    if (/*decklink_sys->i_channels > 0 &&*/ decklink_sys->i_rate > 0)
+    if (/*decklink_sys->i_channels > 0 &&*/ sys->i_rate > 0)
     {
-        result = decklink_sys->p_output->EnableAudioOutput(
-            decklink_sys->i_rate,
+        result = sys->p_output->EnableAudioOutput(
+            sys->i_rate,
             bmdAudioSampleType16bitInteger,
             /*decklink_sys->i_channels*/ 2,
             bmdAudioOutputStreamTimestamped);
@@ -689,8 +692,8 @@ static int OpenDecklink(vout_display_t *vd, struct decklink_sys_t *decklink_sys)
     }
 
     /* start */
-    result = decklink_sys->p_output->StartScheduledPlayback(
-        (mdate() * decklink_sys->timescale) / CLOCK_FREQ, decklink_sys->timescale, 1.0);
+    result = sys->p_output->StartScheduledPlayback(
+        (mdate() * sys->timescale) / CLOCK_FREQ, sys->timescale, 1.0);
     CHECK("Could not start playback");
 
     p_config->Release();
@@ -699,16 +702,16 @@ static int OpenDecklink(vout_display_t *vd, struct decklink_sys_t *decklink_sys)
     p_attributes->Release();
     decklink_iterator->Release();
 
-    vlc_mutex_unlock(&decklink_sys->lock);
+    vlc_mutex_unlock(&sys->lock);
 
     vout_display_DeleteWindow(vd, NULL);
 
     return VLC_SUCCESS;
 
 error:
-    if (decklink_sys->p_output) {
-        decklink_sys->p_output->Release();
-        decklink_sys->p_output = NULL;
+    if (sys->p_output) {
+        sys->p_output->Release();
+        sys->p_output = NULL;
     }
     if (p_card)
         p_card->Release();
@@ -721,7 +724,7 @@ error:
     if (p_display_mode)
         p_display_mode->Release();
 
-    vlc_mutex_unlock(&decklink_sys->lock);
+    vlc_mutex_unlock(&sys->lock);
 
     return VLC_EGENERIC;
 #undef CHECK
@@ -733,10 +736,10 @@ error:
 
 static picture_pool_t *PoolVideo(vout_display_t *vd, unsigned requested_count)
 {
-    vout_display_sys_t *sys = vd->sys;
-    if (!sys->pool)
-        sys->pool = picture_pool_NewFromFormat(&vd->fmt, requested_count);
-    return sys->pool;
+    struct decklink_sys_t *sys = (struct decklink_sys_t *) vd->sys;
+    if (!sys->video.pool)
+        sys->video.pool = picture_pool_NewFromFormat(&vd->fmt, requested_count);
+    return sys->video.pool;
 }
 
 static inline void put_le32(uint8_t **p, uint32_t d)
@@ -860,8 +863,7 @@ static void send_AFD(uint8_t afdcode, uint8_t ar, uint8_t *buf)
 
 static void PrepareVideo(vout_display_t *vd, picture_t *picture, subpicture_t *)
 {
-    vout_display_sys_t *sys = vd->sys;
-    struct decklink_sys_t *decklink_sys = GetDLSys(VLC_OBJECT(vd));
+    decklink_sys_t *sys = (decklink_sys_t *) vd->sys;
     mtime_t now = mdate();
 
     if (!picture)
@@ -869,12 +871,12 @@ static void PrepareVideo(vout_display_t *vd, picture_t *picture, subpicture_t *)
 
     picture_t *orig_picture = picture;
 
-    if (now - picture->date > sys->nosignal_delay * CLOCK_FREQ) {
+    if (now - picture->date > sys->video.nosignal_delay * CLOCK_FREQ) {
         msg_Dbg(vd, "no signal");
-        if (sys->pic_nosignal) {
-            picture = sys->pic_nosignal;
+        if (sys->video.pic_nosignal) {
+            picture = sys->video.pic_nosignal;
         } else {
-            if (sys->tenbits) { // I422_10L
+            if (sys->video.tenbits) { // I422_10L
                 plane_t *y = &picture->p[0];
                 memset(y->p_pixels, 0x0, y->i_lines * y->i_pitch);
                 for (int i = 1; i < picture->i_planes; i++) {
@@ -901,8 +903,8 @@ static void PrepareVideo(vout_display_t *vd, picture_t *picture, subpicture_t *)
     h = vd->fmt.i_height;
 
     IDeckLinkMutableVideoFrame *pDLVideoFrame;
-    result = decklink_sys->p_output->CreateVideoFrame(w, h, w*3,
-        sys->tenbits ? bmdFormat10BitYUV : bmdFormat8BitYUV,
+    result = sys->p_output->CreateVideoFrame(w, h, w*3,
+        sys->video.tenbits ? bmdFormat10BitYUV : bmdFormat8BitYUV,
         bmdFrameFlagDefault, &pDLVideoFrame);
 
     if (result != S_OK) {
@@ -915,13 +917,13 @@ static void PrepareVideo(vout_display_t *vd, picture_t *picture, subpicture_t *)
     pDLVideoFrame->GetBytes((void**)&frame_bytes);
     stride = pDLVideoFrame->GetRowBytes();
 
-    if (sys->tenbits) {
+    if (sys->video.tenbits) {
         IDeckLinkVideoFrameAncillary *vanc;
         int line;
         void *buf;
 
-        result = decklink_sys->p_output->CreateAncillaryData(
-                sys->tenbits ? bmdFormat10BitYUV : bmdFormat8BitYUV, &vanc);
+        result = sys->p_output->CreateAncillaryData(
+                sys->video.tenbits ? bmdFormat10BitYUV : bmdFormat8BitYUV, &vanc);
         if (result != S_OK) {
             msg_Err(vd, "Failed to create vanc: %d", result);
             goto end;
@@ -933,7 +935,7 @@ static void PrepareVideo(vout_display_t *vd, picture_t *picture, subpicture_t *)
             msg_Err(vd, "Failed to get VBI line %d: %d", line, result);
             goto end;
         }
-        send_AFD(vd->sys->afd, vd->sys->ar, (uint8_t*)buf);
+        send_AFD(sys->video.afd, sys->video.ar, (uint8_t*)buf);
 
         v210_convert(frame_bytes, picture, stride);
 
@@ -953,10 +955,10 @@ static void PrepareVideo(vout_display_t *vd, picture_t *picture, subpicture_t *)
 
 
     // compute frame duration in CLOCK_FREQ units
-    length = (decklink_sys->frameduration * CLOCK_FREQ) / decklink_sys->timescale;
+    length = (sys->frameduration * CLOCK_FREQ) / sys->timescale;
 
-    picture->date -= decklink_sys->offset;
-    result = decklink_sys->p_output->ScheduleVideoFrame(pDLVideoFrame,
+    picture->date -= sys->offset;
+    result = sys->p_output->ScheduleVideoFrame(pDLVideoFrame,
         picture->date, length, CLOCK_FREQ);
 
     if (result != S_OK) {
@@ -965,16 +967,16 @@ static void PrepareVideo(vout_display_t *vd, picture_t *picture, subpicture_t *)
         goto end;
     }
 
-    now = mdate() - decklink_sys->offset;
+    now = mdate() - sys->offset;
 
     BMDTimeValue decklink_now;
     double speed;
-    decklink_sys->p_output->GetScheduledStreamTime (CLOCK_FREQ, &decklink_now, &speed);
+    sys->p_output->GetScheduledStreamTime (CLOCK_FREQ, &decklink_now, &speed);
 
     if ((now - decklink_now) > 400000) {
         /* XXX: workaround card clock drift */
-        decklink_sys->offset += 50000;
-        msg_Err(vd, "Delaying: offset now %" PRId64, decklink_sys->offset);
+        sys->offset += 50000;
+        msg_Err(vd, "Delaying: offset now %" PRId64, sys->offset);
     }
 
 end:
@@ -996,27 +998,20 @@ 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;
-    video_format_t *fmt = &vd->fmt;
-    vout_display_sys_t *sys;
-    struct decklink_sys_t *decklink_sys = GetDLSys(p_this, true);
-    if(!decklink_sys)
+    decklink_sys_t *sys = GetDLSys(p_this, true);
+    if(!sys)
         return VLC_ENOMEM;
 
-    vd->sys = sys = (vout_display_sys_t*)malloc(sizeof(*sys));
-    if (!sys)
-    {
-        ReleaseDLSys(p_this);
-        return VLC_ENOMEM;
-    }
+    vd->sys = (vout_display_sys_t*) sys;
 
-    sys->tenbits = var_InheritBool(p_this, VIDEO_CFG_PREFIX "tenbits");
-    sys->nosignal_delay = var_InheritInteger(p_this, VIDEO_CFG_PREFIX "nosignal-delay");
-    sys->afd = var_InheritInteger(p_this, VIDEO_CFG_PREFIX "afd");
-    sys->ar = var_InheritInteger(p_this, VIDEO_CFG_PREFIX "ar");
-    sys->pic_nosignal = NULL;
-    sys->pool = NULL;
+    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;
 
-    if (OpenDecklink(vd, decklink_sys) != VLC_SUCCESS)
+    if (OpenDecklink(vd, sys) != VLC_SUCCESS)
     {
         CloseVideo(p_this);
         return VLC_EGENERIC;
@@ -1025,8 +1020,8 @@ static int OpenVideo(vlc_object_t *p_this)
     char *pic_file = var_InheritString(p_this, VIDEO_CFG_PREFIX "nosignal-image");
     if (pic_file)
     {
-        sys->pic_nosignal = CreateNoSignalPicture(p_this, &vd->fmt, pic_file);
-        if (!sys->pic_nosignal)
+        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);
     }
@@ -1044,22 +1039,20 @@ 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;
-    vout_display_sys_t *sys = vd->sys;
+    decklink_sys_t *sys = (decklink_sys_t *) vd->sys;
 
-    if (sys->pool)
+    if (sys->video.pool)
     {
-        picture_pool_Release(sys->pool);
-        sys->pool = NULL;
+        picture_pool_Release(sys->video.pool);
+        sys->video.pool = NULL;
     }
 
-    if (sys->pic_nosignal)
+    if (sys->video.pic_nosignal)
     {
-        picture_Release(sys->pic_nosignal);
-        sys->pic_nosignal = NULL;
+        picture_Release(sys->video.pic_nosignal);
+        sys->video.pic_nosignal = NULL;
     }
 
-    free(sys);
-
     ReleaseDLSys(p_this);
 }
 
@@ -1069,18 +1062,18 @@ static void CloseVideo(vlc_object_t *p_this)
 
 static void Flush (audio_output_t *aout, bool drain)
 {
-    struct decklink_sys_t *decklink_sys = GetDLSys(VLC_OBJECT(aout));
-    vlc_mutex_lock(&decklink_sys->lock);
-    IDeckLinkOutput *p_output = decklink_sys->p_output;
-    vlc_mutex_unlock(&decklink_sys->lock);
+    decklink_sys_t *sys = (decklink_sys_t *) aout->sys;
+    vlc_mutex_lock(&sys->lock);
+    IDeckLinkOutput *p_output = sys->p_output;
+    vlc_mutex_unlock(&sys->lock);
     if (!p_output)
         return;
 
     if (drain) {
         uint32_t samples;
-        decklink_sys->p_output->GetBufferedAudioSampleFrameCount(&samples);
-        msleep(CLOCK_FREQ * samples / decklink_sys->i_rate);
-    } else if (decklink_sys->p_output->FlushBufferedAudioSamples() == E_FAIL)
+        sys->p_output->GetBufferedAudioSampleFrameCount(&samples);
+        msleep(CLOCK_FREQ * samples / sys->i_rate);
+    } else if (sys->p_output->FlushBufferedAudioSamples() == E_FAIL)
         msg_Err(aout, "Flush failed");
 }
 
@@ -1092,15 +1085,15 @@ static int TimeGet(audio_output_t *, mtime_t* restrict)
 
 static int Start(audio_output_t *aout, audio_sample_format_t *restrict fmt)
 {
-    struct decklink_sys_t *decklink_sys = GetDLSys(VLC_OBJECT(aout));
+    decklink_sys_t *sys = (decklink_sys_t *) aout->sys;
 
-    if (decklink_sys->i_rate == 0)
+    if (sys->i_rate == 0)
         return VLC_EGENERIC;
 
     fmt->i_format = VLC_CODEC_S16N;
     fmt->i_channels = 2; //decklink_sys->i_channels;
     fmt->i_physical_channels = AOUT_CHANS_STEREO; //pi_channels_maps[fmt->i_channels];
-    fmt->i_rate = decklink_sys->i_rate;
+    fmt->i_rate = sys->i_rate;
     fmt->i_bitspersample = 16;
     fmt->i_blockalign = fmt->i_channels * fmt->i_bitspersample /8 ;
     fmt->i_frame_length  = FRAME_SIZE;
@@ -1110,20 +1103,19 @@ static int Start(audio_output_t *aout, audio_sample_format_t *restrict fmt)
 
 static void PlayAudio(audio_output_t *aout, block_t *audio)
 {
-    struct decklink_sys_t *decklink_sys = GetDLSys(VLC_OBJECT(aout));
-    vlc_mutex_lock(&decklink_sys->lock);
-    IDeckLinkOutput *p_output = decklink_sys->p_output;
-    vlc_mutex_unlock(&decklink_sys->lock);
+    decklink_sys_t *sys = (decklink_sys_t *) aout->sys;
+    vlc_mutex_lock(&sys->lock);
+    IDeckLinkOutput *p_output = sys->p_output;
+    audio->i_pts -= sys->offset;
+    vlc_mutex_unlock(&sys->lock);
     if (!p_output) {
         block_Release(audio);
         return;
     }
 
-    audio->i_pts -= decklink_sys->offset;
-
     uint32_t sampleFrameCount = audio->i_buffer / (2 * 2 /*decklink_sys->i_channels*/);
     uint32_t written;
-    HRESULT result = decklink_sys->p_output->ScheduleAudioSamples(
+    HRESULT result = p_output->ScheduleAudioSamples(
             audio->p_buffer, sampleFrameCount, audio->i_pts, CLOCK_FREQ, &written);
 
     if (result != S_OK)
@@ -1137,15 +1129,17 @@ 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;
-    struct decklink_sys_t *decklink_sys = GetDLSys(p_this, true);
-    if(!decklink_sys)
+    decklink_sys_t *sys = GetDLSys(p_this, true);
+    if(!sys)
         return VLC_ENOMEM;
 
-    vlc_mutex_lock(&decklink_sys->lock);
+    aout->sys = (aout_sys_t *) sys;
+
+    vlc_mutex_lock(&sys->lock);
     //decklink_sys->i_channels = var_InheritInteger(vd, AUDIO_CFG_PREFIX "audio-channels");
-    decklink_sys->i_rate = var_InheritInteger(aout, AUDIO_CFG_PREFIX "audio-rate");
-    vlc_cond_signal(&decklink_sys->cond);
-    vlc_mutex_unlock(&decklink_sys->lock);
+    sys->i_rate = var_InheritInteger(aout, AUDIO_CFG_PREFIX "audio-rate");
+    vlc_cond_signal(&sys->cond);
+    vlc_mutex_unlock(&sys->lock);
 
     aout->play      = PlayAudio;
     aout->start     = Start;
@@ -1162,8 +1156,8 @@ static int OpenAudio(vlc_object_t *p_this)
 
 static void CloseAudio(vlc_object_t *p_this)
 {
-    struct decklink_sys_t *decklink_sys = GetDLSys(p_this);
-    vlc_mutex_lock(&decklink_sys->lock);
-    vlc_mutex_unlock(&decklink_sys->lock);
+    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);
 }



More information about the vlc-commits mailing list