static gboolean gst_rpi_cam_src_event (GstBaseSrc * parent, GstEvent * event) { GstRpiCamSrc *src = GST_RPICAMSRC (parent); gboolean ret; switch (GST_EVENT_TYPE (event)) { case GST_EVENT_CUSTOM_DOWNSTREAM: case GST_EVENT_CUSTOM_UPSTREAM: if (gst_video_event_is_force_key_unit (event)) { if (src->started) { ret = raspi_capture_request_i_frame (src->capture_state); } else { ret = FALSE; } gst_event_unref (event); } else { ret = GST_BASE_SRC_CLASS (parent_class)->event (parent, event); } break; default: ret = GST_BASE_SRC_CLASS (parent_class)->event (parent, event); break; } return ret; }
static GstPadProbeReturn encoder_appsink_event_probe (GstPad *pad, GstPadProbeInfo *info, gpointer data) { GstEvent *event = gst_pad_probe_info_get_event (info); Encoder *encoder = data; GstClockTime timestamp, running_time, stream_time; gboolean all_headers; guint count; if (GST_EVENT_TYPE (event) == GST_EVENT_EOS) { GST_ERROR ("End of Stream of encoder %s", encoder->name); *(encoder->output->eos) = TRUE; return GST_PAD_PROBE_OK; } if (!gst_video_event_is_force_key_unit (event)) { return GST_PAD_PROBE_OK; } /* force key unit event */ gst_video_event_parse_downstream_force_key_unit (event, ×tamp, &stream_time, &running_time, &all_headers, &count); if (encoder->last_segment_duration != 0) { encoder->last_running_time = timestamp; } return GST_PAD_PROBE_OK; }
static gboolean mpegtsmux_sink_event (GstPad * pad, GstEvent * event) { MpegTsMux *mux = GST_MPEG_TSMUX (gst_pad_get_parent (pad)); MpegTsPadData *ts_data; gboolean res = TRUE; gboolean forward = TRUE; ts_data = (MpegTsPadData *) gst_pad_get_element_private (pad); switch (GST_EVENT_TYPE (event)) { case GST_EVENT_CUSTOM_DOWNSTREAM: { GstClockTime timestamp, stream_time, running_time; gboolean all_headers; guint count; if (!gst_video_event_is_force_key_unit (event)) goto out; forward = FALSE; gst_video_event_parse_downstream_force_key_unit (event, ×tamp, &stream_time, &running_time, &all_headers, &count); GST_INFO_OBJECT (mux, "have downstream force-key-unit event on pad %s, " "seqnum %d, running-time %" GST_TIME_FORMAT " count %d", gst_pad_get_name (pad), gst_event_get_seqnum (event), GST_TIME_ARGS (running_time), count); if (mux->force_key_unit_event != NULL) { GST_INFO_OBJECT (mux, "skipping downstream force key unit event " "as an upstream force key unit is already queued"); goto out; } if (!all_headers) goto out; mux->pending_key_unit_ts = running_time; gst_event_replace (&mux->force_key_unit_event, event); break; } default: break; } out: if (forward) res = ts_data->eventfunc (pad, event); gst_object_unref (mux); return res; }
static GstPadProbeReturn control_duplicates (GstPad * pad, GstPadProbeInfo * info, gpointer data) { GstEvent *event = GST_PAD_PROBE_INFO_EVENT (info); if (gst_video_event_is_force_key_unit (event)) { if (check_last_request_time (pad)) { GST_TRACE_OBJECT (pad, "Sending keyframe request"); return GST_PAD_PROBE_OK; } else { GST_TRACE_OBJECT (pad, "Dropping keyframe request"); return GST_PAD_PROBE_DROP; } } return GST_PAD_PROBE_OK; }
static GstPadProbeReturn gst_hls_sink_ghost_event_probe (GstPad * pad, GstPadProbeInfo * info, gpointer data) { GstHlsSink *sink = GST_HLS_SINK_CAST (data); GstEvent *event = gst_pad_probe_info_get_event (info); switch (GST_EVENT_TYPE (event)) { case GST_EVENT_SEGMENT: { gst_event_copy_segment (event, &sink->segment); break; } case GST_EVENT_FLUSH_STOP: gst_segment_init (&sink->segment, GST_FORMAT_UNDEFINED); break; case GST_EVENT_CUSTOM_DOWNSTREAM: { GstClockTime timestamp; GstClockTime running_time, stream_time; gboolean all_headers; guint count; if (!gst_video_event_is_force_key_unit (event)) break; gst_event_replace (&sink->force_key_unit_event, event); gst_video_event_parse_downstream_force_key_unit (event, ×tamp, &stream_time, &running_time, &all_headers, &count); GST_INFO_OBJECT (sink, "setting index %d", count); sink->index = count; break; } default: break; } return GST_PAD_PROBE_OK; }
static gboolean gst_multi_file_sink_event (GstBaseSink * sink, GstEvent * event) { GstMultiFileSink *multifilesink; gchar *filename; multifilesink = GST_MULTI_FILE_SINK (sink); switch (GST_EVENT_TYPE (event)) { case GST_EVENT_CUSTOM_DOWNSTREAM: { GstClockTime timestamp, duration; GstClockTime running_time, stream_time; guint64 offset, offset_end; gboolean all_headers; guint count; if (multifilesink->next_file != GST_MULTI_FILE_SINK_NEXT_KEY_UNIT_EVENT || !gst_video_event_is_force_key_unit (event)) goto out; gst_video_event_parse_downstream_force_key_unit (event, ×tamp, &stream_time, &running_time, &all_headers, &count); if (multifilesink->force_key_unit_count != -1 && multifilesink->force_key_unit_count == count) goto out; multifilesink->force_key_unit_count = count; if (multifilesink->file) { duration = GST_CLOCK_TIME_NONE; offset = offset_end = -1; filename = g_strdup_printf (multifilesink->filename, multifilesink->index); gst_multi_file_sink_close_file (multifilesink, NULL); gst_multi_file_sink_post_message_full (multifilesink, timestamp, duration, offset, offset_end, running_time, stream_time, filename); g_free (filename); } if (multifilesink->file == NULL) { if (!gst_multi_file_sink_open_next_file (multifilesink)) goto stdio_write_error; } break; } case GST_EVENT_EOS: if (multifilesink->aggregate_gops) { GstBuffer *buf = gst_buffer_new (); /* push key unit buffer to force writing out the pending GOP data */ GST_INFO_OBJECT (sink, "EOS, write pending GOP data"); GST_BUFFER_FLAG_UNSET (buf, GST_BUFFER_FLAG_DELTA_UNIT); gst_multi_file_sink_render (sink, buf); gst_buffer_unref (buf); } if (multifilesink->file) { gchar *filename; filename = g_strdup_printf (multifilesink->filename, multifilesink->index); gst_multi_file_sink_close_file (multifilesink, NULL); gst_multi_file_sink_post_message_from_time (multifilesink, GST_BASE_SINK (multifilesink)->segment.position, -1, filename); g_free (filename); } break; default: break; } out: return GST_BASE_SINK_CLASS (parent_class)->event (sink, event); /* ERRORS */ stdio_write_error: { GST_ELEMENT_ERROR (multifilesink, RESOURCE, WRITE, ("Error while writing to file."), (NULL)); gst_event_unref (event); return FALSE; } }
static gboolean mpegtsmux_src_event (GstPad * pad, GstEvent * event) { MpegTsMux *mux = GST_MPEG_TSMUX (gst_pad_get_parent (pad)); gboolean res = TRUE; switch (GST_EVENT_TYPE (event)) { case GST_EVENT_CUSTOM_UPSTREAM: { GstIterator *iter; GstIteratorResult iter_ret; GstPad *sinkpad; GstClockTime running_time; gboolean all_headers, done; guint count; if (!gst_video_event_is_force_key_unit (event)) break; gst_video_event_parse_upstream_force_key_unit (event, &running_time, &all_headers, &count); GST_INFO_OBJECT (mux, "received upstream force-key-unit event, " "seqnum %d running_time %" GST_TIME_FORMAT " all_headers %d count %d", gst_event_get_seqnum (event), GST_TIME_ARGS (running_time), all_headers, count); if (!all_headers) break; mux->pending_key_unit_ts = running_time; gst_event_replace (&mux->force_key_unit_event, event); iter = gst_element_iterate_sink_pads (GST_ELEMENT_CAST (mux)); done = FALSE; while (!done) { gboolean res = FALSE, tmp; iter_ret = gst_iterator_next (iter, (gpointer *) & sinkpad); switch (iter_ret) { case GST_ITERATOR_DONE: done = TRUE; break; case GST_ITERATOR_OK: GST_INFO_OBJECT (mux, "forwarding to %s", gst_pad_get_name (sinkpad)); tmp = gst_pad_push_event (sinkpad, gst_event_ref (event)); GST_INFO_OBJECT (mux, "result %d", tmp); /* succeed if at least one pad succeeds */ res |= tmp; gst_object_unref (sinkpad); break; case GST_ITERATOR_ERROR: done = TRUE; break; case GST_ITERATOR_RESYNC: break; } } gst_event_unref (event); break; } default: res = gst_pad_event_default (pad, event); break; } gst_object_unref (mux); return res; }