Blame tests/check/libs/test_transform.c

Packit f546b1
/* GStreamer
Packit f546b1
 *
Packit f546b1
 * some unit tests for GstBaseTransform
Packit f546b1
 *
Packit f546b1
 * Copyright (C) 2008 Wim Taymans <wim.taymans@gmail.com>
Packit f546b1
 *
Packit f546b1
 * This library is free software; you can redistribute it and/or
Packit f546b1
 * modify it under the terms of the GNU Library General Public
Packit f546b1
 * License as published by the Free Software Foundation; either
Packit f546b1
 * version 2 of the License, or (at your option) any later version.
Packit f546b1
 *
Packit f546b1
 * This library is distributed in the hope that it will be useful,
Packit f546b1
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
Packit f546b1
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
Packit f546b1
 * Library General Public License for more details.
Packit f546b1
 *
Packit f546b1
 * You should have received a copy of the GNU Library General Public
Packit f546b1
 * License along with this library; if not, write to the
Packit f546b1
 * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
Packit f546b1
 * Boston, MA 02110-1301, USA.
Packit f546b1
 */
Packit f546b1
#ifdef HAVE_CONFIG_H
Packit f546b1
#include "config.h"
Packit f546b1
#endif
Packit f546b1
Packit f546b1
#include <gst/base/gstbasetransform.h>
Packit f546b1
Packit f546b1
typedef struct
Packit f546b1
{
Packit f546b1
  GstPad *srcpad;
Packit f546b1
  GstPad *sinkpad;
Packit f546b1
  GList *events;
Packit f546b1
  GList *buffers;
Packit f546b1
  GstElement *trans;
Packit f546b1
  GstBaseTransformClass *klass;
Packit f546b1
} TestTransData;
Packit f546b1
Packit f546b1
static GstStaticPadTemplate gst_test_trans_src_template =
Packit f546b1
GST_STATIC_PAD_TEMPLATE ("src",
Packit f546b1
    GST_PAD_SRC,
Packit f546b1
    GST_PAD_ALWAYS,
Packit f546b1
    GST_STATIC_CAPS ("foo/x-bar")
Packit f546b1
    );
Packit f546b1
Packit f546b1
static GstStaticPadTemplate gst_test_trans_sink_template =
Packit f546b1
GST_STATIC_PAD_TEMPLATE ("sink",
Packit f546b1
    GST_PAD_SINK,
Packit f546b1
    GST_PAD_ALWAYS,
Packit f546b1
    GST_STATIC_CAPS ("foo/x-bar")
Packit f546b1
    );
Packit f546b1
Packit f546b1
typedef struct _GstTestTrans GstTestTrans;
Packit f546b1
typedef struct _GstTestTransClass GstTestTransClass;
Packit f546b1
Packit f546b1
#define GST_TEST_TRANS(obj) ((GstTestTrans *)(obj))
Packit f546b1
Packit f546b1
struct _GstTestTrans
Packit f546b1
{
Packit f546b1
  GstBaseTransform element;
Packit f546b1
Packit f546b1
  TestTransData *data;
Packit f546b1
};
Packit f546b1
Packit f546b1
struct _GstTestTransClass
Packit f546b1
{
Packit f546b1
  GstBaseTransformClass parent_class;
Packit f546b1
};
Packit f546b1
Packit f546b1
static GstFlowReturn (*klass_transform) (GstBaseTransform * trans,
Packit f546b1
    GstBuffer * inbuf, GstBuffer * outbuf) = NULL;
Packit f546b1
static GstFlowReturn (*klass_transform_ip) (GstBaseTransform * trans,
Packit f546b1
    GstBuffer * buf) = NULL;
Packit f546b1
static gboolean (*klass_set_caps) (GstBaseTransform * trans, GstCaps * incaps,
Packit f546b1
    GstCaps * outcaps) = NULL;
Packit f546b1
static GstCaps *(*klass_transform_caps) (GstBaseTransform * trans,
Packit f546b1
    GstPadDirection direction, GstCaps * caps, GstCaps * filter) = NULL;
Packit f546b1
static gboolean (*klass_transform_size) (GstBaseTransform * trans,
Packit f546b1
    GstPadDirection direction, GstCaps * caps, gsize size, GstCaps * othercaps,
Packit f546b1
    gsize * othersize) = NULL;
Packit f546b1
static gboolean klass_passthrough_on_same_caps = FALSE;
Packit f546b1
GstFlowReturn (*klass_submit_input_buffer) (GstBaseTransform * trans,
Packit f546b1
    gboolean is_discont, GstBuffer * input) = NULL;
Packit f546b1
GstFlowReturn (*klass_generate_output) (GstBaseTransform * trans,
Packit f546b1
    GstBuffer ** outbuf) = NULL;
