[vlc-commits] sout: sdi: refactor decklink helpers
Francois Cartegnie
git at videolan.org
Mon May 6 20:31:49 CEST 2019
vlc | branch: master | Francois Cartegnie <fcvlcdev at free.fr> | Mon May 6 18:35:20 2019 +0200| [33f6a1a6347f779e4ef0e8e98981b3af5aae2711] | committer: Francois Cartegnie
sout: sdi: refactor decklink helpers
> http://git.videolan.org/gitweb.cgi/vlc.git/?a=commit;h=33f6a1a6347f779e4ef0e8e98981b3af5aae2711
---
modules/stream_out/Makefile.am | 2 +
modules/stream_out/sdi/DBMHelper.cpp | 150 ++++++++++++++++++++++++++++++++
modules/stream_out/sdi/DBMHelper.hpp | 37 ++++++++
modules/stream_out/sdi/DBMSDIOutput.cpp | 133 +++-------------------------
modules/stream_out/sdi/DBMSDIOutput.hpp | 3 -
5 files changed, 201 insertions(+), 124 deletions(-)
diff --git a/modules/stream_out/Makefile.am b/modules/stream_out/Makefile.am
index dfb262c467..599735c01c 100644
--- a/modules/stream_out/Makefile.am
+++ b/modules/stream_out/Makefile.am
@@ -59,6 +59,8 @@ libstream_out_sdi_plugin_la_SOURCES = stream_out/sdi/sdiout.cpp \
stream_out/sdi/Ancillary.hpp \
stream_out/sdi/AES3Audio.cpp \
stream_out/sdi/AES3Audio.hpp \
+ stream_out/sdi/DBMHelper.cpp \
+ stream_out/sdi/DBMHelper.hpp \
stream_out/sdi/DBMSDIOutput.cpp \
stream_out/sdi/DBMSDIOutput.hpp \
stream_out/sdi/SDIAudioMultiplex.cpp \
diff --git a/modules/stream_out/sdi/DBMHelper.cpp b/modules/stream_out/sdi/DBMHelper.cpp
new file mode 100644
index 0000000000..2a9966ba9b
--- /dev/null
+++ b/modules/stream_out/sdi/DBMHelper.cpp
@@ -0,0 +1,150 @@
+/*****************************************************************************
+ * DBMHelper.cpp: Decklink SDI Helpers
+ *****************************************************************************
+ * Copyright © 2014-2016 VideoLAN and VideoLAN Authors
+ * 2018-2019 VideoLabs
+ *
+ * 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.
+ *****************************************************************************/
+#ifdef HAVE_CONFIG_H
+# include "config.h"
+#endif
+
+#include <vlc_common.h>
+#include <vlc_es.h>
+#include <vlc_decklink.h>
+
+#include "DBMHelper.hpp"
+
+#include <arpa/inet.h>
+
+using namespace Decklink;
+
+IDeckLinkDisplayMode * Helper::MatchDisplayMode(vlc_object_t *p_obj,
+ IDeckLinkOutput *p_output,
+ const video_format_t *fmt,
+ BMDDisplayMode forcedmode)
+{
+ HRESULT result;
+ IDeckLinkDisplayMode *p_selected = NULL;
+ IDeckLinkDisplayModeIterator *p_iterator = NULL;
+
+ for(int i=0; i<4 && p_selected==NULL; i++)
+ {
+ int i_width = (i % 2 == 0) ? fmt->i_width : fmt->i_visible_width;
+ int i_height = (i % 2 == 0) ? fmt->i_height : fmt->i_visible_height;
+ int i_div = (i > 2) ? 4 : 0;
+
+ result = p_output->GetDisplayModeIterator(&p_iterator);
+ if(result == S_OK)
+ {
+ IDeckLinkDisplayMode *p_mode = NULL;
+ while(p_iterator->Next(&p_mode) == S_OK)
+ {
+ BMDDisplayMode mode_id = p_mode->GetDisplayMode();
+ BMDTimeValue frameduration;
+ BMDTimeScale timescale;
+ const 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);
+ 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,
+ p_mode->GetWidth(), p_mode->GetHeight(),
+ (const char *)&field,
+ double(timescale) / frameduration,
+ timescale, frameduration);
+ }
+ }
+ else
+ {
+ p_mode->Release();
+ continue;
+ }
+
+ if(forcedmode != bmdDisplayModeNotSupported && unlikely(!p_selected))
+ {
+ BMDDisplayMode modenl = htonl(forcedmode);
+ msg_Dbg(p_obj, "Forced mode '%4.4s'", (char *)&modenl);
+ if(forcedmode == mode_id)
+ p_selected = p_mode;
+ else
+ p_mode->Release();
+ continue;
+ }
+
+ if(p_selected == NULL && forcedmode == bmdDisplayModeNotSupported)
+ {
+ if(i_width >> i_div == p_mode->GetWidth() >> i_div &&
+ i_height >> i_div == p_mode->GetHeight() >> i_div)
+ {
+ unsigned int num_deck, den_deck;
+ unsigned int num_stream, den_stream;
+ vlc_ureduce(&num_deck, &den_deck, timescale, frameduration, 0);
+ vlc_ureduce(&num_stream, &den_stream,
+ fmt->i_frame_rate, fmt->i_frame_rate_base, 0);
+
+ if (num_deck == num_stream && den_deck == den_stream)
+ {
+ msg_Info(p_obj, "Matches incoming stream");
+ p_selected = p_mode;
+ continue;
+ }
+ }
+ }
+
+ p_mode->Release();
+ }
+ p_iterator->Release();
+ }
+ }
+ return p_selected;
+}
+
+const char * Helper::ErrorToString(long i_code)
+{
+ static struct
+ {
+ long i_return_code;
+ const char * const psz_string;
+ } const errors_to_string[] = {
+ { E_UNEXPECTED, "Unexpected error" },
+ { E_NOTIMPL, "Not implemented" },
+ { E_OUTOFMEMORY, "Out of memory" },
+ { E_INVALIDARG, "Invalid argument" },
+ { E_NOINTERFACE, "No interface" },
+ { E_POINTER, "Invalid pointer" },
+ { E_HANDLE, "Invalid handle" },
+ { E_ABORT, "Aborted" },
+ { E_FAIL, "Failed" },
+ { E_ACCESSDENIED,"Access denied" }
+ };
+
+ for(size_t i=0; i<ARRAY_SIZE(errors_to_string); i++)
+ {
+ if(errors_to_string[i].i_return_code == i_code)
+ return errors_to_string[i].psz_string;
+ }
+ return NULL;
+}
diff --git a/modules/stream_out/sdi/DBMHelper.hpp b/modules/stream_out/sdi/DBMHelper.hpp
new file mode 100644
index 0000000000..a2218acb80
--- /dev/null
+++ b/modules/stream_out/sdi/DBMHelper.hpp
@@ -0,0 +1,37 @@
+/*****************************************************************************
+ * DBMHelper.hpp: Decklink SDI Helpers
+ *****************************************************************************
+ * Copyright © 2014-2016 VideoLAN and VideoLAN Authors
+ * 2018-2019 VideoLabs
+ *
+ * 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 DBMHELPER_HPP
+#define DBMHELPER_HPP
+
+namespace Decklink
+{
+ class Helper
+ {
+ public:
+ static IDeckLinkDisplayMode * MatchDisplayMode(vlc_object_t *,
+ IDeckLinkOutput *,
+ const video_format_t *,
+ BMDDisplayMode = bmdDisplayModeNotSupported);
+ static const char *ErrorToString(long i_code);
+ };
+}
+
+#endif
diff --git a/modules/stream_out/sdi/DBMSDIOutput.cpp b/modules/stream_out/sdi/DBMSDIOutput.cpp
index 5cb007c34a..a0fd487810 100644
--- a/modules/stream_out/sdi/DBMSDIOutput.cpp
+++ b/modules/stream_out/sdi/DBMSDIOutput.cpp
@@ -22,6 +22,14 @@
# include "config.h"
#endif
+#include <vlc_common.h>
+#include <vlc_es.h>
+#include <vlc_picture.h>
+#include <vlc_interrupt.h>
+#include <vlc_image.h>
+#include <vlc_decklink.h>
+
+#include "DBMHelper.hpp"
#include "DBMSDIOutput.hpp"
#include "SDIStream.hpp"
#include "SDIAudioMultiplex.hpp"
@@ -29,12 +37,9 @@
#include "V210.hpp"
#include <DeckLinkAPIDispatch.cpp>
+
#include "sdiout.hpp"
-#include <vlc_es.h>
-#include <vlc_picture.h>
-#include <vlc_interrupt.h>
-#include <vlc_image.h>
#include <arpa/inet.h>
using namespace sdi_sout;
@@ -92,125 +97,10 @@ int DBMSDIOutput::Send(AbstractStream *s, block_t *b)
return SDIOutput::Send(s, b);
}
-IDeckLinkDisplayMode * DBMSDIOutput::MatchDisplayMode(const video_format_t *fmt, BMDDisplayMode forcedmode)
-{
- HRESULT result;
- IDeckLinkDisplayMode *p_selected = NULL;
- IDeckLinkDisplayModeIterator *p_iterator = NULL;
-
- for(int i=0; i<4 && p_selected==NULL; i++)
- {
- int i_width = (i % 2 == 0) ? fmt->i_width : fmt->i_visible_width;
- int i_height = (i % 2 == 0) ? fmt->i_height : fmt->i_visible_height;
- int i_div = (i > 2) ? 4 : 0;
-
- result = p_output->GetDisplayModeIterator(&p_iterator);
- if(result == S_OK)
- {
- IDeckLinkDisplayMode *p_mode = NULL;
- while(p_iterator->Next(&p_mode) == S_OK)
- {
- BMDDisplayMode mode_id = p_mode->GetDisplayMode();
- BMDTimeValue frameduration;
- BMDTimeScale timescale;
- const 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);
- psz_mode_name = DECKLINK_STRDUP(tmp_name);
- DECKLINK_FREE(tmp_name);
-
- if(i==0)
- {
- BMDFieldDominance field = htonl(p_mode->GetFieldDominance());
- msg_Dbg(p_stream, "Found mode '%4.4s': %s (%ldx%ld, %4.4s, %.3f fps, scale %ld dur %ld)",
- (const char*)&modenl, psz_mode_name,
- p_mode->GetWidth(), p_mode->GetHeight(),
- (const char *)&field,
- double(timescale) / frameduration,
- timescale, frameduration);
- }
- }
- else
- {
- p_mode->Release();
- continue;
- }
-
- if(forcedmode != bmdDisplayModeNotSupported && unlikely(!p_selected))
- {
- BMDDisplayMode modenl = htonl(forcedmode);
- msg_Dbg(p_stream, "Forced mode '%4.4s'", (char *)&modenl);
- if(forcedmode == mode_id)
- p_selected = p_mode;
- else
- p_mode->Release();
- continue;
- }
-
- if(p_selected == NULL && forcedmode == bmdDisplayModeNotSupported)
- {
- if(i_width >> i_div == p_mode->GetWidth() >> i_div &&
- i_height >> i_div == p_mode->GetHeight() >> i_div)
- {
- unsigned int num_deck, den_deck;
- unsigned int num_stream, den_stream;
- vlc_ureduce(&num_deck, &den_deck, timescale, frameduration, 0);
- vlc_ureduce(&num_stream, &den_stream,
- fmt->i_frame_rate, fmt->i_frame_rate_base, 0);
-
- if (num_deck == num_stream && den_deck == den_stream)
- {
- msg_Info(p_stream, "Matches incoming stream");
- p_selected = p_mode;
- continue;
- }
- }
- }
-
- p_mode->Release();
- }
- p_iterator->Release();
- }
- }
- return p_selected;
-}
-
-
-const char * DBMSDIOutput::ErrorToString(long i_code)
-{
- static struct
- {
- long i_return_code;
- const char * const psz_string;
- } const errors_to_string[] = {
- { E_UNEXPECTED, "Unexpected error" },
- { E_NOTIMPL, "Not implemented" },
- { E_OUTOFMEMORY, "Out of memory" },
- { E_INVALIDARG, "Invalid argument" },
- { E_NOINTERFACE, "No interface" },
- { E_POINTER, "Invalid pointer" },
- { E_HANDLE, "Invalid handle" },
- { E_ABORT, "Aborted" },
- { E_FAIL, "Failed" },
- { E_ACCESSDENIED,"Access denied" }
- };
-
- for(size_t i=0; i<ARRAY_SIZE(errors_to_string); i++)
- {
- if(errors_to_string[i].i_return_code == i_code)
- return errors_to_string[i].psz_string;
- }
- return NULL;
-}
-
#define CHECK(message) do { \
if (result != S_OK) \
{ \
- const char *psz_err = ErrorToString(result); \
+ const char *psz_err = Decklink::Helper::ErrorToString(result); \
if(psz_err)\
msg_Err(p_stream, message ": %s", psz_err); \
else \
@@ -425,7 +315,8 @@ int DBMSDIOutput::ConfigureVideo(const video_format_t *vfmt)
result = p_config->SetInt(bmdDeckLinkConfigVideoOutputConnection, vconn);
CHECK("Could not set video output connection");
- p_display_mode = MatchDisplayMode(vfmt, wanted_mode_id);
+ p_display_mode = Decklink::Helper::MatchDisplayMode(VLC_OBJECT(p_stream),
+ p_output, vfmt, wanted_mode_id);
if(p_display_mode == NULL)
{
msg_Err(p_stream, "Could not negociate a compatible display mode");
diff --git a/modules/stream_out/sdi/DBMSDIOutput.hpp b/modules/stream_out/sdi/DBMSDIOutput.hpp
index 60fca102ef..91550d3e2a 100644
--- a/modules/stream_out/sdi/DBMSDIOutput.hpp
+++ b/modules/stream_out/sdi/DBMSDIOutput.hpp
@@ -60,9 +60,6 @@ namespace sdi_sout
} clock;
bool b_running;
int Start(vlc_tick_t);
- const char *ErrorToString(long i_code);
- IDeckLinkDisplayMode * MatchDisplayMode(const video_format_t *,
- BMDDisplayMode = bmdDisplayModeNotSupported);
int doProcessVideo(picture_t *, block_t *);
picture_t * CreateNoSignalPicture(const char*, const video_format_t *);
void checkClockDrift();
More information about the vlc-commits
mailing list