New typefind system: bytestream is now part of the core all plugins have been modified to use this new typefind syste...

Original commit message from CVS:
New typefind system:
* bytestream is now part of the core
* all plugins have been modified to use this new typefind system
* asf typefinding added
* mpeg video stream typefiding removed because it's broken
* duplicate typefind entries removed
* extra id3 typefinding added, because we've seen 4 types of files
(riff/wav, flac, vorbis, mp3) with id3 headers and each of these needs
to work. Instead, I've added an id3 element and let it redo typefiding
after the id3 header. this needs a hack because spider only typefinds
once. We can remove this hack once spider supports multiple typefinds.
* with all this, mp3 typefinding is semi-rewritten
* id3 typefinding in flac/vorbis is removed, it's no longer needed
* fixed spider and gst-typefind to use this, too.
* Other general cleanups
This commit is contained in:
Ronald S. Bultje 2003-10-01 13:11:45 +00:00
parent 00d6aa9c21
commit 6fbff1c106
16 changed files with 89 additions and 500 deletions

View file

@ -568,7 +568,6 @@ gst/types/Makefile
gst/registries/Makefile
libs/Makefile
libs/gst/Makefile
libs/gst/bytestream/Makefile
libs/gst/getbits/Makefile
libs/gst/control/Makefile
libs/ext/Makefile

View file

@ -210,17 +210,6 @@ macros GST_IS_MIXER () and GST_MIXER () would then look like this:
So the application would just tread it with the known macro, and
everything would look extremely simple to the end user.
Also some convenience function to set the element:
void
gst_interface_set_element (GstInterface *iface,
GstElement *element)
{
g_return_if_fail (GST_IS_INTERFACE (iface));
iface->element = element;
}
4a) mixer
---------
A mixer is a way of controlling volume and input/output channels.
@ -317,7 +306,7 @@ typedef struct _GstOverlayClass {
XID xid);
} GstOverlayClass;
That's all!
That's all! It would look similar for FB & co.
4c) user input
--------------
@ -335,8 +324,9 @@ input-from-application APIs.
5) Status of this document
==========================
This is a proposal, nothing more. Nothing is implemented. Target
release is 0.8.0 or any 0.7.x version.
The interfaces are implemented, more (for metadata, framebuffer-
overlay, video balancing (brightness), user input etc. are all
pending.
6) Copyright and blabla
=======================

View file

@ -16,13 +16,13 @@ GST_LOADSAVE_SRC = gstxml.c
endif
if GST_DISABLE_TYPEFIND
GST_TYPEFIND_SRC =
GST_TYPEFIND_SRC =
else
GST_TYPEFIND_SRC = gsttypefind.c
endif
if GST_DISABLE_AUTOPLUG
GST_AUTOPLUG_SRC =
GST_AUTOPLUG_SRC =
GST_AUTOPLUG_DIRS =
else
GST_AUTOPLUG_SRC = gstautoplug.c
@ -91,11 +91,12 @@ libgstreamer_@GST_MAJORMINOR@_la_SOURCES = \
gstmarshal.c \
$(GST_ENUMTYPES_SRC) \
gstobject.c \
$(GST_AUTOPLUG_SRC) \
gstatomic.c \
$(GST_AUTOPLUG_SRC) \
gstbin.c \
gstbuffer.c \
gstbufferpool-default.c \
gstbytestream.c \
gstcaps.c \
gstclock.c \
gstcpu.c \
@ -157,6 +158,7 @@ gst_headers = \
gstbin.h \
gstbuffer.h \
gstbufferpool-default.h \
gstbytestream.h \
gstcaps.h \
gstclock.h \
gstcompat.h \

View file

@ -27,13 +27,15 @@ libgstautoplugger_la_CFLAGS = $(GST_CFLAGS)
libgstautoplugger_la_LIBADD =
libgstautoplugger_la_LDFLAGS = $(GST_PLUGIN_LDFLAGS)
libgstspider_la_SOURCES = gstspider.c gstspideridentity.c gstsearchfuncs.c
libgstspider_la_SOURCES = \
gstspider.c gstspideridentity.c \
gstsearchfuncs.c
libgstspider_la_CFLAGS = $(GST_CFLAGS)
libgstspider_la_LIBADD =
libgstspider_la_LDFLAGS = $(GST_PLUGIN_LDFLAGS)
noinst_HEADERS = gststaticautoplug.h gststaticautoplugrender.h \
gstspider.h gstspideridentity.h gstsearchfuncs.h
gstspider.h gstspideridentity.h gstsearchfuncs.h
noinst_PROGRAMS = autoplugtest spidertest

