mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2024-11-23 10:11:08 +00:00
decklink{audio,video}src: Only start the streams once both sources are ready and we are in PLAYING
Otherwise we might start the streams before the audio or video streams are actually enabled, and then error out later because they are enabled to late. We enable the streams when getting the caps, which might be *after* we were set to PLAYING state.
This commit is contained in:
parent
00176a1ddf
commit
e2ff5587fe
3 changed files with 38 additions and 14 deletions
|
@ -148,7 +148,6 @@ struct _GstDecklinkOutput {
|
|||
/* Set by the audio sink */
|
||||
GstClock *audio_clock;
|
||||
|
||||
/* <private> */
|
||||
GstElement *audiosink;
|
||||
gboolean audio_enabled;
|
||||
GstElement *videosink;
|
||||
|
@ -176,11 +175,11 @@ struct _GstDecklinkInput {
|
|||
/* Set by the audio source */
|
||||
void (*got_audio_packet) (GstElement *videosrc, IDeckLinkAudioInputPacket * packet, GstClockTime capture_time);
|
||||
|
||||
/* <private> */
|
||||
GstElement *audiosrc;
|
||||
gboolean audio_enabled;
|
||||
GstElement *videosrc;
|
||||
gboolean video_enabled;
|
||||
void (*start_streams) (GstElement *videosrc);
|
||||
};
|
||||
|
||||
GstDecklinkOutput * gst_decklink_acquire_nth_output (gint n, GstElement * sink, gboolean is_audio);
|
||||
|
|
|
@ -381,6 +381,8 @@ gst_decklink_audio_src_set_caps (GstBaseSrc * bsrc, GstCaps * caps)
|
|||
|
||||
g_mutex_lock (&self->input->lock);
|
||||
self->input->audio_enabled = TRUE;
|
||||
if (self->input->start_streams)
|
||||
self->input->start_streams (self->input->videosrc);
|
||||
g_mutex_unlock (&self->input->lock);
|
||||
|
||||
return TRUE;
|
||||
|
@ -657,6 +659,8 @@ gst_decklink_audio_src_close (GstDecklinkAudioSrc * self)
|
|||
g_mutex_lock (&self->input->lock);
|
||||
self->input->got_audio_packet = NULL;
|
||||
self->input->audio_enabled = FALSE;
|
||||
if (self->input->start_streams)
|
||||
self->input->start_streams (self->input->videosrc);
|
||||
g_mutex_unlock (&self->input->lock);
|
||||
|
||||
self->input->input->DisableAudioInput ();
|
||||
|
|
|
@ -100,6 +100,8 @@ static GstFlowReturn gst_decklink_video_src_create (GstPushSrc * psrc,
|
|||
static gboolean gst_decklink_video_src_open (GstDecklinkVideoSrc * self);
|
||||
static gboolean gst_decklink_video_src_close (GstDecklinkVideoSrc * self);
|
||||
|
||||
static void gst_decklink_video_src_start_streams (GstElement * element);
|
||||
|
||||
#define parent_class gst_decklink_video_src_parent_class
|
||||
G_DEFINE_TYPE (GstDecklinkVideoSrc, gst_decklink_video_src, GST_TYPE_PUSH_SRC);
|
||||
|
||||
|
@ -329,6 +331,8 @@ gst_decklink_video_src_set_caps (GstBaseSrc * bsrc, GstCaps * caps)
|
|||
g_mutex_lock (&self->input->lock);
|
||||
self->input->mode = mode;
|
||||
self->input->video_enabled = TRUE;
|
||||
if (self->input->start_streams)
|
||||
self->input->start_streams (self->input->videosrc);
|
||||
g_mutex_unlock (&self->input->lock);
|
||||
|
||||
return TRUE;
|
||||
|
@ -551,6 +555,7 @@ gst_decklink_video_src_open (GstDecklinkVideoSrc * self)
|
|||
g_mutex_lock (&self->input->lock);
|
||||
self->input->mode = mode;
|
||||
self->input->got_video_frame = gst_decklink_video_src_got_frame;
|
||||
self->input->start_streams = gst_decklink_video_src_start_streams;
|
||||
self->input->clock_start_time = GST_CLOCK_TIME_NONE;
|
||||
self->input->clock_last_time = 0;
|
||||
self->input->clock_offset = 0;
|
||||
|
@ -570,6 +575,8 @@ gst_decklink_video_src_close (GstDecklinkVideoSrc * self)
|
|||
self->input->got_video_frame = NULL;
|
||||
self->input->mode = NULL;
|
||||
self->input->video_enabled = FALSE;
|
||||
if (self->input->start_streams)
|
||||
self->input->start_streams (self->input->videosrc);
|
||||
g_mutex_unlock (&self->input->lock);
|
||||
|
||||
self->input->input->DisableVideoInput ();
|
||||
|
@ -581,6 +588,29 @@ gst_decklink_video_src_close (GstDecklinkVideoSrc * self)
|
|||
return TRUE;
|
||||
}
|
||||
|
||||
static void
|
||||
gst_decklink_video_src_start_streams (GstElement * element)
|
||||
{
|
||||
GstDecklinkVideoSrc *self = GST_DECKLINK_VIDEO_SRC_CAST (element);
|
||||
HRESULT res;
|
||||
|
||||
if (self->input->video_enabled && (!self->input->audiosrc
|
||||
|| self->input->audio_enabled)
|
||||
&& GST_STATE (self) == GST_STATE_PLAYING) {
|
||||
GST_DEBUG_OBJECT (self, "Starting streams");
|
||||
res = self->input->input->StartStreams ();
|
||||
if (res != S_OK) {
|
||||
GST_ELEMENT_ERROR (self, STREAM, FAILED,
|
||||
(NULL), ("Failed to start streams: 0x%08x", res));
|
||||
return;
|
||||
}
|
||||
self->input->started = TRUE;
|
||||
self->input->clock_restart = TRUE;
|
||||
} else {
|
||||
GST_DEBUG_OBJECT (self, "Not starting streams yet");
|
||||
}
|
||||
}
|
||||
|
||||
static GstStateChangeReturn
|
||||
gst_decklink_video_src_change_state (GstElement * element,
|
||||
GstStateChange transition)
|
||||
|
@ -588,7 +618,6 @@ gst_decklink_video_src_change_state (GstElement * element,
|
|||
GstDecklinkVideoSrc *self = GST_DECKLINK_VIDEO_SRC_CAST (element);
|
||||
GstStateChangeReturn ret;
|
||||
|
||||
|
||||
switch (transition) {
|
||||
case GST_STATE_CHANGE_NULL_TO_READY:
|
||||
if (!gst_decklink_video_src_open (self)) {
|
||||
|
@ -660,19 +689,11 @@ gst_decklink_video_src_change_state (GstElement * element,
|
|||
break;
|
||||
}
|
||||
case GST_STATE_CHANGE_PAUSED_TO_PLAYING:{
|
||||
HRESULT res;
|
||||
|
||||
GST_DEBUG_OBJECT (self, "Starting streams");
|
||||
res = self->input->input->StartStreams ();
|
||||
if (res != S_OK) {
|
||||
GST_ELEMENT_ERROR (self, STREAM, FAILED,
|
||||
(NULL), ("Failed to start streams: 0x%08x", res));
|
||||
ret = GST_STATE_CHANGE_FAILURE;
|
||||
}
|
||||
g_mutex_lock (&self->input->lock);
|
||||
self->input->started = TRUE;
|
||||
self->input->clock_restart = TRUE;
|
||||
if (self->input->start_streams)
|
||||
self->input->start_streams (self->input->videosrc);
|
||||
g_mutex_unlock (&self->input->lock);
|
||||
|
||||
break;
|
||||
}
|
||||
case GST_STATE_CHANGE_READY_TO_NULL:
|
||||
|
|
Loading…
Reference in a new issue