Beispiel #1
0
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);
}
Beispiel #2
0
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);
}
Beispiel #4
0
//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)));

}
Beispiel #6
0
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;
}
Beispiel #9
0
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);
}
Beispiel #11
0
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;
}
Beispiel #13
0
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;
  }
}
Beispiel #16
0
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;
}
Beispiel #17
0
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);
}