View file

@ -250,11 +250,12 @@ gst_autoplug_factories_filters_with_sink_caps (GList *factories)
GList *ret = NULL;
GstElementFactory *factory;
GList *templs;
while (factories)
{
factory = (GstElementFactory *) factories->data;
templs = factory->padtemplates;
if (GST_PLUGIN_FEATURE (factory)->rank > 0){
gboolean have_src = FALSE;
gboolean have_sink = FALSE;
@ -341,6 +342,7 @@ gst_autoplug_sp (GstCaps *srccaps, GstCaps *sinkcaps, GList *factories)
GST_INFO ("attempting to autoplug via shortest path from %s to %s",
gst_caps_get_mime (srccaps), gst_caps_get_mime (sinkcaps));
gst_caps_debug (srccaps, "source caps");
gst_caps_debug (sinkcaps, "sink caps");
/* wrap all factories as GstAutoplugNode

View file

@ -413,61 +413,22 @@ gst_spider_identity_src_loop (GstSpiderIdentity *ident)
static void
gst_spider_identity_sink_loop_type_finding (GstSpiderIdentity *ident)
{
GstBuffer *buf=NULL;
GstBuffer *typefindbuf = NULL;
gboolean getmorebuf = TRUE;
GstBuffer *buf = NULL;
GList *type_list;
GstCaps *caps;
GstByteStream *bs;
/* this should possibly be a property */
guint bufsizelimit = 4096;
g_return_if_fail (GST_IS_SPIDER_IDENTITY (ident));
while (getmorebuf){
/* check if our buffer is big enough to do a typefind */
if (typefindbuf && GST_BUFFER_SIZE(typefindbuf) >= bufsizelimit){
getmorebuf = FALSE;
break;
}
buf = gst_pad_pull (ident->sink);
/* if it's an event... */
while (GST_IS_EVENT (buf)) {
switch (GST_EVENT_TYPE (GST_EVENT (buf))){
case GST_EVENT_EOS:
getmorebuf = FALSE;
/* FIXME Notify the srcs that EOS has happened */
gst_pad_event_default (ident->sink, GST_EVENT (buf));
break;
default:
gst_pad_event_default (ident->sink, GST_EVENT (buf));
buf = gst_pad_pull (ident->sink);
break;
}
/* handle DISCONT events, please */
}
typefindbuf = buf;
getmorebuf = FALSE;
/* FIXME merging doesn't work for some reason so
* we'll just typefind with the first element
if (!typefindbuf){
typefindbuf = buf;
gst_buffer_ref(buf);
}
else {
GstBuffer *oldbuf = typefindbuf;
typefindbuf = gst_buffer_merge(typefindbuf, buf);
gst_buffer_unref(oldbuf);
gst_buffer_unref(buf);
}
*/
}
if (!typefindbuf){
/* get a bytestream object */
bs = gst_bytestream_new (ident->sink);
if (gst_bytestream_peek (bs, &buf, 1) != 1 || !buf) {
buf = NULL;
g_warning ("Failed to read fake buffer - serious idiocy going on here");
goto end;
} else {
gst_buffer_unref (buf);
buf = NULL;
}
/* maybe there are already valid caps now? */
@ -487,7 +448,7 @@ gst_spider_identity_sink_loop_type_finding (GstSpiderIdentity *ident)
GstTypeFindFunc typefindfunc = (GstTypeFindFunc)factory->typefindfunc;
GST_DEBUG ("trying typefind function %s", GST_PLUGIN_FEATURE_NAME (factory));
if (typefindfunc && (caps = typefindfunc (buf, factory))) {
if (typefindfunc && (caps = typefindfunc (bs, factory))) {
GST_INFO ("typefind function %s found caps", GST_PLUGIN_FEATURE_NAME (factory));
if (gst_pad_try_set_caps (ident->src, caps) <= 0) {
g_warning ("typefind: found type but peer didn't accept it");
@ -501,7 +462,6 @@ gst_spider_identity_sink_loop_type_finding (GstSpiderIdentity *ident)
type_list = g_list_next (type_list);
}
gst_element_error(GST_ELEMENT(ident), "Could not find media type", NULL);
gst_buffer_unref(buf);
buf = GST_BUFFER (gst_event_new (GST_EVENT_EOS));
end:
@ -512,15 +472,19 @@ end:
/* push the buffer */
gst_spider_identity_chain (ident->sink, buf);
/* bytestream no longer needed */
gst_bytestream_destroy (bs);
return;
plug:
gst_caps_debug (caps, "spider starting caps");
gst_caps_sink (caps);
gst_spider_identity_plug (ident);
gst_spider_identity_plug (ident);
gst_bytestream_read (bs, &buf, bs->listavail);
goto end;
}

View file

@ -28,7 +28,7 @@
#include <stdlib.h>
#include <gst/gstinfo.h>
#include "bytestream.h"
#include <gst/gstbytestream.h>
GST_DEBUG_CATEGORY_STATIC(debug_bs);
#define GST_CAT_DEFAULT debug_bs
@ -744,18 +744,3 @@ gst_bytestream_print_status (GstByteStream * bs)
GST_BUFFER_OFFSET (buf), GST_BUFFER_SIZE (buf));
}
}
static gboolean
plugin_init (GModule *module, GstPlugin *plugin)
{
gst_plugin_set_longname (plugin, "GstByteStream: a byte-oriented layer on top of buffer-passing");
return TRUE;
}
GstPluginDesc plugin_desc = {
GST_VERSION_MAJOR,
GST_VERSION_MINOR,
"gstbytestream",
plugin_init
};

View file

@ -20,7 +20,9 @@
#ifndef __GST_BYTESTREAM_H__
#define __GST_BYTESTREAM_H__
#include <gst/gst.h>
#include <glib.h>
#include <gst/gstpad.h>
#include <gst/gstevent.h>
G_BEGIN_DECLS

View file

@ -29,6 +29,7 @@
#include "gst_private.h"
#include "gstbytestream.h"
#include "gsttype.h"
#include "gstregistrypool.h"
#include "gstobject.h"
@ -42,9 +43,7 @@ static guint16 _gst_maxtype;
static void gst_type_factory_class_init (GstTypeFactoryClass *klass);
static void gst_type_factory_init (GstTypeFactory *factory);
static GstCaps* gst_type_type_find_dummy (GstBuffer *buffer, gpointer priv);
static void gst_type_factory_unload_thyself (GstPluginFeature *feature);
static void gst_type_factory_unload_thyself (GstPluginFeature *feature);
static GstPluginFeatureClass *parent_class = NULL;
/* static guint gst_type_factory_signals[LAST_SIGNAL] = { 0 }; */
@ -315,8 +314,8 @@ gst_type_factory_unload_thyself (GstPluginFeature *feature)
factory->typefindfunc = gst_type_type_find_dummy;
}
static GstCaps*
gst_type_type_find_dummy (GstBuffer *buffer, gpointer priv)
GstCaps*
gst_type_type_find_dummy (GstByteStream *bs, gpointer priv)
{
GstCaps *res = NULL;
GstTypeFactory *factory = (GstTypeFactory *)priv;
@ -329,7 +328,7 @@ gst_type_type_find_dummy (GstBuffer *buffer, gpointer priv)
g_warning ("could not load valid typefind function for %s\n", factory->mime);
}
else if (factory->typefindfunc) {
res = factory->typefindfunc (buffer, factory);
res = factory->typefindfunc (bs, priv);
}
}

