please help on my own base element

classic Classic list List threaded Threaded
2 messages Options
Reply | Threaded
Open this post in threaded view
|

please help on my own base element

kevin kelly
hello, there,

I am absolutely a new coder for gstreamer plugin.

I am trying to generate  my own base element called GstMyDecoder, which is very similar to GstbaseTransform, so that I can derive other elements from this base element.

I compiled this GstMyDecoder and generated .so file without any errors. This .so file and header file gstmydecoder.h was copied to /usr/lib/gstream-0.10/ and /usr/include/gstreamer-0.10/gst accordingly.

I also derived GstMyChildDecoder from this GstMyDecoder element. The .so file was also compiled without any errors and was copied to /usr/lib/gstream-0.10/

But when I tried to use "gst-inspect childdecoder", I got following error message:

GStreamer-WARNING **: Failed to load plugin '/usr/lib/gstreamer-0.10/libgstmychilddecoder.so': /usr/lib/gstreamer-0.10/libgstmychilddecoder.so: undefined symbol: gst_my_decoder_get_type

would you please help me to find what's wrong and how to solve this issue? Is there any special procedure to compile this base element?

Thank yo so much for your help!!!



Here are the source code


/****************************************
* gstmydecoder.h
*
*******************************************/


#ifndef __GST_MY_DECODER_H__
#define __GST_MY_DECODER_H__

#include <gst/gst.h>

G_BEGIN_DECLS

#define GST_TYPE_MY_DECODER        (gst_my_decoder_get_type())
#define GST_MY_DECODER(obj)        (G_TYPE_CHECK_INSTANCE_CAST((obj),GST_TYPE_MY_DECODER,GstMYDecoder))
#define GST_MY_DECODER_CLASS(klass)     (G_TYPE_CHECK_CLASS_CAST((klass),GST_TYPE_MY_DECODER,GstMYDecoderClass))
#define GST_MY_DECODER_GET_CLASS(obj)   (G_TYPE_INSTANCE_GET_CLASS((obj),GST_TYPE_MY_DECODER,GstMYDecoderClass))
#define GST_IS_MY_DECODER(obj)        (G_TYPE_CHECK_INSTANCE_TYPE((obj),GST_TYPE_MY_DECODER))
#define GST_IS_MY_DECODER_CLASS(klass)  (G_TYPE_CHECK_CLASS_TYPE((klass),GST_TYPE_MY_DECODER))
#define GST_MY_DECODER_CAST(obj)    ((GstMYDecoder *)(obj))

typedef struct _GstMYDecoder GstMYDecoder;
typedef struct _GstMYDecoderClass GstMYDecoderClass;
typedef struct _GstMYDecoderPrivate GstMYDecoderPrivate;


struct _GstMYDecoder {
  GstElement element;
  GstPad *sinkpad;
  GstPad *srcpad;

  gboolean state;
  gboolean status;
  GMutex *element_lock;
  GstMYDecoderPrivate *priv;
  gpointer       _gst_reserved[GST_PADDING_LARGE - 1];
};


struct _GstMYDecoderClass {
  GstElementClass parent_class;


  GstCaps* (*element_caps) (GstMYDecoder *instance,
                             GstPadDirection direction,
                             GstCaps *caps);
 
 
  gboolean      (*start_decode)        (GstMYDecoder *instance);
  gboolean      (*stop_decode)         (GstMYDecoder *instance);
  gboolean      (*sink_event)        (GstMYDecoder *instance, GstEvent *event);
  gboolean      (*src_event)        (GstMYDecoder *instance, GstEvent *event);
  gpointer       _gst_reserved[GST_PADDING_LARGE - 3];
};

GType           gst_my_decoder_get_type(void);

G_END_DECLS


#endif /* __GST_MY_DECODER_H__ */



/****************************************************
*
* gstmydecoder.c
***************************************************/

#ifdef HAVE_CONFIG_H
#  include "config.h"
#endif

#include <stdlib.h>
#include <string.h>

#include "gstmydecoder.h"
#include <gst/gstmarshal.h>

GST_DEBUG_CATEGORY_STATIC (gst_my_decoder_debug);
#define GST_CAT_DEFAULT gst_my_decoder_debug

