From c9596c9b82245434cfc07fa70cfc9115ba62ad74 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20Dr=C3=B6ge?= Date: Mon, 4 Apr 2016 22:21:30 +0300 Subject: decklinkaudiosrc: Don't crash when receiving video frames but no audio And mark these events as disconts to reset time tracking in the audio source. https://bugzilla.gnome.org/show_bug.cgi?id=747633 --- sys/decklink/gstdecklink.cpp | 13 +++++++++---- sys/decklink/gstdecklink.h | 3 ++- sys/decklink/gstdecklinkaudiosrc.cpp | 7 +++++-- 3 files changed, 16 insertions(+), 7 deletions(-) diff --git a/sys/decklink/gstdecklink.cpp b/sys/decklink/gstdecklink.cpp index 8a2f10144..6d68a9a8a 100644 --- a/sys/decklink/gstdecklink.cpp +++ b/sys/decklink/gstdecklink.cpp @@ -479,7 +479,7 @@ public: IDeckLinkVideoInputFrame * frame, GstDecklinkModeEnum mode, GstClockTime capture_time, GstClockTime capture_duration) = NULL; void (*got_audio_packet) (GstElement * videosrc, - IDeckLinkAudioInputPacket * packet, GstClockTime capture_time) = NULL; + IDeckLinkAudioInputPacket * packet, GstClockTime capture_time, gboolean discont) = NULL; GstDecklinkModeEnum mode; BMDTimeValue capture_time, capture_duration; HRESULT res; @@ -526,9 +526,13 @@ public: } no_video_frame: - - if (audio_packet && got_audio_packet && audiosrc) { - m_input->got_audio_packet (audiosrc, audio_packet, capture_time); + if (got_audio_packet && audiosrc && audio_packet) { + m_input->got_audio_packet (audiosrc, audio_packet, capture_time, m_input->audio_discont); + m_input->audio_discont = FALSE; + } else { + m_input->audio_discont = TRUE; + if (!audio_packet) + GST_DEBUG ("Received no audio packet at %" GST_TIME_FORMAT, GST_TIME_ARGS (capture_time)); } gst_object_replace ((GstObject **) & videosrc, NULL); @@ -779,6 +783,7 @@ gst_decklink_acquire_nth_input (gint n, GstElement * src, gboolean is_audio) g_mutex_lock (&input->lock); if (is_audio && !input->audiosrc) { input->audiosrc = GST_ELEMENT_CAST (gst_object_ref (src)); + input->audio_discont = TRUE; g_mutex_unlock (&input->lock); return input; } else if (!input->videosrc) { diff --git a/sys/decklink/gstdecklink.h b/sys/decklink/gstdecklink.h index 353769faa..418023dca 100644 --- a/sys/decklink/gstdecklink.h +++ b/sys/decklink/gstdecklink.h @@ -174,10 +174,11 @@ struct _GstDecklinkInput { const GstDecklinkMode *mode; /* Set by the audio source */ - void (*got_audio_packet) (GstElement *videosrc, IDeckLinkAudioInputPacket * packet, GstClockTime capture_time); + void (*got_audio_packet) (GstElement *videosrc, IDeckLinkAudioInputPacket * packet, GstClockTime capture_time, gboolean discont); GstElement *audiosrc; gboolean audio_enabled; + gboolean audio_discont; GstElement *videosrc; gboolean video_enabled; void (*start_streams) (GstElement *videosrc); diff --git a/sys/decklink/gstdecklinkaudiosrc.cpp b/sys/decklink/gstdecklinkaudiosrc.cpp index 1171ff368..6360c2a72 100644 --- a/sys/decklink/gstdecklinkaudiosrc.cpp +++ b/sys/decklink/gstdecklinkaudiosrc.cpp @@ -57,6 +57,7 @@ typedef struct { IDeckLinkAudioInputPacket *packet; GstClockTime capture_time; + gboolean discont; } CapturePacket; static void @@ -411,7 +412,7 @@ gst_decklink_audio_src_get_caps (GstBaseSrc * bsrc, GstCaps * filter) static void gst_decklink_audio_src_got_packet (GstElement * element, - IDeckLinkAudioInputPacket * packet, GstClockTime capture_time) + IDeckLinkAudioInputPacket * packet, GstClockTime capture_time, gboolean discont) { GstDecklinkAudioSrc *self = GST_DECKLINK_AUDIO_SRC_CAST (element); GstDecklinkVideoSrc *videosrc = NULL; @@ -447,6 +448,7 @@ gst_decklink_audio_src_got_packet (GstElement * element, p = (CapturePacket *) g_malloc0 (sizeof (CapturePacket)); p->packet = packet; p->capture_time = capture_time; + p->discont = discont; packet->AddRef (); g_queue_push_tail (&self->current_packets, p); g_cond_signal (&self->cond); @@ -501,6 +503,7 @@ gst_decklink_audio_src_create (GstPushSrc * bsrc, GstBuffer ** buffer) ap->input->AddRef (); timestamp = p->capture_time; + discont = p->discont; // Jitter and discontinuity handling, based on audiobasesrc start_time = timestamp; @@ -515,7 +518,7 @@ gst_decklink_audio_src_create (GstPushSrc * bsrc, GstBuffer ** buffer) duration = end_time - start_time; - if (self->next_offset == (guint64) - 1) { + if (discont || self->next_offset == (guint64) - 1) { discont = TRUE; } else { guint64 diff, max_sample_diff; -- cgit v1.2.1