Packit f546b1
Packit f546b1
static GstStaticPadTemplate *sink_template = &gst_test_trans_sink_template;
Packit f546b1
static GstStaticPadTemplate *src_template = &gst_test_trans_src_template;
Packit f546b1
Packit f546b1
static void
Packit f546b1
gst_test_trans_class_init (GstTestTransClass * klass)
Packit f546b1
{
Packit f546b1
  GstElementClass *element_class;
Packit f546b1
  GstBaseTransformClass *trans_class;
Packit f546b1
Packit f546b1
  element_class = (GstElementClass *) klass;
Packit f546b1
  trans_class = (GstBaseTransformClass *) klass;
Packit f546b1
Packit f546b1
  gst_element_class_set_metadata (element_class, "TestTrans",
Packit f546b1
      "Filter/Test", "Test transform", "Wim Taymans <wim.taymans@gmail.com>");
Packit f546b1
Packit f546b1
  gst_element_class_add_static_pad_template (element_class, sink_template);
Packit f546b1
  gst_element_class_add_static_pad_template (element_class, src_template);
Packit f546b1
Packit f546b1
  GST_INFO ("setting up %s", g_type_name (((GTypeClass *) klass)->g_type));
Packit f546b1
Packit f546b1
  trans_class->passthrough_on_same_caps = klass_passthrough_on_same_caps;
Packit f546b1
  if (klass_transform_ip != NULL)
Packit f546b1
    trans_class->transform_ip = klass_transform_ip;
Packit f546b1
  if (klass_transform != NULL)
Packit f546b1
    trans_class->transform = klass_transform;
Packit f546b1
  if (klass_transform_caps != NULL)
Packit f546b1
    trans_class->transform_caps = klass_transform_caps;
Packit f546b1
  if (klass_transform_size != NULL)
Packit f546b1
    trans_class->transform_size = klass_transform_size;
Packit f546b1
  if (klass_set_caps != NULL)
Packit f546b1
    trans_class->set_caps = klass_set_caps;
Packit f546b1
  if (klass_submit_input_buffer != NULL)
Packit f546b1
    trans_class->submit_input_buffer = klass_submit_input_buffer;
Packit f546b1
  if (klass_generate_output)
Packit f546b1
    trans_class->generate_output = klass_generate_output;
Packit f546b1
}
Packit f546b1
Packit f546b1
static void
Packit f546b1
gst_test_trans_init (GstTestTrans * this)
Packit f546b1
{
Packit f546b1
}
Packit f546b1
Packit f546b1
static void
Packit f546b1
gst_test_trans_set_data (GstTestTrans * this, TestTransData * data)
Packit f546b1
{
Packit f546b1
  this->data = data;
Packit f546b1
}
Packit f546b1
Packit f546b1
static GstFlowReturn
Packit f546b1
result_sink_chain (GstPad * pad, GstObject * parent, GstBuffer * buffer)
Packit f546b1
{
Packit f546b1
  TestTransData *data;
Packit f546b1
Packit f546b1
  data = gst_pad_get_element_private (pad);
Packit f546b1
Packit f546b1
  data->buffers = g_list_append (data->buffers, buffer);
Packit f546b1
Packit f546b1
  return GST_FLOW_OK;
Packit f546b1
}
Packit f546b1
Packit f546b1
#if 0
Packit f546b1
static GstFlowReturn
Packit f546b1
result_buffer_alloc (GstPad * pad, guint64 offset, guint size, GstCaps * caps,
Packit f546b1
    GstBuffer ** buf)