enum
{
  LAST_SIGNAL
};

#define DEFAULT_PROP_QOS FALSE

enum
{
  PROP_0,
  PROP_QOS
};

#define GST_MY_DECODER_GET_PRIVATE(obj)  \
    (G_TYPE_INSTANCE_GET_PRIVATE ((obj), GST_TYPE_MY_DECODER, GstMYDecoderPrivate))

struct _GstMYDecoderPrivate
{
  GstCaps *sink_alloc;
  GstCaps *src_alloc;
  GstCaps *sink_suggest;
  guint size_suggest;

};

static GstElementClass *parent_class = NULL;

static void gst_my_decoder_class_init (GstMYDecoderClass * klass);
static void gst_my_decoder_init (GstMYDecoder * instance,
    GstMYDecoderClass * klass);



GType
gst_my_decoder_get_type (void)
{
  static volatile gsize my_decoder_type = 0;

  if (g_once_init_enter (&my_decoder_type)) {
    GType _type;
    static const GTypeInfo my_decoder_info = {
      sizeof (GstMYDecoderClass),
      NULL,
      NULL,
      (GClassInitFunc) gst_my_decoder_class_init,
      NULL,
      NULL,
      sizeof (GstMYDecoder),
      0,
      (GInstanceInitFunc) gst_my_decoder_init,
    };

    _type = g_type_register_static (GST_TYPE_ELEMENT,
        "GstMYDecoder", &my_decoder_info, G_TYPE_FLAG_ABSTRACT);
    g_once_init_leave (&my_decoder_type, _type);
  }
  return my_decoder_type;
}



static void gst_my_decoder_set_property (GObject * object, guint prop_id,
    const GValue * value, GParamSpec * pspec);
static void gst_my_decoder_get_property (GObject * object, guint prop_id,
    GValue * value, GParamSpec * pspec);



static gboolean gst_my_decoder_src_event (GstPad * pad, GstEvent * event);
static gboolean gst_my_decoder_src_eventfunc (GstMYDecoder * instance,
    GstEvent * event);



static gboolean gst_my_decoder_sink_event (GstPad * pad, GstEvent * event);
static gboolean gst_my_decoder_sink_eventfunc (GstMYDecoder * instance,
    GstEvent * event);



static gboolean gst_my_decoder_check_get_range (GstPad * pad);
static GstFlowReturn gst_my_decoder_getrange (GstPad * pad, guint64 offset,
    guint length, GstBuffer ** buffer);

static GstFlowReturn gst_my_decoder_chain (GstPad * pad,
    GstBuffer * buffer);




static GstCaps *gst_my_decoder_getcaps (GstPad * pad);
static gboolean gst_my_decoder_acceptcaps (GstPad * pad, GstCaps * caps);
static gboolean gst_my_decoder_setcaps (GstPad * pad, GstCaps * caps);




static void
gst_my_decoder_class_init (GstMYDecoderClass * klass)
{
  GObjectClass *gobject_class;

  gobject_class = G_OBJECT_CLASS (klass);

  GST_DEBUG_CATEGORY_INIT (gst_my_decoder_debug, "basetransform", 0,
      "basetransform element");

  GST_DEBUG ("gst_my_decoder_class_init");

  g_type_class_add_private (klass, sizeof (GstMYDecoderPrivate));

  parent_class = g_type_class_peek_parent (klass);

  gobject_class->set_property = gst_my_decoder_set_property;
  gobject_class->get_property = gst_my_decoder_get_property;

  klass->sink_event = GST_DEBUG_FUNCPTR (gst_my_decoder_sink_eventfunc);
  klass->src_event = GST_DEBUG_FUNCPTR (gst_my_decoder_src_eventfunc);
}

