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
This commit is contained in:
Sebastian Dröge 2016-04-04 22:21:30 +03:00
parent 8abff20185
commit 0004920c83
3 changed files with 16 additions and 7 deletions

View file

@ -530,7 +530,7 @@ public:
IDeckLinkVideoInputFrame * frame, GstDecklinkModeEnum mode, IDeckLinkVideoInputFrame * frame, GstDecklinkModeEnum mode,
GstClockTime capture_time, GstClockTime capture_duration) = NULL; GstClockTime capture_time, GstClockTime capture_duration) = NULL;
void (*got_audio_packet) (GstElement * videosrc, void (*got_audio_packet) (GstElement * videosrc,
IDeckLinkAudioInputPacket * packet, GstClockTime capture_time) = NULL; IDeckLinkAudioInputPacket * packet, GstClockTime capture_time, gboolean discont) = NULL;
GstDecklinkModeEnum mode; GstDecklinkModeEnum mode;
BMDTimeValue capture_time, capture_duration; BMDTimeValue capture_time, capture_duration;
HRESULT res; HRESULT res;
@ -577,9 +577,13 @@ public:
} }
no_video_frame: no_video_frame:
if (got_audio_packet && audiosrc && audio_packet) {
if (audio_packet && got_audio_packet && audiosrc) { m_input->got_audio_packet (audiosrc, audio_packet, capture_time, m_input->audio_discont);
m_input->got_audio_packet (audiosrc, audio_packet, capture_time); 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); gst_object_replace ((GstObject **) & videosrc, NULL);
@ -830,6 +834,7 @@ gst_decklink_acquire_nth_input (gint n, GstElement * src, gboolean is_audio)
g_mutex_lock (&input->lock); g_mutex_lock (&input->lock);
if (is_audio && !input->audiosrc) { if (is_audio && !input->audiosrc) {
input->audiosrc = GST_ELEMENT_CAST (gst_object_ref (src)); input->audiosrc = GST_ELEMENT_CAST (gst_object_ref (src));
input->audio_discont = TRUE;
g_mutex_unlock (&input->lock); g_mutex_unlock (&input->lock);
return input; return input;
} else if (!input->videosrc) { } else if (!input->videosrc) {

View file

@ -175,10 +175,11 @@ struct _GstDecklinkInput {
BMDPixelFormat format; BMDPixelFormat format;
/* Set by the audio source */ /* 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; GstElement *audiosrc;
gboolean audio_enabled; gboolean audio_enabled;
gboolean audio_discont;
GstElement *videosrc; GstElement *videosrc;
gboolean video_enabled; gboolean video_enabled;
void (*start_streams) (GstElement *videosrc); void (*start_streams) (GstElement *videosrc);

View file

@ -57,6 +57,7 @@ typedef struct
{ {
IDeckLinkAudioInputPacket *packet; IDeckLinkAudioInputPacket *packet;
GstClockTime capture_time; GstClockTime capture_time;
gboolean discont;
} CapturePacket; } CapturePacket;
static void static void
@ -410,7 +411,7 @@ gst_decklink_audio_src_get_caps (GstBaseSrc * bsrc, GstCaps * filter)
static void static void
gst_decklink_audio_src_got_packet (GstElement * element, 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); GstDecklinkAudioSrc *self = GST_DECKLINK_AUDIO_SRC_CAST (element);
GstDecklinkVideoSrc *videosrc = NULL; GstDecklinkVideoSrc *videosrc = NULL;
@ -446,6 +447,7 @@ gst_decklink_audio_src_got_packet (GstElement * element,
p = (CapturePacket *) g_malloc0 (sizeof (CapturePacket)); p = (CapturePacket *) g_malloc0 (sizeof (CapturePacket));
p->packet = packet; p->packet = packet;
p->capture_time = capture_time; p->capture_time = capture_time;
p->discont = discont;
packet->AddRef (); packet->AddRef ();
g_queue_push_tail (&self->current_packets, p); g_queue_push_tail (&self->current_packets, p);
g_cond_signal (&self->cond); g_cond_signal (&self->cond);
@ -500,6 +502,7 @@ gst_decklink_audio_src_create (GstPushSrc * bsrc, GstBuffer ** buffer)
ap->input->AddRef (); ap->input->AddRef ();
timestamp = p->capture_time; timestamp = p->capture_time;
discont = p->discont;
// Jitter and discontinuity handling, based on audiobasesrc // Jitter and discontinuity handling, based on audiobasesrc
start_time = timestamp; start_time = timestamp;
@ -514,7 +517,7 @@ gst_decklink_audio_src_create (GstPushSrc * bsrc, GstBuffer ** buffer)
duration = end_time - start_time; duration = end_time - start_time;
if (self->next_offset == (guint64) - 1) { if (discont || self->next_offset == (guint64) - 1) {
discont = TRUE; discont = TRUE;
} else { } else {
guint64 diff, max_sample_diff; guint64 diff, max_sample_diff;