static void gst_h264_parse_init (GstH264Parse * h264parse, GstH264ParseClass * g_class) { h264parse->frame_out = gst_adapter_new (); /* retrieve and intercept baseparse. * Quite HACKish, but fairly OK since it is needed to perform avc packet * splitting, which is the penultimate de-parsing */ h264parse->parse_chain = GST_PAD_CHAINFUNC (GST_BASE_PARSE_SINK_PAD (h264parse)); gst_pad_set_chain_function (GST_BASE_PARSE_SINK_PAD (h264parse), gst_h264_parse_chain); }
static void gst_dtsdec_init (GstDtsDec * dtsdec) { dtsdec->request_channels = DCA_CHANNEL; dtsdec->dynamic_range_compression = FALSE; /* retrieve and intercept base class chain. * Quite HACKish, but that's dvd specs for you, * since one buffer needs to be split into 2 frames */ dtsdec->base_chain = GST_PAD_CHAINFUNC (GST_AUDIO_DECODER_SINK_PAD (dtsdec)); gst_pad_set_chain_function (GST_AUDIO_DECODER_SINK_PAD (dtsdec), GST_DEBUG_FUNCPTR (gst_dtsdec_chain)); }
static void gst_a52dec_init (GstA52Dec * a52dec) { a52dec->request_channels = A52_CHANNEL; a52dec->dynamic_range_compression = FALSE; a52dec->state = NULL; a52dec->samples = NULL; /* retrieve and intercept base class chain. * Quite HACKish, but that's dvd specs/caps for you, * since one buffer needs to be split into 2 frames */ a52dec->base_chain = GST_PAD_CHAINFUNC (GST_AUDIO_DECODER_SINK_PAD (a52dec)); gst_pad_set_chain_function (GST_AUDIO_DECODER_SINK_PAD (a52dec), GST_DEBUG_FUNCPTR (gst_a52dec_chain)); }
static void stop_typefinding (GstTypeFindElement * typefind) { GstState state; gboolean push_cached_buffers; gst_element_get_state (GST_ELEMENT (typefind), &state, NULL, 0); push_cached_buffers = (state >= GST_STATE_PAUSED); GST_DEBUG_OBJECT (typefind, "stopping typefinding%s", push_cached_buffers ? " and pushing cached buffers" : ""); if (typefind->store) { if (!push_cached_buffers) { gst_buffer_unref (typefind->store); } else { GstPad *peer = gst_pad_get_peer (typefind->src); typefind->mode = MODE_NORMAL; gst_buffer_set_caps (typefind->store, typefind->caps); /* make sure the user gets a meaningful error message in this case, * which is not a core bug or bug of any kind (as the default error * message emitted by gstpad.c otherwise would make you think) */ if (peer && GST_PAD_CHAINFUNC (peer) == NULL) { GST_DEBUG_OBJECT (typefind, "upstream only supports push mode, while " "downstream element only works in pull mode, erroring out"); GST_ELEMENT_ERROR (typefind, STREAM, FAILED, ("%s cannot work in push mode. The operation is not supported " "with this source element or protocol.", G_OBJECT_TYPE_NAME (GST_PAD_PARENT (peer))), ("Downstream pad %s:%s has no chainfunction, and the upstream " "element does not support pull mode", GST_DEBUG_PAD_NAME (peer))); typefind->mode = MODE_ERROR; /* make the chain function error out */ } else { gst_type_find_element_send_cached_events (typefind); gst_pad_push (typefind->src, typefind->store); } if (peer) gst_object_unref (peer); } typefind->store = NULL; } }
static void link_element_to_tee (GstElement * tee, GstElement * element) { GstPad *tee_src = gst_element_get_request_pad (tee, "src_%u"); GstPad *element_sink = gst_element_get_static_pad (element, "sink"); GstPadLinkReturn ret; GstPadChainFunction old_func; /* * HACK Add a custom chain function that does not return error, this way * we avoid race conditions produced by reconnect events not using the stream * lock */ old_func = GST_PAD_CHAINFUNC (element_sink); if (old_func != NULL) { if (old_func != no_fail_chain) { g_object_set_data (G_OBJECT (element_sink), OLD_CHAIN_KEY, old_func); } gst_pad_set_chain_function (element_sink, no_fail_chain); } remove_element_on_unlinked (element, "src", "sink"); g_signal_connect (tee_src, "unlinked", G_CALLBACK (remove_tee_pad_on_unlink), NULL); gst_pad_add_probe (tee_src, GST_PAD_PROBE_TYPE_EVENT_UPSTREAM, tee_src_probe, NULL, NULL); ret = gst_pad_link_full (tee_src, element_sink, GST_PAD_LINK_CHECK_NOTHING); if (G_UNLIKELY (GST_PAD_LINK_FAILED (ret))) { GST_ERROR ("Linking %" GST_PTR_FORMAT " with %" GST_PTR_FORMAT " result %d", tee_src, element_sink, ret); } g_object_unref (element_sink); g_object_unref (tee_src); }
static void stop_typefinding (GstTypeFindElement * typefind) { GstState state; gboolean push_cached_buffers; gsize avail; GstBuffer *buffer; GstClockTime pts, dts; gst_element_get_state (GST_ELEMENT (typefind), &state, NULL, 0); push_cached_buffers = (state >= GST_STATE_PAUSED && typefind->caps); GST_DEBUG_OBJECT (typefind, "stopping typefinding%s", push_cached_buffers ? " and pushing cached events and buffers" : ""); typefind->mode = MODE_NORMAL; if (push_cached_buffers) gst_type_find_element_send_cached_events (typefind); GST_OBJECT_LOCK (typefind); avail = gst_adapter_available (typefind->adapter); if (avail == 0) goto no_data; pts = gst_adapter_prev_pts (typefind->adapter, NULL); dts = gst_adapter_prev_dts (typefind->adapter, NULL); buffer = gst_adapter_take_buffer (typefind->adapter, avail); GST_BUFFER_PTS (buffer) = pts; GST_BUFFER_DTS (buffer) = dts; GST_BUFFER_OFFSET (buffer) = typefind->initial_offset; GST_OBJECT_UNLOCK (typefind); if (!push_cached_buffers) { gst_buffer_unref (buffer); } else { GstPad *peer = gst_pad_get_peer (typefind->src); /* make sure the user gets a meaningful error message in this case, * which is not a core bug or bug of any kind (as the default error * message emitted by gstpad.c otherwise would make you think) */ if (peer && GST_PAD_CHAINFUNC (peer) == NULL) { GST_DEBUG_OBJECT (typefind, "upstream only supports push mode, while " "downstream element only works in pull mode, erroring out"); GST_ELEMENT_ERROR (typefind, STREAM, FAILED, ("%s cannot work in push mode. The operation is not supported " "with this source element or protocol.", G_OBJECT_TYPE_NAME (GST_PAD_PARENT (peer))), ("Downstream pad %s:%s has no chainfunction, and the upstream " "element does not support pull mode", GST_DEBUG_PAD_NAME (peer))); typefind->mode = MODE_ERROR; /* make the chain function error out */ gst_buffer_unref (buffer); } else { gst_pad_push (typefind->src, buffer); } if (peer) gst_object_unref (peer); } return; /* ERRORS */ no_data: { GST_DEBUG_OBJECT (typefind, "we have no data to typefind"); GST_OBJECT_UNLOCK (typefind); return; } }