static void
gst_my_decoder_init (GstMYDecoder * instance,
    GstMYDecoderClass * bclass)
{
  GstPadTemplate *pad_template;

  GST_DEBUG ("gst_my_decoder_init");

  instance->priv = GST_MY_DECODER_GET_PRIVATE (instance);

  pad_template = gst_element_class_get_pad_template (GST_ELEMENT_CLASS (bclass), "sink");
  g_return_if_fail (pad_template != NULL);
  instance->sinkpad = gst_pad_new_from_template (pad_template, "sink");
 
  gst_pad_set_getcaps_function (instance->sinkpad,GST_DEBUG_FUNCPTR (gst_my_decoder_getcaps));
  gst_pad_set_acceptcaps_function (instance->sinkpad,GST_DEBUG_FUNCPTR (gst_my_decoder_acceptcaps));
  gst_pad_set_setcaps_function (instance->sinkpad, GST_DEBUG_FUNCPTR (gst_my_decoder_setcaps));
  gst_pad_set_event_function (instance->sinkpad,GST_DEBUG_FUNCPTR (gst_my_decoder_sink_event));
  gst_pad_set_chain_function (instance->sinkpad,GST_DEBUG_FUNCPTR (gst_my_decoder_chain));
  gst_element_add_pad (GST_ELEMENT (instance), instance->sinkpad);

  pad_template = gst_element_class_get_pad_template (GST_ELEMENT_CLASS (bclass), "src");
  g_return_if_fail (pad_template != NULL);

  instance->srcpad = gst_pad_new_from_template (pad_template, "src");

  gst_pad_set_getcaps_function (instance->srcpad,GST_DEBUG_FUNCPTR (gst_my_decoder_getcaps));
  gst_pad_set_acceptcaps_function (instance->srcpad,GST_DEBUG_FUNCPTR (gst_my_decoder_acceptcaps));
  gst_pad_set_event_function (instance->srcpad,GST_DEBUG_FUNCPTR (gst_my_decoder_src_event));
  gst_pad_set_checkgetrange_function (instance->srcpad,GST_DEBUG_FUNCPTR (gst_my_decoder_check_get_range));
  gst_pad_set_getrange_function (instance->srcpad,GST_DEBUG_FUNCPTR (gst_my_decoder_getrange));
  gst_element_add_pad (GST_ELEMENT (instance), instance->srcpad);

  instance->element_lock= g_mutex_new ();
}

static GstCaps *
gst_my_decoder_getcaps (GstPad * pad)
{
  GstMYDecoder *instance;
  GstPad *otherpad;
  GstCaps *caps;
  instance = GST_MY_DECODER (gst_pad_get_parent (pad));
  otherpad = (pad == instance->srcpad) ? instance->sinkpad : instance->srcpad;
  caps = gst_pad_peer_get_caps_reffed (otherpad);
  return caps;
}

static gboolean
gst_my_decoder_acceptcaps (GstPad * pad, GstCaps * caps)
{
  gboolean ret = TRUE;  
  return ret;
}
static gboolean
gst_my_decoder_setcaps (GstPad * pad, GstCaps * caps)
{
    return TRUE;  
}

static gboolean
gst_my_decoder_sink_event (GstPad * pad, GstEvent * event)
{
  gboolean ret = TRUE;
  return ret;
}

static gboolean
gst_my_decoder_sink_eventfunc (GstMYDecoder * instance, GstEvent * event)
{
    return TRUE;
}

static gboolean
gst_my_decoder_src_event (GstPad * pad, GstEvent * event)
{
  gboolean ret = TRUE;
  return ret;
}

static gboolean
gst_my_decoder_src_eventfunc (GstMYDecoder * instance, GstEvent * event)
{
  gboolean ret= TRUE;
  return ret;
}
static gboolean
gst_my_decoder_check_get_range (GstPad * pad)
{
    return TRUE;
}

static GstFlowReturn
gst_my_decoder_getrange (GstPad * pad, guint64 offset,
    guint length, GstBuffer ** buffer)
{
    GstFlowReturn ret = GST_FLOW_OK;
    return ret;
}

static GstFlowReturn
gst_my_decoder_chain (GstPad * pad, GstBuffer * buffer)
{
   GstFlowReturn ret = GST_FLOW_OK;
   return ret;
}

static void
gst_my_decoder_set_property (GObject * object, guint prop_id,
    const GValue * value, GParamSpec * pspec)
{
    return;
}

static void
gst_my_decoder_get_property (GObject * object, guint prop_id,
    GValue * value, GParamSpec * pspec)
{
    return;
}



