static void owr_inter_src_init(OwrInterSrc *self) { GstPad *srcpad, *sinkpad; GST_OBJECT_FLAG_SET(self, GST_ELEMENT_FLAG_SOURCE); self->queue = gst_element_factory_make("queue", NULL); gst_bin_add(GST_BIN(self), self->queue); srcpad = gst_element_get_static_pad(self->queue, "src"); self->srcpad = gst_ghost_pad_new_from_template("src", srcpad, gst_static_pad_template_get(&src_template)); gst_object_unref(srcpad); gst_element_add_pad(GST_ELEMENT(self), self->srcpad); /* Just to allow linking... */ self->dummy_sinkpad = gst_pad_new("dummy_sinkpad", GST_PAD_SINK); gst_object_set_parent(GST_OBJECT(self->dummy_sinkpad), GST_OBJECT(self)); self->internal_srcpad = gst_pad_new("internal_src", GST_PAD_SRC); gst_object_set_parent(GST_OBJECT(self->internal_srcpad), GST_OBJECT(self->dummy_sinkpad)); gst_pad_set_event_function(self->internal_srcpad, owr_inter_src_internal_src_event); gst_pad_set_query_function(self->internal_srcpad, owr_inter_src_internal_src_query); sinkpad = gst_element_get_static_pad(self->queue, "sink"); gst_pad_link(self->internal_srcpad, sinkpad); gst_object_unref(sinkpad); }
static void gst_rtjpegdec_init (GstRTJpegDec * rtjpegdec) { rtjpegdec->sinkpad = gst_pad_new ("sink", GST_PAD_SINK); gst_element_add_pad (GST_ELEMENT (rtjpegdec), rtjpegdec->sinkpad); gst_pad_set_chain_function (rtjpegdec->sinkpad, gst_rtjpegdec_chain); rtjpegdec->srcpad = gst_pad_new ("src", GST_PAD_SRC); gst_element_add_pad (GST_ELEMENT (rtjpegdec), rtjpegdec->srcpad); }
static void _test_flow_aggregation (GstFlowReturn flow, GstFlowReturn flow1, GstFlowReturn flow2, GstFlowReturn demux_flow, gboolean should_fail) { GstPad *srcpad; GstValidateReport *report; GstValidatePadMonitor *pmonitor, *pmonitor1, *pmonitor2; GstElement *demuxer = fake_demuxer_new (); GstBin *pipeline = GST_BIN (gst_pipeline_new ("validate-pipeline")); GList *reports; GstValidateRunner *runner; GstValidateMonitor *monitor; fail_unless (g_setenv ("GST_VALIDATE_REPORTING_DETAILS", "all", TRUE)); runner = gst_validate_runner_new (); monitor = gst_validate_monitor_factory_create (GST_OBJECT (pipeline), runner, NULL); gst_validate_reporter_set_handle_g_logs (GST_VALIDATE_REPORTER (monitor)); gst_bin_add (pipeline, demuxer); fake_demuxer_prepare_pads (pipeline, demuxer, runner); srcpad = gst_pad_new ("srcpad1", GST_PAD_SRC); gst_pad_link (srcpad, demuxer->sinkpads->data); fail_unless (gst_pad_activate_mode (srcpad, GST_PAD_MODE_PUSH, TRUE)); gst_check_setup_events_with_stream_id (srcpad, demuxer, NULL, GST_FORMAT_TIME, "the-stream"); pmonitor = _get_pad_monitor (gst_pad_get_peer (demuxer->srcpads->data)); pmonitor1 = _get_pad_monitor (gst_pad_get_peer (demuxer->srcpads->next->data)); pmonitor2 = _get_pad_monitor (gst_pad_get_peer (demuxer->srcpads->next->next->data)); pmonitor->last_flow_return = flow; pmonitor1->last_flow_return = flow1; pmonitor2->last_flow_return = flow2; FAKE_DEMUXER (demuxer)->return_value = demux_flow; fail_unless_equals_int (gst_pad_push (srcpad, gst_buffer_new ()), demux_flow); reports = gst_validate_runner_get_reports (runner); if (should_fail) { assert_equals_int (g_list_length (reports), 1); report = reports->data; fail_unless_equals_int (report->level, GST_VALIDATE_REPORT_LEVEL_CRITICAL); fail_unless_equals_int (report->issue->issue_id, WRONG_FLOW_RETURN); } else { assert_equals_int (g_list_length (reports), 0); } g_list_free_full (reports, (GDestroyNotify) gst_validate_report_unref); clean_bus (GST_ELEMENT (pipeline)); gst_element_set_state (GST_ELEMENT (pipeline), GST_STATE_NULL); ASSERT_OBJECT_REFCOUNT (pipeline, "ours", 1); check_destroyed (pipeline, demuxer, NULL); check_destroyed (monitor, pmonitor, NULL); }
//static PadPtr Pad::create(PadDirection direction, const char *name) { GstPad *pad = gst_pad_new(name, static_cast<GstPadDirection>(direction)); if (pad) { gst_object_ref_sink(pad); } return PadPtr::wrap(pad, false); }
static void setup_test_objects (struct TestData *td, GstPadChainFunction chain_func) { td->mycaps = gst_caps_new_empty_simple ("test/test"); td->funnel = gst_element_factory_make ("funnel", NULL); td->funnelsrc = gst_element_get_static_pad (td->funnel, "src"); fail_unless (td->funnelsrc != NULL); td->funnelsink11 = gst_element_get_request_pad (td->funnel, "sink_11"); fail_unless (td->funnelsink11 != NULL); fail_unless (!strcmp (GST_OBJECT_NAME (td->funnelsink11), "sink_11")); td->funnelsink22 = gst_element_get_request_pad (td->funnel, "sink_22"); fail_unless (td->funnelsink22 != NULL); fail_unless (!strcmp (GST_OBJECT_NAME (td->funnelsink22), "sink_22")); fail_unless (gst_element_set_state (td->funnel, GST_STATE_PLAYING) == GST_STATE_CHANGE_SUCCESS); td->mysink = gst_pad_new ("sink", GST_PAD_SINK); gst_pad_set_chain_function (td->mysink, chain_func); gst_pad_set_active (td->mysink, TRUE); td->mysrc1 = gst_pad_new ("src1", GST_PAD_SRC); gst_pad_set_active (td->mysrc1, TRUE); gst_check_setup_events_with_stream_id (td->mysrc1, td->funnel, td->mycaps, GST_FORMAT_BYTES, "test1"); td->mysrc2 = gst_pad_new ("src2", GST_PAD_SRC); gst_pad_set_active (td->mysrc2, TRUE); gst_check_setup_events_with_stream_id (td->mysrc2, td->funnel, td->mycaps, GST_FORMAT_BYTES, "test2"); fail_unless (GST_PAD_LINK_SUCCESSFUL (gst_pad_link (td->funnelsrc, td->mysink))); fail_unless (GST_PAD_LINK_SUCCESSFUL (gst_pad_link (td->mysrc1, td->funnelsink11))); fail_unless (GST_PAD_LINK_SUCCESSFUL (gst_pad_link (td->mysrc2, td->funnelsink22))); }
static void setup_test_objects (struct TestData *td, GstPadChainFunction chain_func, GstPadBufferAllocFunction alloc_func) { td->mycaps = gst_caps_new_simple ("test/test", NULL); td->funnel = gst_element_factory_make ("fsfunnel", NULL); td->funnelsrc = gst_element_get_static_pad (td->funnel, "src"); fail_unless (td->funnelsrc != NULL); td->funnelsink11 = gst_element_get_request_pad (td->funnel, "sink11"); fail_unless (td->funnelsink11 != NULL); fail_unless (!strcmp (GST_OBJECT_NAME (td->funnelsink11), "sink11")); td->funnelsink22 = gst_element_get_request_pad (td->funnel, "sink22"); fail_unless (td->funnelsink22 != NULL); fail_unless (!strcmp (GST_OBJECT_NAME (td->funnelsink22), "sink22")); fail_unless (gst_element_set_state (td->funnel, GST_STATE_PLAYING) == GST_STATE_CHANGE_SUCCESS); td->mysink = gst_pad_new ("sink", GST_PAD_SINK); gst_pad_set_chain_function (td->mysink, chain_func); gst_pad_set_bufferalloc_function (td->mysink, alloc_func); gst_pad_set_active (td->mysink, TRUE); gst_pad_set_caps (td->mysink, td->mycaps); td->mysrc1 = gst_pad_new ("src1", GST_PAD_SRC); gst_pad_set_active (td->mysrc1, TRUE); gst_pad_set_caps (td->mysrc1, td->mycaps); td->mysrc2 = gst_pad_new ("src2", GST_PAD_SRC); gst_pad_set_active (td->mysrc2, TRUE); gst_pad_set_caps (td->mysrc2, td->mycaps); fail_unless (GST_PAD_LINK_SUCCESSFUL( gst_pad_link (td->funnelsrc, td->mysink))); fail_unless (GST_PAD_LINK_SUCCESSFUL( gst_pad_link (td->mysrc1, td->funnelsink11))); fail_unless (GST_PAD_LINK_SUCCESSFUL( gst_pad_link (td->mysrc2, td->funnelsink22))); }
static void gst_tag_mux_init (GstTagMux * mux, GstTagMuxClass * mux_class) { GstElementClass *element_klass = GST_ELEMENT_CLASS (mux_class); GstPadTemplate *tmpl; mux->priv = G_TYPE_INSTANCE_GET_PRIVATE (mux, GST_TYPE_TAG_MUX, GstTagMuxPrivate); /* pad through which data comes in to the element */ tmpl = gst_element_class_get_pad_template (element_klass, "sink"); if (tmpl) { mux->priv->sinkpad = gst_pad_new_from_template (tmpl, "sink"); } else { g_warning ("GstTagMux subclass '%s' did not install a %s pad template!\n", G_OBJECT_CLASS_NAME (element_klass), "sink"); mux->priv->sinkpad = gst_pad_new ("sink", GST_PAD_SINK); } gst_pad_set_chain_function (mux->priv->sinkpad, GST_DEBUG_FUNCPTR (gst_tag_mux_chain)); gst_pad_set_event_function (mux->priv->sinkpad, GST_DEBUG_FUNCPTR (gst_tag_mux_sink_event)); gst_element_add_pad (GST_ELEMENT (mux), mux->priv->sinkpad); /* pad through which data goes out of the element */ tmpl = gst_element_class_get_pad_template (element_klass, "src"); if (tmpl) { GstCaps *tmpl_caps = gst_pad_template_get_caps (tmpl); mux->priv->srcpad = gst_pad_new_from_template (tmpl, "src"); gst_pad_use_fixed_caps (mux->priv->srcpad); if (tmpl_caps != NULL && gst_caps_is_fixed (tmpl_caps)) { gst_pad_set_caps (mux->priv->srcpad, tmpl_caps); } } else { g_warning ("GstTagMux subclass '%s' did not install a %s pad template!\n", G_OBJECT_CLASS_NAME (element_klass), "source"); mux->priv->srcpad = gst_pad_new ("src", GST_PAD_SRC); } gst_element_add_pad (GST_ELEMENT (mux), mux->priv->srcpad); mux->priv->render_start_tag = TRUE; mux->priv->render_end_tag = TRUE; }
GList * gst_media_descriptor_get_pads (GstMediaDescriptor * self) { GList *ret = NULL, *tmp; for (tmp = self->filenode->streams; tmp; tmp = tmp->next) { StreamNode *snode = (StreamNode *) tmp->data; ret = g_list_append (ret, gst_pad_new (snode->padname, GST_PAD_UNKNOWN)); } return ret; }
void buffer_alloc_harness_setup (BufferAllocHarness * h, gint countdown) { h->tee = gst_check_setup_element ("tee"); fail_if (h->tee == NULL); h->countdown = countdown; fail_unless_equals_int (gst_element_set_state (h->tee, GST_STATE_PLAYING), TRUE); h->caps = gst_caps_new_simple ("video/x-raw-yuv", NULL); h->start_srcpad = gst_pad_new ("src", GST_PAD_SRC); fail_if (h->start_srcpad == NULL); fail_unless (gst_pad_set_caps (h->start_srcpad, h->caps) == TRUE); fail_unless (gst_pad_set_active (h->start_srcpad, TRUE) == TRUE); h->tee_sinkpad = gst_element_get_static_pad (h->tee, "sink"); fail_if (h->tee_sinkpad == NULL); h->tee_srcpad = gst_element_get_request_pad (h->tee, "src%d"); fail_if (h->tee_srcpad == NULL); h->final_sinkpad = gst_pad_new ("sink", GST_PAD_SINK); fail_if (h->final_sinkpad == NULL); gst_pad_set_bufferalloc_function (h->final_sinkpad, final_sinkpad_bufferalloc); fail_unless (gst_pad_set_caps (h->final_sinkpad, h->caps) == TRUE); fail_unless (gst_pad_set_active (h->final_sinkpad, TRUE) == TRUE); g_object_set_qdata (G_OBJECT (h->final_sinkpad), g_quark_from_static_string ("buffer-alloc-harness"), h); fail_unless_equals_int (gst_pad_link (h->start_srcpad, h->tee_sinkpad), GST_PAD_LINK_OK); fail_unless_equals_int (gst_pad_link (h->tee_srcpad, h->final_sinkpad), GST_PAD_LINK_OK); }
static void rsn_stream_selector_init (RsnStreamSelector * sel) { sel->srcpad = gst_pad_new ("src", GST_PAD_SRC); gst_pad_set_iterate_internal_links_function (sel->srcpad, GST_DEBUG_FUNCPTR (rsn_stream_selector_iterate_linked_pads)); gst_pad_set_getcaps_function (sel->srcpad, GST_DEBUG_FUNCPTR (rsn_stream_selector_getcaps)); gst_element_add_pad (GST_ELEMENT (sel), sel->srcpad); /* sinkpad management */ sel->padcount = 0; sel->active_sinkpad = NULL; gst_segment_init (&sel->segment, GST_FORMAT_UNDEFINED); }
void gstreamer_determine_video_dimensions(const char *uri, int *video_width, int *video_height) { GMainLoop *loop = g_main_loop_new(NULL, FALSE); char *playbin_launch_str = malloc(strlen(uri) + 64); sprintf(playbin_launch_str, PLAYBIN_STR " uri=%s audio-sink=fakesink video-sink=fakesink", uri); GError *error2 = NULL; GstElement *playbin = gst_parse_launch(playbin_launch_str, &error2); if (error2) { printf("Error: Could not create gstreamer pipeline for identification.\n"); printf("Parse error: %s\n", error2->message); exit(1); } playbin_pipeline = playbin; bus_quit_on_playing = TRUE; GstBus *playbin_bus = gst_pipeline_get_bus(GST_PIPELINE(playbin)); guint type_find_bus_watch_id = gst_bus_add_watch(playbin_bus, bus_callback, loop); gst_object_unref(playbin_bus); gst_element_set_state(GST_ELEMENT(playbin), GST_STATE_READY); gst_element_set_state(GST_ELEMENT(playbin), GST_STATE_PLAYING); g_main_loop_run(loop); gst_element_set_state(GST_ELEMENT(playbin), GST_STATE_PAUSED); GstPad *pad = gst_pad_new("", GST_PAD_UNKNOWN); g_signal_emit_by_name(playbin, "get-video-pad", 0, &pad, NULL); GstCaps *caps = gst_pad_get_current_caps(pad); *video_width = g_value_get_int(gst_structure_get_value( gst_caps_get_structure(caps, 0), "width")); *video_height = g_value_get_int(gst_structure_get_value( gst_caps_get_structure(caps, 0), "height")); g_object_unref(pad); gst_element_set_state(GST_ELEMENT(playbin), GST_STATE_NULL); gst_object_unref(GST_OBJECT(playbin)); g_source_remove(type_find_bus_watch_id); g_main_loop_unref(loop); }
static void gst_input_selector_init (GstInputSelector * sel) { sel->srcpad = gst_pad_new ("src", GST_PAD_SRC); gst_pad_set_iterate_internal_links_function (sel->srcpad, GST_DEBUG_FUNCPTR (gst_selector_pad_iterate_linked_pads)); gst_pad_set_getcaps_function (sel->srcpad, GST_DEBUG_FUNCPTR (gst_input_selector_getcaps)); gst_pad_set_query_function (sel->srcpad, GST_DEBUG_FUNCPTR (gst_input_selector_query)); gst_pad_set_event_function (sel->srcpad, GST_DEBUG_FUNCPTR (gst_input_selector_event)); gst_element_add_pad (GST_ELEMENT (sel), sel->srcpad); /* sinkpad management */ sel->active_sinkpad = NULL; sel->padcount = 0; gst_segment_init (&sel->segment, GST_FORMAT_UNDEFINED); sel->lock = g_mutex_new (); sel->cond = g_cond_new (); sel->blocked = FALSE; sel->select_all = FALSE; }
static HRESULT Gstreamer_transform_ConnectInput(GstTfImpl *This, const AM_MEDIA_TYPE *amt, GstCaps *capsin, GstCaps *capsout) { GstIterator *it; int done = 0, found = 0, ret; This->filter = gst_element_factory_make(This->gstreamer_name, NULL); if (!This->filter) { FIXME("Could not make %s filter\n", This->gstreamer_name); return E_FAIL; } This->my_src = gst_pad_new(NULL, GST_PAD_SRC); gst_pad_set_element_private (This->my_src, This); This->my_sink = gst_pad_new(NULL, GST_PAD_SINK); gst_pad_set_chain_function(This->my_sink, got_data); gst_pad_set_bufferalloc_function(This->my_sink, request_buffer); gst_pad_set_element_private (This->my_sink, This); ret = gst_pad_set_caps(This->my_src, capsin); if (ret < 0) { WARN("Failed to set caps on own source with %i\n", ret); return E_FAIL; } ret = gst_pad_set_caps(This->my_sink, capsout); if (ret < 0) { WARN("Failed to set caps on own sink with %i\n", ret); return E_FAIL; } it = gst_element_iterate_sink_pads(This->filter); while (!done) { gpointer item; switch (gst_iterator_next(it, &item)) { case GST_ITERATOR_RESYNC: gst_iterator_resync (it); break; case GST_ITERATOR_OK: This->their_sink = item; case GST_ITERATOR_ERROR: case GST_ITERATOR_DONE: done = 1; break; } } gst_iterator_free(it); if (!This->their_sink) { ERR("Could not find sink on filter %s\n", This->gstreamer_name); return E_FAIL; } it = gst_element_iterate_src_pads(This->filter); gst_iterator_resync(it); done = 0; while (!done) { gpointer item; switch (gst_iterator_next(it, &item)) { case GST_ITERATOR_RESYNC: gst_iterator_resync (it); break; case GST_ITERATOR_OK: This->their_src = item; case GST_ITERATOR_ERROR: case GST_ITERATOR_DONE: done = 1; break; } } gst_iterator_free(it); found = !!This->their_src; if (!found) g_signal_connect(This->filter, "pad-added", G_CALLBACK(Gstreamer_transform_pad_added), This); ret = gst_pad_link(This->my_src, This->their_sink); if (ret < 0) { WARN("Failed to link with %i\n", ret); return E_FAIL; } if (found) Gstreamer_transform_pad_added(This->filter, This->their_src, This); if (!gst_pad_is_linked(This->my_sink)) return E_FAIL; TRACE("Connected\n"); return S_OK; }
static void _check_media_info (GstSegment * segment, BufferDesc * bufs) { GList *reports; GstEvent *segev; GstBuffer *buffer; GstElement *decoder; GstPad *srcpad, *sinkpad; GstValidateReport *report; GstValidateMonitor *monitor; GstValidateRunner *runner; GstMediaDescriptor *mdesc; GError *err = NULL; gint i, num_issues = 0; fail_unless (g_setenv ("GST_VALIDATE_REPORTING_DETAILS", "all", TRUE)); runner = gst_validate_runner_new (); mdesc = (GstMediaDescriptor *) gst_media_descriptor_parser_new_from_xml (runner, media_info, &err); decoder = fake_decoder_new (); monitor = gst_validate_monitor_factory_create (GST_OBJECT (decoder), runner, NULL); gst_validate_monitor_set_media_descriptor (monitor, mdesc); srcpad = gst_pad_new ("src", GST_PAD_SRC); sinkpad = decoder->sinkpads->data; ASSERT_OBJECT_REFCOUNT (sinkpad, "decoder ref", 1); fail_unless (gst_pad_activate_mode (srcpad, GST_PAD_MODE_PUSH, TRUE)); fail_unless_equals_int (gst_element_set_state (decoder, GST_STATE_PLAYING), GST_STATE_CHANGE_SUCCESS); assert_equals_string (gst_pad_link_get_name (gst_pad_link (srcpad, sinkpad)), gst_pad_link_get_name (GST_PAD_LINK_OK)); gst_check_setup_events_with_stream_id (srcpad, decoder, gst_caps_from_string ("video/x-fake"), GST_FORMAT_TIME, "the-stream"); if (segment) { segev = gst_event_new_segment (segment); fail_unless (gst_pad_push_event (srcpad, segev)); } for (i = 0; bufs[i].content != NULL; i++) { BufferDesc *buf = &bufs[i]; buffer = _create_buffer (buf); assert_equals_string (gst_flow_get_name (gst_pad_push (srcpad, buffer)), gst_flow_get_name (GST_FLOW_OK)); reports = gst_validate_runner_get_reports (runner); num_issues += buf->num_issues; assert_equals_int (g_list_length (reports), num_issues); if (buf->num_issues) { GList *tmp = g_list_nth (reports, num_issues - buf->num_issues); while (tmp) { report = tmp->data; fail_unless_equals_int (report->level, GST_VALIDATE_REPORT_LEVEL_WARNING); fail_unless_equals_int (report->issue->issue_id, WRONG_BUFFER); tmp = tmp->next; } } } /* clean up */ fail_unless (gst_pad_activate_mode (sinkpad, GST_PAD_MODE_PUSH, FALSE)); fail_unless_equals_int (gst_element_set_state (decoder, GST_STATE_NULL), GST_STATE_CHANGE_SUCCESS); gst_object_unref (srcpad); check_destroyed (decoder, sinkpad, NULL); check_destroyed (runner, NULL, NULL); }
static gboolean setup_recoder_pipeline (GstSmartEncoder * smart_encoder) { GstPad *tmppad; GstCaps *caps; /* Fast path */ if (G_UNLIKELY (smart_encoder->encoder)) return TRUE; GST_DEBUG ("Creating internal decoder and encoder"); /* Create decoder/encoder */ caps = gst_pad_get_current_caps (smart_encoder->sinkpad); smart_encoder->decoder = get_decoder (caps); if (G_UNLIKELY (smart_encoder->decoder == NULL)) goto no_decoder; gst_caps_unref (caps); gst_element_set_bus (smart_encoder->decoder, GST_ELEMENT_BUS (smart_encoder)); caps = gst_pad_get_current_caps (smart_encoder->sinkpad); smart_encoder->encoder = get_encoder (caps); if (G_UNLIKELY (smart_encoder->encoder == NULL)) goto no_encoder; gst_caps_unref (caps); gst_element_set_bus (smart_encoder->encoder, GST_ELEMENT_BUS (smart_encoder)); GST_DEBUG ("Creating internal pads"); /* Create internal pads */ /* Source pad which we'll use to feed data to decoders */ smart_encoder->internal_srcpad = gst_pad_new ("internal_src", GST_PAD_SRC); g_object_set_qdata ((GObject *) smart_encoder->internal_srcpad, INTERNAL_ELEMENT, smart_encoder); gst_pad_set_active (smart_encoder->internal_srcpad, TRUE); /* Sink pad which will get the buffers from the encoder. * Note: We don't need an event function since we'll be discarding all * of them. */ smart_encoder->internal_sinkpad = gst_pad_new ("internal_sink", GST_PAD_SINK); g_object_set_qdata ((GObject *) smart_encoder->internal_sinkpad, INTERNAL_ELEMENT, smart_encoder); gst_pad_set_chain_function (smart_encoder->internal_sinkpad, internal_chain); gst_pad_set_active (smart_encoder->internal_sinkpad, TRUE); GST_DEBUG ("Linking pads to elements"); /* Link everything */ tmppad = gst_element_get_static_pad (smart_encoder->encoder, "src"); if (GST_PAD_LINK_FAILED (gst_pad_link (tmppad, smart_encoder->internal_sinkpad))) goto sinkpad_link_fail; gst_object_unref (tmppad); if (!gst_element_link (smart_encoder->decoder, smart_encoder->encoder)) goto encoder_decoder_link_fail; tmppad = gst_element_get_static_pad (smart_encoder->decoder, "sink"); if (GST_PAD_LINK_FAILED (gst_pad_link (smart_encoder->internal_srcpad, tmppad))) goto srcpad_link_fail; gst_object_unref (tmppad); GST_DEBUG ("Done creating internal elements/pads"); return TRUE; no_decoder: { GST_WARNING ("Couldn't find a decoder for %" GST_PTR_FORMAT, caps); gst_caps_unref (caps); return FALSE; } no_encoder: { GST_WARNING ("Couldn't find an encoder for %" GST_PTR_FORMAT, caps); gst_caps_unref (caps); return FALSE; } srcpad_link_fail: { gst_object_unref (tmppad); GST_WARNING ("Couldn't link internal srcpad to decoder"); return FALSE; } sinkpad_link_fail: { gst_object_unref (tmppad); GST_WARNING ("Couldn't link encoder to internal sinkpad"); return FALSE; } encoder_decoder_link_fail: { GST_WARNING ("Couldn't link decoder to encoder"); return FALSE; } }
static HRESULT Gstreamer_transform_ConnectInput(GstTfImpl *This, const AM_MEDIA_TYPE *amt, GstCaps *capsin, GstCaps *capsout) { GstIterator *it; BOOL done = FALSE, found = FALSE; int ret; TRACE("%p %p %p %p\n", This, amt, capsin, capsout); mark_wine_thread(); This->filter = gst_element_factory_make(This->gstreamer_name, NULL); if (!This->filter) { FIXME("Could not make %s filter\n", This->gstreamer_name); return E_FAIL; } This->my_src = gst_pad_new("yuvsrc", GST_PAD_SRC); gst_pad_set_element_private (This->my_src, This); gst_pad_set_active(This->my_src, 1); This->my_sink = gst_pad_new("yuvsink", GST_PAD_SINK); gst_pad_set_chain_function(This->my_sink, got_data_wrapper); gst_pad_set_element_private (This->my_sink, This); gst_pad_set_active(This->my_sink, 1); it = gst_element_iterate_sink_pads(This->filter); while (!done) { GValue item = {0}; switch (gst_iterator_next(it, &item)) { case GST_ITERATOR_RESYNC: gst_iterator_resync (it); break; case GST_ITERATOR_OK: This->their_sink = g_value_get_object(&item); gst_object_ref(This->their_sink); g_value_reset(&item); case GST_ITERATOR_ERROR: case GST_ITERATOR_DONE: done = TRUE; break; } } gst_iterator_free(it); if (!This->their_sink) { ERR("Could not find sink on filter %s\n", This->gstreamer_name); return E_FAIL; } it = gst_element_iterate_src_pads(This->filter); gst_iterator_resync(it); done = FALSE; while (!done) { GValue item = {0}; switch (gst_iterator_next(it, &item)) { case GST_ITERATOR_RESYNC: gst_iterator_resync (it); break; case GST_ITERATOR_OK: This->their_src = g_value_get_object(&item); gst_object_ref(This->their_src); g_value_reset(&item); case GST_ITERATOR_ERROR: case GST_ITERATOR_DONE: done = TRUE; break; } } gst_iterator_free(it); found = !!This->their_src; if (!found) g_signal_connect(This->filter, "pad-added", G_CALLBACK(Gstreamer_transform_pad_added_wrapper), This); ret = gst_pad_link(This->my_src, This->their_sink); if (ret < 0) { WARN("Failed to link with %i\n", ret); return E_FAIL; } ret = gst_pad_set_caps(This->my_src, capsin); if (ret < 0) { WARN("Failed to set caps on own source with %i\n", ret); return E_FAIL; } if (found) Gstreamer_transform_pad_added(This->filter, This->their_src, This); if (!gst_pad_is_linked(This->my_sink)) return E_FAIL; ret = gst_pad_set_caps(This->my_sink, capsout); if (ret < 0) { WARN("Failed to set caps on own sink with %i\n", ret); return E_FAIL; } TRACE("Connected\n"); return S_OK; }
static void run_output_order_test (gint n_linked) { /* This test creates a multiqueue with 2 linked output, and 3 outputs that * return 'not-linked' when data is pushed, then verifies that all buffers * are received on not-linked pads only after earlier buffers on the * 'linked' pads are made */ GstElement *pipe; GstElement *mq; GstPad *inputpads[5]; GstPad *sinkpads[5]; struct PadData pad_data[5]; guint32 max_linked_id; guint32 eos_seen; GMutex *mutex; GCond *cond; gint i; const gint NPADS = 5; const gint NBUFFERS = 1000; mutex = g_mutex_new (); cond = g_cond_new (); pipe = gst_bin_new ("testbin"); mq = gst_element_factory_make ("multiqueue", NULL); fail_unless (mq != NULL); gst_bin_add (GST_BIN (pipe), mq); /* No limits */ g_object_set (mq, "max-size-bytes", (guint) 0, "max-size-buffers", (guint) 0, "max-size-time", (guint64) 0, "extra-size-bytes", (guint) 0, "extra-size-buffers", (guint) 0, "extra-size-time", (guint64) 0, NULL); /* Construct NPADS dummy output pads. The first 'n_linked' return FLOW_OK, the rest * return NOT_LINKED. The not-linked ones check the expected ordering of * output buffers */ for (i = 0; i < NPADS; i++) { GstPad *mq_srcpad, *mq_sinkpad; gchar *name; name = g_strdup_printf ("dummysrc%d", i); inputpads[i] = gst_pad_new (name, GST_PAD_SRC); g_free (name); gst_pad_set_getcaps_function (inputpads[i], mq_dummypad_getcaps); mq_sinkpad = gst_element_get_request_pad (mq, "sink%d"); fail_unless (mq_sinkpad != NULL); gst_pad_link (inputpads[i], mq_sinkpad); gst_pad_set_active (inputpads[i], TRUE); mq_srcpad = mq_sinkpad_to_srcpad (mq, mq_sinkpad); name = g_strdup_printf ("dummysink%d", i); sinkpads[i] = gst_pad_new (name, GST_PAD_SINK); g_free (name); gst_pad_set_chain_function (sinkpads[i], mq_dummypad_chain); gst_pad_set_event_function (sinkpads[i], mq_dummypad_event); gst_pad_set_getcaps_function (sinkpads[i], mq_dummypad_getcaps); pad_data[i].pad_num = i; pad_data[i].max_linked_id_ptr = &max_linked_id; pad_data[i].eos_count_ptr = &eos_seen; pad_data[i].is_linked = (i < n_linked ? TRUE : FALSE); pad_data[i].n_linked = n_linked; pad_data[i].cond = cond; pad_data[i].mutex = mutex; pad_data[i].first_buf = TRUE; gst_pad_set_element_private (sinkpads[i], pad_data + i); gst_pad_link (mq_srcpad, sinkpads[i]); gst_pad_set_active (sinkpads[i], TRUE); gst_object_unref (mq_sinkpad); gst_object_unref (mq_srcpad); } /* Run the test. Push 1000 buffers through the multiqueue in a pattern */ max_linked_id = 0; eos_seen = 0; gst_element_set_state (pipe, GST_STATE_PLAYING); for (i = 0; i < NBUFFERS; i++) { const guint8 pad_pattern[] = { 0, 0, 0, 0, 1, 1, 2, 1, 0, 2, 3, 2, 3, 1, 4 }; const guint n = sizeof (pad_pattern) / sizeof (guint8); guint8 cur_pad; GstBuffer *buf; GstFlowReturn ret; cur_pad = pad_pattern[i % n]; buf = gst_buffer_new_and_alloc (4); g_static_mutex_lock (&_check_lock); fail_if (buf == NULL); g_static_mutex_unlock (&_check_lock); GST_WRITE_UINT32_BE (GST_BUFFER_DATA (buf), i + 1); GST_BUFFER_TIMESTAMP (buf) = (i + 1) * GST_SECOND; ret = gst_pad_push (inputpads[cur_pad], buf); g_static_mutex_lock (&_check_lock); if (pad_data[cur_pad].is_linked) { fail_unless (ret == GST_FLOW_OK, "Push on pad %d returned %d when FLOW_OK was expected", cur_pad, ret); } else { /* Expect OK initially, then NOT_LINKED when the srcpad starts pushing */ fail_unless (ret == GST_FLOW_OK || ret == GST_FLOW_NOT_LINKED, "Push on pad %d returned %d when FLOW_OK or NOT_LINKED was expected", cur_pad, ret); } g_static_mutex_unlock (&_check_lock); } for (i = 0; i < NPADS; i++) { gst_pad_push_event (inputpads[i], gst_event_new_eos ()); } /* Wait while the buffers are processed */ g_mutex_lock (mutex); while (eos_seen < 5) { g_cond_wait (cond, mutex); } g_mutex_unlock (mutex); /* Clean up */ for (i = 0; i < 5; i++) { GstPad *mq_input = gst_pad_get_peer (inputpads[i]); gst_pad_unlink (inputpads[i], mq_input); gst_element_release_request_pad (mq, mq_input); gst_object_unref (mq_input); gst_object_unref (inputpads[i]); gst_object_unref (sinkpads[i]); } gst_element_set_state (pipe, GST_STATE_NULL); gst_object_unref (pipe); g_cond_free (cond); g_mutex_free (mutex); }
static void test_videoframe_audiolevel_generic (void) { GstElement *alevel; GstPad *asink, *vsink, *asrc, *vsrc, *aoutput_sink, *voutput_sink; GThread *athread, *vthread; GstBus *bus; guint i; got_eos = FALSE; audio_buffer_count = 0; video_buffer_count = 0; num_msgs = 0; g_queue_init (&v_timestamp_q); g_queue_init (&msg_timestamp_q); alevel = gst_element_factory_make ("videoframe-audiolevel", NULL); fail_unless (alevel != NULL); bus = gst_bus_new (); gst_element_set_bus (alevel, bus); gst_bus_set_sync_handler (bus, on_message, NULL, NULL); asink = gst_element_get_static_pad (alevel, "asink"); fail_unless (asink != NULL); vsink = gst_element_get_static_pad (alevel, "vsink"); fail_unless (vsink != NULL); asrc = gst_element_get_static_pad (alevel, "asrc"); aoutput_sink = gst_pad_new ("sink", GST_PAD_SINK); fail_unless (aoutput_sink != NULL); fail_unless (gst_pad_link (asrc, aoutput_sink) == GST_PAD_LINK_OK); vsrc = gst_element_get_static_pad (alevel, "vsrc"); voutput_sink = gst_pad_new ("sink", GST_PAD_SINK); fail_unless (voutput_sink != NULL); fail_unless (gst_pad_link (vsrc, voutput_sink) == GST_PAD_LINK_OK); gst_pad_set_chain_function (aoutput_sink, output_achain); gst_pad_set_event_function (aoutput_sink, output_aevent); gst_pad_set_chain_function (voutput_sink, output_vchain); gst_pad_set_event_function (voutput_sink, output_vevent); gst_pad_set_active (aoutput_sink, TRUE); gst_pad_set_active (voutput_sink, TRUE); fail_unless (gst_element_set_state (alevel, GST_STATE_PLAYING) == GST_STATE_CHANGE_SUCCESS); athread = g_thread_new ("athread", (GThreadFunc) push_abuffers, asink); vthread = g_thread_new ("vthread", (GThreadFunc) push_vbuffers, vsink); g_thread_join (vthread); g_thread_join (athread); fail_unless (got_eos); fail_unless_equals_int (audio_buffer_count, n_abuffers); fail_unless_equals_int (video_buffer_count, n_vbuffers); if (!long_video) fail_unless_equals_int (num_msgs, n_vbuffers); fail_unless_equals_int (g_queue_get_length (&v_timestamp_q), n_vbuffers); /* num_msgs is equal to n_vbuffers except in the case of long_video */ fail_unless_equals_int (g_queue_get_length (&msg_timestamp_q), num_msgs); for (i = 0; i < g_queue_get_length (&msg_timestamp_q); i++) { GstClockTime *vt = g_queue_pop_head (&v_timestamp_q); GstClockTime *mt = g_queue_pop_head (&msg_timestamp_q); fail_unless (vt != NULL); fail_unless (mt != NULL); if (!video_gaps && !video_overlaps && !early_video) fail_unless_equals_uint64 (*vt, *mt); g_free (vt); g_free (mt); } /* teardown */ gst_element_set_state (alevel, GST_STATE_NULL); gst_bus_set_flushing (bus, TRUE); gst_object_unref (bus); g_queue_foreach (&v_timestamp_q, (GFunc) g_free, NULL); g_queue_foreach (&msg_timestamp_q, (GFunc) g_free, NULL); g_queue_clear (&v_timestamp_q); g_queue_clear (&msg_timestamp_q); gst_pad_unlink (asrc, aoutput_sink); gst_object_unref (asrc); gst_pad_unlink (vsrc, voutput_sink); gst_object_unref (vsrc); gst_object_unref (asink); gst_object_unref (vsink); gst_pad_set_active (aoutput_sink, FALSE); gst_object_unref (aoutput_sink); gst_pad_set_active (voutput_sink, FALSE); gst_object_unref (voutput_sink); gst_object_unref (alevel); }