static gboolean gst_sctp_dec_src_event(GstPad *pad, GstSctpDec *self, GstEvent *event) { switch (GST_EVENT_TYPE(event)) { case GST_EVENT_RECONFIGURE: case GST_EVENT_FLUSH_STOP: { GstSctpDecPad *sctpdec_pad = GST_SCTP_DEC_PAD(pad); /* Unflush and start task again */ gst_data_queue_set_flushing(sctpdec_pad->packet_queue, FALSE); gst_pad_start_task(pad, (GstTaskFunction)gst_sctp_data_srcpad_loop, pad, NULL); return gst_pad_event_default(pad, GST_OBJECT(self), event); } case GST_EVENT_FLUSH_START: { GstSctpDecPad *sctpdec_pad = GST_SCTP_DEC_PAD(pad); gst_data_queue_set_flushing(sctpdec_pad->packet_queue, TRUE); gst_data_queue_flush(sctpdec_pad->packet_queue); return gst_pad_event_default(pad, GST_OBJECT(self), event); } default: return gst_pad_event_default(pad, GST_OBJECT(self), event); } }
static void flush_srcpad(const GValue *item, gpointer user_data) { GstSctpDecPad *sctpdec_pad = g_value_get_object(item); gboolean flush = GPOINTER_TO_INT(user_data); if (flush) { gst_data_queue_set_flushing(sctpdec_pad->packet_queue, TRUE); gst_data_queue_flush(sctpdec_pad->packet_queue); } else { gst_data_queue_set_flushing(sctpdec_pad->packet_queue, FALSE); gst_pad_start_task(GST_PAD(sctpdec_pad), (GstTaskFunction)gst_sctp_data_srcpad_loop, sctpdec_pad, NULL); } }
static gboolean gst_eglglessink_stop (GstEglGlesSink * eglglessink) { GST_DEBUG_OBJECT (eglglessink, "Stopping"); gst_data_queue_set_flushing (eglglessink->queue, TRUE); g_mutex_lock (eglglessink->render_lock); g_cond_broadcast (eglglessink->render_cond); g_mutex_unlock (eglglessink->render_lock); if (eglglessink->thread) { g_thread_join (eglglessink->thread); eglglessink->thread = NULL; } eglglessink->last_flow = GST_FLOW_WRONG_STATE; if (eglglessink->using_own_window) { gst_egl_adaptation_destroy_native_window (eglglessink->egl_context, &eglglessink->own_window_data); eglglessink->have_window = FALSE; } if (eglglessink->current_caps) { gst_caps_unref (eglglessink->current_caps); eglglessink->current_caps = NULL; } GST_DEBUG_OBJECT (eglglessink, "Stopped"); return TRUE; }
static gboolean gst_sctp_enc_src_activate_mode (GstPad * pad, GstObject * parent, GstPadMode mode, gboolean active) { GstSctpEnc *self = GST_SCTP_ENC(parent); gboolean ret = FALSE; switch (mode) { case GST_PAD_MODE_PUSH: if (active) { self->need_segment = self->need_stream_start_caps = TRUE; gst_data_queue_set_flushing(self->outbound_sctp_packet_queue, FALSE); gst_pad_start_task(self->src_pad, (GstTaskFunction)gst_sctp_enc_srcpad_loop, self->src_pad, NULL); ret = configure_association(self); } else { sctpenc_cleanup(self); ret = TRUE; } GST_DEBUG_OBJECT (self, "activate_mode: active %d, ret %d", active, ret); break; default: break; } return ret; }
static void gst_sctp_data_srcpad_loop(GstPad *pad) { GstSctpDecPad *sctpdec_pad = GST_SCTP_DEC_PAD(pad); GstDataQueueItem *item; if (gst_data_queue_pop(sctpdec_pad->packet_queue, &item)) { GstFlowReturn flow_ret; flow_ret = gst_pad_push(pad, GST_BUFFER(item->object)); item->object = NULL; if (G_UNLIKELY(flow_ret == GST_FLOW_FLUSHING || flow_ret == GST_FLOW_NOT_LINKED)) { GST_DEBUG_OBJECT(pad, "Push failed on packet source pad. Error: %s", gst_flow_get_name(flow_ret)); } else if (G_UNLIKELY(flow_ret != GST_FLOW_OK)) { GST_ERROR_OBJECT(pad, "Push failed on packet source pad. Error: %s", gst_flow_get_name(flow_ret)); } if (G_UNLIKELY(flow_ret != GST_FLOW_OK)) { GST_DEBUG_OBJECT(pad, "Pausing task because of an error"); gst_data_queue_set_flushing(sctpdec_pad->packet_queue, TRUE); gst_data_queue_flush(sctpdec_pad->packet_queue); gst_pad_pause_task(pad); } item->destroy(item); } else { GST_DEBUG_OBJECT(pad, "Pausing task because we're flushing"); gst_pad_pause_task(pad); } }
static void splitmux_part_pad_finalize (GObject * obj) { GstSplitMuxPartPad *pad = (GstSplitMuxPartPad *) (obj); GST_DEBUG_OBJECT (obj, "finalize"); gst_data_queue_set_flushing (pad->queue, TRUE); gst_data_queue_flush (pad->queue); gst_object_unref (GST_OBJECT_CAST (pad->queue)); pad->queue = NULL; G_OBJECT_CLASS (gst_splitmux_part_pad_parent_class)->finalize (obj); }
static gboolean gst_eglglessink_start (GstEglGlesSink * eglglessink) { GError *error = NULL; GST_DEBUG_OBJECT (eglglessink, "Starting"); if (!eglglessink->egl_started) { GST_ERROR_OBJECT (eglglessink, "EGL uninitialized. Bailing out"); goto HANDLE_ERROR; } /* Ask for a window to render to */ if (!eglglessink->have_window) gst_x_overlay_prepare_xwindow_id (GST_X_OVERLAY (eglglessink)); if (!eglglessink->have_window && !eglglessink->create_window) { GST_ERROR_OBJECT (eglglessink, "Window handle unavailable and we " "were instructed not to create an internal one. Bailing out."); goto HANDLE_ERROR; } eglglessink->last_flow = GST_FLOW_OK; eglglessink->display_region.w = 0; eglglessink->display_region.h = 0; gst_data_queue_set_flushing (eglglessink->queue, FALSE); #if !GLIB_CHECK_VERSION (2, 31, 0) eglglessink->thread = g_thread_create ((GThreadFunc) render_thread_func, eglglessink, TRUE, &error); #else eglglessink->thread = g_thread_try_new ("eglglessink-render", (GThreadFunc) render_thread_func, eglglessink, &error); #endif if (!eglglessink->thread || error != NULL) goto HANDLE_ERROR; GST_DEBUG_OBJECT (eglglessink, "Started"); return TRUE; HANDLE_ERROR: GST_ERROR_OBJECT (eglglessink, "Couldn't start"); g_clear_error (&error); return FALSE; }
void gst_splitmux_part_reader_set_flushing_locked (GstSplitMuxPartReader * reader, gboolean flushing) { GList *cur; GST_LOG_OBJECT (reader, "%s dataqueues", flushing ? "Flushing" : "Done flushing"); for (cur = g_list_first (reader->pads); cur != NULL; cur = g_list_next (cur)) { GstSplitMuxPartPad *part_pad = SPLITMUX_PART_PAD_CAST (cur->data); gst_data_queue_set_flushing (part_pad->queue, flushing); if (flushing) gst_data_queue_flush (part_pad->queue); } };
static gboolean splitmux_part_pad_event (GstPad * pad, GstObject * parent, GstEvent * event) { GstSplitMuxPartPad *part_pad = SPLITMUX_PART_PAD_CAST (pad); GstSplitMuxPartReader *reader = part_pad->reader; gboolean ret = TRUE; SplitMuxSrcPad *target; GstDataQueueItem *item; SPLITMUX_PART_LOCK (reader); target = gst_object_ref (part_pad->target); GST_LOG_OBJECT (reader, "Pad %" GST_PTR_FORMAT " event %" GST_PTR_FORMAT, pad, event); if (part_pad->flushing && GST_EVENT_TYPE (event) != GST_EVENT_FLUSH_STOP) goto drop_event; switch (GST_EVENT_TYPE (event)) { case GST_EVENT_SEGMENT:{ GstSegment *seg = &part_pad->segment; GST_LOG_OBJECT (pad, "Received segment %" GST_PTR_FORMAT, event); gst_event_copy_segment (event, seg); gst_event_copy_segment (event, &part_pad->orig_segment); if (seg->format != GST_FORMAT_TIME) goto wrong_segment; /* Adjust segment */ /* Adjust start/stop so the overall file is 0 + start_offset based */ if (seg->stop != -1) { seg->stop -= seg->start; seg->stop += seg->time + reader->start_offset; } seg->start = seg->time + reader->start_offset; seg->time += reader->start_offset; seg->position += reader->start_offset; GST_LOG_OBJECT (pad, "Adjusted segment now %" GST_PTR_FORMAT, event); /* Replace event */ gst_event_unref (event); event = gst_event_new_segment (seg); if (reader->prep_state != PART_STATE_PREPARING_COLLECT_STREAMS && reader->prep_state != PART_STATE_PREPARING_MEASURE_STREAMS) break; /* Only do further stuff with segments during initial measuring */ /* Take the first segment from the first part */ if (target->segment.format == GST_FORMAT_UNDEFINED) { gst_segment_copy_into (seg, &target->segment); GST_DEBUG_OBJECT (reader, "Target pad segment now %" GST_SEGMENT_FORMAT, &target->segment); } if (seg->stop != -1 && target->segment.stop != -1) { GstClockTime stop = seg->base + seg->stop; if (stop > target->segment.stop) { target->segment.stop = stop; GST_DEBUG_OBJECT (reader, "Adjusting segment stop by %" GST_TIME_FORMAT " output now %" GST_SEGMENT_FORMAT, GST_TIME_ARGS (reader->start_offset), &target->segment); } } GST_LOG_OBJECT (pad, "Forwarding segment %" GST_PTR_FORMAT, event); break; } case GST_EVENT_EOS:{ GST_DEBUG_OBJECT (part_pad, "State %u EOS event. MaxTS seen %" GST_TIME_FORMAT, reader->prep_state, GST_TIME_ARGS (part_pad->max_ts)); if (reader->prep_state == PART_STATE_PREPARING_COLLECT_STREAMS || reader->prep_state == PART_STATE_PREPARING_MEASURE_STREAMS) { /* Mark this pad as EOS */ part_pad->is_eos = TRUE; if (splitmux_part_is_eos_locked (reader)) { /* Finished measuring things, set state and tell the state change func * so it can seek back to the start */ GST_LOG_OBJECT (reader, "EOS while measuring streams. Resetting for ready"); reader->prep_state = PART_STATE_PREPARING_RESET_FOR_READY; SPLITMUX_PART_BROADCAST (reader); } goto drop_event; } break; } case GST_EVENT_FLUSH_START: reader->flushing = TRUE; part_pad->flushing = TRUE; GST_LOG_OBJECT (reader, "Pad %" GST_PTR_FORMAT " flushing dataqueue", part_pad); gst_data_queue_set_flushing (part_pad->queue, TRUE); SPLITMUX_PART_BROADCAST (reader); break; case GST_EVENT_FLUSH_STOP:{ gst_data_queue_set_flushing (part_pad->queue, FALSE); gst_data_queue_flush (part_pad->queue); part_pad->seen_buffer = FALSE; part_pad->flushing = FALSE; part_pad->is_eos = FALSE; reader->flushing = splitmux_is_flushing (reader); GST_LOG_OBJECT (reader, "%s pad %" GST_PTR_FORMAT " flush_stop. Overall flushing=%d", reader->path, pad, reader->flushing); SPLITMUX_PART_BROADCAST (reader); break; } default: break; } /* Don't send events downstream while preparing */ if (reader->prep_state != PART_STATE_READY) goto drop_event; /* Don't pass flush events - those are done by the parent */ if (GST_EVENT_TYPE (event) == GST_EVENT_FLUSH_START || GST_EVENT_TYPE (event) == GST_EVENT_FLUSH_STOP) goto drop_event; if (!block_until_can_push (reader)) { SPLITMUX_PART_UNLOCK (reader); gst_object_unref (target); gst_event_unref (event); return FALSE; } switch (GST_EVENT_TYPE (event)) { case GST_EVENT_GAP:{ /* FIXME: Drop initial gap (if any) in each segment, not all GAPs */ goto drop_event; } default: break; } /* We are active, and one queue is empty, place this buffer in * the dataqueue */ gst_object_ref (part_pad->queue); SPLITMUX_PART_UNLOCK (reader); GST_LOG_OBJECT (reader, "Enqueueing event %" GST_PTR_FORMAT, event); item = g_slice_new (GstDataQueueItem); item->destroy = (GDestroyNotify) splitmux_part_free_queue_item; item->object = GST_MINI_OBJECT (event); item->size = 0; item->duration = 0; if (item->duration == GST_CLOCK_TIME_NONE) item->duration = 0; item->visible = FALSE; if (!gst_data_queue_push (part_pad->queue, item)) { splitmux_part_free_queue_item (item); ret = FALSE; } gst_object_unref (part_pad->queue); gst_object_unref (target); return ret; wrong_segment: gst_event_unref (event); gst_object_unref (target); SPLITMUX_PART_UNLOCK (reader); GST_ELEMENT_ERROR (reader, STREAM, FAILED, (NULL), ("Received non-time segment - reader %s pad %" GST_PTR_FORMAT, reader->path, pad)); return FALSE; drop_event: GST_LOG_OBJECT (pad, "Dropping event %" GST_PTR_FORMAT " from %" GST_PTR_FORMAT " on %" GST_PTR_FORMAT, event, pad, target); gst_event_unref (event); gst_object_unref (target); SPLITMUX_PART_UNLOCK (reader); return TRUE; }