1 /* GStreamer
2 * Copyright (C) 2011 David Schleef <ds@entropywave.com>
3 * Copyright (C) 2014 Sebastian Dröge <sebastian@centricular.com>
4 *
5 * This library is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU Library General Public
7 * License as published by the Free Software Foundation; either
8 * version 2 of the License, or (at your option) any later version.
9 *
10 * This library is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 * Library General Public License for more details.
14 *
15 * You should have received a copy of the GNU Library General Public
16 * License along with this library; if not, write to the
17 * Free Software Foundation, Inc., 51 Franklin Street, Suite 500,
18 * Boston, MA 02110-1335, USA.
19 */
20 /**
21 * SECTION:element-decklinkaudiosrc
22 * @short_description: Inputs Audio from a BlackMagic DeckLink Device
23 * @see_also: decklinkvideosrc
24 *
25 * Capture Video and Audio from a BlackMagic DeckLink Device. Can only be used
26 * in conjunction with decklinkvideosink.
27 *
28 * ## Sample pipeline
29 * |[
30 * gst-launch-1.0 \
31 * decklinkvideosrc device-number=0 mode=1080p25 ! autovideosink \
32 * decklinkaudiosrc device-number=0 ! autoaudiosink
33 * ]|
34 * Capturing 1080p25 video and audio from the SDI-In of Card 0. Devices are numbered
35 * starting with 0.
36 */
37
38 #ifdef HAVE_CONFIG_H
39 #include "config.h"
40 #endif
41
42 #include "gstdecklinkaudiosrc.h"
43 #include "gstdecklinkvideosrc.h"
44 #include <string.h>
45
46 GST_DEBUG_CATEGORY_STATIC (gst_decklink_audio_src_debug);
47 #define GST_CAT_DEFAULT gst_decklink_audio_src_debug
48
49 #define DEFAULT_CONNECTION (GST_DECKLINK_AUDIO_CONNECTION_AUTO)
50 #define DEFAULT_BUFFER_SIZE (5)
51
52 #define DEFAULT_ALIGNMENT_THRESHOLD (40 * GST_MSECOND)
53 #define DEFAULT_DISCONT_WAIT (1 * GST_SECOND)
54 #define DEFAULT_CHANNELS (GST_DECKLINK_AUDIO_CHANNELS_2)
55
56 #ifndef ABSDIFF
57 #define ABSDIFF(x, y) ( (x) > (y) ? ((x) - (y)) : ((y) - (x)) )
58 #endif
59
60 enum
61 {
62 PROP_0,
63 PROP_CONNECTION,
64 PROP_DEVICE_NUMBER,
65 PROP_ALIGNMENT_THRESHOLD,
66 PROP_DISCONT_WAIT,
67 PROP_BUFFER_SIZE,
68 PROP_CHANNELS,
69 PROP_HW_SERIAL_NUMBER
70 };
71
72 static GstStaticPadTemplate sink_template = GST_STATIC_PAD_TEMPLATE ("src",
73 GST_PAD_SRC,
74 GST_PAD_ALWAYS,
75 GST_STATIC_CAPS
76 ("audio/x-raw, format={S16LE,S32LE}, channels=2, rate=48000, "
77 "layout=interleaved;"
78 "audio/x-raw, format={S16LE,S32LE}, channels={8,16}, channel-mask=(bitmask)0, rate=48000, "
79 "layout=interleaved")
80 );
81
82 typedef struct
83 {
84 IDeckLinkAudioInputPacket *packet;
85 GstClockTime timestamp;
86 GstClockTime stream_timestamp;
87 GstClockTime stream_duration;
88 GstClockTime hardware_timestamp;
89 GstClockTime hardware_duration;
90 gboolean no_signal;
91 } CapturePacket;
92
93 static void
capture_packet_clear(CapturePacket * packet)94 capture_packet_clear (CapturePacket * packet)
95 {
96 packet->packet->Release ();
97 memset (packet, 0, sizeof (*packet));
98 }
99
100 typedef struct
101 {
102 IDeckLinkAudioInputPacket *packet;
103 IDeckLinkInput *input;
104 } AudioPacket;
105
106 static void
audio_packet_free(void * data)107 audio_packet_free (void *data)
108 {
109 AudioPacket *packet = (AudioPacket *) data;
110
111 packet->packet->Release ();
112 packet->input->Release ();
113 g_free (packet);
114 }
115
116 static void gst_decklink_audio_src_set_property (GObject * object,
117 guint property_id, const GValue * value, GParamSpec * pspec);
118 static void gst_decklink_audio_src_get_property (GObject * object,
119 guint property_id, GValue * value, GParamSpec * pspec);
120 static void gst_decklink_audio_src_finalize (GObject * object);
121
122 static GstStateChangeReturn
123 gst_decklink_audio_src_change_state (GstElement * element,
124 GstStateChange transition);
125
126 static gboolean gst_decklink_audio_src_unlock (GstBaseSrc * bsrc);
127 static gboolean gst_decklink_audio_src_unlock_stop (GstBaseSrc * bsrc);
128 static GstCaps *gst_decklink_audio_src_get_caps (GstBaseSrc * bsrc,
129 GstCaps * filter);
130 static gboolean gst_decklink_audio_src_query (GstBaseSrc * bsrc,
131 GstQuery * query);
132
133 static GstFlowReturn gst_decklink_audio_src_create (GstPushSrc * psrc,
134 GstBuffer ** buffer);
135
136 static gboolean gst_decklink_audio_src_open (GstDecklinkAudioSrc * self);
137 static gboolean gst_decklink_audio_src_close (GstDecklinkAudioSrc * self);
138
139 static gboolean gst_decklink_audio_src_stop (GstDecklinkAudioSrc * self);
140
141 #define parent_class gst_decklink_audio_src_parent_class
142 G_DEFINE_TYPE (GstDecklinkAudioSrc, gst_decklink_audio_src, GST_TYPE_PUSH_SRC);
143 GST_ELEMENT_REGISTER_DEFINE_WITH_CODE (decklinkaudiosrc, "decklinkaudiosrc", GST_RANK_NONE,
144 GST_TYPE_DECKLINK_AUDIO_SRC, decklink_element_init (plugin));
145
146 static void
gst_decklink_audio_src_class_init(GstDecklinkAudioSrcClass * klass)147 gst_decklink_audio_src_class_init (GstDecklinkAudioSrcClass * klass)
148 {
149 GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
150 GstElementClass *element_class = GST_ELEMENT_CLASS (klass);
151 GstBaseSrcClass *basesrc_class = GST_BASE_SRC_CLASS (klass);
152 GstPushSrcClass *pushsrc_class = GST_PUSH_SRC_CLASS (klass);
153
154 gobject_class->set_property = gst_decklink_audio_src_set_property;
155 gobject_class->get_property = gst_decklink_audio_src_get_property;
156 gobject_class->finalize = gst_decklink_audio_src_finalize;
157
158 element_class->change_state =
159 GST_DEBUG_FUNCPTR (gst_decklink_audio_src_change_state);
160
161 basesrc_class->query = GST_DEBUG_FUNCPTR (gst_decklink_audio_src_query);
162 basesrc_class->negotiate = NULL;
163 basesrc_class->get_caps = GST_DEBUG_FUNCPTR (gst_decklink_audio_src_get_caps);
164 basesrc_class->unlock = GST_DEBUG_FUNCPTR (gst_decklink_audio_src_unlock);
165 basesrc_class->unlock_stop =
166 GST_DEBUG_FUNCPTR (gst_decklink_audio_src_unlock_stop);
167
168 pushsrc_class->create = GST_DEBUG_FUNCPTR (gst_decklink_audio_src_create);
169
170 g_object_class_install_property (gobject_class, PROP_CONNECTION,
171 g_param_spec_enum ("connection", "Connection",
172 "Audio input connection to use",
173 GST_TYPE_DECKLINK_AUDIO_CONNECTION, DEFAULT_CONNECTION,
174 (GParamFlags) (G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS |
175 G_PARAM_CONSTRUCT)));
176
177 g_object_class_install_property (gobject_class, PROP_DEVICE_NUMBER,
178 g_param_spec_int ("device-number", "Device number",
179 "Output device instance to use", 0, G_MAXINT, 0,
180 (GParamFlags) (G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS |
181 G_PARAM_CONSTRUCT)));
182
183 g_object_class_install_property (gobject_class, PROP_ALIGNMENT_THRESHOLD,
184 g_param_spec_uint64 ("alignment-threshold", "Alignment Threshold",
185 "Timestamp alignment threshold in nanoseconds", 0,
186 G_MAXUINT64 - 1, DEFAULT_ALIGNMENT_THRESHOLD,
187 (GParamFlags) (G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)));
188
189 g_object_class_install_property (gobject_class, PROP_DISCONT_WAIT,
190 g_param_spec_uint64 ("discont-wait", "Discont Wait",
191 "Window of time in nanoseconds to wait before "
192 "creating a discontinuity", 0,
193 G_MAXUINT64 - 1, DEFAULT_DISCONT_WAIT,
194 (GParamFlags) (G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)));
195
196 g_object_class_install_property (gobject_class, PROP_BUFFER_SIZE,
197 g_param_spec_uint ("buffer-size", "Buffer Size",
198 "Size of internal buffer in number of video frames", 1,
199 G_MAXINT, DEFAULT_BUFFER_SIZE,
200 (GParamFlags) (G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)));
201
202 g_object_class_install_property (gobject_class, PROP_CHANNELS,
203 g_param_spec_enum ("channels", "Channels",
204 "Audio channels",
205 GST_TYPE_DECKLINK_AUDIO_CHANNELS, DEFAULT_CHANNELS,
206 (GParamFlags) (G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS |
207 G_PARAM_CONSTRUCT)));
208
209 g_object_class_install_property (gobject_class, PROP_HW_SERIAL_NUMBER,
210 g_param_spec_string ("hw-serial-number", "Hardware serial number",
211 "The serial number (hardware ID) of the Decklink card",
212 NULL, (GParamFlags) (G_PARAM_READABLE | G_PARAM_STATIC_STRINGS)));
213
214 gst_element_class_add_static_pad_template (element_class, &sink_template);
215
216 gst_element_class_set_static_metadata (element_class, "Decklink Audio Source",
217 "Audio/Source/Hardware", "Decklink Source",
218 "David Schleef <ds@entropywave.com>, "
219 "Sebastian Dröge <sebastian@centricular.com>");
220
221 GST_DEBUG_CATEGORY_INIT (gst_decklink_audio_src_debug, "decklinkaudiosrc",
222 0, "debug category for decklinkaudiosrc element");
223 }
224
225 static void
gst_decklink_audio_src_init(GstDecklinkAudioSrc * self)226 gst_decklink_audio_src_init (GstDecklinkAudioSrc * self)
227 {
228 self->device_number = 0;
229 self->alignment_threshold = DEFAULT_ALIGNMENT_THRESHOLD;
230 self->discont_wait = DEFAULT_DISCONT_WAIT;
231 self->buffer_size = DEFAULT_BUFFER_SIZE;
232 self->channels = DEFAULT_CHANNELS;
233
234 gst_base_src_set_live (GST_BASE_SRC (self), TRUE);
235 gst_base_src_set_format (GST_BASE_SRC (self), GST_FORMAT_TIME);
236
237 gst_pad_use_fixed_caps (GST_BASE_SRC_PAD (self));
238
239 g_mutex_init (&self->lock);
240 g_cond_init (&self->cond);
241
242 self->current_packets =
243 gst_queue_array_new_for_struct (sizeof (CapturePacket),
244 DEFAULT_BUFFER_SIZE);
245
246 self->skipped_last = 0;
247 self->skip_from_timestamp = GST_CLOCK_TIME_NONE;
248 self->skip_to_timestamp = GST_CLOCK_TIME_NONE;
249 }
250
251 void
gst_decklink_audio_src_set_property(GObject * object,guint property_id,const GValue * value,GParamSpec * pspec)252 gst_decklink_audio_src_set_property (GObject * object, guint property_id,
253 const GValue * value, GParamSpec * pspec)
254 {
255 GstDecklinkAudioSrc *self = GST_DECKLINK_AUDIO_SRC_CAST (object);
256
257 switch (property_id) {
258 case PROP_CONNECTION:
259 self->connection =
260 (GstDecklinkAudioConnectionEnum) g_value_get_enum (value);
261 break;
262 case PROP_DEVICE_NUMBER:
263 self->device_number = g_value_get_int (value);
264 break;
265 case PROP_ALIGNMENT_THRESHOLD:
266 self->alignment_threshold = g_value_get_uint64 (value);
267 break;
268 case PROP_DISCONT_WAIT:
269 self->discont_wait = g_value_get_uint64 (value);
270 break;
271 case PROP_BUFFER_SIZE:
272 self->buffer_size = g_value_get_uint (value);
273 break;
274 case PROP_CHANNELS:
275 self->channels = (GstDecklinkAudioChannelsEnum) g_value_get_enum (value);
276 break;
277 default:
278 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
279 break;
280 }
281 }
282
283 void
gst_decklink_audio_src_get_property(GObject * object,guint property_id,GValue * value,GParamSpec * pspec)284 gst_decklink_audio_src_get_property (GObject * object, guint property_id,
285 GValue * value, GParamSpec * pspec)
286 {
287 GstDecklinkAudioSrc *self = GST_DECKLINK_AUDIO_SRC_CAST (object);
288
289 switch (property_id) {
290 case PROP_CONNECTION:
291 g_value_set_enum (value, self->connection);
292 break;
293 case PROP_DEVICE_NUMBER:
294 g_value_set_int (value, self->device_number);
295 break;
296 case PROP_ALIGNMENT_THRESHOLD:
297 g_value_set_uint64 (value, self->alignment_threshold);
298 break;
299 case PROP_DISCONT_WAIT:
300 g_value_set_uint64 (value, self->discont_wait);
301 break;
302 case PROP_BUFFER_SIZE:
303 g_value_set_uint (value, self->buffer_size);
304 break;
305 case PROP_CHANNELS:
306 g_value_set_enum (value, self->channels);
307 break;
308 case PROP_HW_SERIAL_NUMBER:
309 if (self->input)
310 g_value_set_string (value, self->input->hw_serial_number);
311 else
312 g_value_set_string (value, NULL);
313 break;
314 default:
315 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
316 break;
317 }
318 }
319
320 void
gst_decklink_audio_src_finalize(GObject * object)321 gst_decklink_audio_src_finalize (GObject * object)
322 {
323 GstDecklinkAudioSrc *self = GST_DECKLINK_AUDIO_SRC_CAST (object);
324
325 g_mutex_clear (&self->lock);
326 g_cond_clear (&self->cond);
327 if (self->current_packets) {
328 while (gst_queue_array_get_length (self->current_packets) > 0) {
329 CapturePacket *tmp = (CapturePacket *)
330 gst_queue_array_pop_head_struct (self->current_packets);
331 capture_packet_clear (tmp);
332 }
333 gst_queue_array_free (self->current_packets);
334 self->current_packets = NULL;
335 }
336
337 G_OBJECT_CLASS (parent_class)->finalize (object);
338 }
339
340 static gboolean
gst_decklink_audio_src_start(GstDecklinkAudioSrc * self)341 gst_decklink_audio_src_start (GstDecklinkAudioSrc * self)
342 {
343 BMDAudioSampleType sample_depth;
344 HRESULT ret;
345 BMDAudioConnection conn = (BMDAudioConnection) - 1;
346 GstCaps *allowed_caps, *caps;
347
348 g_mutex_lock (&self->input->lock);
349 if (self->input->audio_enabled) {
350 g_mutex_unlock (&self->input->lock);
351 return TRUE;
352 }
353 g_mutex_unlock (&self->input->lock);
354
355 /* Negotiate the format / sample depth with downstream */
356 allowed_caps = gst_pad_get_allowed_caps (GST_BASE_SRC_PAD (self));
357 if (!allowed_caps)
358 allowed_caps = gst_pad_get_pad_template_caps (GST_BASE_SRC_PAD (self));
359
360 sample_depth = bmdAudioSampleType32bitInteger;
361 if (!gst_caps_is_empty (allowed_caps)) {
362 GstStructure *s;
363
364 allowed_caps = gst_caps_simplify (allowed_caps);
365
366 s = gst_caps_get_structure (allowed_caps, 0);
367
368 /* If it's not a string then both formats are supported */
369 if (gst_structure_has_field_typed (s, "format", G_TYPE_STRING)) {
370 const gchar *format = gst_structure_get_string (s, "format");
371 if (g_str_equal (format, "S16LE")) {
372 sample_depth = bmdAudioSampleType16bitInteger;
373 }
374 }
375 }
376 gst_caps_unref (allowed_caps);
377
378 switch (self->connection) {
379 case GST_DECKLINK_AUDIO_CONNECTION_AUTO:{
380 GstElement *videosrc = NULL;
381 GstDecklinkConnectionEnum vconn;
382
383 // Try to get the connection from the videosrc and try
384 // to select a sensible audio connection based on that
385 g_mutex_lock (&self->input->lock);
386 if (self->input->videosrc)
387 videosrc = GST_ELEMENT_CAST (gst_object_ref (self->input->videosrc));
388 g_mutex_unlock (&self->input->lock);
389
390 if (videosrc) {
391 g_object_get (videosrc, "connection", &vconn, NULL);
392 gst_object_unref (videosrc);
393
394 switch (vconn) {
395 case GST_DECKLINK_CONNECTION_SDI:
396 conn = bmdAudioConnectionEmbedded;
397 break;
398 case GST_DECKLINK_CONNECTION_HDMI:
399 conn = bmdAudioConnectionEmbedded;
400 break;
401 case GST_DECKLINK_CONNECTION_OPTICAL_SDI:
402 conn = bmdAudioConnectionEmbedded;
403 break;
404 case GST_DECKLINK_CONNECTION_COMPONENT:
405 conn = bmdAudioConnectionAnalog;
406 break;
407 case GST_DECKLINK_CONNECTION_COMPOSITE:
408 conn = bmdAudioConnectionAnalog;
409 break;
410 case GST_DECKLINK_CONNECTION_SVIDEO:
411 conn = bmdAudioConnectionAnalog;
412 break;
413 default:
414 // Use default
415 break;
416 }
417 }
418
419 break;
420 }
421 case GST_DECKLINK_AUDIO_CONNECTION_EMBEDDED:
422 conn = bmdAudioConnectionEmbedded;
423 break;
424 case GST_DECKLINK_AUDIO_CONNECTION_AES_EBU:
425 conn = bmdAudioConnectionAESEBU;
426 break;
427 case GST_DECKLINK_AUDIO_CONNECTION_ANALOG:
428 conn = bmdAudioConnectionAnalog;
429 break;
430 case GST_DECKLINK_AUDIO_CONNECTION_ANALOG_XLR:
431 conn = bmdAudioConnectionAnalogXLR;
432 break;
433 case GST_DECKLINK_AUDIO_CONNECTION_ANALOG_RCA:
434 conn = bmdAudioConnectionAnalogRCA;
435 break;
436 default:
437 g_assert_not_reached ();
438 break;
439 }
440
441 if (conn != (BMDAudioConnection) - 1) {
442 ret =
443 self->input->config->SetInt (bmdDeckLinkConfigAudioInputConnection,
444 conn);
445 if (ret != S_OK) {
446 GST_ERROR ("set configuration (audio input connection): 0x%08lx",
447 (unsigned long) ret);
448 return FALSE;
449 }
450 }
451
452 ret = self->input->input->EnableAudioInput (bmdAudioSampleRate48kHz,
453 sample_depth, self->channels_found);
454 if (ret != S_OK) {
455 GST_WARNING_OBJECT (self, "Failed to enable audio input: 0x%08lx",
456 (unsigned long) ret);
457 return FALSE;
458 }
459 gst_audio_info_set_format (&self->info,
460 sample_depth ==
461 bmdAudioSampleType16bitInteger ? GST_AUDIO_FORMAT_S16LE :
462 GST_AUDIO_FORMAT_S32LE, 48000, self->channels_found, NULL);
463
464 g_mutex_lock (&self->input->lock);
465 self->input->audio_enabled = TRUE;
466 if (self->input->start_streams && self->input->videosrc)
467 self->input->start_streams (self->input->videosrc);
468 g_mutex_unlock (&self->input->lock);
469
470 caps = gst_audio_info_to_caps (&self->info);
471 if (!gst_base_src_set_caps (GST_BASE_SRC (self), caps)) {
472 gst_caps_unref (caps);
473 GST_WARNING_OBJECT (self, "Failed to set caps");
474 return FALSE;
475 }
476 gst_caps_unref (caps);
477
478 self->skipped_last = 0;
479 self->skip_from_timestamp = GST_CLOCK_TIME_NONE;
480 self->skip_to_timestamp = GST_CLOCK_TIME_NONE;
481
482 return TRUE;
483 }
484
485 static void
gst_decklink_audio_src_got_packet(GstElement * element,IDeckLinkAudioInputPacket * packet,GstClockTime capture_time,GstClockTime stream_time,GstClockTime stream_duration,GstClockTime hardware_time,GstClockTime hardware_duration,gboolean no_signal)486 gst_decklink_audio_src_got_packet (GstElement * element,
487 IDeckLinkAudioInputPacket * packet, GstClockTime capture_time,
488 GstClockTime stream_time, GstClockTime stream_duration,
489 GstClockTime hardware_time, GstClockTime hardware_duration,
490 gboolean no_signal)
491 {
492 GstDecklinkAudioSrc *self = GST_DECKLINK_AUDIO_SRC_CAST (element);
493 GstClockTime timestamp = GST_CLOCK_TIME_NONE;
494
495 GST_LOG_OBJECT (self,
496 "Got audio packet at %" GST_TIME_FORMAT " / %" GST_TIME_FORMAT
497 ", no signal %d", GST_TIME_ARGS (capture_time),
498 GST_TIME_ARGS (stream_time), no_signal);
499
500 g_mutex_lock (&self->input->lock);
501 if (self->input->videosrc) {
502 GstDecklinkVideoSrc *videosrc =
503 GST_DECKLINK_VIDEO_SRC_CAST (gst_object_ref (self->input->videosrc));
504
505 if (videosrc->drop_no_signal_frames && no_signal) {
506 g_mutex_unlock (&self->input->lock);
507 return;
508 }
509
510 if (videosrc->first_time == GST_CLOCK_TIME_NONE)
511 videosrc->first_time = stream_time;
512
513 if (GST_CLOCK_TIME_IS_VALID (videosrc->first_time) &&
514 GST_CLOCK_TIME_IS_VALID (stream_time) &&
515 videosrc->skip_first_time > 0 &&
516 stream_time - videosrc->first_time < videosrc->skip_first_time) {
517 GST_DEBUG_OBJECT (self,
518 "Skipping frame as requested: %" GST_TIME_FORMAT " < %"
519 GST_TIME_FORMAT, GST_TIME_ARGS (stream_time),
520 GST_TIME_ARGS (videosrc->skip_first_time + videosrc->first_time));
521 g_mutex_unlock (&self->input->lock);
522 return;
523 }
524
525 if (videosrc->output_stream_time)
526 timestamp = stream_time;
527 else if (GST_CLOCK_TIME_IS_VALID (stream_time))
528 timestamp = gst_clock_adjust_with_calibration (NULL, stream_time,
529 videosrc->current_time_mapping.xbase,
530 videosrc->current_time_mapping.b, videosrc->current_time_mapping.num,
531 videosrc->current_time_mapping.den);
532 } else {
533 timestamp = capture_time;
534 }
535 g_mutex_unlock (&self->input->lock);
536
537 GST_LOG_OBJECT (self, "Converted times to %" GST_TIME_FORMAT,
538 GST_TIME_ARGS (timestamp));
539
540 g_mutex_lock (&self->lock);
541 if (!self->flushing) {
542 CapturePacket p;
543 guint skipped_packets = 0;
544
545 while (gst_queue_array_get_length (self->current_packets) >=
546 self->buffer_size) {
547 CapturePacket *tmp = (CapturePacket *)
548 gst_queue_array_pop_head_struct (self->current_packets);
549 if (skipped_packets == 0 && self->skipped_last == 0)
550 self->skip_from_timestamp = tmp->timestamp;
551 skipped_packets++;
552 self->skip_to_timestamp = tmp->timestamp;
553 capture_packet_clear (tmp);
554 }
555
556 if (self->skipped_last == 0 && skipped_packets > 0) {
557 GST_WARNING_OBJECT (self, "Starting to drop audio packets");
558 }
559
560 if (skipped_packets == 0 && self->skipped_last > 0) {
561 GST_ELEMENT_WARNING_WITH_DETAILS (self,
562 STREAM, FAILED,
563 ("Dropped %u old packets from %" GST_TIME_FORMAT " to %"
564 GST_TIME_FORMAT, self->skipped_last,
565 GST_TIME_ARGS (self->skip_from_timestamp),
566 GST_TIME_ARGS (self->skip_to_timestamp)),
567 (NULL),
568 ("dropped", G_TYPE_UINT, self->skipped_last,
569 "from", G_TYPE_UINT64, self->skip_from_timestamp,
570 "to", G_TYPE_UINT64, self->skip_to_timestamp, NULL));
571 self->skipped_last = 0;
572 }
573 self->skipped_last += skipped_packets;
574
575 memset (&p, 0, sizeof (p));
576 p.packet = packet;
577 p.timestamp = timestamp;
578 p.stream_timestamp = stream_time;
579 p.stream_duration = stream_duration;
580 p.hardware_timestamp = hardware_time;
581 p.hardware_duration = hardware_duration;
582 p.no_signal = no_signal;
583 packet->AddRef ();
584 gst_queue_array_push_tail_struct (self->current_packets, &p);
585 g_cond_signal (&self->cond);
586 }
587 g_mutex_unlock (&self->lock);
588 }
589
590 static GstFlowReturn
gst_decklink_audio_src_create(GstPushSrc * bsrc,GstBuffer ** buffer)591 gst_decklink_audio_src_create (GstPushSrc * bsrc, GstBuffer ** buffer)
592 {
593 GstDecklinkAudioSrc *self = GST_DECKLINK_AUDIO_SRC_CAST (bsrc);
594 GstFlowReturn flow_ret = GST_FLOW_OK;
595 const guint8 *data;
596 glong sample_count;
597 gsize data_size;
598 CapturePacket p;
599 AudioPacket *ap;
600 GstClockTime timestamp, duration;
601 GstClockTime start_time, end_time;
602 guint64 start_offset, end_offset;
603 gboolean discont = FALSE;
604 static GstStaticCaps stream_reference =
605 GST_STATIC_CAPS ("timestamp/x-decklink-stream");
606 static GstStaticCaps hardware_reference =
607 GST_STATIC_CAPS ("timestamp/x-decklink-hardware");
608
609 if (!gst_decklink_audio_src_start (self)) {
610 return GST_FLOW_NOT_NEGOTIATED;
611 }
612
613 retry:
614 g_mutex_lock (&self->lock);
615 while (gst_queue_array_is_empty (self->current_packets) && !self->flushing) {
616 g_cond_wait (&self->cond, &self->lock);
617 }
618
619 if (self->flushing) {
620 GST_DEBUG_OBJECT (self, "Flushing");
621 g_mutex_unlock (&self->lock);
622 return GST_FLOW_FLUSHING;
623 }
624
625 p = *(CapturePacket *)
626 gst_queue_array_pop_head_struct (self->current_packets);
627 g_mutex_unlock (&self->lock);
628
629 p.packet->GetBytes ((gpointer *) & data);
630 sample_count = p.packet->GetSampleFrameCount ();
631 data_size = self->info.bpf * sample_count;
632
633 timestamp = p.timestamp;
634
635 if (!GST_CLOCK_TIME_IS_VALID (timestamp)) {
636 if (self->next_offset == (guint64) - 1) {
637 GST_DEBUG_OBJECT (self,
638 "Got packet without timestamp before initial "
639 "timestamp after discont - dropping");
640 capture_packet_clear (&p);
641 goto retry;
642 } else {
643 GST_INFO_OBJECT (self, "Unknown timestamp value");
644
645 /* Likely the case where IDeckLinkInputCallback::VideoInputFrameArrived()
646 * didn't provide video frame, so no reference video stream timestamp
647 * is available. It can happen as per SDK documentation
648 * under the following circumstances:
649 * - On Intensity Pro with progressive NTSC only, every video frame will
650 * have two audio packets.
651 * - With 3:2 pulldown there are five audio packets for each four
652 * video frames.
653 * - If video processing is not fast enough, audio will still be delivered
654 *
655 * Assume there was no packet drop from previous valid packet, and use
656 * previously calculated expected timestamp here */
657 timestamp = gst_util_uint64_scale (self->next_offset,
658 GST_SECOND, self->info.rate);
659 }
660 }
661
662 ap = (AudioPacket *) g_malloc0 (sizeof (AudioPacket));
663
664 *buffer =
665 gst_buffer_new_wrapped_full ((GstMemoryFlags) GST_MEMORY_FLAG_READONLY,
666 (gpointer) data, data_size, 0, data_size, ap,
667 (GDestroyNotify) audio_packet_free);
668
669 ap->packet = p.packet;
670 p.packet->AddRef ();
671 ap->input = self->input->input;
672 ap->input->AddRef ();
673
674 // Jitter and discontinuity handling, based on audiobasesrc
675 start_time = timestamp;
676
677 // Convert to the sample numbers
678 start_offset =
679 gst_util_uint64_scale (start_time, self->info.rate, GST_SECOND);
680 // Convert back to round down to a sample multiple and get rid of rounding errors
681 start_time = gst_util_uint64_scale (start_offset, GST_SECOND, self->info.rate);
682
683 end_offset = start_offset + sample_count;
684 end_time = gst_util_uint64_scale_int (end_offset, GST_SECOND,
685 self->info.rate);
686
687 duration = end_time - start_time;
688
689 if (self->next_offset == (guint64) - 1) {
690 discont = TRUE;
691 } else {
692 guint64 diff, max_sample_diff;
693
694 // Check discont
695 if (start_offset <= self->next_offset)
696 diff = self->next_offset - start_offset;
697 else
698 diff = start_offset - self->next_offset;
699
700 max_sample_diff =
701 gst_util_uint64_scale_int (self->alignment_threshold, self->info.rate,
702 GST_SECOND);
703
704 // Discont!
705 if (self->alignment_threshold > 0
706 && self->alignment_threshold != GST_CLOCK_TIME_NONE
707 && G_UNLIKELY (diff >= max_sample_diff)) {
708 if (self->discont_wait > 0) {
709 if (self->discont_time == GST_CLOCK_TIME_NONE) {
710 self->discont_time = start_time;
711 } else if (start_time - self->discont_time >= self->discont_wait) {
712 discont = TRUE;
713 self->discont_time = GST_CLOCK_TIME_NONE;
714 }
715 } else {
716 discont = TRUE;
717 }
718 } else if (G_UNLIKELY (self->discont_time != GST_CLOCK_TIME_NONE)) {
719 // we have had a discont, but are now back on track!
720 self->discont_time = GST_CLOCK_TIME_NONE;
721 }
722 }
723
724 if (discont) {
725 // Have discont, need resync and use the capture timestamps
726 if (self->next_offset != (guint64) - 1)
727 GST_INFO_OBJECT (self, "Have discont. Expected %"
728 G_GUINT64_FORMAT ", got %" G_GUINT64_FORMAT,
729 self->next_offset, start_offset);
730 GST_BUFFER_FLAG_SET (*buffer, GST_BUFFER_FLAG_DISCONT);
731 self->next_offset = end_offset;
732 // Got a discont and adjusted, reset the discont_time marker.
733 self->discont_time = GST_CLOCK_TIME_NONE;
734 } else if (self->alignment_threshold == 0) {
735 // Don't align, just pass through timestamps
736 } else {
737 // No discont, just keep counting
738 timestamp =
739 gst_util_uint64_scale (self->next_offset, GST_SECOND, self->info.rate);
740 self->next_offset += sample_count;
741 duration =
742 gst_util_uint64_scale (self->next_offset, GST_SECOND,
743 self->info.rate) - timestamp;
744 }
745
746 // Detect gaps in stream time
747 self->processed += sample_count;
748 if (self->expected_stream_time != GST_CLOCK_TIME_NONE
749 && p.stream_timestamp == GST_CLOCK_TIME_NONE) {
750 /* We missed a frame. Extrapolate the timestamps */
751 p.stream_timestamp = self->expected_stream_time;
752 p.stream_duration =
753 gst_util_uint64_scale_int (sample_count, GST_SECOND, self->info.rate);
754 }
755 if (self->last_hardware_time != GST_CLOCK_TIME_NONE
756 && p.hardware_timestamp == GST_CLOCK_TIME_NONE) {
757 /* This should always happen when the previous one also does, but let's
758 * have two separate checks just in case */
759 GstClockTime start_hw_offset, end_hw_offset;
760 start_hw_offset =
761 gst_util_uint64_scale (self->last_hardware_time, self->info.rate,
762 GST_SECOND);
763 end_hw_offset = start_hw_offset + sample_count;
764 p.hardware_timestamp =
765 gst_util_uint64_scale_int (end_hw_offset, GST_SECOND, self->info.rate);
766 /* Will be the same as the stream duration - reuse it */
767 p.hardware_duration = p.stream_duration;
768 }
769
770 if (p.stream_timestamp != GST_CLOCK_TIME_NONE) {
771 GstClockTime start_stream_time, end_stream_time;
772
773 start_stream_time = p.stream_timestamp;
774
775 start_offset =
776 gst_util_uint64_scale (start_stream_time, self->info.rate, GST_SECOND);
777
778 end_offset = start_offset + sample_count;
779 end_stream_time = gst_util_uint64_scale_int (end_offset, GST_SECOND,
780 self->info.rate);
781
782 /* With drop-frame we have gaps of 1 sample every now and then (rounding
783 * errors because of the samples-per-frame pattern which is not 100%
784 * accurate), and due to rounding errors in the calculations these can be
785 * 2>x>1 */
786 if (self->expected_stream_time != GST_CLOCK_TIME_NONE &&
787 ABSDIFF (self->expected_stream_time, p.stream_timestamp) >
788 gst_util_uint64_scale (2, GST_SECOND, self->info.rate)) {
789 GstMessage *msg;
790 GstClockTime running_time;
791
792 self->dropped +=
793 gst_util_uint64_scale (ABSDIFF (self->expected_stream_time,
794 p.stream_timestamp), self->info.rate, GST_SECOND);
795 running_time =
796 gst_segment_to_running_time (&GST_BASE_SRC (self)->segment,
797 GST_FORMAT_TIME, timestamp);
798
799 msg =
800 gst_message_new_qos (GST_OBJECT (self), TRUE, running_time,
801 p.stream_timestamp, timestamp, duration);
802 gst_message_set_qos_stats (msg, GST_FORMAT_DEFAULT, self->processed,
803 self->dropped);
804 gst_element_post_message (GST_ELEMENT (self), msg);
805 }
806 self->expected_stream_time = end_stream_time;
807 }
808 self->last_hardware_time = p.hardware_timestamp;
809
810 if (p.no_signal)
811 GST_BUFFER_FLAG_SET (*buffer, GST_BUFFER_FLAG_GAP);
812 GST_BUFFER_TIMESTAMP (*buffer) = timestamp;
813 GST_BUFFER_DURATION (*buffer) = duration;
814
815 gst_buffer_add_reference_timestamp_meta (*buffer,
816 gst_static_caps_get (&stream_reference), p.stream_timestamp,
817 p.stream_duration);
818 gst_buffer_add_reference_timestamp_meta (*buffer,
819 gst_static_caps_get (&hardware_reference), p.hardware_timestamp,
820 p.hardware_duration);
821
822 GST_DEBUG_OBJECT (self,
823 "Outputting buffer %p with timestamp %" GST_TIME_FORMAT " and duration %"
824 GST_TIME_FORMAT, *buffer, GST_TIME_ARGS (GST_BUFFER_TIMESTAMP (*buffer)),
825 GST_TIME_ARGS (GST_BUFFER_DURATION (*buffer)));
826
827 capture_packet_clear (&p);
828
829 return flow_ret;
830 }
831
832 static GstCaps *
gst_decklink_audio_src_get_caps(GstBaseSrc * bsrc,GstCaps * filter)833 gst_decklink_audio_src_get_caps (GstBaseSrc * bsrc, GstCaps * filter)
834 {
835 GstDecklinkAudioSrc *self = GST_DECKLINK_AUDIO_SRC_CAST (bsrc);
836 GstCaps *caps, *template_caps;
837 const GstStructure *s;
838 gint channels;
839
840 channels = self->channels;
841 if (channels == 0)
842 channels = self->channels_found;
843
844 template_caps = gst_pad_get_pad_template_caps (GST_BASE_SRC_PAD (bsrc));
845 if (channels == 0) {
846 caps = template_caps;
847 } else {
848 if (channels > 2)
849 s = gst_caps_get_structure (template_caps, 1);
850 else
851 s = gst_caps_get_structure (template_caps, 0);
852
853 caps = gst_caps_new_full (gst_structure_copy (s), NULL);
854 gst_caps_set_simple (caps, "channels", G_TYPE_INT, channels, NULL);
855 gst_caps_unref (template_caps);
856 }
857
858 if (filter) {
859 GstCaps *tmp =
860 gst_caps_intersect_full (filter, caps, GST_CAPS_INTERSECT_FIRST);
861 gst_caps_unref (caps);
862 caps = tmp;
863 }
864
865 return caps;
866 }
867
868 static gboolean
gst_decklink_audio_src_query(GstBaseSrc * bsrc,GstQuery * query)869 gst_decklink_audio_src_query (GstBaseSrc * bsrc, GstQuery * query)
870 {
871 GstDecklinkAudioSrc *self = GST_DECKLINK_AUDIO_SRC_CAST (bsrc);
872 gboolean ret = TRUE;
873
874 switch (GST_QUERY_TYPE (query)) {
875 case GST_QUERY_LATENCY:{
876 if (self->input) {
877 g_mutex_lock (&self->input->lock);
878 if (self->input->mode) {
879 GstClockTime min, max;
880
881 min =
882 gst_util_uint64_scale_ceil (GST_SECOND, self->input->mode->fps_d,
883 self->input->mode->fps_n);
884 max = self->buffer_size * min;
885
886 gst_query_set_latency (query, TRUE, min, max);
887 ret = TRUE;
888 } else {
889 ret = FALSE;
890 }
891 g_mutex_unlock (&self->input->lock);
892 } else {
893 ret = FALSE;
894 }
895
896 break;
897 }
898 default:
899 ret = GST_BASE_SRC_CLASS (parent_class)->query (bsrc, query);
900 break;
901 }
902
903 return ret;
904 }
905
906 static gboolean
gst_decklink_audio_src_unlock(GstBaseSrc * bsrc)907 gst_decklink_audio_src_unlock (GstBaseSrc * bsrc)
908 {
909 GstDecklinkAudioSrc *self = GST_DECKLINK_AUDIO_SRC_CAST (bsrc);
910
911 g_mutex_lock (&self->lock);
912 self->flushing = TRUE;
913 g_cond_signal (&self->cond);
914 g_mutex_unlock (&self->lock);
915
916 return TRUE;
917 }
918
919 static gboolean
gst_decklink_audio_src_unlock_stop(GstBaseSrc * bsrc)920 gst_decklink_audio_src_unlock_stop (GstBaseSrc * bsrc)
921 {
922 GstDecklinkAudioSrc *self = GST_DECKLINK_AUDIO_SRC_CAST (bsrc);
923
924 g_mutex_lock (&self->lock);
925 self->flushing = FALSE;
926 while (gst_queue_array_get_length (self->current_packets) > 0) {
927 CapturePacket *tmp = (CapturePacket *)
928 gst_queue_array_pop_head_struct (self->current_packets);
929 capture_packet_clear (tmp);
930 }
931 g_mutex_unlock (&self->lock);
932
933 return TRUE;
934 }
935
936 static gboolean
gst_decklink_audio_src_open(GstDecklinkAudioSrc * self)937 gst_decklink_audio_src_open (GstDecklinkAudioSrc * self)
938 {
939 GST_DEBUG_OBJECT (self, "Opening");
940
941 self->input =
942 gst_decklink_acquire_nth_input (self->device_number,
943 GST_ELEMENT_CAST (self), TRUE);
944 if (!self->input) {
945 GST_ERROR_OBJECT (self, "Failed to acquire input");
946 return FALSE;
947 }
948
949 g_object_notify (G_OBJECT (self), "hw-serial-number");
950
951 g_mutex_lock (&self->input->lock);
952 if (self->channels > 0) {
953 self->channels_found = self->channels;
954 } else {
955 if (self->input->attributes) {
956 int64_t channels_found;
957
958 HRESULT ret = self->input->attributes->GetInt
959 (BMDDeckLinkMaximumAudioChannels, &channels_found);
960 self->channels_found = channels_found;
961
962 /* Sometimes the card may report an invalid number of channels. In
963 * that case, we should (empirically) use 8. */
964 if (ret != S_OK ||
965 self->channels_found == 0 || g_enum_get_value ((GEnumClass *)
966 g_type_class_peek (GST_TYPE_DECKLINK_AUDIO_CHANNELS),
967 self->channels_found)
968 == NULL) {
969 self->channels_found = GST_DECKLINK_AUDIO_CHANNELS_8;
970 }
971 }
972 }
973 self->input->got_audio_packet = gst_decklink_audio_src_got_packet;
974 g_mutex_unlock (&self->input->lock);
975
976 return TRUE;
977 }
978
979 static gboolean
gst_decklink_audio_src_close(GstDecklinkAudioSrc * self)980 gst_decklink_audio_src_close (GstDecklinkAudioSrc * self)
981 {
982 GST_DEBUG_OBJECT (self, "Closing");
983
984 if (self->input) {
985 g_mutex_lock (&self->input->lock);
986 self->input->got_audio_packet = NULL;
987 g_mutex_unlock (&self->input->lock);
988
989 gst_decklink_release_nth_input (self->device_number,
990 GST_ELEMENT_CAST (self), TRUE);
991 self->input = NULL;
992 }
993
994 return TRUE;
995 }
996
997 static gboolean
gst_decklink_audio_src_stop(GstDecklinkAudioSrc * self)998 gst_decklink_audio_src_stop (GstDecklinkAudioSrc * self)
999 {
1000 GST_DEBUG_OBJECT (self, "Stopping");
1001
1002 while (gst_queue_array_get_length (self->current_packets) > 0) {
1003 CapturePacket *tmp = (CapturePacket *)
1004 gst_queue_array_pop_head_struct (self->current_packets);
1005 capture_packet_clear (tmp);
1006 }
1007
1008 if (self->input && self->input->audio_enabled) {
1009 g_mutex_lock (&self->input->lock);
1010 self->input->audio_enabled = FALSE;
1011 g_mutex_unlock (&self->input->lock);
1012
1013 self->input->input->DisableAudioInput ();
1014 }
1015
1016 return TRUE;
1017 }
1018
1019 #if 0
1020 static gboolean
1021 in_same_pipeline (GstElement * a, GstElement * b)
1022 {
1023 GstObject *root = NULL, *tmp;
1024 gboolean ret = FALSE;
1025
1026 tmp = gst_object_get_parent (GST_OBJECT_CAST (a));
1027 while (tmp != NULL) {
1028 if (root)
1029 gst_object_unref (root);
1030 root = tmp;
1031 tmp = gst_object_get_parent (root);
1032 }
1033
1034 ret = root && gst_object_has_ancestor (GST_OBJECT_CAST (b), root);
1035
1036 if (root)
1037 gst_object_unref (root);
1038
1039 return ret;
1040 }
1041 #endif
1042
1043 static GstStateChangeReturn
gst_decklink_audio_src_change_state(GstElement * element,GstStateChange transition)1044 gst_decklink_audio_src_change_state (GstElement * element,
1045 GstStateChange transition)
1046 {
1047 GstDecklinkAudioSrc *self = GST_DECKLINK_AUDIO_SRC_CAST (element);
1048 GstStateChangeReturn ret;
1049
1050 switch (transition) {
1051 case GST_STATE_CHANGE_NULL_TO_READY:
1052 self->processed = 0;
1053 self->dropped = 0;
1054 self->expected_stream_time = GST_CLOCK_TIME_NONE;
1055 if (!gst_decklink_audio_src_open (self)) {
1056 ret = GST_STATE_CHANGE_FAILURE;
1057 goto out;
1058 }
1059 break;
1060 case GST_STATE_CHANGE_READY_TO_PAUSED:{
1061 GstElement *videosrc = NULL;
1062
1063 // Check if there is a video src for this input too and if it
1064 // is actually in the same pipeline
1065 g_mutex_lock (&self->input->lock);
1066 if (self->input->videosrc)
1067 videosrc = GST_ELEMENT_CAST (gst_object_ref (self->input->videosrc));
1068 g_mutex_unlock (&self->input->lock);
1069
1070 if (!videosrc) {
1071 GST_ELEMENT_ERROR (self, STREAM, FAILED,
1072 (NULL), ("Audio src needs a video src for its operation"));
1073 ret = GST_STATE_CHANGE_FAILURE;
1074 goto out;
1075 }
1076 // FIXME: This causes deadlocks sometimes
1077 #if 0
1078 else if (!in_same_pipeline (GST_ELEMENT_CAST (self), videosrc)) {
1079 GST_ELEMENT_ERROR (self, STREAM, FAILED,
1080 (NULL),
1081 ("Audio src and video src need to be in the same pipeline"));
1082 ret = GST_STATE_CHANGE_FAILURE;
1083 gst_object_unref (videosrc);
1084 goto out;
1085 }
1086 #endif
1087
1088 if (videosrc)
1089 gst_object_unref (videosrc);
1090
1091 self->flushing = FALSE;
1092 self->next_offset = -1;
1093 break;
1094 }
1095 default:
1096 break;
1097 }
1098
1099 ret = GST_ELEMENT_CLASS (parent_class)->change_state (element, transition);
1100 if (ret == GST_STATE_CHANGE_FAILURE)
1101 return ret;
1102
1103 switch (transition) {
1104 case GST_STATE_CHANGE_PAUSED_TO_READY:
1105 gst_decklink_audio_src_stop (self);
1106 break;
1107 case GST_STATE_CHANGE_READY_TO_NULL:
1108 gst_decklink_audio_src_close (self);
1109 break;
1110 default:
1111 break;
1112 }
1113 out:
1114
1115 return ret;
1116 }
1117