/*******************************************
*gstchilddecoder.h
*
********************************************/

#ifndef __GST_CHILDDECODER_H__
#define __GST_CHILDDECODER_H__


#include <gst/gst.h>
#include <gst/gstmydecoder.h>

G_BEGIN_DECLS


#define GST_TYPE_CHILDDECODER \
  (gst_childdecoder_get_type())
#define GST_CHILDDECODER(obj) \
  (G_TYPE_CHECK_INSTANCE_CAST((obj),GST_TYPE_CHILDDECODER,GstChildDecoder))
#define GST_CHILDDECODER_CLASS(klass) \
  (G_TYPE_CHECK_CLASS_CAST((klass),GST_TYPE_CHILDDECODER,GstChildDecoderClass))
#define GST_CHILDDECODER_GET_CLASS(obj) \
  (G_TYPE_INSTANCE_GET_CLASS((obj),GST_TYPE_CHILDDECODER,GstChildDecoderClass))
#define GST_IS_CHILDDECODER(obj) \
  (G_TYPE_CHECK_INSTANCE_TYPE((obj),GST_TYPE_CHILDDECODER))
#define GST_IS_CHILDDECODER_CLASS(klass) \
  (G_TYPE_CHECK_CLASS_TYPE((klass),GST_TYPE_CHILDDECODER))


typedef struct _GstChildDecoder GstChildDecoder;
typedef struct _GstChildDecoderClass GstChildDecoderClass;

/**
 * GstChildDecoder:
 *
 * Opaque data structure.
 */
struct _GstChildDecoder {
  GstMYDecoder element;
  gboolean message; /* whether or not to post messages */
  void (*process)(gpointer, guint, guint, gdouble*, gdouble*);
};

struct _GstChildDecoderClass {
  GstMYDecoderClass parent_class;
};

GType gst_childdecoder_get_type (void);

G_END_DECLS

#endif /* __GST_CHILDDECODER_H__ */



/*****************************************
*
*gstchilddecoder.c
*
********************************************/


#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include <string.h>
#include <math.h>
#include <gst/gst.h>


/*private header files*/
#include "gstchilddecoder.h"

GST_DEBUG_CATEGORY_STATIC (childdecoder_debug);
#define GST_CAT_DEFAULT childdecoder_debug


static GstStaticPadTemplate sink_template_factory =
    GST_STATIC_PAD_TEMPLATE ("sink",
    GST_PAD_SINK,
    GST_PAD_ALWAYS,
    GST_STATIC_CAPS ("any")
    );

static GstStaticPadTemplate src_template_factory =
    GST_STATIC_PAD_TEMPLATE ("src",
    GST_PAD_SRC,
    GST_PAD_ALWAYS,
    GST_STATIC_CAPS ("any")
    );

GST_BOILERPLATE (GstChildDecoder, gst_childdecoder, GstMYDecoder,
    GST_TYPE_MY_DECODER);

static void gst_childdecoder_set_property (GObject * object, guint prop_id,
    const GValue * value, GParamSpec * pspec);
static void gst_childdecoder_get_property (GObject * object, guint prop_id,
    GValue * value, GParamSpec * pspec);

static gboolean gst_childdecoder_start_decode (GstMYDecoder * trans);
static gboolean gst_childdecoder_stop_decode (GstMYDecoder * trans);





static void
gst_childdecoder_base_init (gpointer g_class)
{
  GstElementClass *element_class = g_class;

  gst_element_class_add_pad_template (element_class,
      gst_static_pad_template_get (&sink_template_factory));
  gst_element_class_add_pad_template (element_class,
      gst_static_pad_template_get (&src_template_factory));
  gst_element_class_set_details_simple (element_class, "ChildDecoder",
      "Child decoder",
      "My own child decoder",
      "Private Use Only");
}

