static GstStateChangeReturn gst_decklink_video_src_change_state (GstElement * element, GstStateChange transition) { GstDecklinkVideoSrc *self = GST_DECKLINK_VIDEO_SRC_CAST (element); GstStateChangeReturn ret = GST_STATE_CHANGE_SUCCESS; switch (transition) { case GST_STATE_CHANGE_NULL_TO_READY: if (!gst_decklink_video_src_open (self)) { ret = GST_STATE_CHANGE_FAILURE; goto out; } if (self->mode == GST_DECKLINK_MODE_AUTO && self->video_format != GST_DECKLINK_VIDEO_FORMAT_AUTO) { GST_WARNING_OBJECT (self, "Warning: mode=auto and format!=auto may \ not work"); } break; case GST_STATE_CHANGE_READY_TO_PAUSED: g_mutex_lock (&self->input->lock); self->input->clock_start_time = GST_CLOCK_TIME_NONE; self->input->clock_epoch += self->input->clock_last_time; self->input->clock_last_time = 0; self->input->clock_offset = 0; g_mutex_unlock (&self->input->lock); gst_element_post_message (element, gst_message_new_clock_provide (GST_OBJECT_CAST (element), self->input->clock, TRUE)); self->flushing = FALSE; break; case GST_STATE_CHANGE_PAUSED_TO_PLAYING:{ GstClock *clock; clock = gst_element_get_clock (GST_ELEMENT_CAST (self)); if (clock) { if (clock != self->input->clock) { gst_clock_set_master (self->input->clock, clock); } gst_object_unref (clock); } else { GST_ELEMENT_ERROR (self, STREAM, FAILED, (NULL), ("Need a clock to go to PLAYING")); ret = GST_STATE_CHANGE_FAILURE; } break; } default: break; }
static GstStateChangeReturn gst_decklink_video_src_change_state (GstElement * element, GstStateChange transition) { 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)) { ret = GST_STATE_CHANGE_FAILURE; goto out; } break; case GST_STATE_CHANGE_READY_TO_PAUSED: g_mutex_lock (&self->input->lock); self->input->clock_start_time = GST_CLOCK_TIME_NONE; self->input->clock_last_time = 0; self->input->clock_offset = 0; g_mutex_unlock (&self->input->lock); gst_element_post_message (element, gst_message_new_clock_provide (GST_OBJECT_CAST (element), self->input->clock, TRUE)); self->flushing = FALSE; break; case GST_STATE_CHANGE_PAUSED_TO_PLAYING:{ GstClock *clock; clock = gst_element_get_clock (GST_ELEMENT_CAST (self)); if (clock && clock != self->input->clock) { gst_clock_set_master (self->input->clock, clock); } if (clock) gst_object_unref (clock); break; } default: break; } ret = GST_ELEMENT_CLASS (parent_class)->change_state (element, transition); if (ret == GST_STATE_CHANGE_FAILURE) return ret; switch (transition) { case GST_STATE_CHANGE_PAUSED_TO_READY: gst_element_post_message (element, gst_message_new_clock_lost (GST_OBJECT_CAST (element), self->input->clock)); gst_clock_set_master (self->input->clock, NULL); // Reset calibration to make the clock reusable next time we use it gst_clock_set_calibration (self->input->clock, 0, 0, 1, 1); g_mutex_lock (&self->input->lock); self->input->clock_start_time = GST_CLOCK_TIME_NONE; self->input->clock_last_time = 0; self->input->clock_offset = 0; g_mutex_unlock (&self->input->lock); g_queue_foreach (&self->current_frames, (GFunc) capture_frame_free, NULL); g_queue_clear (&self->current_frames); self->caps_mode = GST_DECKLINK_MODE_AUTO; break; case GST_STATE_CHANGE_PLAYING_TO_PAUSED:{ HRESULT res; GST_DEBUG_OBJECT (self, "Stopping streams"); g_mutex_lock (&self->input->lock); self->input->started = FALSE; g_mutex_unlock (&self->input->lock); res = self->input->input->StopStreams (); if (res != S_OK) { GST_ELEMENT_ERROR (self, STREAM, FAILED, (NULL), ("Failed to stop streams: 0x%08x", res)); ret = GST_STATE_CHANGE_FAILURE; } self->internal_base_time = GST_CLOCK_TIME_NONE; self->external_base_time = GST_CLOCK_TIME_NONE; break; } case GST_STATE_CHANGE_PAUSED_TO_PLAYING:{ g_mutex_lock (&self->input->lock); 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: gst_decklink_video_src_close (self); break; default: break; } out: return ret; }