[vlc-devel] [PATCH 2/2] Make decklink input/output modules build on OSX
Devin Heitmueller
dheitmueller at ltnglobal.com
Thu Sep 6 22:16:07 CEST 2018
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, ×cale) == 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, ×cale) == 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
More information about the vlc-devel
mailing list