1 /* GStreamer
2  * Copyright (C) 2011 David Schleef <ds@schleef.org>
3  * Copyright (C) 2014 Sebastian Dröge <sebastian@centricular.com>
4  * Copyright (C) 2015 Florian Langlois <florian.langlois@fr.thalesgroup.com>
5  *
6  * This library is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU Library General Public
8  * License as published by the Free Software Foundation; either
9  * version 2 of the License, or (at your option) any later version.
10  *
11  * This library is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14  * Library General Public License for more details.
15  *
16  * You should have received a copy of the GNU Library General Public
17  * License along with this library; if not, write to the
18  * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
19  * Boston, MA 02110-1301, USA.
20  */
21 
22 #ifndef _GST_DECKLINK_H_
23 #define _GST_DECKLINK_H_
24 
25 #include <gst/gst.h>
26 #include <gst/video/video.h>
27 
28 #include <stdint.h>
29 
30 #ifdef G_OS_UNIX
31 #include "linux/DeckLinkAPI.h"
32 #endif
33 
34 #ifdef G_OS_WIN32
35 #include "win/DeckLinkAPI.h"
36 
37 #include <stdio.h>
38 #include <comutil.h>
39 
40 #define bool BOOL
41 #define COMSTR_T BSTR
42 /* MinGW does not have comsuppw.lib, so no _com_util::ConvertBSTRToString */
43 # ifdef __MINGW32__
44 #  define CONVERT_COM_STRING(s) BSTR _s = (BSTR)s; s = (char*) malloc(100); wcstombs(s, _s, 100); ::SysFreeString(_s);
45 #  define FREE_COM_STRING(s) free(s);
46 # else
47 #  define CONVERT_COM_STRING(s) BSTR _s = (BSTR)s; s = _com_util::ConvertBSTRToString(_s); ::SysFreeString(_s);
48 #  define FREE_COM_STRING(s) delete[] s;
49 # endif /* __MINGW32__ */
50 #else
51 #define COMSTR_T const char*
52 #define CONVERT_COM_STRING(s)
53 #define FREE_COM_STRING(s)
54 #define WINAPI
55 #endif /* G_OS_WIN32 */
56 
57 typedef enum {
58   GST_DECKLINK_MODE_AUTO,
59 
60   GST_DECKLINK_MODE_NTSC,
61   GST_DECKLINK_MODE_NTSC2398,
62   GST_DECKLINK_MODE_PAL,
63   GST_DECKLINK_MODE_NTSC_P,
64   GST_DECKLINK_MODE_PAL_P,
65 
66   GST_DECKLINK_MODE_1080p2398,
67   GST_DECKLINK_MODE_1080p24,
68   GST_DECKLINK_MODE_1080p25,
69   GST_DECKLINK_MODE_1080p2997,
70   GST_DECKLINK_MODE_1080p30,
71 
72   GST_DECKLINK_MODE_1080i50,
73   GST_DECKLINK_MODE_1080i5994,
74   GST_DECKLINK_MODE_1080i60,
75 
76   GST_DECKLINK_MODE_1080p50,
77   GST_DECKLINK_MODE_1080p5994,
78   GST_DECKLINK_MODE_1080p60,
79 
80   GST_DECKLINK_MODE_720p50,
81   GST_DECKLINK_MODE_720p5994,
82   GST_DECKLINK_MODE_720p60,
83 
84   GST_DECKLINK_MODE_1556p2398,
85   GST_DECKLINK_MODE_1556p24,
86   GST_DECKLINK_MODE_1556p25,
87 
88   GST_DECKLINK_MODE_2160p2398,
89   GST_DECKLINK_MODE_2160p24,
90   GST_DECKLINK_MODE_2160p25,
91   GST_DECKLINK_MODE_2160p2997,
92   GST_DECKLINK_MODE_2160p30,
93   GST_DECKLINK_MODE_2160p50,
94   GST_DECKLINK_MODE_2160p5994,
95   GST_DECKLINK_MODE_2160p60
96 } GstDecklinkModeEnum;
97 #define GST_TYPE_DECKLINK_MODE (gst_decklink_mode_get_type ())
98 GType gst_decklink_mode_get_type (void);
99 
100 typedef enum {
101   GST_DECKLINK_CONNECTION_AUTO,
102   GST_DECKLINK_CONNECTION_SDI,
103   GST_DECKLINK_CONNECTION_HDMI,
104   GST_DECKLINK_CONNECTION_OPTICAL_SDI,
105   GST_DECKLINK_CONNECTION_COMPONENT,
106   GST_DECKLINK_CONNECTION_COMPOSITE,
107   GST_DECKLINK_CONNECTION_SVIDEO
108 } GstDecklinkConnectionEnum;
109 #define GST_TYPE_DECKLINK_CONNECTION (gst_decklink_connection_get_type ())
110 GType gst_decklink_connection_get_type (void);
111 
112 typedef enum {
113   GST_DECKLINK_AUDIO_CONNECTION_AUTO,
114   GST_DECKLINK_AUDIO_CONNECTION_EMBEDDED,
115   GST_DECKLINK_AUDIO_CONNECTION_AES_EBU,
116   GST_DECKLINK_AUDIO_CONNECTION_ANALOG,
117   GST_DECKLINK_AUDIO_CONNECTION_ANALOG_XLR,
118   GST_DECKLINK_AUDIO_CONNECTION_ANALOG_RCA
119 } GstDecklinkAudioConnectionEnum;
120 #define GST_TYPE_DECKLINK_AUDIO_CONNECTION (gst_decklink_audio_connection_get_type ())
121 GType gst_decklink_audio_connection_get_type (void);
122 
123 typedef enum {
124   GST_DECKLINK_AUDIO_CHANNELS_MAX = 0,
125   GST_DECKLINK_AUDIO_CHANNELS_2 = 2,
126   GST_DECKLINK_AUDIO_CHANNELS_8 = 8,
127   GST_DECKLINK_AUDIO_CHANNELS_16 = 16
128 } GstDecklinkAudioChannelsEnum;
129 #define GST_TYPE_DECKLINK_AUDIO_CHANNELS (gst_decklink_audio_channels_get_type ())
130 GType gst_decklink_audio_channels_get_type (void);
131 
132 typedef enum {
133   GST_DECKLINK_VIDEO_FORMAT_AUTO,
134   GST_DECKLINK_VIDEO_FORMAT_8BIT_YUV, /* bmdFormat8BitYUV */
135   GST_DECKLINK_VIDEO_FORMAT_10BIT_YUV, /* bmdFormat10BitYUV */
136   GST_DECKLINK_VIDEO_FORMAT_8BIT_ARGB, /* bmdFormat8BitARGB */
137   GST_DECKLINK_VIDEO_FORMAT_8BIT_BGRA, /* bmdFormat8BitBGRA */
138   GST_DECKLINK_VIDEO_FORMAT_10BIT_RGB, /* bmdFormat10BitRGB */
139   GST_DECKLINK_VIDEO_FORMAT_12BIT_RGB, /* bmdFormat12BitRGB */
140   GST_DECKLINK_VIDEO_FORMAT_12BIT_RGBLE, /* bmdFormat12BitRGBLE */
141   GST_DECKLINK_VIDEO_FORMAT_10BIT_RGBXLE, /* bmdFormat10BitRGBXLE */
142   GST_DECKLINK_VIDEO_FORMAT_10BIT_RGBX, /* bmdFormat10BitRGBX */
143 } GstDecklinkVideoFormat;
144 #define GST_TYPE_DECKLINK_VIDEO_FORMAT (gst_decklink_video_format_get_type ())
145 GType gst_decklink_video_format_get_type (void);
146 
147 typedef enum {
148   GST_DECKLINK_DUPLEX_MODE_HALF, /* bmdDuplexModeHalf */
149   GST_DECKLINK_DUPLEX_MODE_FULL, /* bmdDuplexModeFull */
150 } GstDecklinkDuplexMode;
151 #define GST_TYPE_DECKLINK_DUPLEX_MODE (gst_decklink_duplex_mode_get_type ())
152 GType gst_decklink_duplex_mode_get_type (void);
153 
154 typedef enum {
155   GST_DECKLINK_TIMECODE_FORMAT_RP188VITC1, /*bmdTimecodeRP188VITC1 */
156   GST_DECKLINK_TIMECODE_FORMAT_RP188VITC2, /*bmdTimecodeRP188VITC2 */
157   GST_DECKLINK_TIMECODE_FORMAT_RP188LTC, /*bmdTimecodeRP188LTC */
158   GST_DECKLINK_TIMECODE_FORMAT_RP188ANY, /*bmdTimecodeRP188Any */
159   GST_DECKLINK_TIMECODE_FORMAT_VITC, /*bmdTimecodeVITC */
160   GST_DECKLINK_TIMECODE_FORMAT_VITCFIELD2, /*bmdTimecodeVITCField2 */
161   GST_DECKLINK_TIMECODE_FORMAT_SERIAL /* bmdTimecodeSerial */
162 } GstDecklinkTimecodeFormat;
163 #define GST_TYPE_DECKLINK_TIMECODE_FORMAT (gst_decklink_timecode_format_get_type ())
164 GType gst_decklink_timecode_format_get_type (void);
165 
166 typedef enum
167 {
168   GST_DECKLINK_KEYER_MODE_OFF,
169   GST_DECKLINK_KEYER_MODE_INTERNAL,
170   GST_DECKLINK_KEYER_MODE_EXTERNAL
171 } GstDecklinkKeyerMode;
172 #define GST_TYPE_DECKLINK_KEYER_MODE (gst_decklink_keyer_mode_get_type ())
173 GType gst_decklink_keyer_mode_get_type (void);
174 
175 /* Enum BMDKeyerMode options of off, internal and external @@@ DJ @@@ */
176 
177 typedef uint32_t BMDKeyerMode;
178 enum _BMDKeyerMode
179 {
180   bmdKeyerModeOff = /* 'off' */ 0,
181   bmdKeyerModeInternal = /* 'int' */ 1,
182   bmdKeyerModeExternal = /* 'ext' */ 2
183 };
184 
185 const BMDPixelFormat gst_decklink_pixel_format_from_type (GstDecklinkVideoFormat t);
186 const gint gst_decklink_bpp_from_type (GstDecklinkVideoFormat t);
187 const GstDecklinkVideoFormat gst_decklink_type_from_video_format (GstVideoFormat f);
188 GstVideoFormat gst_decklink_video_format_from_type (BMDPixelFormat pf);
189 const BMDTimecodeFormat gst_decklink_timecode_format_from_enum (GstDecklinkTimecodeFormat f);
190 const GstDecklinkTimecodeFormat gst_decklink_timecode_format_to_enum (BMDTimecodeFormat f);
191 const BMDDuplexMode gst_decklink_duplex_mode_from_enum (GstDecklinkDuplexMode m);
192 const GstDecklinkDuplexMode gst_decklink_duplex_mode_to_enum (BMDDuplexMode m);
193 const BMDKeyerMode gst_decklink_keyer_mode_from_enum (GstDecklinkKeyerMode m);
194 const GstDecklinkKeyerMode gst_decklink_keyer_mode_to_enum (BMDKeyerMode m);
195 
196 typedef struct _GstDecklinkMode GstDecklinkMode;
197 struct _GstDecklinkMode {
198   BMDDisplayMode mode;
199   int width;
200   int height;
201   int fps_n;
202   int fps_d;
203   gboolean interlaced;
204   int par_n;
205   int par_d;
206   gboolean tff;
207   const gchar *colorimetry;
208 };
209 
210 const GstDecklinkMode * gst_decklink_get_mode (GstDecklinkModeEnum e);
211 const GstDecklinkModeEnum gst_decklink_get_mode_enum_from_bmd (BMDDisplayMode mode);
212 const BMDVideoConnection gst_decklink_get_connection (GstDecklinkConnectionEnum e);
213 GstCaps * gst_decklink_mode_get_caps (GstDecklinkModeEnum e, BMDPixelFormat f, gboolean input);
214 GstCaps * gst_decklink_mode_get_template_caps (gboolean input);
215 
216 typedef struct _GstDecklinkOutput GstDecklinkOutput;
217 struct _GstDecklinkOutput {
218   IDeckLink *device;
219   IDeckLinkOutput *output;
220   IDeckLinkAttributes *attributes;
221   IDeckLinkKeyer *keyer;
222 
223   gchar *hw_serial_number;
224 
225   GstClock *clock;
226   GstClockTime clock_start_time, clock_last_time, clock_epoch;
227   GstClockTimeDiff clock_offset;
228   gboolean started;
229   gboolean clock_restart;
230 
231   /* Everything below protected by mutex */
232   GMutex lock;
233   GCond cond;
234 
235   /* Set by the video source */
236   /* Configured mode or NULL */
237   const GstDecklinkMode *mode;
238 
239   GstElement *audiosink;
240   gboolean audio_enabled;
241   GstElement *videosink;
242   gboolean video_enabled;
243   void (*start_scheduled_playback) (GstElement *videosink);
244 };
245 
246 typedef struct _GstDecklinkInput GstDecklinkInput;
247 struct _GstDecklinkInput {
248   IDeckLink *device;
249   IDeckLinkInput *input;
250   IDeckLinkConfiguration *config;
251   IDeckLinkAttributes *attributes;
252 
253   gchar *hw_serial_number;
254 
255   /* Everything below protected by mutex */
256   GMutex lock;
257 
258   /* Set by the video source */
259   void (*got_video_frame) (GstElement *videosrc, IDeckLinkVideoInputFrame * frame, GstDecklinkModeEnum mode, GstClockTime capture_time, GstClockTime stream_time, GstClockTime stream_duration, GstClockTime hardware_time, GstClockTime hardware_duration, IDeckLinkTimecode *dtc, gboolean no_signal);
260   /* Configured mode or NULL */
261   const GstDecklinkMode *mode;
262   BMDPixelFormat format;
263 
264   /* Set by the audio source */
265   void (*got_audio_packet) (GstElement *videosrc, IDeckLinkAudioInputPacket * packet, GstClockTime capture_time, GstClockTime stream_time, GstClockTime stream_duration, GstClockTime hardware_time, GstClockTime hardware_duration, gboolean no_signal);
266 
267   GstElement *audiosrc;
268   gboolean audio_enabled;
269   GstElement *videosrc;
270   gboolean video_enabled;
271   void (*start_streams) (GstElement *videosrc);
272 };
273 
274 GstDecklinkOutput * gst_decklink_acquire_nth_output (gint n, GstElement * sink, gboolean is_audio);
275 void                gst_decklink_release_nth_output (gint n, GstElement * sink, gboolean is_audio);
276 
277 GstDecklinkInput *  gst_decklink_acquire_nth_input (gint n, GstElement * src, gboolean is_audio);
278 void                gst_decklink_release_nth_input (gint n, GstElement * src, gboolean is_audio);
279 
280 const GstDecklinkMode * gst_decklink_find_mode_for_caps (GstCaps * caps);
281 const GstDecklinkMode * gst_decklink_find_mode_and_format_for_caps (GstCaps * caps, BMDPixelFormat * format);
282 GstCaps * gst_decklink_mode_get_caps_all_formats (GstDecklinkModeEnum e, gboolean input);
283 GstCaps * gst_decklink_pixel_format_get_caps (BMDPixelFormat f, gboolean input);
284 
285 #endif
286