diff options
| -rw-r--r-- | ChangeLog | 11 | ||||
| -rw-r--r-- | gst/debug/Makefile.am | 10 | ||||
| -rw-r--r-- | gst/debug/gstdebug.c | 2 | ||||
| -rw-r--r-- | gst/debug/gstpushfilesrc.c | 205 | ||||
| -rw-r--r-- | gst/debug/gstpushfilesrc.h | 58 | 
5 files changed, 285 insertions, 1 deletions
@@ -1,3 +1,14 @@ +2007-02-12  Tim-Philipp Müller  <tim at centricular dot net> + +	* gst/debug/Makefile.am: +	* gst/debug/gstdebug.c: (plugin_init): +	* gst/debug/gstpushfilesrc.c: +	* gst/debug/gstpushfilesrc.h: +	  Add code for a pushfilesrc element that implements a pushfile:// URI +	  handler, to make debugging push-mode operation of demuxer/decoders +	  that support both easier in connection with seek/playbin/etc. +	  The element isn't registered at the moment. +  2007-02-11  Sébastien Moutte  <sebastien@moutte.net>  	* gst/avi/gstavimux.c: diff --git a/gst/debug/Makefile.am b/gst/debug/Makefile.am index df88c8ed..13f0df5b 100644 --- a/gst/debug/Makefile.am +++ b/gst/debug/Makefile.am @@ -6,7 +6,13 @@ endif  plugin_LTLIBRARIES = $(EFENCE_PLUGIN) libgstdebug.la libgstnavigationtest.la  -noinst_HEADERS = efence.h gstnavigationtest.h gstnavseek.h progressreport.h tests.h +noinst_HEADERS = \ +	efence.h \ +	gstnavigationtest.h \ +	gstnavseek.h \ +	gstpushfilesrc.h \ +	progressreport.h \ +	tests.h  libgstefence_la_SOURCES = efence.c  libgstefence_la_CFLAGS = $(GST_CFLAGS) @@ -26,6 +32,8 @@ libgstdebug_la_SOURCES = \   	progressreport.c \   	progressreport.h \  	gstnavseek.c \ +	gstpushfilesrc.c \ +	gstpushfilesrc.h \   	tests.c \   	testplugin.c  # 	negotiation.c diff --git a/gst/debug/gstdebug.c b/gst/debug/gstdebug.c index 958d472d..c396befc 100644 --- a/gst/debug/gstdebug.c +++ b/gst/debug/gstdebug.c @@ -27,6 +27,7 @@ gboolean gst_progress_report_plugin_init (GstPlugin * plugin);  gboolean gst_navseek_plugin_init (GstPlugin * plugin);  gboolean gst_test_plugin_init (GstPlugin * plugin);  gboolean gst_break_my_data_plugin_init (GstPlugin * plugin); +gboolean gst_push_file_src_plugin_init (GstPlugin * plugin);  /* gboolean gst_negotiation_plugin_init (GstPlugin * plugin); */ @@ -35,6 +36,7 @@ plugin_init (GstPlugin * plugin)  {    if (!gst_break_my_data_plugin_init (plugin) ||        !gst_navseek_plugin_init (plugin) || +/*    !gst_push_file_src_plugin_init (plugin) || */  /*    !gst_negotiation_plugin_init (plugin) || */        !gst_progress_report_plugin_init (plugin) ||        !gst_test_plugin_init (plugin)) diff --git a/gst/debug/gstpushfilesrc.c b/gst/debug/gstpushfilesrc.c new file mode 100644 index 00000000..3fb91630 --- /dev/null +++ b/gst/debug/gstpushfilesrc.c @@ -0,0 +1,205 @@ +/* GStreamer Push File Source + * Copyright (C) <2007> Tim-Philipp Müller <tim centricular net> + * + * 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. + */ + +/** + * SECTION:element-pushfilesrc + * @short_description: Works like a filesrc, but only push-based (for debugging) + * @see_also: filesrc + * + * <refsect2> + * <para> + * This element is only useful for debugging purposes. It implements an URI + * protocol handler for the 'pushfile' protocol and behaves like a file source + * element that cannot be activated in pull-mode. This makes it very easy to + * debug demuxers or decoders that can operate both pull and push-based in + * connection with the playbin element (which creates a source based on the + * URI passed). + * </para> + * <title>Example launch line</title> + * <para> + * <programlisting> + * gst-launch -m playbin uri=pushfile:///home/you/some/file.ogg + * </programlisting> + * This plays back the given file using playbin, with the demuxer operating + * push-based. + * </para> + * </refsect2> + */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include "gstpushfilesrc.h" + +#include <gst/gst.h> + +GST_DEBUG_CATEGORY_STATIC (pushfilesrc_debug); +#define GST_CAT_DEFAULT pushfilesrc_debug + +static const GstElementDetails pushfilesrc_details = +GST_ELEMENT_DETAILS ("Push File Source", +    "Testing", +    "Implements pushfile:// URI-handler for push-based file access", +    "Tim-Philipp Müller <tim centricular net>"); + +static GstStaticPadTemplate srctemplate = GST_STATIC_PAD_TEMPLATE ("src", +    GST_PAD_SRC, +    GST_PAD_ALWAYS, +    GST_STATIC_CAPS_ANY); + +static void gst_push_file_src_uri_handler_init (gpointer g_iface, +    gpointer iface_data); +static void gst_file_push_src_add_uri_handler (GType type); + +GST_BOILERPLATE_FULL (GstPushFileSrc, gst_push_file_src, GstBin, GST_TYPE_BIN, +    gst_file_push_src_add_uri_handler); + +static void +gst_file_push_src_add_uri_handler (GType type) +{ +  static const GInterfaceInfo info = { +    gst_push_file_src_uri_handler_init, +    NULL, +    NULL +  }; + +  g_type_add_interface_static (type, GST_TYPE_URI_HANDLER, &info); +  GST_DEBUG_CATEGORY_INIT (pushfilesrc_debug, "pushfilesrc", 0, +      "pushfilesrc element"); +} + +static void +gst_push_file_src_base_init (gpointer g_class) +{ +  GstElementClass *element_class = GST_ELEMENT_CLASS (g_class); + +  gst_element_class_add_pad_template (element_class, +      gst_static_pad_template_get (&srctemplate)); + +  gst_element_class_set_details (element_class, &pushfilesrc_details); +} + +static void +gst_push_file_src_dispose (GObject * obj) +{ +  GstPushFileSrc *src = GST_PUSH_FILE_SRC (obj); + +  if (src->srcpad) { +    gst_element_remove_pad (GST_ELEMENT (src), src->srcpad); +    src->srcpad = NULL; +  } +  if (src->filesrc) { +    gst_bin_remove (GST_BIN (src), src->filesrc); +    src->filesrc = NULL; +  } + +  G_OBJECT_CLASS (parent_class)->dispose (obj); +} + +static void +gst_push_file_src_class_init (GstPushFileSrcClass * g_class) +{ +  GObjectClass *gobject_class; + +  gobject_class = G_OBJECT_CLASS (g_class); + +  gobject_class->dispose = gst_push_file_src_dispose; +} + +static gboolean +gst_push_file_src_ghostpad_checkgetrange (GstPad * pad) +{ +  return FALSE; +} + +static void +gst_push_file_src_init (GstPushFileSrc * src, GstPushFileSrcClass * g_class) +{ +  src->filesrc = gst_element_factory_make ("filesrc", "real-filesrc"); +  if (src->filesrc) { +    GstPad *pad; + +    gst_bin_add (GST_BIN (src), src->filesrc); +    pad = gst_element_get_static_pad (src->filesrc, "src"); +    g_assert (pad != NULL); +    src->srcpad = gst_ghost_pad_new ("src", pad); +    /* FIXME^H^HCORE: try pushfile:///foo/bar.ext ! typefind ! fakesink without +     * this and watch core bugginess (some pad stays in flushing state) */ +    gst_pad_set_checkgetrange_function (src->srcpad, +        GST_DEBUG_FUNCPTR (gst_push_file_src_ghostpad_checkgetrange)); +    gst_element_add_pad (GST_ELEMENT (src), src->srcpad); +    gst_object_unref (pad); +  } +} + +/*** GSTURIHANDLER INTERFACE *************************************************/ + +static GstURIType +gst_push_file_src_uri_get_type (void) +{ +  return GST_URI_SRC; +} +static gchar ** +gst_push_file_src_uri_get_protocols (void) +{ +  static gchar *protocols[] = { "pushfile", NULL }; + +  return protocols; +} +static const gchar * +gst_push_file_src_uri_get_uri (GstURIHandler * handler) +{ +  GstPushFileSrc *src = GST_PUSH_FILE_SRC (handler); + +  if (src->filesrc == NULL) +    return NULL; + +  return gst_uri_handler_get_uri (GST_URI_HANDLER (src->filesrc)); +} + +static gboolean +gst_push_file_src_uri_set_uri (GstURIHandler * handler, const gchar * uri) +{ +  GstPushFileSrc *src = GST_PUSH_FILE_SRC (handler); + +  if (src->filesrc == NULL || !g_str_has_prefix (uri, "pushfile://")) +    return FALSE; + +  /* skip 'push' bit */ +  return gst_uri_handler_set_uri (GST_URI_HANDLER (src->filesrc), uri + 4); +} + +static void +gst_push_file_src_uri_handler_init (gpointer g_iface, gpointer iface_data) +{ +  GstURIHandlerInterface *iface = (GstURIHandlerInterface *) g_iface; + +  iface->get_type = gst_push_file_src_uri_get_type; +  iface->get_protocols = gst_push_file_src_uri_get_protocols; +  iface->get_uri = gst_push_file_src_uri_get_uri; +  iface->set_uri = gst_push_file_src_uri_set_uri; +} + +gboolean +gst_push_file_src_plugin_init (GstPlugin * plugin) +{ +  return gst_element_register (plugin, "pushfilesrc", GST_RANK_NONE, +      GST_TYPE_PUSH_FILE_SRC); +} diff --git a/gst/debug/gstpushfilesrc.h b/gst/debug/gstpushfilesrc.h new file mode 100644 index 00000000..b3b6b887 --- /dev/null +++ b/gst/debug/gstpushfilesrc.h @@ -0,0 +1,58 @@ +/* GStreamer Push File Source + * Copyright (C) <2007> Tim-Philipp Müller <tim centricular net> + * + * 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. + */ + +#ifndef __GST_PUSH_FILE_SRC_H__ +#define __GST_PUSH_FILE_SRC_H__ + +#include <gst/gstbin.h> + +G_BEGIN_DECLS + +#define GST_TYPE_PUSH_FILE_SRC \ +  (gst_push_file_src_get_type()) +#define GST_PUSH_FILE_SRC(obj) \ +  (G_TYPE_CHECK_INSTANCE_CAST((obj),GST_TYPE_PUSH_FILE_SRC,GstPushFileSrc)) +#define GST_PUSH_FILE_SRC_CLASS(klass) \ +  (G_TYPE_CHECK_CLASS_CAST((klass),GST_TYPE_PUSH_FILE_SRC,GstPushFileSrcClass)) +#define GST_IS_PUSH_FILE_SRC(obj) \ +  (G_TYPE_CHECK_INSTANCE_TYPE((obj),GST_TYPE_PUSH_FILE_SRC)) +#define GST_IS_PUSH_FILE_SRC_CLASS(klass) \ +  (G_TYPE_CHECK_CLASS_TYPE((klass),GST_TYPE_PUSH_FILE_SRC)) + +typedef struct _GstPushFileSrc GstPushFileSrc; +typedef struct _GstPushFileSrcClass GstPushFileSrcClass; + +struct _GstPushFileSrc +{ +  GstBin parent; + +  /*< private >*/ +  GstElement *filesrc; +  GstPad     *srcpad; +}; + +struct _GstPushFileSrcClass +{ +  GstBinClass parent_class; +}; + +G_END_DECLS + +#endif /* __GST_PUSH_FILE_SRC_H__*/ +  | 
