[vlc-commits] [Git][videolan/vlc][master] 14 commits: sout: sdi: replace <mutex> with vlc_mutex_t
Hugo Beauzée-Luyssen (@chouquette)
gitlab at videolan.org
Mon Dec 6 14:39:47 UTC 2021
Hugo Beauzée-Luyssen pushed to branch master at VideoLAN / VLC
Commits:
e0872532 by Steve Lhomme at 2021-12-06T12:58:11+00:00
sout: sdi: replace <mutex> with vlc_mutex_t
<mutex> is not available with gcc for mingw64
- - - - -
10150dcb by Steve Lhomme at 2021-12-06T12:58:11+00:00
contrib: add the Decklink SDK headers
The official SDK has headers with Boost License which is MIT-like and GPLv2 compatible.
Co-authored-by: Marvin Scholz <epirat07 at gmail.com>
- - - - -
a3f4baad by Steve Lhomme at 2021-12-06T12:58:11+00:00
configure: fix decklink detection
DeckLinkAPIDispatch.cpp is not available on Windows.
DeckLinkAPI.h is available on all supported platforms.
Allow decklink SDK from the contribs if --with-decklink-sdk is not used.
Co-authored-by: Marvin Scholz <epirat07 at gmail.com>
- - - - -
9f8068f6 by Steve Lhomme at 2021-12-06T12:58:11+00:00
sdi: out: fix missing STDMETHODCALLTYPE for IDeckLinkVideoOutputCallback methods
The SDK has this modifier. I was not in some older SDKs.
- - - - -
9168091a by Steve Lhomme at 2021-12-06T12:58:11+00:00
decklink: fix compilation on Windows
DeckLinkAPIDispatch.cpp doesn't exist on Windows and CreateDeckLinkIteratorInstance()
too. Instead we should use CoCreateInstance().
The strings are BSTR.
Use the proper enum values where appropriate.
Some types are different between Windows and Linux/macOS.
- - - - -
a63a5257 by Steve Lhomme at 2021-12-06T12:58:11+00:00
decklink: fix enum to string conversions
- - - - -
793353f5 by Steve Lhomme at 2021-12-06T12:58:11+00:00
decklink: fix HRESULT printing
- - - - -
e76393e5 by Steve Lhomme at 2021-12-06T12:58:11+00:00
sout: sdi: fix timescale/frameduration logging
* On Windows they are LONGLONG and PRId64 is "lld".
* On Linux/macOS they are int64_t and should use PRId64 as well.
- - - - -
2544aa8b by Steve Lhomme at 2021-12-06T12:58:11+00:00
sout: sdi: fix reading the output mode string
- - - - -
268acdd5 by Steve Lhomme at 2021-12-06T12:58:11+00:00
vout: decklink: fix reading the output mode string
- - - - -
bec5eaac by Steve Lhomme at 2021-12-06T12:58:11+00:00
sout: sdi: remove checks on impossible bmdVideoConnectionUnspecified
getVConn() never returns bmdVideoConnectionUnspecified which is 0 but it
returns bmdVideoConnectionSDI by default.
- - - - -
2ecc9cf1 by Steve Lhomme at 2021-12-06T12:58:11+00:00
sout: sdi: fix DECKLINK_STRDUP output leaks
- - - - -
e726ac2c by Steve Lhomme at 2021-12-06T12:58:11+00:00
decklink: link with the proper necessary libraries on each OS
Windows: LIBCOM
Linux: -lpthread and $(LIBDL) (pthread_once and dlopen)
Mac: None (pthread_once is part of libc)
- - - - -
b1e3ca3b by Steve Lhomme at 2021-12-06T12:58:11+00:00
sout: sdi: use the proper CPPFLAGS and LIBS for that target
The CPPFLAGS were already defined for stream_out_sdi but not the LIBS.
- - - - -
15 changed files:
- configure.ac
- + contrib/src/decklink/rules.mak
- modules/access/Makefile.am
- modules/access/decklink.cpp
- modules/access/vlc_decklink.h
- modules/stream_out/Makefile.am
- modules/stream_out/sdi/AES3Audio.cpp
- modules/stream_out/sdi/AES3Audio.hpp
- modules/stream_out/sdi/DBMHelper.cpp
- modules/stream_out/sdi/DBMSDIOutput.cpp
- modules/stream_out/sdi/DBMSDIOutput.hpp
- modules/stream_out/sdi/SDIStream.cpp
- modules/stream_out/sdi/SDIStream.hpp
- modules/video_output/Makefile.am
- modules/video_output/decklink.cpp
Changes:
=====================================
configure.ac
=====================================
@@ -2100,14 +2100,17 @@ then
if test "${with_decklink_sdk}" != "no" -a -n "${with_decklink_sdk}"
then
VLC_ADD_CPPFLAGS([decklink decklinkoutput stream_out_sdi],[-I${with_decklink_sdk}/include])
+ elif test -d "${CONTRIB_DIR}/include/decklink"
+ then
+ VLC_ADD_CPPFLAGS([decklink decklinkoutput stream_out_sdi],[-I${CONTRIB_DIR}/include/decklink])
fi
VLC_SAVE_FLAGS
CPPFLAGS="${CPPFLAGS} ${CPPFLAGS_decklink}"
AC_LANG_PUSH([C++])
- AC_CHECK_HEADERS([DeckLinkAPIDispatch.cpp], [
+ AC_CHECK_HEADERS([DeckLinkAPI.h], [
have_decklink=yes
AS_IF([test "${SYS}" = "darwin"], [
- VLC_ADD_LIBS([decklink decklinkoutput],[-Wl,-framework,CoreFoundation])
+ VLC_ADD_LIBS([decklink decklinkoutput stream_out_sdi],[-Wl,-framework,CoreFoundation])
])
], [
AS_IF([test "${enable_decklink}" = "yes"], [
=====================================
contrib/src/decklink/rules.mak
=====================================
@@ -0,0 +1,38 @@
+# decklink OSS version
+DECKLINK_VERSION := 1977bf76bb5bde80d171373cf8d80dd01161679b
+DECKLINK_GITURL := https://gitlab.com/robUx4/decklink-oss.git
+
+# enable build on supported platforms
+ifdef HAVE_LINUX
+PKGS += decklink
+endif
+ifdef HAVE_MACOSX
+PKGS += decklink
+endif
+ifdef HAVE_WIN32
+PKGS += decklink
+endif
+
+$(TARBALLS)/decklink-$(DECKLINK_VERSION).tar.xz:
+ $(call download_git,$(DECKLINK_GITURL),,$(DECKLINK_VERSION))
+
+.sum-decklink: $(TARBALLS)/decklink-$(DECKLINK_VERSION).tar.xz
+ $(call check_githash,$(DECKLINK_VERSION))
+ touch $@
+
+decklink: decklink-$(DECKLINK_VERSION).tar.xz .sum-decklink
+ $(UNPACK)
+ $(MOVE)
+
+.decklink: decklink
+ mkdir -p -- "$(PREFIX)/include/"
+ifdef HAVE_LINUX
+ cp -R $</Linux/include/ "$(PREFIX)/include/decklink/"
+else ifdef HAVE_MACOSX
+ cp -R $</Mac/include/ "$(PREFIX)/include/decklink/"
+else ifdef HAVE_WIN32
+ cp -R $</Win/include/ "$(PREFIX)/include/decklink/"
+else
+ $(error Decklink SDK contrib not implemented for your OS!)
+endif
+ touch $@
=====================================
modules/access/Makefile.am
=====================================
@@ -127,7 +127,13 @@ EXTRA_LTLIBRARIES += liblinsys_hdsdi_plugin.la liblinsys_sdi_plugin.la
libdecklink_plugin_la_SOURCES = access/decklink.cpp access/sdi.c access/sdi.h access/vlc_decklink.h
libdecklink_plugin_la_CXXFLAGS = $(AM_CXXFLAGS) $(CPPFLAGS_decklink)
-libdecklink_plugin_la_LIBADD = $(LIBS_decklink) $(LIBDL) -lpthread
+libdecklink_plugin_la_LIBADD = $(LIBS_decklink)
+if HAVE_WIN32
+libdecklink_plugin_la_LIBADD += $(LIBCOM)
+endif
+if HAVE_LINUX
+libdecklink_plugin_la_LIBADD += $(LIBDL) -lpthread
+endif
if HAVE_DECKLINK
access_LTLIBRARIES += libdecklink_plugin.la
endif
=====================================
modules/access/decklink.cpp
=====================================
@@ -40,7 +40,9 @@
#endif
#include "vlc_decklink.h"
+#ifndef _WIN32
#include <DeckLinkAPIDispatch.cpp>
+#endif
#include <DeckLinkAPIVersion.h>
#if BLACKMAGIC_DECKLINK_API_VERSION < 0x0b010000
#define IID_IDeckLinkProfileAttributes IID_IDeckLinkAttributes
@@ -152,7 +154,11 @@ struct demux_sys_t
IDeckLinkConfiguration *config;
IDeckLinkProfileAttributes *attributes;
+#ifdef _WIN32
+ BOOL autodetect;
+#else
bool autodetect;
+#endif
es_out_id_t *video_es;
es_format_t video_fmt;
@@ -620,7 +626,7 @@ static int Open(vlc_object_t *p_this)
char str[4];
} u;
- u.id = 0;
+ u.id = bmdModeUnknown;
char *mode;
mode = var_CreateGetNonEmptyString(demux, "decklink-mode");
@@ -631,7 +637,7 @@ static int Open(vlc_object_t *p_this)
msg_Dbg(demux, "Card supports input format detection");
flags |= bmdVideoInputEnableFormatDetection;
/* Enable a random format, we will reconfigure on format detection */
- u.id = htonl(bmdModeHD1080p2997);
+ u.id = bmdModeHD1080p2997;
} else {
if (!mode || strlen(mode) < 3 || strlen(mode) > 4) {
msg_Err(demux, "Invalid mode: \'%s\'", mode ? mode : "");
@@ -656,7 +662,11 @@ static int Open(vlc_object_t *p_this)
BMDTimeValue frame_duration, time_scale;
uint32_t field_flags;
const char *field = GetFieldDominance(m->GetFieldDominance(), &field_flags);
- BMDDisplayMode id = ntohl(m->GetDisplayMode());
+ union {
+ BMDDisplayMode id;
+ char str[4];
+ } mode;
+ mode.id = m->GetDisplayMode();
if (m->GetName(&tmp_name) != S_OK) {
mode_name = "unknown";
@@ -670,11 +680,11 @@ static int Open(vlc_object_t *p_this)
}
msg_Dbg(demux, "Found mode '%4.4s': %s (%dx%d, %.3f fps%s)",
- (char*)&id, mode_name,
+ mode.str, mode_name,
(int)m->GetWidth(), (int)m->GetHeight(),
double(time_scale) / frame_duration, field);
- if (u.id == id) {
+ if (u.id == mode.id) {
sys->video_fmt = GetModeSettings(demux, m, bmdDetectedVideoInputYCbCr422);
msg_Dbg(demux, "Using that mode");
}
@@ -683,11 +693,11 @@ static int Open(vlc_object_t *p_this)
mode_it->Release();
if (sys->video_fmt.video.i_width == 0) {
- msg_Err(demux, "Unknown video mode `%4.4s\' specified.", (char*)&u.id);
+ msg_Err(demux, "Unknown video mode `%4.4s\' specified.", u.str);
goto finish;
}
- if (sys->input->EnableVideoInput(htonl(u.id), fmt, flags) != S_OK) {
+ if (sys->input->EnableVideoInput(u.id, fmt, flags) != S_OK) {
msg_Err(demux, "Failed to enable video input");
goto finish;
}
@@ -716,7 +726,7 @@ static int Open(vlc_object_t *p_this)
}
rate = var_InheritInteger(demux, "decklink-audio-rate");
if (rate > 0 && sys->channels > 0) {
- if (sys->input->EnableAudioInput(rate, bmdAudioSampleType16bitInteger, sys->channels) != S_OK) {
+ if (sys->input->EnableAudioInput(BMDAudioSampleRate(rate), bmdAudioSampleType16bitInteger, sys->channels) != S_OK) {
msg_Err(demux, "Failed to enable audio input");
goto finish;
}
=====================================
modules/access/vlc_decklink.h
=====================================
@@ -28,6 +28,9 @@
* This file defines Decklink portability macros and other functions
*/
+#ifdef _WIN32
+#include <initguid.h>
+#endif
#include <DeckLinkAPI.h>
/* Portability code to deal with differences how the Blackmagic SDK
@@ -38,10 +41,28 @@
typedef CFStringRef decklink_str_t;
#define DECKLINK_STRDUP(s) FromCFString(s, kCFStringEncodingUTF8)
#define DECKLINK_FREE(s) CFRelease(s)
+#define PRIHR "X"
+#elif defined(_WIN32)
+#include <vlc_charset.h> // FromWide
+typedef BSTR decklink_str_t;
+#define DECKLINK_STRDUP(s) FromWide(s)
+#define DECKLINK_FREE(s) SysFreeString(s)
+#define PRIHR "lX"
+
+static inline IDeckLinkIterator *CreateDeckLinkIteratorInstance(void)
+{
+ IDeckLinkIterator *decklink_iterator;
+ if (SUCCEEDED(CoCreateInstance(CLSID_CDeckLinkIterator, nullptr, CLSCTX_ALL,
+ IID_PPV_ARGS (&decklink_iterator))))
+ return decklink_iterator;
+ return nullptr;
+}
+
#else
typedef const char* decklink_str_t;
-#define DECKLINK_STRDUP strdup
+#define DECKLINK_STRDUP(s) strdup(s)
#define DECKLINK_FREE(s) free((void *) s)
+#define PRIHR "X"
#endif
#endif /* VLC_DECKLINK_H */
=====================================
modules/stream_out/Makefile.am
=====================================
@@ -53,8 +53,14 @@ sout_LTLIBRARIES = \
libstream_out_udp_plugin.la
if HAVE_DECKLINK
-libstream_out_sdi_plugin_la_CXXFLAGS = $(AM_CXXFLAGS) $(CPPFLAGS_decklinkoutput)
-libstream_out_sdi_plugin_la_LIBADD = $(LIBS_decklink) $(LIBDL) -lpthread
+libstream_out_sdi_plugin_la_CXXFLAGS = $(AM_CXXFLAGS) $(CPPFLAGS_stream_out_sdi)
+libstream_out_sdi_plugin_la_LIBADD = $(LIBS_stream_out_sdi)
+if HAVE_WIN32
+libstream_out_sdi_plugin_la_LIBADD += $(LIBCOM)
+endif
+if HAVE_LINUX
+libstream_out_sdi_plugin_la_LIBADD += $(LIBDL) -lpthread
+endif
libstream_out_sdi_plugin_la_SOURCES = stream_out/sdi/sdiout.cpp \
stream_out/sdi/sdiout.hpp \
stream_out/sdi/Ancillary.cpp \
=====================================
modules/stream_out/sdi/AES3Audio.cpp
=====================================
@@ -31,6 +31,7 @@ using namespace sdi_sout;
AES3AudioBuffer::AES3AudioBuffer(vlc_object_t *p_obj, unsigned count)
{
obj = p_obj;
+ vlc_mutex_init(&bytestream_mutex);
setSubFramesCount(count);
block_BytestreamInit(&bytestream);
toconsume = 0;
@@ -49,9 +50,8 @@ void AES3AudioBuffer::setSubFramesCount(uint8_t c)
void AES3AudioBuffer::push(block_t *p_block)
{
- bytestream_mutex.lock();
+ vlc_mutex_locker locker(&bytestream_mutex);
block_BytestreamPush(&bytestream, p_block);
- bytestream_mutex.unlock();
}
unsigned AES3AudioBuffer::read(void *dstbuf, unsigned count, vlc_tick_t from,
@@ -92,7 +92,8 @@ unsigned AES3AudioBuffer::read(void *dstbuf, unsigned count, vlc_tick_t from,
assert(count + dstpad <= orig);
#endif
- bytestream_mutex.lock();
+ {
+ vlc_mutex_locker locker(&bytestream_mutex);
uint8_t *dst = reinterpret_cast<uint8_t *>(dstbuf);
for(unsigned i=0; i<count; i++)
{
@@ -107,7 +108,7 @@ unsigned AES3AudioBuffer::read(void *dstbuf, unsigned count, vlc_tick_t from,
if(dst)
block_PeekOffsetBytes(&bytestream, srcoffset, &dst[dstoffset], sizeof(uint16_t));
}
- bytestream_mutex.unlock();
+ }
return 0;
}
@@ -149,12 +150,13 @@ void AES3AudioBuffer::flushConsumed()
if(toconsume)
{
size_t bytes = FramesToBytes(toconsume);
- bytestream_mutex.lock();
+ {
+ vlc_mutex_locker locker(&bytestream_mutex);
if(block_SkipBytes(&bytestream, bytes) == VLC_SUCCESS)
block_BytestreamFlush(&bytestream);
else
block_BytestreamEmpty(&bytestream);
- bytestream_mutex.unlock();
+ }
#ifdef SDI_MULTIPLEX_DEBUG
msg_Dbg(obj, "%4.4s flushed off %zd -> pts %ld",
reinterpret_cast<const char *>(&i_codec),
@@ -219,11 +221,10 @@ vlc_fourcc_t AES3AudioBuffer::getCodec() const
vlc_tick_t AES3AudioBuffer::bufferStart() const
{
vlc_tick_t start = VLC_TICK_INVALID;
- bytestream_mutex.lock();
+ vlc_mutex_locker locker(&bytestream_mutex);
if(bytestream.p_block)
start = bytestream.p_block->i_pts +
FramesToDuration(BytesToFrames(bytestream.i_block_offset));
- bytestream_mutex.unlock();
return start;
}
@@ -233,10 +234,12 @@ unsigned AES3AudioBuffer::availableVirtualSamples(vlc_tick_t from) const
if(start == VLC_TICK_INVALID)
return 0;
- bytestream_mutex.lock();
+ unsigned samples;
+ {
+ vlc_mutex_locker locker(&bytestream_mutex);
/* FIXME */
- unsigned samples = BytesToFrames(block_BytestreamRemaining(&bytestream));
- bytestream_mutex.unlock();
+ samples = BytesToFrames(block_BytestreamRemaining(&bytestream));
+ }
int offset = OffsetToBufferStart(from);
if(offset > 0)
=====================================
modules/stream_out/sdi/AES3Audio.hpp
=====================================
@@ -23,7 +23,6 @@
#include <vlc_common.h>
#include <vlc_block.h>
#include <vlc_block_helper.h>
-#include <mutex>
#include <vlc_es.h>
#define MAX_AES3_AUDIO_FRAMES 8
@@ -69,7 +68,7 @@ namespace sdi_sout
unsigned BytesToFrames(size_t) const;
unsigned TicksDurationToFrames(vlc_tick_t) const;
block_bytestream_t bytestream;
- mutable std::mutex bytestream_mutex;
+ mutable vlc_mutex_t bytestream_mutex;
uint8_t buffersubframes;
unsigned toconsume;
vlc_fourcc_t i_codec;
=====================================
modules/stream_out/sdi/DBMHelper.cpp
=====================================
@@ -63,26 +63,35 @@ IDeckLinkDisplayMode * Helper::MatchDisplayMode(vlc_object_t *p_obj,
BMDDisplayMode mode_id = p_mode->GetDisplayMode();
BMDTimeValue frameduration;
BMDTimeScale timescale;
- const char *psz_mode_name;
+ char *psz_mode_name;
decklink_str_t tmp_name;
if(p_mode->GetFrameRate(&frameduration, ×cale) == S_OK &&
p_mode->GetName(&tmp_name) == S_OK)
{
- BMDDisplayMode modenl = htonl(mode_id);
+ union {
+ BMDDisplayMode id;
+ char str[4];
+ } mode;
+ mode.id = mode_id;
psz_mode_name = DECKLINK_STRDUP(tmp_name);
DECKLINK_FREE(tmp_name);
if(i==0)
{
- BMDFieldDominance field = htonl(p_mode->GetFieldDominance());
- msg_Dbg(p_obj, "Found mode '%4.4s': %s (%ldx%ld, %4.4s, %.3f fps, scale %ld dur %ld)",
- (const char*)&modenl, psz_mode_name,
+ union {
+ BMDFieldDominance id;
+ char str[4];
+ } field;
+ field.id = p_mode->GetFieldDominance();
+ msg_Dbg(p_obj, "Found mode '%4.4s': %s (%ldx%ld, %4.4s, %.3f fps, scale %" PRId64 " dur %" PRId64 ")",
+ mode.str, psz_mode_name,
p_mode->GetWidth(), p_mode->GetHeight(),
- (const char *)&field,
+ field.str,
double(timescale) / frameduration,
timescale, frameduration);
}
+ free(psz_mode_name);
}
else
{
@@ -92,8 +101,12 @@ IDeckLinkDisplayMode * Helper::MatchDisplayMode(vlc_object_t *p_obj,
if(forcedmode != bmdModeUnknown && unlikely(!p_selected))
{
- BMDDisplayMode modenl = htonl(forcedmode);
- msg_Dbg(p_obj, "Forced mode '%4.4s'", (char *)&modenl);
+ union {
+ BMDDisplayMode id;
+ char str[4];
+ } mode;
+ mode.id = forcedmode;
+ msg_Dbg(p_obj, "Forced mode '%4.4s'", mode.str);
if(forcedmode == mode_id)
p_selected = p_mode;
else
=====================================
modules/stream_out/sdi/DBMSDIOutput.cpp
=====================================
@@ -36,7 +36,9 @@
#include "Ancillary.hpp"
#include "V210.hpp"
+#ifndef _WIN32
#include <DeckLinkAPIDispatch.cpp>
+#endif
#include <DeckLinkAPIVersion.h>
#if BLACKMAGIC_DECKLINK_API_VERSION < 0x0b010000
#define IID_IDeckLinkProfileAttributes IID_IDeckLinkAttributes
@@ -124,7 +126,7 @@ AbstractStream *DBMSDIOutput::Add(const es_format_t *fmt)
if(psz_err)\
msg_Err(p_stream, message ": %s", psz_err); \
else \
- msg_Err(p_stream, message ": 0x%X", result); \
+ msg_Err(p_stream, message ":0x%" PRIHR, result); \
goto error; \
} \
} while(0)
@@ -152,7 +154,11 @@ HRESULT STDMETHODCALLTYPE DBMSDIOutput::ScheduledFrameCompleted
else if(result == bmdOutputFrameDisplayedLate)
msg_Warn(p_stream, "late frame");
+#ifdef _WIN32
+ BOOL b_active;
+#else
bool b_active;
+#endif
vlc_mutex_lock(&feeder.lock);
if((S_OK == p_output->IsScheduledPlaybackRunning(&b_active)) && b_active)
vlc_cond_signal(&feeder.cond);
@@ -198,13 +204,14 @@ int DBMSDIOutput::Open()
}
decklink_str_t tmp_name;
- const char *psz_model_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(p_stream, "Opened DeckLink PCI card %s", psz_model_name);
+ free(psz_model_name);
result = p_card->QueryInterface(IID_IDeckLinkOutput, (void**)&p_output);
CHECK("No outputs");
@@ -316,7 +323,11 @@ static BMDVideoConnection getVConn(const char *psz)
int DBMSDIOutput::ConfigureVideo(const video_format_t *vfmt)
{
HRESULT result;
- BMDDisplayMode wanted_mode_id = bmdModeUnknown;
+ union {
+ BMDDisplayMode id;
+ char str[4];
+ } wanted_mode;
+ wanted_mode.id = bmdModeUnknown;
IDeckLinkConfiguration *p_config = NULL;
IDeckLinkProfileAttributes *p_attributes = NULL;
IDeckLinkDisplayMode *p_display_mode = NULL;
@@ -356,9 +367,7 @@ int DBMSDIOutput::ConfigureVideo(const video_format_t *vfmt)
msg_Err(p_stream, "Invalid mode %s", psz_string);
goto error;
}
- memset(&wanted_mode_id, ' ', 4);
- strncpy((char*)&wanted_mode_id, psz_string, 4);
- wanted_mode_id = ntohl(wanted_mode_id);
+ strncpy(wanted_mode.str, psz_string, 4);
free(psz_string);
}
@@ -366,24 +375,24 @@ int DBMSDIOutput::ConfigureVideo(const video_format_t *vfmt)
result = p_card->QueryInterface(IID_IDeckLinkProfileAttributes, (void**)&p_attributes);
CHECK("Could not get IDeckLinkAttributes");
- int64_t vconn;
- result = p_attributes->GetInt(BMDDeckLinkVideoOutputConnections, &vconn); /* reads mask */
+#ifdef _WIN32
+ LONGLONG iconn;
+#else
+ int64_t iconn;
+#endif
+ BMDVideoConnection vconn;
+ result = p_attributes->GetInt(BMDDeckLinkVideoOutputConnections, &iconn); /* reads mask */
CHECK("Could not get BMDDeckLinkVideoOutputConnections");
psz_string = var_InheritString(p_stream, CFG_PREFIX "video-connection");
vconn = getVConn(psz_string);
free(psz_string);
- if (vconn == 0)
- {
- msg_Err(p_stream, "Invalid video connection specified");
- goto error;
- }
result = p_config->SetInt(bmdDeckLinkConfigVideoOutputConnection, vconn);
CHECK("Could not set video output connection");
p_display_mode = Decklink::Helper::MatchDisplayMode(VLC_OBJECT(p_stream),
- p_output, vfmt, wanted_mode_id);
+ p_output, vfmt, wanted_mode.id);
if(p_display_mode == NULL)
{
msg_Err(p_stream, "Could not negociate a compatible display mode");
@@ -391,22 +400,29 @@ int DBMSDIOutput::ConfigureVideo(const video_format_t *vfmt)
}
else
{
- BMDDisplayMode mode_id = p_display_mode->GetDisplayMode();
- BMDDisplayMode modenl = htonl(mode_id);
- msg_Dbg(p_stream, "Selected mode '%4.4s'", (char *) &modenl);
+ union {
+ BMDDisplayMode id;
+ char str[4];
+ } mode;
+ mode.id = p_display_mode->GetDisplayMode();
+ msg_Dbg(p_stream, "Selected mode '%4.4s'", mode.str);
BMDPixelFormat pixelFormat = video.tenbits ? bmdFormat10BitYUV : bmdFormat8BitYUV;
BMDVideoOutputFlags flags = bmdVideoOutputVANC;
- if (mode_id == bmdModeNTSC ||
- mode_id == bmdModeNTSC2398 ||
- mode_id == bmdModePAL)
+ if (mode.id == bmdModeNTSC ||
+ mode.id == bmdModeNTSC2398 ||
+ mode.id == bmdModePAL)
{
flags = bmdVideoOutputVITC;
}
+#ifdef _WIN32
+ BOOL supported;
+#else
bool supported;
+#endif
#if BLACKMAGIC_DECKLINK_API_VERSION < 0x0b010000
BMDDisplayModeSupport support = bmdDisplayModeNotSupported;
- result = p_output->DoesSupportVideoMode(mode_id,
+ result = p_output->DoesSupportVideoMode(mode.id,
pixelFormat,
flags,
&support,
@@ -414,7 +430,7 @@ int DBMSDIOutput::ConfigureVideo(const video_format_t *vfmt)
supported = (support != bmdDisplayModeNotSupported);
#else
result = p_output->DoesSupportVideoMode(vconn,
- mode_id,
+ mode.id,
pixelFormat,
bmdSupportedVideoModeDefault,
NULL,
@@ -437,7 +453,7 @@ int DBMSDIOutput::ConfigureVideo(const video_format_t *vfmt)
×cale);
CHECK("Could not read frame rate");
- result = p_output->EnableVideoOutput(mode_id, flags);
+ result = p_output->EnableVideoOutput(mode.id, flags);
CHECK("Could not enable video output");
p_output->SetScheduledFrameCompletionCallback(this);
@@ -681,7 +697,7 @@ int DBMSDIOutput::ProcessAudio(block_t *p_block)
scheduleTime, CLOCK_FREQ, &written);
if (result != S_OK)
- msg_Err(p_stream, "Failed to schedule audio sample: 0x%X", result);
+ msg_Err(p_stream, "Failed to schedule audio sample:0x%" PRIHR, result);
else
{
lasttimestamp = __MAX(p_block->i_pts, lasttimestamp);
@@ -737,7 +753,7 @@ int DBMSDIOutput::doProcessVideo(picture_t *picture, block_t *p_cc)
video.tenbits ? bmdFormat10BitYUV : bmdFormat8BitYUV,
bmdFrameFlagDefault, &pDLVideoFrame);
if(result != S_OK) {
- msg_Err(p_stream, "Failed to create video frame: 0x%X", result);
+ msg_Err(p_stream, "Failed to create video frame:0x%" PRIHR, result);
goto error;
}
@@ -752,13 +768,13 @@ int DBMSDIOutput::doProcessVideo(picture_t *picture, block_t *p_cc)
result = p_output->CreateAncillaryData(bmdFormat10BitYUV, &vanc);
if (result != S_OK) {
- msg_Err(p_stream, "Failed to create vanc: %d", result);
+ msg_Err(p_stream, "Failed to create vanc:0x%" PRIHR, result);
goto error;
}
result = vanc->GetBufferForVerticalBlankingLine(ancillary.afd_line, &buf);
if (result != S_OK) {
- msg_Err(p_stream, "Failed to get VBI line %u: %d", ancillary.afd_line, result);
+ msg_Err(p_stream, "Failed to get VBI line %u:0x%" PRIHR, ancillary.afd_line, result);
goto error;
}
@@ -769,7 +785,7 @@ int DBMSDIOutput::doProcessVideo(picture_t *picture, block_t *p_cc)
{
result = vanc->GetBufferForVerticalBlankingLine(ancillary.captions_line, &buf);
if (result != S_OK) {
- msg_Err(p_stream, "Failed to get VBI line %u: %d", ancillary.captions_line, result);
+ msg_Err(p_stream, "Failed to get VBI line %u:0x%" PRIHR, ancillary.captions_line, result);
goto error;
}
sdi::Captions captions(p_cc->p_buffer, p_cc->i_buffer, timescale, frameduration);
@@ -781,7 +797,7 @@ int DBMSDIOutput::doProcessVideo(picture_t *picture, block_t *p_cc)
result = pDLVideoFrame->SetAncillaryData(vanc);
vanc->Release();
if (result != S_OK) {
- msg_Err(p_stream, "Failed to set vanc: %d", result);
+ msg_Err(p_stream, "Failed to set vanc:0x%" PRIHR, result);
goto error;
}
}
@@ -799,7 +815,7 @@ int DBMSDIOutput::doProcessVideo(picture_t *picture, block_t *p_cc)
scheduleTime = picture->date + DECKLINK_SCHED_OFFSET;
result = p_output->ScheduleVideoFrame(pDLVideoFrame, scheduleTime, length, CLOCK_FREQ);
if (result != S_OK) {
- msg_Err(p_stream, "Dropped Video frame %" PRId64 ": 0x%x",
+ msg_Err(p_stream, "Dropped Video frame %" PRId64 ":0x%" PRIHR,
picture->date, result);
goto error;
}
=====================================
modules/stream_out/sdi/DBMSDIOutput.hpp
=====================================
@@ -41,8 +41,8 @@ namespace sdi_sout
virtual HRESULT STDMETHODCALLTYPE QueryInterface (REFIID, LPVOID *);
virtual ULONG STDMETHODCALLTYPE AddRef ();
virtual ULONG STDMETHODCALLTYPE Release ();
- virtual HRESULT ScheduledFrameCompleted (IDeckLinkVideoFrame *, BMDOutputFrameCompletionResult);
- virtual HRESULT ScheduledPlaybackHasStopped (void);
+ virtual HRESULT STDMETHODCALLTYPE ScheduledFrameCompleted (IDeckLinkVideoFrame *, BMDOutputFrameCompletionResult);
+ virtual HRESULT STDMETHODCALLTYPE ScheduledPlaybackHasStopped (void);
protected:
int ProcessVideo(picture_t *, block_t *);
=====================================
modules/stream_out/sdi/SDIStream.cpp
=====================================
@@ -43,6 +43,7 @@ AbstractStreamOutputBuffer::~AbstractStreamOutputBuffer()
AbstractQueueStreamOutputBuffer::AbstractQueueStreamOutputBuffer()
{
b_draining = false;
+ vlc_mutex_init(&buffer_mutex);
}
AbstractQueueStreamOutputBuffer::~AbstractQueueStreamOutputBuffer()
@@ -52,37 +53,32 @@ AbstractQueueStreamOutputBuffer::~AbstractQueueStreamOutputBuffer()
void AbstractQueueStreamOutputBuffer::Enqueue(void *p)
{
- buffer_mutex.lock();
+ vlc_mutex_locker locker(&buffer_mutex);
queued.push(p);
- buffer_mutex.unlock();
}
void *AbstractQueueStreamOutputBuffer::Dequeue()
{
void *p = NULL;
- buffer_mutex.lock();
+ vlc_mutex_locker locker(&buffer_mutex);
if(!queued.empty())
{
p = queued.front();
queued.pop();
}
- buffer_mutex.unlock();
return p;
}
void AbstractQueueStreamOutputBuffer::Drain()
{
- buffer_mutex.lock();
+ vlc_mutex_locker locker(&buffer_mutex);
b_draining = true;
- buffer_mutex.unlock();
}
bool AbstractQueueStreamOutputBuffer::isEOS()
{
- buffer_mutex.lock();
- bool b = b_draining && queued.empty();
- buffer_mutex.unlock();
- return b;
+ vlc_mutex_locker locker(&buffer_mutex);
+ return b_draining && queued.empty();
}
BlockStreamOutputBuffer::BlockStreamOutputBuffer()
@@ -139,12 +135,11 @@ void PictureStreamOutputBuffer::FlushQueued()
vlc_tick_t PictureStreamOutputBuffer::NextPictureTime()
{
vlc_tick_t t;
- buffer_mutex.lock();
+ vlc_mutex_locker locker(&buffer_mutex);
if(!queued.empty())
t = reinterpret_cast<picture_t *>(queued.front())->date;
else
t = VLC_TICK_INVALID;
- buffer_mutex.unlock();
return t;
}
@@ -700,6 +695,7 @@ AbstractRawStream::AbstractRawStream(vlc_object_t *p_obj, const StreamID &id,
{
pcr = VLC_TICK_INVALID;
b_draining = false;
+ vlc_mutex_init(&buffer_mutex);
}
AbstractRawStream::~AbstractRawStream()
@@ -716,9 +712,8 @@ int AbstractRawStream::Send(block_t *p_block)
outputbuffer->Enqueue(p_block);
else
block_Release(p_block);
- buffer_mutex.lock();
+ vlc_mutex_locker locker(&buffer_mutex);
pcr = std::max(pcr, t);
- buffer_mutex.unlock();
return VLC_SUCCESS;
}
@@ -729,26 +724,22 @@ void AbstractRawStream::Flush()
void AbstractRawStream::Drain()
{
- buffer_mutex.lock();
+ vlc_mutex_locker locker(&buffer_mutex);
b_draining = true;
- buffer_mutex.unlock();
}
bool AbstractRawStream::ReachedPlaybackTime(vlc_tick_t t)
{
- buffer_mutex.lock();
+ vlc_mutex_locker locker(&buffer_mutex);
bool b = (pcr != VLC_TICK_INVALID) && t < pcr;
b |= b_draining;
- buffer_mutex.unlock();
return b;
}
bool AbstractRawStream::isEOS()
{
- buffer_mutex.lock();
- bool b = b_draining;
- buffer_mutex.unlock();
- return b;
+ vlc_mutex_locker locker(&buffer_mutex);
+ return b_draining;
}
void AbstractRawStream::FlushQueued()
=====================================
modules/stream_out/sdi/SDIStream.hpp
=====================================
@@ -25,7 +25,6 @@
#include <vlc_aout.h>
#include <vlc_codec.h>
#include <queue>
-#include <mutex>
#include <string>
#include <list>
@@ -54,7 +53,7 @@ namespace sdi_sout
protected:
bool b_draining;
- std::mutex buffer_mutex;
+ vlc_mutex_t buffer_mutex;
std::queue<void *> queued;
};
@@ -207,7 +206,7 @@ namespace sdi_sout
virtual bool isEOS(); /* impl */
protected:
- std::mutex buffer_mutex;
+ vlc_mutex_t buffer_mutex;
vlc_tick_t pcr;
bool b_draining;
void FlushQueued();
=====================================
modules/video_output/Makefile.am
=====================================
@@ -22,7 +22,13 @@ libdecklinkoutput_plugin_la_SOURCES = video_output/decklink.cpp \
stream_out/sdi/V210.cpp \
stream_out/sdi/V210.hpp
libdecklinkoutput_plugin_la_CXXFLAGS = $(AM_CXXFLAGS) $(CPPFLAGS_decklinkoutput)
-libdecklinkoutput_plugin_la_LIBADD = $(LIBS_decklink) $(LIBDL) -lpthread
+libdecklinkoutput_plugin_la_LIBADD = $(LIBS_decklinkoutput)
+if HAVE_WIN32
+libdecklinkoutput_plugin_la_LIBADD += $(LIBCOM)
+endif
+if HAVE_LINUX
+libdecklinkoutput_plugin_la_LIBADD += $(LIBDL) -lpthread
+endif
vout_LTLIBRARIES += libdecklinkoutput_plugin.la
endif
=====================================
modules/video_output/decklink.cpp
=====================================
@@ -52,7 +52,9 @@
#include "../stream_out/sdi/Ancillary.hpp"
#include "../stream_out/sdi/DBMHelper.hpp"
#include "../stream_out/sdi/SDIGenerator.hpp"
+#ifndef _WIN32
#include <DeckLinkAPIDispatch.cpp>
+#endif
#include <DeckLinkAPIVersion.h>
#if BLACKMAGIC_DECKLINK_API_VERSION < 0x0b010000
#define IID_IDeckLinkProfileAttributes IID_IDeckLinkAttributes
@@ -368,9 +370,9 @@ static void ReleaseDLSys(vlc_object_t *obj, int i_cat)
sys_lock.unlock();
}
-static BMDVideoConnection getVConn(vout_display_t *vd, BMDVideoConnection mask)
+static BMDVideoConnection getVConn(vout_display_t *vd, int mask)
{
- BMDVideoConnection conn = 0;
+ BMDVideoConnection conn = bmdVideoConnectionUnspecified;
char *psz = var_InheritString(vd, VIDEO_CFG_PREFIX "video-connection");
if (psz)
{
@@ -386,8 +388,8 @@ static BMDVideoConnection getVConn(vout_display_t *vd, BMDVideoConnection mask)
}
else /* Pick one as default connection */
{
- conn = vlc_ctz(mask);
- conn = conn ? ( 1 << conn ) : bmdVideoConnectionSDI;
+ int iconn = vlc_ctz(mask);
+ conn = iconn ? BMDVideoConnection( 1 << iconn ) : bmdVideoConnectionSDI;
}
return conn;
}
@@ -404,7 +406,7 @@ static int OpenDecklink(vout_display_t *vd, decklink_sys_t *sys, video_format_t
if(psz_err)\
msg_Err(vd, message ": %s", psz_err); \
else \
- msg_Err(vd, message ": 0x%X", result); \
+ msg_Err(vd, message ":0x%" PRIHR, result); \
goto error; \
} \
} while(0)
@@ -415,7 +417,11 @@ static int OpenDecklink(vout_display_t *vd, decklink_sys_t *sys, video_format_t
IDeckLinkConfiguration *p_config = NULL;
IDeckLinkProfileAttributes *p_attributes = NULL;
IDeckLink *p_card = NULL;
- BMDDisplayMode wanted_mode_id = bmdModeUnknown;
+ union {
+ BMDDisplayMode id;
+ char str[4];
+ } wanted_mode;
+ wanted_mode.id = bmdModeUnknown;
vlc_mutex_lock(&sys->lock);
@@ -436,9 +442,7 @@ static int OpenDecklink(vout_display_t *vd, decklink_sys_t *sys, video_format_t
msg_Err(vd, "Invalid mode %s", mode);
goto error;
}
- memset(&wanted_mode_id, ' ', 4);
- strncpy((char*)&wanted_mode_id, mode, 4);
- wanted_mode_id = ntohl(wanted_mode_id);
+ strncpy(wanted_mode.str, mode, 4);
free(mode);
}
@@ -478,8 +482,13 @@ static int OpenDecklink(vout_display_t *vd, decklink_sys_t *sys, video_format_t
result = p_card->QueryInterface(IID_IDeckLinkProfileAttributes, (void**)&p_attributes);
CHECK("Could not get IDeckLinkAttributes");
- int64_t vconn;
- result = p_attributes->GetInt(BMDDeckLinkVideoOutputConnections, &vconn); /* reads mask */
+#ifdef _WIN32
+ LONGLONG iconn;
+#else
+ int64_t iconn;
+#endif
+ BMDVideoConnection vconn;
+ result = p_attributes->GetInt(BMDDeckLinkVideoOutputConnections, &iconn); /* reads mask */
CHECK("Could not get BMDDeckLinkVideoOutputConnections");
result = p_card->QueryInterface(IID_IDeckLinkOutput,
@@ -492,18 +501,18 @@ static int OpenDecklink(vout_display_t *vd, decklink_sys_t *sys, video_format_t
/* Now configure card */
- vconn = getVConn(vd, (BMDVideoConnection) vconn);
- if (vconn == 0)
+ vconn = getVConn(vd, iconn);
+ if (vconn == bmdVideoConnectionUnspecified)
{
msg_Err(vd, "Invalid video connection specified");
goto error;
}
- result = p_config->SetInt(bmdDeckLinkConfigVideoOutputConnection, (BMDVideoConnection) vconn);
+ result = p_config->SetInt(bmdDeckLinkConfigVideoOutputConnection, vconn);
CHECK("Could not set video output connection");
p_display_mode = Decklink::Helper::MatchDisplayMode(VLC_OBJECT(vd), sys->p_output,
- vd->source, wanted_mode_id);
+ vd->source, wanted_mode.id);
if(p_display_mode == NULL)
{
msg_Err(vd, "Could not negociate a compatible display mode");
@@ -511,22 +520,29 @@ static int OpenDecklink(vout_display_t *vd, decklink_sys_t *sys, video_format_t
}
else
{
- BMDDisplayMode mode_id = p_display_mode->GetDisplayMode();
- BMDDisplayMode modenl = htonl(mode_id);
- msg_Dbg(vd, "Selected mode '%4.4s'", (char *) &modenl);
+ union {
+ BMDDisplayMode id;
+ char str[4];
+ } mode;
+ mode.id = p_display_mode->GetDisplayMode();
+ msg_Dbg(vd, "Selected mode '%4.4s'", mode.str);
BMDPixelFormat pixelFormat = sys->video.tenbits ? bmdFormat10BitYUV : bmdFormat8BitYUV;
BMDVideoOutputFlags flags = bmdVideoOutputVANC;
- if (mode_id == bmdModeNTSC ||
- mode_id == bmdModeNTSC2398 ||
- mode_id == bmdModePAL)
+ if (mode.id == bmdModeNTSC ||
+ mode.id == bmdModeNTSC2398 ||
+ mode.id == bmdModePAL)
{
flags = bmdVideoOutputVITC;
}
+#ifdef _WIN32
+ BOOL supported;
+#else
bool supported;
+#endif
#if BLACKMAGIC_DECKLINK_API_VERSION < 0x0b010000
BMDDisplayModeSupport support = bmdDisplayModeNotSupported;
- result = sys->p_output->DoesSupportVideoMode(mode_id,
+ result = sys->p_output->DoesSupportVideoMode(mode.id,
pixelFormat,
flags,
&support,
@@ -534,7 +550,7 @@ static int OpenDecklink(vout_display_t *vd, decklink_sys_t *sys, video_format_t
supported = (support != bmdDisplayModeNotSupported);
#else
result = sys->p_output->DoesSupportVideoMode(vconn,
- mode_id,
+ mode.id,
pixelFormat,
bmdSupportedVideoModeDefault,
NULL,
@@ -557,7 +573,7 @@ static int OpenDecklink(vout_display_t *vd, decklink_sys_t *sys, video_format_t
&sys->timescale);
CHECK("Could not read frame rate");
- result = sys->p_output->EnableVideoOutput(mode_id, flags);
+ result = sys->p_output->EnableVideoOutput(mode.id, flags);
CHECK("Could not enable video output");
video_format_Copy(fmt, vd->source);
@@ -575,7 +591,7 @@ static int OpenDecklink(vout_display_t *vd, decklink_sys_t *sys, video_format_t
if (/*decklink_sys->i_channels > 0 &&*/ sys->i_rate > 0)
{
result = sys->p_output->EnableAudioOutput(
- sys->i_rate,
+ BMDAudioSampleRate(sys->i_rate),
bmdAudioSampleType16bitInteger,
/*decklink_sys->i_channels*/ 2,
bmdAudioOutputStreamTimestamped);
@@ -669,7 +685,7 @@ static void PrepareVideo(vout_display_t *vd, picture_t *picture, subpicture_t *,
bmdFrameFlagDefault, &pDLVideoFrame);
if (result != S_OK) {
- msg_Err(vd, "Failed to create video frame: 0x%X", result);
+ msg_Err(vd, "Failed to create video frame:0x%" PRIHR, result);
pDLVideoFrame = NULL;
goto end;
}
@@ -686,14 +702,14 @@ static void PrepareVideo(vout_display_t *vd, picture_t *picture, subpicture_t *,
result = sys->p_output->CreateAncillaryData(
sys->video.tenbits ? bmdFormat10BitYUV : bmdFormat8BitYUV, &vanc);
if (result != S_OK) {
- msg_Err(vd, "Failed to create vanc: %d", result);
+ msg_Err(vd, "Failed to create vanc:0x%" PRIHR, result);
goto end;
}
line = var_InheritInteger(vd, VIDEO_CFG_PREFIX "afd-line");
result = vanc->GetBufferForVerticalBlankingLine(line, &buf);
if (result != S_OK) {
- msg_Err(vd, "Failed to get VBI line %d: %d", line, result);
+ msg_Err(vd, "Failed to get VBI line %d:0x%" PRIHR, line, result);
goto end;
}
@@ -705,7 +721,7 @@ static void PrepareVideo(vout_display_t *vd, picture_t *picture, subpicture_t *,
result = pDLVideoFrame->SetAncillaryData(vanc);
vanc->Release();
if (result != S_OK) {
- msg_Err(vd, "Failed to set vanc: %d", result);
+ msg_Err(vd, "Failed to set vanc:0x%" PRIHR, result);
goto end;
}
}
@@ -725,7 +741,7 @@ static void PrepareVideo(vout_display_t *vd, picture_t *picture, subpicture_t *,
date, length, CLOCK_FREQ);
if (result != S_OK) {
- msg_Err(vd, "Dropped Video frame %" PRId64 ": 0x%x", date, result);
+ msg_Err(vd, "Dropped Video frame %" PRId64 ":0x%" PRIHR, date, result);
goto end;
}
@@ -889,7 +905,7 @@ static void PlayAudio(audio_output_t *aout, block_t *audio, vlc_tick_t systempts
audio->p_buffer, sampleFrameCount, systempts, CLOCK_FREQ, &written);
if (result != S_OK)
- msg_Err(aout, "Failed to schedule audio sample: 0x%X", result);
+ msg_Err(aout, "Failed to schedule audio sample:0x%" PRIHR, result);
else if (sampleFrameCount != written)
msg_Err(aout, "Written only %d samples out of %d", written, sampleFrameCount);
View it on GitLab: https://code.videolan.org/videolan/vlc/-/compare/0d4bbac02ffcf1da972047b17f55d6674daaf6e7...b1e3ca3b0f7a1de47cf4a914cf47a7f0dd0cd60e
--
View it on GitLab: https://code.videolan.org/videolan/vlc/-/compare/0d4bbac02ffcf1da972047b17f55d6674daaf6e7...b1e3ca3b0f7a1de47cf4a914cf47a7f0dd0cd60e
You're receiving this email because of your account on code.videolan.org.
More information about the vlc-commits
mailing list