[vlc-devel] [PATCH 2/2] Make decklink input/output modules build on OSX

Jean-Baptiste Kempf jb at videolan.org
Thu Sep 6 22:44:24 CEST 2018


This is not the correct way, sorry:
- either you patch the SDK when building the contribs 
- or you add this header next to the decklink.cpp file and include with ../

Btw, some features already exist, like dup_wchar_to_utf8 that is exactly FromWide() from vlc_charset.h
and related functions.


On Thu, 6 Sep 2018, at 22:16, Devin Heitmueller wrote:
> The Decklink SDK has platform-specific implementations for various
> calls which return strings.  Add some portability macros to
> properly handle those calls and then normalize the result down to
> a C char * as we would typically see in VLC.
> 
> Signed-off-by: Devin Heitmueller <dheitmueller at ltnglobal.com>
> ---
>  configure.ac                            |  3 ++
>  include/vlc_decklink.h                  | 65 +++++++++++++++++++++++++++++++++
>  modules/access/decklink.cpp             | 33 +++++++++++++----
>  modules/stream_out/sdi/DBMSDIOutput.cpp | 11 +++++-
>  modules/stream_out/sdi/DBMSDIOutput.hpp |  3 +-
>  modules/video_output/decklink.cpp       | 19 +++++++---
>  6 files changed, 117 insertions(+), 17 deletions(-)
>  create mode 100644 include/vlc_decklink.h
> 
> diff --git a/configure.ac b/configure.ac
> index 9700ec121e..43ab9ec31b 100644
> --- a/configure.ac
> +++ b/configure.ac
> @@ -1903,6 +1903,9 @@ then
>    AC_LANG_PUSH(C++)
>    AC_CHECK_HEADERS(DeckLinkAPIDispatch.cpp, [
>        have_decklink=yes
> +      AS_IF([test "${SYS}" = "darwin"], [
> +        VLC_ADD_LIBS([decklink decklinkoutput],[-Wl,-
> framework,CoreFoundation])
> +      ])
>    ], [
>        AC_MSG_WARN(Blackmagic DeckLink SDI include files not found, 
> decklink disabled)
>    ])
> diff --git a/include/vlc_decklink.h b/include/vlc_decklink.h
> new file mode 100644
> index 0000000000..846ab43a68
> --- /dev/null
> +++ b/include/vlc_decklink.h
> @@ -0,0 +1,65 @@
> +/
> *****************************************************************************
> + * vlc_decklink.h: Decklink Common includes
> + 
> *****************************************************************************
> + * Copyright (C) 2018 LTN Global Communications
> + *
> + * Authors: Devin Heitmueller <dheitmueller at ltnglobal.com>
> + *
> + * This program is free software; you can redistribute it and/or modify 
> it
> + * under the terms of the GNU Lesser General Public License as 
> published by
> + * the Free Software Foundation; either version 2.1 of the License, or
> + * (at your option) any later version.
> + *
> + * This program is distributed in the hope that it will be useful,
> + * but WITHOUT ANY WARRANTY; without even the implied warranty of
> + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
> + * GNU Lesser General Public License for more details.
> + *
> + * You should have received a copy of the GNU Lesser General Public 
> License
> + * along with this program; if not, write to the Free Software 
> Foundation,
> + * Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
> + 
> *****************************************************************************/
> +
> +#ifndef VLC_DECKLINK_H
> +#define VLC_DECKLINK_H 1
> +
> +/**
> + * \file
> + * This file defines Decklink portability macros and other functions
> + */
> +
> +#include <DeckLinkAPI.h>
> +
> +/* Portability code to deal with differences how the Blackmagic SDK
> +   handles strings on various platforms */
> +#ifdef _WIN32
> +static char *dup_wchar_to_utf8(wchar_t *w)
> +{
> +    char *s = NULL;
> +    int l = WideCharToMultiByte(CP_UTF8, 0, w, -1, 0, 0, 0, 0);
> +    s = (char *) av_malloc(l);
> +    if (s)
> +        WideCharToMultiByte(CP_UTF8, 0, w, -1, s, l, 0, 0);
> +    return s;
> +}
> +#define DECKLINK_STR    OLECHAR *
> +#define DECKLINK_STRDUP dup_wchar_to_utf8
> +#define DECKLINK_FREE(s) SysFreeString(s)
> +#elif defined(__APPLE__)
> +static char *dup_cfstring_to_utf8(CFStringRef w)
> +{
> +    char s[256];
> +    CFStringGetCString(w, s, 255, kCFStringEncodingUTF8);
> +    return strdup(s);
> +}
> +#define DECKLINK_STR    const __CFString *
> +#define DECKLINK_STRDUP dup_cfstring_to_utf8
> +#define DECKLINK_FREE(s) CFRelease(s)
> +#else
> +#define DECKLINK_STR    const char *
> +#define DECKLINK_STRDUP strdup
> +#define DECKLINK_FREE(s) free((void *) s)
> +#endif
> +
> +#endif /* VLC_DECKLINK_H */
> +
> diff --git a/modules/access/decklink.cpp b/modules/access/decklink.cpp
> index 2412750c31..6d1c1364d3 100644
> --- a/modules/access/decklink.cpp
> +++ b/modules/access/decklink.cpp
> @@ -29,12 +29,12 @@
>  #include <vlc_common.h>
>  #include <vlc_plugin.h>
>  #include <vlc_demux.h>
> +#include <vlc_decklink.h>
>  
>  #ifdef HAVE_ARPA_INET_H
>  #include <arpa/inet.h>
>  #endif
>  
> -#include <DeckLinkAPI.h>
>  #include <DeckLinkAPIDispatch.cpp>
>  
>  #include "sdi.h"
> @@ -260,11 +260,17 @@ public:
>          if( !(events & bmdVideoInputDisplayModeChanged ))
>              return S_OK;
>  
> -        const char *mode_name;
> -        if (mode->GetName(&mode_name) != S_OK)
> -            mode_name = "unknown";
> +        DECKLINK_STR tmp_name;
> +        char *mode_name;
> +        if (mode->GetName(&tmp_name) != S_OK) {
> +            mode_name = strdup("unknown");
> +        } else {
> +            mode_name = DECKLINK_STRDUP(tmp_name);
> +            DECKLINK_STRDUP(tmp_name);
> +        }
>  
>          msg_Dbg(demux_, "Video input format changed to %s", mode_name);
> +        free(mode_name);
>          if (!sys->autodetect) {
>              msg_Err(demux_, "Video format detection disabled");
>              return S_OK;
> @@ -531,11 +537,17 @@ static int Open(vlc_object_t *p_this)
>          }
>      }
>  
> -    const char *model_name;
> -    if (sys->card->GetModelName(&model_name) != S_OK)
> -        model_name = "unknown";
> +    DECKLINK_STR tmp_name;
> +    char *model_name;
> +    if (sys->card->GetModelName(&tmp_name) != S_OK) {
> +        model_name = strdup("unknown");
> +    } else {
> +        model_name = DECKLINK_STRDUP(tmp_name);
> +        DECKLINK_FREE(tmp_name);
> +    }
>  
>      msg_Dbg(demux, "Opened DeckLink PCI card %d (%s)", card_index, model_name);
> +    free(model_name);
>  
>      if (sys->card->QueryInterface(IID_IDeckLinkInput, (void**)&sys-
> >input) != S_OK) {
>          msg_Err(demux, "Card has no inputs");
> @@ -612,9 +624,14 @@ static int Open(vlc_object_t *p_this)
>          uint32_t field_flags;
>          const char *field = GetFieldDominance(m->GetFieldDominance(), 
> &field_flags);
>          BMDDisplayMode id = ntohl(m->GetDisplayMode());
> +        DECKLINK_STR tmp_name;
>  
> -        if (m->GetName(&mode_name) != S_OK)
> +        if (m->GetName(&tmp_name) != S_OK) {
>              mode_name = "unknown";
> +        } else {
> +            mode_name = DECKLINK_STRDUP(tmp_name);
> +            DECKLINK_FREE(tmp_name);
> +        }
>          if (m->GetFrameRate(&frame_duration, &time_scale) != S_OK) {
>              time_scale = 0;
>              frame_duration = 1;
> diff --git a/modules/stream_out/sdi/DBMSDIOutput.cpp b/modules/
> stream_out/sdi/DBMSDIOutput.cpp
> index 0818e4fc03..785d391c9b 100644
> --- a/modules/stream_out/sdi/DBMSDIOutput.cpp
> +++ b/modules/stream_out/sdi/DBMSDIOutput.cpp
> @@ -107,11 +107,15 @@ IDeckLinkDisplayMode * 
> DBMSDIOutput::MatchDisplayMode(const video_format_t *fmt,
>                  BMDTimeValue frameduration;
>                  BMDTimeScale timescale;
>                  const char *psz_mode_name;
> +                DECKLINK_STR tmp_name;
>  
>                  if(p_mode->GetFrameRate(&frameduration, &timescale) == 
> S_OK &&
> -                        p_mode->GetName(&psz_mode_name) == S_OK)
> +                        p_mode->GetName(&tmp_name) == S_OK)
>                  {
>                      BMDDisplayMode modenl = htonl(mode_id);
> +                    psz_mode_name = DECKLINK_STRDUP(tmp_name);
> +                    DECKLINK_FREE(tmp_name);
> +
>                      if(i==0)
>                      {
>                          BMDFieldDominance field = htonl(p_mode-
> >GetFieldDominance());
> @@ -239,9 +243,12 @@ int DBMSDIOutput::Open()
>          CHECK("Card not found");
>      }
>  
> +    DECKLINK_STR tmp_name;
>      const char *psz_model_name;
> -    result = p_card->GetModelName(&psz_model_name);
> +    result = p_card->GetModelName(&tmp_name);
>      CHECK("Unknown model name");
> +    psz_model_name = DECKLINK_STRDUP(tmp_name);
> +    DECKLINK_FREE(tmp_name);
>  
>      msg_Dbg(p_stream, "Opened DeckLink PCI card %s", psz_model_name);
>  
> diff --git a/modules/stream_out/sdi/DBMSDIOutput.hpp b/modules/
> stream_out/sdi/DBMSDIOutput.hpp
> index 13a65fd29f..42ae69638b 100644
> --- a/modules/stream_out/sdi/DBMSDIOutput.hpp
> +++ b/modules/stream_out/sdi/DBMSDIOutput.hpp
> @@ -24,8 +24,7 @@
>  #include "SDIOutput.hpp"
>  
>  #include <vlc_es.h>
> -
> -#include <DeckLinkAPI.h>
> +#include <vlc_decklink.h>
>  
>  namespace sdi_sout
>  {
> diff --git a/modules/video_output/decklink.cpp b/modules/video_output/
> decklink.cpp
> index 3e6a291b7a..9e7cea72c7 100644
> --- a/modules/video_output/decklink.cpp
> +++ b/modules/video_output/decklink.cpp
> @@ -43,11 +43,11 @@
>  #include <vlc_block.h>
>  #include <vlc_image.h>
>  #include <vlc_aout.h>
> +#include <vlc_decklink.h>
>  #ifdef HAVE_ARPA_INET_H
>  #include <arpa/inet.h>
>  #endif
>  
> -#include <DeckLinkAPI.h>
>  #include <DeckLinkAPIDispatch.cpp>
>  
>  #define FRAME_SIZE 1920
> @@ -490,12 +490,16 @@ static IDeckLinkDisplayMode * 
> MatchDisplayMode(vout_display_t *vd,
>                  BMDDisplayMode mode_id = p_mode->GetDisplayMode();
>                  BMDTimeValue frameduration;
>                  BMDTimeScale timescale;
> -                const char *psz_mode_name;
> +                char *psz_mode_name;
>  
> +                DECKLINK_STR tmp_name;
>                  if(p_mode->GetFrameRate(&frameduration, &timescale) == 
> S_OK &&
> -                        p_mode->GetName(&psz_mode_name) == S_OK)
> +                        p_mode->GetName(&tmp_name) == S_OK)
>                  {
>                      BMDDisplayMode modenl = htonl(mode_id);
> +                    psz_mode_name = DECKLINK_STRDUP(tmp_name);
> +                    DECKLINK_FREE(tmp_name);
> +
>                      if(i==0)
>                      {
>                          BMDFieldDominance field = htonl(p_mode-
> >GetFieldDominance());
> @@ -506,6 +510,7 @@ static IDeckLinkDisplayMode * 
> MatchDisplayMode(vout_display_t *vd,
>                                  double(timescale) / frameduration,
>                                  timescale, frameduration);
>                      }
> +		    free(psz_mode_name);
>                  }
>                  else
>                  {
> @@ -620,11 +625,15 @@ static int OpenDecklink(vout_display_t *vd, 
> decklink_sys_t *sys)
>          CHECK("Card not found");
>      }
>  
> -    const char *psz_model_name;
> -    result = p_card->GetModelName(&psz_model_name);
> +    DECKLINK_STR tmp_name;
> +    char *psz_model_name;
> +    result = p_card->GetModelName(&tmp_name);
>      CHECK("Unknown model name");
> +    psz_model_name = DECKLINK_STRDUP(tmp_name);
> +    DECKLINK_FREE(tmp_name);
>  
>      msg_Dbg(vd, "Opened DeckLink PCI card %s", psz_model_name);
> +    free(psz_model_name);
>  
>      /* Read attributes */
>  
> -- 
> 2.13.2
> 
> _______________________________________________
> vlc-devel mailing list
> To unsubscribe or modify your subscription options:
> https://mailman.videolan.org/listinfo/vlc-devel


-- 
Jean-Baptiste Kempf -  President
+33 672 704 734


More information about the vlc-devel mailing list