Packit f546b1
{
Packit f546b1
  GstFlowReturn res;
Packit f546b1
  TestTransData *data;
Packit f546b1
Packit f546b1
  data = gst_pad_get_element_private (pad);
Packit f546b1
Packit f546b1
  *buf = gst_buffer_new_and_alloc (size);
Packit f546b1
  gst_buffer_set_caps (*buf, caps);
Packit f546b1
  res = GST_FLOW_OK;
Packit f546b1
Packit f546b1
  return res;
Packit f546b1
}
Packit f546b1
#endif
Packit f546b1
Packit f546b1
static TestTransData *
Packit f546b1
gst_test_trans_new (void)
Packit f546b1
{
Packit f546b1
  TestTransData *res;
Packit f546b1
  GstPad *tmp;
Packit f546b1
  GstPadTemplate *templ;
Packit f546b1
  GType type;
Packit f546b1
Packit f546b1
  /* we register a new sub-class for every test-run, so the class init
Packit f546b1
   * function is called for every test run and can be set up properly
Packit f546b1
   * even with CK_FORK=no */
Packit f546b1
  {
Packit f546b1
    static gint counter = 0;
Packit f546b1
    gchar name[100];
Packit f546b1
Packit f546b1
    g_snprintf (name, sizeof (name), "GstTestTrans%d", ++counter);
Packit f546b1
Packit f546b1
    type = g_type_register_static_simple (GST_TYPE_BASE_TRANSFORM, name,
Packit f546b1
        sizeof (GstTestTransClass), (GClassInitFunc) gst_test_trans_class_init,
Packit f546b1
        sizeof (GstTestTrans), (GInstanceInitFunc) gst_test_trans_init, 0);
Packit f546b1
  }
Packit f546b1
Packit f546b1
  res = g_new0 (TestTransData, 1);
Packit f546b1
  res->trans = g_object_new (type, NULL);
Packit f546b1
Packit f546b1
  templ = gst_static_pad_template_get (sink_template);
Packit f546b1
  templ->direction = GST_PAD_SRC;
Packit f546b1
  res->srcpad = gst_pad_new_from_template (templ, "src");
Packit f546b1
  gst_object_unref (templ);
Packit f546b1
Packit f546b1
  templ = gst_static_pad_template_get (src_template);
Packit f546b1
  templ->direction = GST_PAD_SINK;
Packit f546b1
  res->sinkpad = gst_pad_new_from_template (templ, "sink");
Packit f546b1
  gst_object_unref (templ);
Packit f546b1
Packit f546b1
  res->klass = GST_BASE_TRANSFORM_GET_CLASS (res->trans);
Packit f546b1
Packit f546b1
  gst_test_trans_set_data (GST_TEST_TRANS (res->trans), res);
Packit f546b1
  gst_pad_set_element_private (res->sinkpad, res);
Packit f546b1
Packit f546b1
  gst_pad_set_chain_function (res->sinkpad, result_sink_chain);
Packit f546b1
Packit f546b1
  tmp = gst_element_get_static_pad (res->trans, "sink");
Packit f546b1
  gst_pad_link (res->srcpad, tmp);
Packit f546b1
  gst_object_unref (tmp);
Packit f546b1
Packit f546b1
  tmp = gst_element_get_static_pad (res->trans, "src");
Packit f546b1
  gst_pad_link (tmp, res->sinkpad);
Packit f546b1
  gst_object_unref (tmp);
Packit f546b1
Packit f546b1
  gst_pad_set_active (res->sinkpad, TRUE);
Packit f546b1
  gst_element_set_state (res->trans, GST_STATE_PAUSED);
Packit f546b1
  gst_pad_set_active (res->srcpad, TRUE);
Packit f546b1
Packit f546b1
  gst_pad_push_event (res->srcpad, gst_event_new_stream_start ("test"));
Packit f546b1
Packit f546b1
  return res;
Packit f546b1
}
Packit f546b1
Packit f546b1
static void
Packit f546b1
gst_test_trans_free (TestTransData * data)
Packit f546b1
{
Packit f546b1
  GstPad *tmp;
Packit f546b1
Packit f546b1
  gst_pad_set_active (data->sinkpad, FALSE);
Packit f546b1
  gst_element_set_state (data->trans, GST_STATE_NULL);
Packit f546b1
  gst_pad_set_active (data->srcpad, FALSE);
Packit f546b1
Packit f546b1
  tmp = gst_element_get_static_pad (data->trans, "src");
Packit f546b1
  gst_pad_unlink (tmp, data->sinkpad);
Packit f546b1
  gst_object_unref (tmp);
Packit f546b1
Packit f546b1
  tmp = gst_element_get_static_pad (data->trans, "sink");
Packit f546b1
  gst_pad_link (data->srcpad, tmp);
Packit f546b1
  gst_object_unref (tmp);
Packit f546b1
Packit f546b1
  gst_object_unref (data->srcpad);
Packit f546b1
  gst_object_unref (data->sinkpad);
Packit f546b1
  gst_object_unref (data->trans);
Packit f546b1
Packit f546b1
  g_free (data);
Packit f546b1
}
Packit f546b1
Packit f546b1
static GstFlowReturn
Packit f546b1
gst_test_trans_push (TestTransData * data, GstBuffer * buffer)
Packit f546b1
{
Packit f546b1
  GstFlowReturn ret;
Packit f546b1
Packit f546b1
  ret = gst_pad_push (data->srcpad, buffer);
Packit f546b1
Packit f546b1
  return ret;
Packit f546b1
}
Packit f546b1
Packit f546b1
static GstBuffer *
Packit f546b1
gst_test_trans_pop (TestTransData * data)
Packit f546b1
{
Packit f546b1
  GstBuffer *ret;
Packit f546b1
Packit f546b1
  if (data->buffers) {
Packit f546b1
    ret = data->buffers->data;
Packit f546b1
    data->buffers = g_list_delete_link (data->buffers, data->buffers);
Packit f546b1
  } else {
Packit f546b1
    ret = NULL;
Packit f546b1
  }
Packit f546b1
  return ret;
Packit f546b1
}
Packit f546b1
Packit f546b1
static gboolean
Packit f546b1
gst_test_trans_setcaps (TestTransData * data, GstCaps * caps)
Packit f546b1
{
Packit f546b1
  return gst_pad_set_caps (data->srcpad, caps);
Packit f546b1
}
Packit f546b1
Packit f546b1
static gboolean
Packit f546b1
gst_test_trans_push_segment (TestTransData * data)
Packit f546b1
{
Packit f546b1
  GstSegment segment;
Packit f546b1
Packit f546b1
  gst_segment_init (&segment, GST_FORMAT_TIME);
Packit f546b1
Packit f546b1
  return gst_pad_push_event (data->srcpad, gst_event_new_segment (&segment));
Packit f546b1
}