static void
gst_childdecoder_class_init (GstChildDecoderClass * klass)
{
  GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
  GstMYDecoderClass *trans_class = GST_MY_DECODER_CLASS (klass);

  gobject_class->set_property = gst_childdecoder_set_property;
  gobject_class->get_property = gst_childdecoder_get_property;
 
  GST_DEBUG_CATEGORY_INIT (childdecoder_debug, "childdecoder", 0, "Child decoder debug");

  trans_class->start_decode = GST_DEBUG_FUNCPTR (gst_childdecoder_start_decode);
  trans_class->stop_decode  = GST_DEBUG_FUNCPTR (gst_childdecoder_stop_decode);
}

static void
gst_childdecoder_init (GstChildDecoder * filter, GstChildDecoderClass * g_class)
{
  filter->message = TRUE;
  filter->process = NULL;  
}

static void
gst_childdecoder_set_property (GObject * object, guint prop_id,
    const GValue * value, GParamSpec * pspec)
{
    return;
}

static void
gst_childdecoder_get_property (GObject * object, guint prop_id,
    GValue * value, GParamSpec * pspec)
{
    return;
}

static gboolean
gst_childdecoder_start_decode (GstMYDecoder * trans)
{
  return TRUE;
}

static gboolean
gst_childdecoder_stop_decode (GstMYDecoder * trans)
{
    return TRUE;
}

static gboolean
childdecoder_plugin_init (GstPlugin * plugin)
{
  /*oil_init (); */

  return gst_element_register (plugin, "childdecoder", GST_RANK_NONE, GST_TYPE_CHILDDECODER);
}

GST_PLUGIN_DEFINE
(
    GST_VERSION_MAJOR,
    GST_VERSION_MINOR,
    "childdecoder",
    "My childdecoder plugin",
    childdecoder_plugin_init,
    VERSION,
    "My own decoder",
    "CHILDER_DECODER",
    "PRIVATE USE ONLY"
);













Reply | Threaded
Open this post in threaded view
|

Re: please help on my own base element

Tim-Philipp Müller-2
On Mon, 2011-01-31 at 15:43 -0800, kevin kelly wrote:

> I am trying to generate  my own base element called GstMyDecoder, which is
> very similar to GstbaseTransform, so that I can derive other elements from
> this base element.
>
> I compiled this GstMyDecoder and generated .so file without any errors. This
> .so file and header file gstmydecoder.h was copied to /usr/lib/gstream-0.10/
> and /usr/include/gstreamer-0.10/gst accordingly.
>
> I also derived GstMyChildDecoder from this GstMyDecoder element. The .so
> file was also compiled without any errors and was copied to
> /usr/lib/gstream-0.10/
>
> But when I tried to use "gst-inspect childdecoder", I got following error
> message:
>
> GStreamer-WARNING **: Failed to load plugin
> '/usr/lib/gstreamer-0.10/libgstmychilddecoder.so':
> /usr/lib/gstreamer-0.10/libgstmychilddecoder.so: undefined symbol:
> gst_my_decoder_get_type
>
> would you please help me to find what's wrong and how to solve this issue?
> Is there any special procedure to compile this base element?

There are two types of .so files in a GStreamer context:

(a) libraries which provide (export) API such as functions to external
users; these are usually installed into /usr/lib/ (e.g.
libgst*-0.10.so), with headers going somewhere into /usr/include. Users
of such libraries usually link to the libraries needed when building the
application/library dependent on it.

(b) plugins, which are usually found and loaded at runtime and do not
export any public symbols (other than an entry point with a plugin
description and the plugin init function).

If you want to make a new base class available, you need to create a
library, not a plugin (please don't name it libgst* though, but libmy*).

Having said that, there is no reason why you can't include such a base
class in your plugin if only elements in this plugin depend on it (see
e.g. the audioparsers plugin in -bad which contains an internal copy of
a GstBaseParse).

Cheers
 -Tim



------------------------------------------------------------------------------
Special Offer-- Download ArcSight Logger for FREE (a $49 USD value)!
Finally, a world-class log management solution at an even better price-free!
Download using promo code Free_Logger_4_Dev2Dev. Offer expires
February 28th, so secure your free ArcSight Logger TODAY!
http://p.sf.net/sfu/arcsight-sfd2d
_______________________________________________
gstreamer-devel mailing list
[hidden email]
https://lists.sourceforge.net/lists/listinfo/gstreamer-devel