View file

@ -24,14 +24,14 @@
#ifndef __GST_TYPE_H__
#define __GST_TYPE_H__
#include <gst/gstbuffer.h>
#include <gst/gstcaps.h>
#include <gst/gstpluginfeature.h>
#include <gst/gstbytestream.h>
G_BEGIN_DECLS
/* type of function used to check a stream for equality with type */
typedef GstCaps* (*GstTypeFindFunc) (GstBuffer *buf, gpointer priv);
typedef GstCaps* (*GstTypeFindFunc) (GstByteStream *bs, gpointer priv);
typedef struct _GstType GstType;
typedef struct _GstTypeDefinition GstTypeDefinition;
@ -74,7 +74,7 @@ struct _GstTypeFactory {
struct _GstTypeFactoryClass {
GstPluginFeatureClass parent;
gpointer dummy[8];
gpointer dummy[8];
};
@ -98,6 +98,9 @@ GstType* gst_type_find_by_id (guint16 id);
/* get the list of registered types (returns list of GstType!) */
const GList* gst_type_get_list (void);
/* dummy typefind function */
GstCaps* gst_type_type_find_dummy (GstByteStream *bs, gpointer priv);
G_END_DECLS
#endif /* __GST_TYPE_H__ */

View file

@ -26,8 +26,6 @@
#include "gstinfo.h"
#include "gsttypefind.h"
#define DEFAULT_MAX_BUFFERS 1
GstElementDetails gst_type_find_details = {
"TypeFind",
"Generic",
@ -39,6 +37,13 @@ GstElementDetails gst_type_find_details = {
"(C) 1999",
};
/* generic templates */
GST_PAD_TEMPLATE_FACTORY (type_find_sink_factory,
"sink",
GST_PAD_SINK,
GST_PAD_ALWAYS,
NULL
);
/* TypeFind signals and args */
enum {
@ -49,7 +54,6 @@ enum {
enum {
ARG_0,
ARG_CAPS,
ARG_MAX_BUFFERS,
};
@ -63,7 +67,7 @@ static void gst_type_find_get_property (GObject *object, guint prop_id,
GValue *value,
GParamSpec *pspec);
static void gst_type_find_chain (GstPad *pad, GstBuffer *buf);
static void gst_type_find_loopfunc (GstElement *element);
static GstElementStateReturn
gst_type_find_change_state (GstElement *element);
@ -88,7 +92,9 @@ gst_type_find_get_type (void)
(GInstanceInitFunc)gst_type_find_init,
NULL
};
typefind_type = g_type_register_static (GST_TYPE_ELEMENT, "GstTypeFind", &typefind_info, 0);
typefind_type = g_type_register_static (GST_TYPE_ELEMENT,
"GstTypeFind",
&typefind_info, 0);
}
return typefind_type;
}
@ -106,11 +112,6 @@ gst_type_find_class_init (GstTypeFindClass *klass)
g_object_class_install_property (G_OBJECT_CLASS (klass), ARG_CAPS,
g_param_spec_pointer ("caps", "Caps", "Found capabilities", G_PARAM_READABLE));
g_object_class_install_property (G_OBJECT_CLASS (klass), ARG_MAX_BUFFERS,
g_param_spec_int ("max_buffers",
"Max Buffers",
"Maximal amount of buffers before giving en error (0 == unlimited)",
0, G_MAXINT, DEFAULT_MAX_BUFFERS, G_PARAM_READWRITE));
gst_type_find_signals[HAVE_TYPE] =
g_signal_new ("have_type", G_TYPE_FROM_CLASS (klass), G_SIGNAL_RUN_LAST,
@ -127,12 +128,13 @@ gst_type_find_class_init (GstTypeFindClass *klass)
static void
gst_type_find_init (GstTypeFind *typefind)
{
typefind->sinkpad = gst_pad_new ("sink", GST_PAD_SINK);
typefind->sinkpad = gst_pad_new_from_template (
GST_PAD_TEMPLATE_GET (type_find_sink_factory), "sink");
gst_element_add_pad (GST_ELEMENT (typefind), typefind->sinkpad);
gst_pad_set_chain_function (typefind->sinkpad, gst_type_find_chain);
typefind->num_buffer = 0;
typefind->max_buffers = DEFAULT_MAX_BUFFERS;
gst_element_set_loop_function (GST_ELEMENT (typefind),
gst_type_find_loopfunc);
typefind->caps = NULL;
}
@ -147,9 +149,6 @@ gst_type_find_set_property (GObject *object, guint prop_id,
typefind = GST_TYPE_FIND (object);
switch (prop_id) {
case ARG_MAX_BUFFERS:
typefind->max_buffers = g_value_get_int (value);
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
break;
@ -170,9 +169,6 @@ gst_type_find_get_property (GObject *object, guint prop_id,
case ARG_CAPS:
g_value_set_pointer (value, typefind->caps);
break;
case ARG_MAX_BUFFERS:
g_value_set_int (value, typefind->max_buffers);
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
break;
@ -180,18 +176,16 @@ gst_type_find_get_property (GObject *object, guint prop_id,
}
static void
gst_type_find_chain (GstPad *pad, GstBuffer *buf)
gst_type_find_loopfunc (GstElement *element)
{
GstTypeFind *typefind;
const GList *type_list;
GstType *type;
g_return_if_fail (GST_IS_PAD (pad));
typefind = GST_TYPE_FIND (element);
typefind = GST_TYPE_FIND (GST_OBJECT_PARENT (pad));
GST_DEBUG ("got buffer of %d bytes in '%s'",
GST_BUFFER_SIZE (buf), GST_OBJECT_NAME (typefind));
GST_DEBUG ("Started typefinding loop in '%s'",
GST_OBJECT_NAME (typefind));
type_list = gst_type_get_list ();
@ -203,42 +197,34 @@ gst_type_find_chain (GstPad *pad, GstBuffer *buf)
while (factories) {
GstTypeFactory *factory = GST_TYPE_FACTORY (factories->data);
GstTypeFindFunc typefindfunc = (GstTypeFindFunc)factory->typefindfunc;
GstTypeFindFunc typefindfunc = (GstTypeFindFunc) factory->typefindfunc;
GstCaps *caps;
GST_CAT_DEBUG (GST_CAT_TYPES, "try type (%p) :%d \"%s\" %p",
factory, type->id, type->mime, typefindfunc);
if (typefindfunc && (caps = typefindfunc (buf, factory))) {
if (typefindfunc && (caps = typefindfunc (typefind->bs, factory))) {
GST_CAT_DEBUG (GST_CAT_TYPES, "found type: %d \"%s\" \"%s\"",
caps->id, type->mime, gst_caps_get_name (caps));
typefind->caps = caps;
gst_caps_replace (&typefind->caps, caps);
if (gst_pad_try_set_caps (pad, caps) <= 0) {
if (gst_pad_try_set_caps (typefind->sinkpad, caps) <= 0) {
g_warning ("typefind: found type but peer didn't accept it");
}
{
gst_object_ref (GST_OBJECT (typefind));
g_signal_emit (G_OBJECT (typefind), gst_type_find_signals[HAVE_TYPE], 0,
typefind->caps);
gst_object_unref (GST_OBJECT (typefind));
goto end;
}
gst_object_ref (GST_OBJECT (typefind));
g_signal_emit (G_OBJECT (typefind), gst_type_find_signals[HAVE_TYPE],
0, typefind->caps);
gst_object_unref (GST_OBJECT (typefind));
return;
}
factories = g_slist_next (factories);
}
type_list = g_list_next (type_list);
}
typefind->num_buffer++;
end:
gst_buffer_unref (buf);
if (typefind->max_buffers && typefind->num_buffer >= typefind->max_buffers) {
gst_element_error (GST_ELEMENT (typefind),
"typefind could not determine type after %d buffers", typefind->num_buffer);
}
/* if we get here, nothing worked... :'(. */
gst_element_error (GST_ELEMENT (typefind),
"media type could not be detected");
}
static GstElementStateReturn
@ -250,17 +236,14 @@ gst_type_find_change_state (GstElement *element)
typefind = GST_TYPE_FIND (element);
switch (GST_STATE_TRANSITION (element)) {
case GST_STATE_NULL_TO_READY:
break;
case GST_STATE_READY_TO_PAUSED:
typefind->num_buffer = 0;
gst_caps_unref (typefind->caps);
typefind->caps = NULL;
typefind->bs = gst_bytestream_new (typefind->sinkpad);
break;
case GST_STATE_PAUSED_TO_PLAYING:
case GST_STATE_PLAYING_TO_PAUSED:
case GST_STATE_PAUSED_TO_READY:
case GST_STATE_READY_TO_NULL:
gst_bytestream_destroy (typefind->bs);
gst_caps_replace (&typefind->caps, NULL);
break;
default:
break;
}

View file

@ -27,6 +27,7 @@
#ifndef GST_DISABLE_TYPE_FIND
#include <gst/gstelement.h>
#include <gst/gstbytestream.h>
G_BEGIN_DECLS
@ -46,11 +47,9 @@ struct _GstTypeFind {
GstElement element;
GstPad *sinkpad;
GstByteStream *bs;
GstCaps *caps;
gint num_buffer;
gint max_buffers;
};
struct _GstTypeFindClass {

View file

@ -711,29 +711,6 @@ gst_xml_registry_parse_element_factory (GMarkupParseContext *context, const gcha
return TRUE;
}
static GstCaps*
gst_type_type_find_dummy (GstBuffer *buffer, gpointer priv)
{
GstTypeFactory *factory = (GstTypeFactory *)priv;
GST_CAT_DEBUG (GST_CAT_TYPES,"gsttype: need to load typefind function for %s", factory->mime);
if (gst_plugin_feature_ensure_loaded (GST_PLUGIN_FEATURE (factory))) {
if (factory->typefindfunc) {
if (factory->typefindfunc == gst_type_type_find_dummy) {
GST_CAT_WARNING (GST_CAT_TYPES, "GstTypeFactory %s for mime %s exts %s does not install a valid typefindfunc",
factory->feature.name, factory->mime, factory->exts);
} else {
GstCaps *res = factory->typefindfunc (buffer, factory);
if (res)
return res;
}
}
}
return NULL;
}
static gboolean
gst_xml_registry_parse_type_factory (GMarkupParseContext *context, const gchar *tag, const gchar *text,
gsize text_len, GstXMLRegistry *registry, GError **error)

View file

@ -1,3 +1,3 @@
SUBDIRS = bytestream control getbits
SUBDIRS = control getbits
DIST_SUBDIRS = bytestream control getbits
DIST_SUBDIRS = control getbits

View file

@ -1,14 +0,0 @@
librarydir = $(libdir)/gstreamer-@GST_MAJORMINOR@
library_LTLIBRARIES = libgstbytestream.la
noinst_LTLIBRARIES = libgstbstest.la
libgstbytestreamincludedir = $(includedir)/gstreamer-@GST_MAJORMINOR@/gst/bytestream
libgstbytestreaminclude_HEADERS = bytestream.h
libgstbytestream_la_SOURCES = bytestream.c
libgstbytestream_la_CFLAGS = $(GST_CFLAGS)
libgstbytestream_la_LDFLAGS = $(GST_PLUGIN_LDFLAGS)
libgstbstest_la_SOURCES = bstest.c
libgstbstest_la_CFLAGS = $(GST_CFLAGS)

View file

@ -1,304 +0,0 @@
/* GStreamer
* Copyright (C) 1999,2000 Erik Walthinsen <omega@cse.ogi.edu>
* 2000 Wim Taymans <wtay@chello.be>
*
* gstidentity.c:
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Library General Public License for more details.
*
* You should have received a copy of the GNU Library General Public
* License along with this library; if not, write to the
* Free Software Foundation, Inc., 59 Temple Place - Suite 330,
* Boston, MA 02111-1307, USA.
*/
#ifdef HAVE_CONFIG_H
# include "config.h"
#endif
#include <stdlib.h>
#include <gst/gst.h>
#include "bytestream.h"
#define GST_TYPE_IDENTITY \
(gst_identity_get_type())
#define GST_IDENTITY(obj) \
(G_TYPE_CHECK_INSTANCE_CAST((obj),GST_TYPE_IDENTITY,GstIdentity))
#define GST_IDENTITY_CLASS(klass) \
(G_TYPE_CHECK_CLASS_CAST((klass),GST_TYPE_IDENTITY,GstIdentityClass))
#define GST_IS_IDENTITY(obj) \
(G_TYPE_CHECK_INSTANCE_TYPE((obj),GST_TYPE_IDENTITY))
#define GST_IS_IDENTITY_CLASS(obj) \
(G_TYPE_CHECK_CLASS_TYPE((klass),GST_TYPE_IDENTITY))
typedef struct _GstIdentity GstIdentity;
typedef struct _GstIdentityClass GstIdentityClass;
struct _GstIdentity {
GstElement element;
GstPad *sinkpad;
GstPad *srcpad;
GstByteStream *bs;
gint byte_size;
gint count;
};
struct _GstIdentityClass {
GstElementClass parent_class;
};
GType gst_identity_get_type(void);
GstElementDetails gst_identity_details = {
"ByteStreamTest",
"Filter",
"Test for the GstByteStream code",
VERSION,
"Erik Walthinsen <omega@temple-baptist.com>",
"(C) 2001",
};
/* Identity signals and args */
enum {
/* FILL ME */
LAST_SIGNAL
};
enum {
ARG_0,
ARG_BYTE_SIZE,
ARG_COUNT,
};
static void gst_identity_class_init (GstIdentityClass *klass);
static void gst_identity_init (GstIdentity *identity);
static void gst_identity_set_property (GObject *object, guint prop_id, const GValue *value, GParamSpec *pspec);
static void gst_identity_get_property (GObject *object, guint prop_id, GValue *value, GParamSpec *pspec);
static void gst_identity_loop (GstElement *element);
static GstElementClass *parent_class = NULL;
/* static guint gst_identity_signals[LAST_SIGNAL] = { 0 }; */
GType
gst_identity_get_type (void)
{
static GType identity_type = 0;
if (!identity_type) {
static const GTypeInfo identity_info = {
sizeof(GstIdentityClass), NULL,
NULL,
(GClassInitFunc)gst_identity_class_init,
NULL,
NULL,
sizeof(GstIdentity),
0,
(GInstanceInitFunc)gst_identity_init,
};
identity_type = g_type_register_static (GST_TYPE_ELEMENT, "GstBSTest", &identity_info, 0);
}
return identity_type;
}
static void
gst_identity_class_init (GstIdentityClass *klass)
{
GObjectClass *gobject_class;
gobject_class = (GObjectClass*)klass;
parent_class = g_type_class_ref (GST_TYPE_ELEMENT);
g_object_class_install_property (G_OBJECT_CLASS (klass), ARG_BYTE_SIZE,
g_param_spec_uint ("byte_size", "byte_size", "byte_size",
0, G_MAXUINT, 0, G_PARAM_READWRITE));
g_object_class_install_property (G_OBJECT_CLASS (klass), ARG_COUNT,
g_param_spec_uint ("count", "count", "count",
0, G_MAXUINT, 0, G_PARAM_READWRITE));
gobject_class->set_property = GST_DEBUG_FUNCPTR (gst_identity_set_property);
gobject_class->get_property = GST_DEBUG_FUNCPTR (gst_identity_get_property);
}
/*
static GstPadNegotiateReturn
gst_identity_negotiate_src (GstPad *pad, GstCaps **caps, gpointer *data)
{
GstIdentity *identity;
identity = GST_IDENTITY (gst_pad_get_parent (pad));
return gst_pad_negotiate_proxy (pad, identity->sinkpad, caps);
}
static GstPadNegotiateReturn
gst_identity_negotiate_sink (GstPad *pad, GstCaps **caps, gpointer *data)
{
GstIdentity *identity;
identity = GST_IDENTITY (gst_pad_get_parent (pad));
return gst_pad_negotiate_proxy (pad, identity->srcpad, caps);
}
*/
static void
gst_identity_init (GstIdentity *identity)
{
identity->sinkpad = gst_pad_new ("sink", GST_PAD_SINK);
gst_element_add_pad (GST_ELEMENT (identity), identity->sinkpad);
/*gst_pad_set_negotiate_function (identity->sinkpad, gst_identity_negotiate_sink); */
identity->srcpad = gst_pad_new ("src", GST_PAD_SRC);
gst_element_add_pad (GST_ELEMENT (identity), identity->srcpad);
/*gst_pad_set_negotiate_function (identity->srcpad, gst_identity_negotiate_src); */
gst_element_set_loop_function (GST_ELEMENT (identity), gst_identity_loop);
identity->byte_size = 384;
identity->count = 5;
identity->bs = gst_bytestream_new(identity->sinkpad);
}
static void
gst_identity_loop (GstElement *element)
{
GstIdentity *identity;
GstBuffer *buf;
int i;
g_return_if_fail (element != NULL);
g_return_if_fail (GST_IS_IDENTITY (element));
identity = GST_IDENTITY (element);
/* THIS IS THE BUFFER BASED ONE
do {
* g_print("\n"); *
for (i=0;i<identity->count;i++) {
* g_print("bstest: getting a buffer of %d bytes\n",identity->byte_size); *
buf = gst_bytestream_read(identity->bs,identity->byte_size);
if (!buf) g_print("BUFFER IS BOGUS\n");
* g_print("pushing the buffer, %d bytes at %d\n",GST_BUFFER_SIZE(buf),GST_BUFFER_OFFSET(buf)); *
gst_pad_push(identity->srcpad,buf);
* g_print("\n"); *
gst_bytestream_print_status(identity->bs);
* g_print("\n\n"); *
}
exit(1);
} while (!GST_ELEMENT_IS_COTHREAD_STOPPING(element));
*/
/* THIS IS THE BYTE BASED ONE*/
do {
for (i=0;i<identity->count;i++) {
guint8 *data;
buf = gst_buffer_new();
/* note that this is dangerous, as it does *NOT* refcount the data, it can go away!!! */
GST_BUFFER_SIZE(buf) = gst_bytestream_peek_bytes(identity->bs, &data, identity->byte_size);
GST_BUFFER_DATA(buf) = data;
GST_BUFFER_FLAG_SET(buf,GST_BUFFER_DONTFREE);
gst_pad_push(identity->srcpad,buf);
gst_bytestream_flush(identity->bs,identity->byte_size);
}
exit(1);
/* implicit declaration of function `GST_ELEMENT_IS_COTHREAD_STOPPING' */
#define GST_ELEMENT_IS_COTHREAD_STOPPING(element) GST_FLAG_IS_SET((element), GST_ELEMENT_SCHEDULER_PRIVATE1)
} while (!GST_ELEMENT_IS_COTHREAD_STOPPING(element));
/**/
}
static void
gst_identity_set_property (GObject *object, guint prop_id, const GValue *value, GParamSpec *pspec)
{
GstIdentity *identity;
/* it's not null if we got it, but it might not be ours */
g_return_if_fail (GST_IS_IDENTITY (object));
identity = GST_IDENTITY (object);
switch (prop_id) {
case ARG_BYTE_SIZE:
identity->byte_size = g_value_get_uint (value);
break;
case ARG_COUNT:
identity->count = g_value_get_uint (value);
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
break;
}
}
static void gst_identity_get_property(GObject *object, guint prop_id, GValue *value, GParamSpec *pspec) {
GstIdentity *identity;
/* it's not null if we got it, but it might not be ours */
g_return_if_fail (GST_IS_IDENTITY (object));
identity = GST_IDENTITY (object);
switch (prop_id) {
case ARG_BYTE_SIZE:
g_value_set_uint (value, identity->byte_size);
break;
case ARG_COUNT:
g_value_set_uint (value, identity->count);
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
break;
}
}
static gboolean
plugin_init (GModule *module, GstPlugin *plugin)
{
GstElementFactory *factory;
/* we need gstbytestream */
if (!gst_library_load ("gstbytestream")) {
g_print("can't load bytestream\n");
return FALSE;
}
/* We need to create an ElementFactory for each element we provide.
* This consists of the name of the element, the GType identifier,
* and a pointer to the details structure at the top of the file.
*/
factory = gst_element_factory_new("gstbstest", GST_TYPE_IDENTITY, &gst_identity_details);
g_return_val_if_fail(factory != NULL, FALSE);
/* The very last thing is to register the elementfactory with the plugin. */
gst_plugin_add_feature (plugin, GST_PLUGIN_FEATURE (factory));
return TRUE;
}
GstPluginDesc plugin_desc = {
GST_VERSION_MAJOR,
GST_VERSION_MINOR,
"gstbstest",
plugin_init
};