/** * hls_progress_buffer_activatepush_src() * * Set the source pad's push mode. */ static gboolean hls_progress_buffer_activatepush_src(GstPad *pad, gboolean active) { HLSProgressBuffer *element = HLS_PROGRESS_BUFFER(GST_PAD_PARENT(pad)); if (active) { g_mutex_lock(element->lock); element->srcresult = GST_FLOW_OK; g_mutex_unlock(element->lock); if (gst_pad_is_linked(pad)) return gst_pad_start_task(pad, hls_progress_buffer_loop, element); else return TRUE; } else { g_mutex_lock(element->lock); element->srcresult = GST_FLOW_WRONG_STATE; g_cond_signal(element->add_cond); g_cond_signal(element->del_cond); g_mutex_unlock(element->lock); return gst_pad_stop_task(pad); } }
static gboolean gst_amc_video_dec_stop (GstVideoDecoder * decoder) { GstAmcVideoDec *self; GError *err = NULL; self = GST_AMC_VIDEO_DEC (decoder); GST_DEBUG_OBJECT (self, "Stopping decoder"); self->flushing = TRUE; if (self->started) { gst_amc_codec_flush (self->codec, &err); if (err) GST_ELEMENT_WARNING_FROM_ERROR (self, err); gst_amc_codec_stop (self->codec, &err); if (err) GST_ELEMENT_WARNING_FROM_ERROR (self, err); self->started = FALSE; } gst_pad_stop_task (GST_VIDEO_DECODER_SRC_PAD (decoder)); self->downstream_flow_ret = GST_FLOW_FLUSHING; self->drained = TRUE; g_mutex_lock (&self->drain_lock); self->draining = FALSE; g_cond_broadcast (&self->drain_cond); g_mutex_unlock (&self->drain_lock); g_free (self->codec_data); self->codec_data_size = 0; if (self->input_state) gst_video_codec_state_unref (self->input_state); self->input_state = NULL; GST_DEBUG_OBJECT (self, "Stopped decoder"); return TRUE; }
static gboolean gst_rnd_buffer_size_activate_mode (GstPad * pad, GstObject * parent, GstPadMode mode, gboolean active) { gboolean res; GstRndBufferSize *self = GST_RND_BUFFER_SIZE (parent); switch (mode) { case GST_PAD_MODE_PULL: if (active) { GST_INFO_OBJECT (self, "starting pull"); res = gst_pad_start_task (pad, (GstTaskFunction) gst_rnd_buffer_size_loop, self); self->need_newsegment = TRUE; } else { GST_INFO_OBJECT (self, "stopping pull"); res = gst_pad_stop_task (pad); } break; default: res = FALSE; break; } return res; }
static gboolean gst_v4l2_video_dec_flush (GstVideoDecoder * decoder) { GstV4l2VideoDec *self = GST_V4L2_VIDEO_DEC (decoder); GST_DEBUG_OBJECT (self, "Flushed"); /* Ensure the processing thread has stopped for the reverse playback * discount case */ if (gst_pad_get_task_state (decoder->srcpad) == GST_TASK_STARTED) { GST_VIDEO_DECODER_STREAM_UNLOCK (decoder); gst_v4l2_object_unlock (self->v4l2output); gst_v4l2_object_unlock (self->v4l2capture); gst_pad_stop_task (decoder->srcpad); GST_VIDEO_DECODER_STREAM_LOCK (decoder); } self->output_flow = GST_FLOW_OK; gst_v4l2_object_unlock_stop (self->v4l2output); gst_v4l2_object_unlock_stop (self->v4l2capture); return TRUE; }
static GstFlowReturn gst_vaapiencode_finish (GstVideoEncoder * venc) { GstVaapiEncode *const encode = GST_VAAPIENCODE_CAST (venc); GstVaapiEncoderStatus status; GstFlowReturn ret = GST_FLOW_OK; /* Don't try to destroy encoder if none was created in the first place. Return "not-negotiated" error since this means we did not even reach GstVideoEncoder::set_format() state, where the encoder could have been created */ if (!encode->encoder) return GST_FLOW_NOT_NEGOTIATED; status = gst_vaapi_encoder_flush (encode->encoder); GST_VIDEO_ENCODER_STREAM_UNLOCK (encode); gst_pad_stop_task (GST_VAAPI_PLUGIN_BASE_SRC_PAD (encode)); GST_VIDEO_ENCODER_STREAM_LOCK (encode); while (status == GST_VAAPI_ENCODER_STATUS_SUCCESS && ret == GST_FLOW_OK) ret = gst_vaapiencode_push_frame (encode, 0); if (ret == GST_VAAPI_ENCODE_FLOW_TIMEOUT) ret = GST_FLOW_OK; return ret; }
static gboolean mpegts_base_sink_activate_mode (GstPad * pad, GstObject * parent, GstPadMode mode, gboolean active) { gboolean res; MpegTSBase *base = GST_MPEGTS_BASE (parent); switch (mode) { case GST_PAD_MODE_PUSH: base->mode = BASE_MODE_PUSHING; res = TRUE; break; case GST_PAD_MODE_PULL: if (active) { base->mode = BASE_MODE_SCANNING; /* When working pull-based, we always use offsets for estimation */ base->packetizer->calculate_offset = TRUE; base->packetizer->calculate_skew = FALSE; gst_segment_init (&base->segment, GST_FORMAT_BYTES); res = gst_pad_start_task (pad, (GstTaskFunction) mpegts_base_loop, base, NULL); } else res = gst_pad_stop_task (pad); break; default: res = FALSE; break; } return res; }
static gboolean gst_asf_parse_sink_activate_mode (GstPad * pad, GstObject * parent, GstPadMode mode, gboolean active) { gboolean res; switch (mode) { case GST_PAD_MODE_PULL: if (active) { res = gst_pad_start_task (pad, (GstTaskFunction) gst_asf_parse_loop, pad, NULL); } else { res = gst_pad_stop_task (pad); } case GST_PAD_MODE_PUSH: res = TRUE; break; default: res = FALSE; break; } return res; }
static gboolean gst_v4l2_video_dec_sink_event (GstVideoDecoder * decoder, GstEvent * event) { GstV4l2VideoDec *self = GST_V4L2_VIDEO_DEC (decoder); gboolean ret; switch (GST_EVENT_TYPE (event)) { case GST_EVENT_FLUSH_START: GST_DEBUG_OBJECT (self, "flush start"); gst_v4l2_object_unlock (self->v4l2output); gst_v4l2_object_unlock (self->v4l2capture); break; default: break; } ret = GST_VIDEO_DECODER_CLASS (parent_class)->sink_event (decoder, event); switch (GST_EVENT_TYPE (event)) { case GST_EVENT_FLUSH_START: /* The processing thread should stop now, wait for it */ gst_pad_stop_task (decoder->srcpad); GST_DEBUG_OBJECT (self, "flush start done"); break; default: break; } return ret; }
static gboolean gst_omx_audio_dec_stop (GstAudioDecoder * decoder) { GstOMXAudioDec *self; self = GST_OMX_AUDIO_DEC (decoder); GST_DEBUG_OBJECT (self, "Stopping decoder"); gst_omx_port_set_flushing (self->dec_in_port, 5 * GST_SECOND, TRUE); gst_omx_port_set_flushing (self->dec_out_port, 5 * GST_SECOND, TRUE); gst_pad_stop_task (GST_AUDIO_DECODER_SRC_PAD (decoder)); if (gst_omx_component_get_state (self->dec, 0) > OMX_StateIdle) gst_omx_component_set_state (self->dec, OMX_StateIdle); self->downstream_flow_ret = GST_FLOW_FLUSHING; self->started = FALSE; g_mutex_lock (&self->drain_lock); self->draining = FALSE; g_cond_broadcast (&self->drain_cond); g_mutex_unlock (&self->drain_lock); gst_omx_component_get_state (self->dec, 5 * GST_SECOND); gst_buffer_replace (&self->codec_data, NULL); GST_DEBUG_OBJECT (self, "Stopped decoder"); return TRUE; }
static gboolean src_activate_mode(GstPad *pad, GstObject *parent, GstPadMode mode, gboolean active) { GstErDtlsEnc *self = GST_ER_DTLS_ENC (parent); gboolean success = TRUE; g_return_val_if_fail(mode == GST_PAD_MODE_PUSH, FALSE); if (active) { GST_DEBUG_OBJECT(self, "src pad activating in push mode"); self->send_initial_events = TRUE; success = gst_pad_start_task(pad, (GstTaskFunction) src_task_loop, self->src, NULL); if (!success) { GST_WARNING_OBJECT(self, "failed to activate pad task"); } } else { GST_DEBUG_OBJECT(self, "deactivating src pad"); g_mutex_lock(&self->queue_lock); GST_PAD_MODE(pad) = GST_PAD_MODE_NONE; g_cond_signal(&self->queue_cond_add); g_mutex_unlock(&self->queue_lock); success = gst_pad_stop_task(pad); if (!success) { GST_WARNING_OBJECT(self, "failed to deactivate pad task"); } } return success; }
static gboolean gst_real_audio_demux_sink_activate_mode (GstPad * sinkpad, GstObject * parent, GstPadMode mode, gboolean active) { gboolean res; GstRealAudioDemux *demux; demux = GST_REAL_AUDIO_DEMUX (parent); switch (mode) { case GST_PAD_MODE_PUSH: demux->seekable = FALSE; res = TRUE; break; case GST_PAD_MODE_PULL: if (active) { demux->seekable = TRUE; res = gst_pad_start_task (sinkpad, (GstTaskFunction) gst_real_audio_demux_loop, demux, NULL); } else { demux->seekable = FALSE; res = gst_pad_stop_task (sinkpad); } break; default: res = FALSE; break; } return res; }
static gboolean gst_v4l2_video_dec_stop (GstVideoDecoder * decoder) { GstV4l2VideoDec *self = GST_V4L2_VIDEO_DEC (decoder); GST_DEBUG_OBJECT (self, "Stopping"); gst_v4l2_object_unlock (self->v4l2output); gst_v4l2_object_unlock (self->v4l2capture); /* Wait for capture thread to stop */ gst_pad_stop_task (decoder->srcpad); GST_VIDEO_DECODER_STREAM_LOCK (decoder); self->output_flow = GST_FLOW_OK; GST_VIDEO_DECODER_STREAM_UNLOCK (decoder); /* Should have been flushed already */ g_assert (g_atomic_int_get (&self->active) == FALSE); gst_v4l2_object_stop (self->v4l2output); gst_v4l2_object_stop (self->v4l2capture); if (self->input_state) { gst_video_codec_state_unref (self->input_state); self->input_state = NULL; } GST_DEBUG_OBJECT (self, "Stopped"); return TRUE; }
static gboolean gst_live_adder_src_activate_push (GstPad * pad, gboolean active) { gboolean result = TRUE; GstLiveAdder *adder = NULL; adder = GST_LIVE_ADDER (gst_pad_get_parent (pad)); if (active) { /* Mark as non flushing */ GST_OBJECT_LOCK (adder); adder->srcresult = GST_FLOW_OK; GST_OBJECT_UNLOCK (adder); /* start pushing out buffers */ GST_DEBUG_OBJECT (adder, "Starting task on srcpad"); gst_pad_start_task (adder->srcpad, (GstTaskFunction) gst_live_adder_loop, adder); } else { /* make sure all data processing stops ASAP */ gst_live_adder_flush_start (adder); /* NOTE this will hardlock if the state change is called from the src pad * task thread because we will _join() the thread. */ GST_DEBUG_OBJECT (adder, "Stopping task on srcpad"); result = gst_pad_stop_task (pad); } gst_object_unref (adder); return result; }
static gboolean gst_rdt_manager_src_activate_mode (GstPad * pad, GstObject * parent, GstPadMode mode, gboolean active) { gboolean result; GstRDTManager *rdtmanager; GstRDTManagerSession *session; session = gst_pad_get_element_private (pad); rdtmanager = session->dec; switch (mode) { case GST_PAD_MODE_PUSH: if (active) { /* allow data processing */ JBUF_LOCK (session); GST_DEBUG_OBJECT (rdtmanager, "Enabling pop on queue"); /* Mark as non flushing */ session->srcresult = GST_FLOW_OK; gst_segment_init (&session->segment, GST_FORMAT_TIME); session->last_popped_seqnum = -1; session->last_out_time = -1; session->next_seqnum = -1; session->eos = FALSE; JBUF_UNLOCK (session); /* start pushing out buffers */ GST_DEBUG_OBJECT (rdtmanager, "Starting task on srcpad"); result = gst_pad_start_task (pad, (GstTaskFunction) gst_rdt_manager_loop, pad, NULL); } else { /* make sure all data processing stops ASAP */ JBUF_LOCK (session); /* mark ourselves as flushing */ session->srcresult = GST_FLOW_FLUSHING; GST_DEBUG_OBJECT (rdtmanager, "Disabling pop on queue"); /* this unblocks any waiting pops on the src pad task */ JBUF_SIGNAL (session); /* unlock clock, we just unschedule, the entry will be released by * the locking streaming thread. */ if (session->clock_id) gst_clock_id_unschedule (session->clock_id); JBUF_UNLOCK (session); /* NOTE this will hardlock if the state change is called from the src pad * task thread because we will _join() the thread. */ GST_DEBUG_OBJECT (rdtmanager, "Stopping task on srcpad"); result = gst_pad_stop_task (pad); } break; default: result = FALSE; break; } return result; }
static gboolean gst_timidity_activatepull (GstPad * pad, gboolean active) { if (active) { return gst_pad_start_task (pad, (GstTaskFunction) gst_timidity_loop, pad); } else { return gst_pad_stop_task (pad); } }
static gboolean activate_push (GstPad *pad, gboolean active) { gboolean result = TRUE; GstOmxBaseFilter *self; self = GST_OMX_BASE_FILTER (gst_pad_get_parent (pad)); if (active) { GST_DEBUG_OBJECT (self, "activate"); /* task may carry on */ g_atomic_int_set (&self->last_pad_push_return, GST_FLOW_OK); /* we do not start the task yet if the pad is not connected */ if (gst_pad_is_linked (pad)) { if (self->ready) { /** @todo link callback function also needed */ g_omx_port_resume (self->in_port); g_omx_port_resume (self->out_port); result = gst_pad_start_task (pad, output_loop, pad); } } } else { GST_DEBUG_OBJECT (self, "deactivate"); /* persuade task to bail out */ g_atomic_int_set (&self->last_pad_push_return, GST_FLOW_WRONG_STATE); if (self->ready) { /** @todo disable this until we properly reinitialize the buffers. */ #if 0 /* flush all buffers */ OMX_SendCommand (self->gomx->omx_handle, OMX_CommandFlush, OMX_ALL, NULL); #endif /* unlock loops */ g_omx_port_pause (self->in_port); g_omx_port_pause (self->out_port); } /* make sure streaming finishes */ result = gst_pad_stop_task (pad); } gst_object_unref (self); return result; }
/* this function gets called when we activate ourselves in pull mode. * We can perform random access to the resource and we start a task * to start reading */ static gboolean gst_pngdec_sink_activate_pull (GstPad * sinkpad, gboolean active) { if (active) { return gst_pad_start_task (sinkpad, (GstTaskFunction) gst_pngdec_task, sinkpad); } else { return gst_pad_stop_task (sinkpad); } }
static gboolean gst_tcp_mix_src_pad_stop (GstTCPMixSrcPad * pad, GstTaskFunction func) { gboolean res; if (GST_PAD_TASK (pad) != NULL) { // FIXME: pad->status == started res = gst_pad_stop_task (GST_PAD (pad)); } return res; }
static gboolean activate_push (GstPad *pad, gboolean active) { gboolean result = TRUE; GstOmxBaseFilter21 *self; int i; self = GST_OMX_BASE_FILTER21 (gst_pad_get_parent (pad)); if (active) { GST_DEBUG_OBJECT (self, "activate"); self->last_pad_push_return = GST_FLOW_OK; /* we do not start the task yet if the pad is not connected */ if (gst_pad_is_linked (pad)) { if (self->ready) { /** @todo link callback function also needed */ for (i = 0; i < NUM_INPUTS; i++) g_omx_port_resume (self->in_port[i]); g_omx_port_resume (self->out_port); //result = gst_pad_start_task (pad, output_loop, pad); } } } else { GST_DEBUG_OBJECT (self, "deactivate"); if (self->ready) { /* unlock loops */ for (i = 0; i < NUM_INPUTS; i++) g_omx_port_pause (self->in_port[i]); g_omx_port_pause (self->out_port); } /* make sure streaming finishes */ result = gst_pad_stop_task (pad); } gst_object_unref (self); return result; }
static gboolean gst_cdxa_parse_sink_activate_pull (GstPad * sinkpad, gboolean active) { if (active) { /* if we have a scheduler we can start the task */ gst_pad_start_task (sinkpad, (GstTaskFunction) gst_cdxa_parse_loop, sinkpad, NULL); } else { gst_pad_stop_task (sinkpad); } return TRUE; }
static void gst_omx_audio_dec_flush (GstAudioDecoder * decoder, gboolean hard) { GstOMXAudioDec *self = GST_OMX_AUDIO_DEC (decoder); OMX_ERRORTYPE err = OMX_ErrorNone; GST_DEBUG_OBJECT (self, "Flushing decoder"); if (gst_omx_component_get_state (self->dec, 0) == OMX_StateLoaded) return; /* 0) Pause the components */ if (gst_omx_component_get_state (self->dec, 0) == OMX_StateExecuting) { gst_omx_component_set_state (self->dec, OMX_StatePause); gst_omx_component_get_state (self->dec, GST_CLOCK_TIME_NONE); } /* 1) Wait until the srcpad loop is stopped, * unlock GST_AUDIO_DECODER_STREAM_LOCK to prevent deadlocks * caused by using this lock from inside the loop function */ GST_AUDIO_DECODER_STREAM_UNLOCK (self); gst_pad_stop_task (GST_AUDIO_DECODER_SRC_PAD (decoder)); GST_DEBUG_OBJECT (self, "Flushing -- task stopped"); GST_AUDIO_DECODER_STREAM_LOCK (self); /* 2) Flush the ports */ GST_DEBUG_OBJECT (self, "flushing ports"); gst_omx_port_set_flushing (self->dec_in_port, 5 * GST_SECOND, TRUE); gst_omx_port_set_flushing (self->dec_out_port, 5 * GST_SECOND, TRUE); /* 3) Resume components */ gst_omx_component_set_state (self->dec, OMX_StateExecuting); gst_omx_component_get_state (self->dec, GST_CLOCK_TIME_NONE); /* 4) Unset flushing to allow ports to accept data again */ gst_omx_port_set_flushing (self->dec_in_port, 5 * GST_SECOND, FALSE); gst_omx_port_set_flushing (self->dec_out_port, 5 * GST_SECOND, FALSE); err = gst_omx_port_populate (self->dec_out_port); if (err != OMX_ErrorNone) { GST_WARNING_OBJECT (self, "Failed to populate output port: %s (0x%08x)", gst_omx_error_to_string (err), err); } /* Reset our state */ self->last_upstream_ts = 0; self->downstream_flow_ret = GST_FLOW_OK; self->started = FALSE; GST_DEBUG_OBJECT (self, "Flush finished"); }
static gboolean gst_aiff_parse_sink_activate_pull (GstPad * sinkpad, gboolean active) { GstAiffParse *aiff = GST_AIFF_PARSE (GST_OBJECT_PARENT (sinkpad)); if (active) { aiff->segment_running = TRUE; return gst_pad_start_task (sinkpad, (GstTaskFunction) gst_aiff_parse_loop, sinkpad); } else { aiff->segment_running = FALSE; return gst_pad_stop_task (sinkpad); } };
static gboolean gst_rnd_buffer_size_activate_pull (GstPad * pad, gboolean active) { GstRndBufferSize *self = GST_RND_BUFFER_SIZE (GST_OBJECT_PARENT (pad)); if (active) { GST_INFO_OBJECT (self, "starting pull"); return gst_pad_start_task (pad, (GstTaskFunction) gst_rnd_buffer_size_loop, self); } else { GST_INFO_OBJECT (self, "stopping pull"); return gst_pad_stop_task (pad); } }
static gboolean gst_musepackdec_sink_activate_pull (GstPad * sinkpad, gboolean active) { gboolean result; if (active) { result = gst_pad_start_task (sinkpad, (GstTaskFunction) gst_musepackdec_loop, sinkpad); } else { result = gst_pad_stop_task (sinkpad); } return result; }
static gboolean gst_nuv_demux_sink_activate_pull (GstPad * sinkpad, gboolean active) { GstNuvDemux *nuv = GST_NUV_DEMUX (gst_pad_get_parent (sinkpad)); if (active) { gst_pad_start_task (sinkpad, (GstTaskFunction) gst_nuv_demux_loop, sinkpad); } else { gst_pad_stop_task (sinkpad); } gst_object_unref (nuv); return TRUE; }
static gboolean gst_wavpack_parse_sink_activate_pull (GstPad * sinkpad, gboolean active) { gboolean result; if (active) { result = gst_pad_start_task (sinkpad, (GstTaskFunction) gst_wavpack_parse_loop, GST_PAD_PARENT (sinkpad)); } else { result = gst_pad_stop_task (sinkpad); } return result; }
static GstFlowReturn gst_v4l2_video_dec_finish (GstVideoDecoder * decoder) { GstV4l2VideoDec *self = GST_V4L2_VIDEO_DEC (decoder); GstFlowReturn ret = GST_FLOW_OK; GstBuffer *buffer; if (!g_atomic_int_get (&self->processing)) goto done; GST_DEBUG_OBJECT (self, "Finishing decoding"); GST_VIDEO_DECODER_STREAM_UNLOCK (decoder); if (gst_v4l2_decoder_cmd (self->v4l2output, V4L2_DEC_CMD_STOP, 0)) { GstTask *task = decoder->srcpad->task; /* If the decoder stop command succeeded, just wait until processing is * finished */ GST_OBJECT_LOCK (task); while (GST_TASK_STATE (task) == GST_TASK_STARTED) GST_TASK_WAIT (task); GST_OBJECT_UNLOCK (task); ret = GST_FLOW_FLUSHING; } else { /* otherwise keep queuing empty buffers until the processing thread has * stopped, _pool_process() will return FLUSHING when that happened */ while (ret == GST_FLOW_OK) { buffer = gst_buffer_new (); ret = gst_v4l2_buffer_pool_process (GST_V4L2_BUFFER_POOL (self-> v4l2output->pool), &buffer); gst_buffer_unref (buffer); } } /* and ensure the processing thread has stopped in case another error * occured. */ gst_v4l2_object_unlock (self->v4l2capture); gst_pad_stop_task (decoder->srcpad); GST_VIDEO_DECODER_STREAM_LOCK (decoder); if (ret == GST_FLOW_FLUSHING) ret = self->output_flow; GST_DEBUG_OBJECT (decoder, "Done draining buffers"); done: return ret; }
/* this function gets called when we activate ourselves in pull mode. * We can perform random access to the resource and we start a task * to start reading */ static gboolean gst_pngdec_sink_activate_pull (GstPad * sinkpad, gboolean active) { GstPngDec *pngdec; pngdec = GST_PNGDEC (GST_OBJECT_PARENT (sinkpad)); if (active) { return gst_pad_start_task (sinkpad, (GstTaskFunction) gst_pngdec_task, sinkpad); } else { return gst_pad_stop_task (sinkpad); } }
static gboolean gst_tta_parse_activate_pull (GstPad * pad, gboolean active) { GstTtaParse *ttaparse = GST_TTA_PARSE (GST_OBJECT_PARENT (pad)); if (active) { gst_pad_start_task (pad, (GstTaskFunction) gst_tta_parse_loop, ttaparse, NULL); } else { gst_pad_stop_task (pad); } return TRUE; }
static gboolean gst_freeze_sink_activate_pull (GstPad * sinkpad, gboolean active) { gboolean result; if (active) { /* if we have a scheduler we can start the task */ result = gst_pad_start_task (sinkpad, (GstTaskFunction) gst_freeze_loop, sinkpad); } else { result = gst_pad_stop_task (sinkpad); } return result; }