[svn r615] added concat element trunk
authorrenatofilho
Tue May 01 16:31:26 2007 +0100 (2007-05-01)
branchtrunk
changeset 6094aac30345986
parent 608 43ce4ea2f9fb
child 610 3cdc32e43041
[svn r615] added concat element
gst-gmyth/Makefile.am
gst-gmyth/concatmux/Makefile.am
gst-gmyth/concatmux/gstconcatmux.c
gst-gmyth/configure.ac
     1.1 --- a/gst-gmyth/Makefile.am	Tue May 01 16:04:02 2007 +0100
     1.2 +++ b/gst-gmyth/Makefile.am	Tue May 01 16:31:26 2007 +0100
     1.3 @@ -1,3 +1,9 @@
     1.4 -SUBDIRS = mythtvsrc nuvdemux
     1.5 +SUBDIRS = \
     1.6 +	mythtvsrc \
     1.7 +	nuvdemux \
     1.8 +	concatmux
     1.9  
    1.10 -DIST_SUBDIRS = mythtvsrc nuvdemux
    1.11 +DIST_SUBDIRS = \
    1.12 +	mythtvsrc \
    1.13 +	nuvdemux \
    1.14 +	concatmux
     2.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     2.2 +++ b/gst-gmyth/concatmux/Makefile.am	Tue May 01 16:31:26 2007 +0100
     2.3 @@ -0,0 +1,22 @@
     2.4 +plugin_LTLIBRARIES = libgstconcatmux.la
     2.5 +
     2.6 +libgstconcatmux_la_SOURCES =	\
     2.7 +	gstconcatmux.c 
     2.8 +
     2.9 +libgstconcatmux_la_CFLAGS = \
    2.10 +	$(GST_CFLAGS) \
    2.11 +	$(GST_BASE_CFLAGS) \
    2.12 +	$(GST_PLUGINS_BASE_CFLAGS)
    2.13 +
    2.14 +libgstconcatmux_la_LIBADD = \
    2.15 +	$(GST_LIBS_LIBS)
    2.16 +
    2.17 +libgstconcatmux_la_LDFLAGS = \
    2.18 +	$(GST_LIBS) \
    2.19 +	$(GST_PLUGIN_LDFLAGS) \
    2.20 +	$(GST_BASE_LIBS) \
    2.21 +	$(GST_PLUGINS_BASE_LIBS)
    2.22 +
    2.23 +noinst_HEADERS = \
    2.24 +	gstconcatmux.h 
    2.25 +
     3.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     3.2 +++ b/gst-gmyth/concatmux/gstconcatmux.c	Tue May 01 16:31:26 2007 +0100
     3.3 @@ -0,0 +1,539 @@
     3.4 +/* concat muxer plugin for GStreamer
     3.5 + * Copyright (C) 2004 Renato Filhps <renato.filho@indt.org.br>
     3.6 + *
     3.7 + * This library is free software; you can redistribute it and/or
     3.8 + * modify it under the terms of the GNU Library General Public
     3.9 + * License as published by the Free Software Foundation; either
    3.10 + * version 2 of the License, or (at your option) any later version.
    3.11 + *
    3.12 + * This library is distributed in the hope that it will be useful,
    3.13 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
    3.14 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
    3.15 + * Library General Public License for more details.
    3.16 + *
    3.17 + * You should have received a copy of the GNU Library General Public
    3.18 + * License along with this library; if not, write to the
    3.19 + * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
    3.20 + * Boston, MA 02111-1307, USA.
    3.21 + */
    3.22 +
    3.23 +/**
    3.24 + * SECTION:element-concatmux
    3.25 + * @short_description: Concat that takes one or several digital streams
    3.26 + * and muxes them to a single stream.
    3.27 + *
    3.28 + * <refsect2>
    3.29 + * <title>Sample pipelines</title>
    3.30 + * <para>
    3.31 + * Here is a simple pipeline to concat 2 files into a another file:
    3.32 + * <programlisting>
    3.33 + * gst-launch concatmux name=m ! filesink location=output.txt  filesrc location=file_a.txt !  m. filesrc location=file_b.txt ! m.
    3.34 + * </programlisting>
    3.35 + * </para>
    3.36 + * </refsect2>
    3.37 + */
    3.38 +
    3.39 +#ifdef HAVE_CONFIG_H
    3.40 +#include "config.h"
    3.41 +#endif
    3.42 +
    3.43 +#include <gst/gst.h>
    3.44 +#include <gst/base/gstcollectpads.h>
    3.45 +
    3.46 +#include <string.h>
    3.47 +
    3.48 +GST_DEBUG_CATEGORY_STATIC (gst_concat_mux_debug);
    3.49 +#define GST_CAT_DEFAULT gst_concat_mux_debug
    3.50 +
    3.51 +#define GST_TYPE_CONCAT_MUX (gst_concat_mux_get_type())
    3.52 +#define GST_CONCAT_MUX(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj),GST_TYPE_CONCAT_MUX, GstConcatMux))
    3.53 +#define GST_CONCAT_MUX_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass),GST_TYPE_CONCAT_MUX, GstConcatMux))
    3.54 +#define GST_IS_CONCAT_MUX(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj),GST_TYPE_CONCAT_MUX))
    3.55 +#define GST_IS_CONCAT_MUX_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass),GST_TYPE_CONCAT_MUX))
    3.56 +
    3.57 +typedef struct _GstConcatMux GstConcatMux;
    3.58 +typedef struct _GstConcatMuxClass GstConcatMuxClass;
    3.59 +
    3.60 +/**
    3.61 + * GstConcatMux:
    3.62 + *
    3.63 + * The opaque #GstConcatMux structure.
    3.64 + */
    3.65 +struct _GstConcatMux
    3.66 +{
    3.67 +  GstElement element;
    3.68 +
    3.69 +  /* Caps */
    3.70 +  GstCaps *sink_caps;
    3.71 +
    3.72 +  /* pad */
    3.73 +  GstPad *srcpad;
    3.74 +  GstPad *sinkpad;
    3.75 +
    3.76 +  /* sinkpads */
    3.77 +  GSList *sinks;
    3.78 +  gint numpads;
    3.79 +
    3.80 +  /* offset in stream */
    3.81 +  guint64 offset;
    3.82 +  guint64 timeoffset;
    3.83 +  guint64 start_time;
    3.84 +
    3.85 +  gboolean negotiated;
    3.86 +  gboolean resync;
    3.87 +  gboolean done;
    3.88 +};
    3.89 +
    3.90 +struct _GstConcatMuxClass
    3.91 +{
    3.92 +  GstElementClass parent_class;
    3.93 +};
    3.94 +
    3.95 +/* elementfactory information */
    3.96 +static const GstElementDetails gst_concat_mux_details =
    3.97 +GST_ELEMENT_DETAILS ("Concat muxer",
    3.98 +    "Codec/Muxer",
    3.99 +    "mux concat streams",
   3.100 +    "Renato Filho <renato.filho@indt.org>");
   3.101 +
   3.102 +static GstStaticPadTemplate src_factory = GST_STATIC_PAD_TEMPLATE ("src",
   3.103 +    GST_PAD_SRC,
   3.104 +    GST_PAD_ALWAYS,
   3.105 +    GST_STATIC_CAPS_ANY
   3.106 +    );
   3.107 +
   3.108 +static GstStaticPadTemplate sink_factory = GST_STATIC_PAD_TEMPLATE ("sink_%d",
   3.109 +    GST_PAD_SINK,
   3.110 +    GST_PAD_REQUEST,
   3.111 +    GST_STATIC_CAPS_ANY         
   3.112 +    );
   3.113 +
   3.114 +static void gst_concat_mux_base_init (gpointer g_class);
   3.115 +static void gst_concat_mux_class_init (GstConcatMuxClass * klass);
   3.116 +static void gst_concat_mux_init (GstConcatMux * concat_mux);
   3.117 +
   3.118 +static void gst_concat_mux_finalize (GObject * object);
   3.119 +
   3.120 +static gboolean gst_concat_mux_handle_src_event (GstPad * pad,
   3.121 +    GstEvent * event);
   3.122 +static gboolean gst_concat_mux_handle_sink_event (GstPad * pad,
   3.123 +    GstEvent * event);
   3.124 +
   3.125 +static GstPad *gst_concat_mux_request_new_pad (GstElement * element,
   3.126 +    GstPadTemplate * templ, const gchar * name);
   3.127 +static GstStateChangeReturn gst_concat_mux_change_state (GstElement *
   3.128 +    element, GstStateChange transition);
   3.129 +
   3.130 +static GstFlowReturn gst_concat_mux_chain (GstPad * pad,  GstBuffer * buf);
   3.131 +static void gst_concat_mux_clear (GstConcatMux *mux);
   3.132 +
   3.133 +
   3.134 +static GstElementClass *parent_class = NULL;
   3.135 +
   3.136 +GType
   3.137 +gst_concat_mux_get_type (void)
   3.138 +{
   3.139 +  static GType concat_mux_type = 0;
   3.140 +
   3.141 +  if (!concat_mux_type) {
   3.142 +    static const GTypeInfo concat_mux_info = {
   3.143 +      sizeof (GstConcatMuxClass),
   3.144 +      gst_concat_mux_base_init,
   3.145 +      NULL,
   3.146 +      (GClassInitFunc) gst_concat_mux_class_init,
   3.147 +      NULL,
   3.148 +      NULL,
   3.149 +      sizeof (GstConcatMux),
   3.150 +      0,
   3.151 +      (GInstanceInitFunc) gst_concat_mux_init,
   3.152 +    };
   3.153 +
   3.154 +    concat_mux_type =
   3.155 +        g_type_register_static (GST_TYPE_ELEMENT, "GstConcatMux",
   3.156 +        &concat_mux_info, 0);
   3.157 +  }
   3.158 +  return concat_mux_type;
   3.159 +}
   3.160 +
   3.161 +static void
   3.162 +gst_concat_mux_base_init (gpointer g_class)
   3.163 +{
   3.164 +  GstElementClass *element_class = GST_ELEMENT_CLASS (g_class);
   3.165 +
   3.166 +  gst_element_class_add_pad_template (element_class,
   3.167 +      gst_static_pad_template_get (&src_factory));
   3.168 +  gst_element_class_add_pad_template (element_class,
   3.169 +      gst_static_pad_template_get (&sink_factory));
   3.170 +
   3.171 +  gst_element_class_set_details (element_class, &gst_concat_mux_details);
   3.172 +}
   3.173 +
   3.174 +static void
   3.175 +gst_concat_mux_class_init (GstConcatMuxClass * klass)
   3.176 +{
   3.177 +  GObjectClass *gobject_class;
   3.178 +  GstElementClass *gstelement_class;
   3.179 +
   3.180 +  gobject_class = (GObjectClass *) klass;
   3.181 +  gstelement_class = (GstElementClass *) klass;
   3.182 +
   3.183 +  parent_class = g_type_class_peek_parent (klass);
   3.184 +
   3.185 +  gobject_class->finalize = gst_concat_mux_finalize;
   3.186 +
   3.187 +  gstelement_class->request_new_pad = gst_concat_mux_request_new_pad;
   3.188 +  gstelement_class->change_state = gst_concat_mux_change_state;
   3.189 +}
   3.190 +
   3.191 +static void
   3.192 +gst_concat_mux_init (GstConcatMux * concat_mux)
   3.193 +{
   3.194 +  GstElementClass *klass = GST_ELEMENT_GET_CLASS (concat_mux);
   3.195 +
   3.196 +  concat_mux->srcpad =
   3.197 +      gst_pad_new_from_template (gst_element_class_get_pad_template (klass,
   3.198 +          "src"), "src");
   3.199 +  gst_pad_set_event_function (concat_mux->srcpad,
   3.200 +      gst_concat_mux_handle_src_event);
   3.201 +  gst_element_add_pad (GST_ELEMENT (concat_mux), concat_mux->srcpad);
   3.202 +}
   3.203 +
   3.204 +static void
   3.205 +gst_concat_mux_finalize (GObject * object)
   3.206 +{
   3.207 +  GstConcatMux *concat_mux;
   3.208 +
   3.209 +  concat_mux = GST_CONCAT_MUX (object);
   3.210 +  gst_concat_mux_clear (GST_CONCAT_MUX (object));
   3.211 +
   3.212 +  G_OBJECT_CLASS (parent_class)->finalize (object);
   3.213 +}
   3.214 +
   3.215 +static void
   3.216 +gst_concat_mux_free_pad (gpointer data,
   3.217 +                            gpointer user_data)
   3.218 +{
   3.219 +   GMutex *mux;
   3.220 +
   3.221 +   mux = gst_pad_get_element_private (GST_PAD (data));
   3.222 +   g_mutex_unlock (mux);
   3.223 +   g_mutex_free (mux);
   3.224 +   gst_object_unref (GST_OBJECT (data)); 
   3.225 +}
   3.226 +
   3.227 +static void
   3.228 +gst_concat_mux_clear (GstConcatMux *mux)
   3.229 +{
   3.230 +  mux->resync = TRUE;
   3.231 +  mux->timeoffset = 0;
   3.232 +  mux->offset = 0;
   3.233 +  mux->negotiated = FALSE;
   3.234 +  mux->done = TRUE;
   3.235 +  if (mux->sinks != NULL) {
   3.236 +    g_slist_foreach (mux->sinks, gst_concat_mux_free_pad, mux);
   3.237 +    g_slist_free (mux->sinks);
   3.238 +    mux->sinks = NULL;
   3.239 +  }
   3.240 +}
   3.241 +
   3.242 +
   3.243 +static GstPadLinkReturn
   3.244 +gst_concat_mux_sinkconnect (GstPad * pad, GstPad * peer)
   3.245 +{
   3.246 +  gchar *pad_name = NULL;
   3.247 +  GstConcatMux *concat_mux;
   3.248 +
   3.249 +  concat_mux = GST_CONCAT_MUX (gst_pad_get_parent (pad));
   3.250 +
   3.251 +  if (concat_mux->sink_caps != NULL) {
   3.252 +      GstCaps *peer_caps = gst_pad_get_caps (peer);
   3.253 +      GstCaps *intersect;
   3.254 +
   3.255 +      intersect =  gst_caps_intersect (concat_mux->sink_caps, peer_caps);
   3.256 +      if (intersect == NULL) {
   3.257 +          gst_caps_unref (peer_caps);
   3.258 +          return GST_PAD_LINK_NOFORMAT;
   3.259 +      }
   3.260 +      gst_caps_unref (peer_caps);
   3.261 +      gst_caps_unref (intersect);
   3.262 +  } else {
   3.263 +      concat_mux->sink_caps = gst_pad_get_caps (pad);
   3.264 +  }
   3.265 +
   3.266 +  pad_name = gst_pad_get_name (pad);
   3.267 +
   3.268 +  GST_DEBUG_OBJECT (concat_mux, "sinkconnect triggered on %s", pad_name);
   3.269 +
   3.270 +  g_free (pad_name);
   3.271 +
   3.272 +  gst_object_unref (concat_mux);
   3.273 +
   3.274 +  return GST_PAD_LINK_OK;
   3.275 +}
   3.276 +
   3.277 +static GstPad *
   3.278 +gst_concat_mux_request_new_pad (GstElement * element,
   3.279 +    GstPadTemplate * templ, const gchar * req_name)
   3.280 +{
   3.281 +  GstConcatMux *concat_mux;
   3.282 +  GstPad *newpad;
   3.283 +  GstElementClass *klass = GST_ELEMENT_GET_CLASS (element);
   3.284 +  GMutex *mutex;
   3.285 +
   3.286 +  g_return_val_if_fail (templ != NULL, NULL);
   3.287 +
   3.288 +  if (templ->direction != GST_PAD_SINK) {
   3.289 +    g_warning ("concat_mux: request pad that is not a SINK pad\n");
   3.290 +    return NULL;
   3.291 +  }
   3.292 +
   3.293 +  g_return_val_if_fail (GST_IS_CONCAT_MUX (element), NULL);
   3.294 +
   3.295 +  concat_mux = GST_CONCAT_MUX (element);
   3.296 +
   3.297 +  if (templ == gst_element_class_get_pad_template (klass, "sink_%d")) {
   3.298 +    gchar *name;
   3.299 +
   3.300 +    /* create new pad with the name */
   3.301 +    name = g_strdup_printf ("sink_%02d", concat_mux->numpads);
   3.302 +    g_debug ("NEw pad %s", name);
   3.303 +    newpad = gst_pad_new_from_template (templ, name);
   3.304 +    g_free (name);
   3.305 +    concat_mux->sinks = g_slist_append (concat_mux->sinks, newpad);
   3.306 +    g_debug ("New sink %p / %d", newpad, g_slist_length (concat_mux->sinks));
   3.307 +    concat_mux->numpads++;
   3.308 +  } else {
   3.309 +    g_warning ("concat_mux: this is not our template!\n");
   3.310 +    return NULL;
   3.311 +  }
   3.312 +
   3.313 +  mutex = g_mutex_new ();
   3.314 +
   3.315 +  if (concat_mux->sinkpad == NULL) {
   3.316 +      concat_mux->sinkpad = newpad;
   3.317 +  }
   3.318 +  else {
   3.319 +      g_mutex_lock (mutex);
   3.320 +  }
   3.321 +
   3.322 +  gst_pad_set_element_private (newpad, mutex);
   3.323 +  /* setup some pad functions */
   3.324 +  gst_pad_set_link_function (newpad, gst_concat_mux_sinkconnect);
   3.325 +  gst_pad_set_event_function (newpad, gst_concat_mux_handle_sink_event);
   3.326 +  gst_pad_set_chain_function (newpad, gst_concat_mux_chain);
   3.327 +
   3.328 +  /* add the pad to the element */
   3.329 +  gst_element_add_pad (element, newpad);
   3.330 +
   3.331 +  return newpad;
   3.332 +}
   3.333 +
   3.334 +/* handle events */
   3.335 +static gboolean
   3.336 +gst_concat_mux_handle_src_event (GstPad * pad, GstEvent * event)
   3.337 +{
   3.338 +  GstConcatMux *concat_mux;
   3.339 +  GstEventType type;
   3.340 +
   3.341 +  concat_mux = GST_CONCAT_MUX (gst_pad_get_parent (pad));
   3.342 +
   3.343 +  type = event ? GST_EVENT_TYPE (event) : GST_EVENT_UNKNOWN;
   3.344 +
   3.345 +  switch (type) {
   3.346 +    case GST_EVENT_SEEK:
   3.347 +      /* disable seeking for now */
   3.348 +      return FALSE;
   3.349 +    default:
   3.350 +      break;
   3.351 +  }
   3.352 +
   3.353 +  gst_object_unref (concat_mux);
   3.354 +
   3.355 +  return gst_pad_event_default (pad, event);
   3.356 +}
   3.357 +
   3.358 +/* handle events */
   3.359 +static gboolean
   3.360 +gst_concat_mux_handle_sink_event (GstPad * pad, GstEvent * event)
   3.361 +{
   3.362 +  GstConcatMux *mux;
   3.363 +  GstEventType type;
   3.364 +
   3.365 +  mux = GST_CONCAT_MUX (gst_pad_get_parent (pad));
   3.366 +
   3.367 +  type = event ? GST_EVENT_TYPE (event) : GST_EVENT_UNKNOWN;
   3.368 +
   3.369 +  switch (type) {
   3.370 +    case GST_EVENT_EOS:
   3.371 +    {
   3.372 +        mux->resync = TRUE;
   3.373 +        g_debug ("sink EOS %p / %d", pad, g_slist_length (mux->sinks));
   3.374 +        /* mark pad eos */
   3.375 +        mux->sinks  = g_slist_remove (mux->sinks, pad);
   3.376 +        g_debug ("sink len %d", g_slist_length (mux->sinks));
   3.377 +        if (g_slist_length (mux->sinks) != 0) {
   3.378 +           GMutex *mutex;
   3.379 +           mux->sinkpad = mux->sinks->data;
   3.380 +           mutex = (GMutex *) gst_pad_get_element_private (mux->sinkpad);
   3.381 +           g_mutex_unlock (mutex);
   3.382 +           g_debug ("sink pad %p", mux->sinkpad);
   3.383 +           return TRUE;
   3.384 +        }
   3.385 +
   3.386 +        g_debug ("sink list is empty");
   3.387 +    }
   3.388 +    default:
   3.389 +      break;
   3.390 +  }
   3.391 +
   3.392 +  gst_object_unref (mux);
   3.393 +
   3.394 +  return gst_pad_event_default (pad, event);
   3.395 +}
   3.396 +
   3.397 +static GstFlowReturn
   3.398 +gst_concat_mux_chain (GstPad * pad,  GstBuffer * buf)
   3.399 +{
   3.400 +  GstConcatMux *mux = (GstConcatMux *) GST_PAD_PARENT (pad);
   3.401 +  GstBuffer *databuf = NULL;
   3.402 +  GstFlowReturn ret = GST_FLOW_OK;
   3.403 +  GMutex *mutex;
   3.404 +
   3.405 +
   3.406 +  mutex = (GMutex*) gst_pad_get_element_private (pad);
   3.407 +
   3.408 +  g_mutex_lock (mutex);
   3.409 +  if (mux->done) {
   3.410 +      g_debug ("DONE pad %p", pad);
   3.411 +      return GST_FLOW_OK;
   3.412 +  }
   3.413 +
   3.414 +  databuf = gst_buffer_make_metadata_writable (buf);
   3.415 +
   3.416 +  if (!mux->negotiated) {
   3.417 +      /*
   3.418 +    GstCaps *newcaps;
   3.419 +    newcaps = gst_pad_get_caps (mux->sinkpad);
   3.420 +
   3.421 +    g_debug ("CAPS: %s",gst_caps_to_string (newcaps));
   3.422 +
   3.423 +    if (!gst_pad_set_caps (mux->srcpad, newcaps))
   3.424 +      goto nego_error;
   3.425 +    */
   3.426 +    mux->negotiated = TRUE;            
   3.427 +  } 
   3.428 +
   3.429 +  g_debug ("Running [%s]\n"
   3.430 +        "\tTOFFSET    [%"G_GUINT64_FORMAT"]\n"
   3.431 +        "\tB_TSTAMP   [%"G_GUINT64_FORMAT"]\n"
   3.432 +        "\tB_DURATION [%"G_GUINT64_FORMAT"]\n"
   3.433 +        "\tOFFSET     [%"G_GUINT64_FORMAT"]\n"
   3.434 +        "\tB_OFFSET   [%"G_GUINT64_FORMAT"]",
   3.435 +        gst_element_get_name (mux),
   3.436 +        mux->timeoffset, 
   3.437 +        GST_BUFFER_TIMESTAMP (databuf),
   3.438 +        GST_BUFFER_DURATION (databuf),
   3.439 +        mux->offset,
   3.440 +        GST_BUFFER_OFFSET (databuf));
   3.441 +
   3.442 +
   3.443 +  if (mux->resync) {
   3.444 +    g_debug ("RESYNC [%s]", gst_element_get_name (mux));
   3.445 +    mux->timeoffset += GST_BUFFER_TIMESTAMP (databuf);
   3.446 +    GST_BUFFER_TIMESTAMP (databuf) = mux->timeoffset;
   3.447 +    mux->timeoffset += GST_BUFFER_DURATION (databuf);
   3.448 +
   3.449 +    mux->offset += GST_BUFFER_OFFSET (databuf);
   3.450 +    GST_BUFFER_OFFSET (databuf) = mux->offset;
   3.451 +    mux->offset += GST_BUFFER_SIZE (databuf);
   3.452 +    mux->resync = FALSE;
   3.453 +  } else {
   3.454 +
   3.455 +    GST_BUFFER_TIMESTAMP (databuf) = mux->timeoffset;
   3.456 +    mux->timeoffset += GST_BUFFER_DURATION (databuf);
   3.457 +
   3.458 +    GST_BUFFER_OFFSET (databuf) = mux->offset;
   3.459 +    mux->offset += GST_BUFFER_SIZE (databuf);
   3.460 +  }
   3.461 +
   3.462 +  gst_buffer_set_caps (databuf, GST_PAD_CAPS (pad));
   3.463 +  ret = gst_pad_push (mux->srcpad, databuf);
   3.464 +
   3.465 +  //gst_buffer_unref (buf);
   3.466 +
   3.467 +  g_mutex_unlock (mutex);
   3.468 +  return ret;
   3.469 +/*
   3.470 +nego_error:
   3.471 +  {
   3.472 +    GST_WARNING_OBJECT (mux, "failed to set caps");
   3.473 +    GST_ELEMENT_ERROR (mux, CORE, NEGOTIATION, (NULL), (NULL));
   3.474 +    return GST_FLOW_NOT_NEGOTIATED;
   3.475 +  }
   3.476 +  */
   3.477 +  /*
   3.478 +no_caps:
   3.479 +  {
   3.480 +    GST_WARNING_OBJECT (mux, "no caps on the incoming buffer %p", best->buffer);
   3.481 +    GST_ELEMENT_ERROR (mux, CORE, NEGOTIATION, (NULL), (NULL));
   3.482 +    ret = GST_FLOW_NOT_NEGOTIATED;
   3.483 +    goto beach;
   3.484 +  }
   3.485 +  */
   3.486 +}
   3.487 +
   3.488 +static GstStateChangeReturn
   3.489 +gst_concat_mux_change_state (GstElement * element, GstStateChange transition)
   3.490 +{
   3.491 +  GstConcatMux *concat_mux;
   3.492 +  GstStateChangeReturn ret;
   3.493 +
   3.494 +  concat_mux = GST_CONCAT_MUX (element);
   3.495 +
   3.496 +  switch (transition) {
   3.497 +    case GST_STATE_CHANGE_READY_TO_PAUSED:
   3.498 +      concat_mux->done = FALSE;
   3.499 +      concat_mux->resync = TRUE;
   3.500 +      GST_DEBUG_OBJECT (concat_mux, "starting collect pads");
   3.501 +      break;
   3.502 +    case GST_STATE_CHANGE_PAUSED_TO_READY:
   3.503 +      GST_DEBUG_OBJECT (concat_mux, "stopping collect pads");
   3.504 +      gst_concat_mux_clear (concat_mux);
   3.505 +      break;
   3.506 +    default:
   3.507 +      break;
   3.508 +  }
   3.509 +
   3.510 +  ret = GST_ELEMENT_CLASS (parent_class)->change_state (element, transition);
   3.511 +  if (ret == GST_STATE_CHANGE_FAILURE)
   3.512 +    return ret;
   3.513 +
   3.514 +  switch (transition) {
   3.515 +    default:
   3.516 +      break;
   3.517 +  }
   3.518 +
   3.519 +  return ret;
   3.520 +}
   3.521 +
   3.522 +gboolean
   3.523 +gst_concat_mux_plugin_init (GstPlugin * plugin)
   3.524 +{
   3.525 +#ifdef ENABLE_NLS
   3.526 +  setlocale (LC_ALL, "");
   3.527 +  bindtextdomain (GETTEXT_PACKAGE, LOCALEDIR);
   3.528 +#endif /* ENABLE_NLS */
   3.529 +
   3.530 +  GST_DEBUG_CATEGORY_INIT (gst_concat_mux_debug, "concatmux", 0,
   3.531 +      "concat muxer");
   3.532 +      
   3.533 +  return gst_element_register (plugin, "concatmux", GST_RANK_NONE,
   3.534 +      GST_TYPE_CONCAT_MUX);
   3.535 +}
   3.536 +
   3.537 +GST_PLUGIN_DEFINE (GST_VERSION_MAJOR,
   3.538 +    GST_VERSION_MINOR,
   3.539 +    "concat muxer",
   3.540 +    "Concat streamers",
   3.541 +     plugin_init, VERSION, "LGPL", "ConcatMux", "")
   3.542 +
     4.1 --- a/gst-gmyth/configure.ac	Tue May 01 16:04:02 2007 +0100
     4.2 +++ b/gst-gmyth/configure.ac	Tue May 01 16:31:26 2007 +0100
     4.3 @@ -166,7 +166,9 @@
     4.4  
     4.5  AC_CONFIG_FILES([
     4.6  Makefile
     4.7 -src/Makefile
     4.8 +mythtvsrc/Makefile
     4.9 +nuvdemux/Makefile
    4.10 +concatmux/Makefile
    4.11  ])
    4.12  
    4.13  AC_OUTPUT