[svn r606] added suport for multiple files trunk
authorrenatofilho
Thu Apr 26 22:33:00 2007 +0100 (2007-04-26)
branchtrunk
changeset 6007da2a5e32fa6
parent 599 5555b47e102b
child 601 a3252ef8e61b
[svn r606] added suport for multiple files
gmyth-stream/gmemcoder/Makefile.am
gmyth-stream/gmemcoder/configure.ac
gmyth-stream/gmemcoder/src/gmencoder.c
gmyth-stream/gmemcoder/src/gmencoder.h
gmyth-stream/gmemcoder/src/main.c
     1.1 --- a/gmyth-stream/gmemcoder/Makefile.am	Thu Apr 26 19:50:02 2007 +0100
     1.2 +++ b/gmyth-stream/gmemcoder/Makefile.am	Thu Apr 26 22:33:00 2007 +0100
     1.3 @@ -1,4 +1,4 @@
     1.4 -SUBDIRS = src
     1.5 +SUBDIRS = src tests
     1.6  
     1.7  EXTRA_DIST = 			\
     1.8  	ChangeLog
     2.1 --- a/gmyth-stream/gmemcoder/configure.ac	Thu Apr 26 19:50:02 2007 +0100
     2.2 +++ b/gmyth-stream/gmemcoder/configure.ac	Thu Apr 26 22:33:00 2007 +0100
     2.3 @@ -73,6 +73,7 @@
     2.4  AC_OUTPUT([
     2.5  Makefile
     2.6  src/Makefile
     2.7 +tests/Makefile
     2.8  ])
     2.9  
    2.10  if test "x$enable_debug" != "xno"; then
     3.1 --- a/gmyth-stream/gmemcoder/src/gmencoder.c	Thu Apr 26 19:50:02 2007 +0100
     3.2 +++ b/gmyth-stream/gmemcoder/src/gmencoder.c	Thu Apr 26 22:33:00 2007 +0100
     3.3 @@ -2,6 +2,9 @@
     3.4  #include "config.h"
     3.5  #endif
     3.6  
     3.7 +#include <sys/stat.h>
     3.8 +#include <fcntl.h>
     3.9 +#include <unistd.h>
    3.10  #include <glib.h>
    3.11  #include <gst/gst.h>
    3.12  #include <string.h>
    3.13 @@ -13,6 +16,22 @@
    3.14  
    3.15  
    3.16  typedef struct _GMencoderPrivate GMencoderPrivate;
    3.17 +typedef struct _SetupInfo SetupInfo;
    3.18 +
    3.19 +struct _SetupInfo
    3.20 +{
    3.21 +    gchar* video_encode;
    3.22 +    gchar* mux_name;
    3.23 +    gchar** video_encode_prop;
    3.24 +    gdouble video_fps;
    3.25 +    gdouble video_rate;
    3.26 +    guint video_width;
    3.27 +    guint video_height;                        
    3.28 +    gchar* audio_encode;
    3.29 +    gchar** audio_encode_prop;
    3.30 +    guint audio_rate;
    3.31 +};
    3.32 +
    3.33  
    3.34  struct _GMencoderPrivate
    3.35  {    
    3.36 @@ -21,10 +40,13 @@
    3.37  	GstElement *vbin;
    3.38  	GstElement *sink;
    3.39  	gboolean ready;
    3.40 +    SetupInfo *info;
    3.41 +    GstClockTime videot;
    3.42 +    GstClockTime audiot;
    3.43 +    gint fd;
    3.44  };
    3.45  
    3.46  enum {
    3.47 -  READY,
    3.48    PAUSED,
    3.49    PLAYING,
    3.50    STOPED,
    3.51 @@ -38,13 +60,11 @@
    3.52  static void g_mencoder_dispose  	    (GObject *object);
    3.53  static void g_mencoder_finalize 	    (GObject *object);
    3.54  static GstElement*
    3.55 -            _create_audio_bin           (GMencoder *self,
    3.56 -                                        const gchar* encode,
    3.57 -                                        gchar** encode_prop,
    3.58 -                                        gint rate);
    3.59 +            _create_audio_bin           (const gchar* encode,
    3.60 +                                         gchar** encode_prop,
    3.61 +                                         gint rate);
    3.62  static GstElement*
    3.63 -            _create_video_bin           (GMencoder* self, 
    3.64 -                                        const gchar* encode,
    3.65 +            _create_video_bin           (const gchar* encode,
    3.66                                          gchar** encode_prop,
    3.67                                          gdouble fps,
    3.68                                          gint rate,
    3.69 @@ -63,6 +83,24 @@
    3.70  		                         	     GstPad* pad,
    3.71                                           GstCaps* caps,
    3.72                                           gpointer user_data);
    3.73 +static void _close_output              (GMencoder *self);
    3.74 +static void _open_output               (GMencoder *self,
    3.75 +                                         const gchar* uri);
    3.76 +static GstElement* _create_source       (const gchar* uri);
    3.77 +static GstElement*_create_pipeline      (GMencoder *self,
    3.78 +                                          const gchar* video_encode,
    3.79 +                                          const gchar* mux_name,
    3.80 +                                          gchar** video_encode_prop,
    3.81 +                                          gdouble video_fps,
    3.82 +                                          gdouble video_rate,
    3.83 +                                          guint video_width, 
    3.84 +                                          guint video_height,                         
    3.85 +                                          const gchar* audio_encode,
    3.86 +                                          gchar** audio_encode_prop,
    3.87 +                                          guint audio_rate);
    3.88 +
    3.89 +
    3.90 +
    3.91  
    3.92  
    3.93  static guint g_mencoder_signals[LAST_SIGNAL] = { 0 };
    3.94 @@ -81,14 +119,6 @@
    3.95  	object_class->dispose  = g_mencoder_dispose;
    3.96  	object_class->finalize = g_mencoder_finalize;	
    3.97  	
    3.98 -    g_mencoder_signals[READY] =
    3.99 -        g_signal_new ("ready",
   3.100 -    		  G_OBJECT_CLASS_TYPE (object_class),
   3.101 -    		  G_SIGNAL_RUN_FIRST,
   3.102 -    		  0, NULL, NULL,
   3.103 -    		  g_cclosure_marshal_VOID__VOID,
   3.104 -    		  G_TYPE_NONE, 0);
   3.105 -
   3.106      g_mencoder_signals[PAUSED] =
   3.107          g_signal_new ("paused",
   3.108      		  G_OBJECT_CLASS_TYPE (object_class),
   3.109 @@ -134,6 +164,8 @@
   3.110  static void
   3.111  g_mencoder_init (GMencoder *self)
   3.112  {
   3.113 +	GMencoderPrivate *priv = G_MENCODER_GET_PRIVATE (self);
   3.114 +    priv->info = g_new0 (SetupInfo, 1);
   3.115  }
   3.116  
   3.117  static void 
   3.118 @@ -144,6 +176,7 @@
   3.119  static void 
   3.120  g_mencoder_finalize (GObject *object)
   3.121  {
   3.122 +    //TODO: clear vars
   3.123  	g_mencoder_close_stream (G_MENCODER (object));
   3.124  }
   3.125  
   3.126 @@ -153,6 +186,7 @@
   3.127      return g_object_new (G_TYPE_MENCODER, NULL);
   3.128  }
   3.129  
   3.130 +
   3.131  static void
   3.132  _obj_set_prop (GObject *obj, 
   3.133                  const gchar *prop_name,
   3.134 @@ -167,8 +201,6 @@
   3.135      g_value_init (&v, G_TYPE_STRING);
   3.136      g_value_set_string (&v, prop_val);
   3.137  
   3.138 -    g_debug ("PROP [%s] VAL [%s]", prop_name, prop_val);
   3.139 -
   3.140      s = g_object_class_find_property (k, prop_name);
   3.141      if (s == NULL) {
   3.142          g_print ("Invalid property name: %s\n", prop_name);
   3.143 @@ -201,8 +233,6 @@
   3.144      GstElement *ret;
   3.145      int i;
   3.146  
   3.147 -
   3.148 -    g_debug ("SET OBJ [%s]", factory_name);
   3.149      ret = gst_element_factory_make (factory_name, element_name);
   3.150      if (ret == NULL)
   3.151          return NULL;
   3.152 @@ -222,10 +252,9 @@
   3.153  }
   3.154  
   3.155  static GstElement*
   3.156 -_create_audio_bin (GMencoder* self,
   3.157 -                    const gchar* encode,
   3.158 -                    gchar** encode_prop,
   3.159 -                    gint rate)
   3.160 +_create_audio_bin (const gchar* encode,
   3.161 +                   gchar** encode_prop,
   3.162 +                   gint rate)
   3.163  {
   3.164      GstElement *abin = NULL;
   3.165      GstElement *aqueue = NULL;
   3.166 @@ -247,8 +276,17 @@
   3.167  		goto error;
   3.168  	}
   3.169  
   3.170 +    g_object_set (G_OBJECT (aencode), "bitrate", 32, NULL);
   3.171 +    /*
   3.172 +    if (rate > 0) {
   3.173 +        g_object_set (G_OBJECT (aencode), "bitrate", 32, NULL);
   3.174 +    }
   3.175 +    */
   3.176 +
   3.177  	gst_bin_add_many (GST_BIN (abin), aqueue, aconvert, aencode, aqueue_src, NULL);
   3.178 -	gst_element_link_many (aqueue, aconvert, aencode, aqueue_src, NULL);
   3.179 +	if (gst_element_link_many (aqueue, aconvert, aencode, aqueue_src, NULL) == FALSE) {
   3.180 +        g_warning ("Not Link audio elements");
   3.181 +    }
   3.182  
   3.183      //TODO: apply audio rate 
   3.184  
   3.185 @@ -289,8 +327,7 @@
   3.186  
   3.187  //queue ! videoscale ! video/x-raw-yuv,width=240,height=144 ! colorspace ! rate ! encode ! queue
   3.188  static GstElement*
   3.189 -_create_video_bin (GMencoder* self, 
   3.190 -                    const gchar* encode,
   3.191 +_create_video_bin (const gchar* encode,
   3.192                      gchar** encode_prop,
   3.193                      gdouble fps,
   3.194                      gint rate,
   3.195 @@ -320,6 +357,7 @@
   3.196  		
   3.197  	gst_bin_add_many (GST_BIN (vbin), vqueue, vcolorspace, vencode, vqueue_src, NULL);
   3.198  
   3.199 +
   3.200  	
   3.201      if ((width > 0) && (height > 0)) {        
   3.202          //Scalling video
   3.203 @@ -345,6 +383,7 @@
   3.204      } else {
   3.205          gst_element_link (vqueue, vcolorspace);
   3.206      }
   3.207 +    
   3.208  
   3.209      if (fps > 0) {
   3.210          //Changing the video fps
   3.211 @@ -371,7 +410,6 @@
   3.212              goto error;
   3.213          }
   3.214      }
   3.215 -
   3.216      
   3.217      gst_element_link (vencode, vqueue_src);
   3.218  
   3.219 @@ -409,66 +447,251 @@
   3.220  }
   3.221  
   3.222  
   3.223 -gboolean
   3.224 +
   3.225 +void
   3.226  g_mencoder_setup_stream (GMencoder *self, 
   3.227 -                         const gchar* uri, 
   3.228                           const gchar* video_encode,
   3.229 +                         const gchar* mux_name,
   3.230                           gchar** video_encode_prop,
   3.231                           gdouble video_fps,
   3.232                           gdouble video_rate,
   3.233                           guint video_width, 
   3.234 -                         guint video_height,
   3.235 +                         guint video_height,                         
   3.236                           const gchar* audio_encode,
   3.237                           gchar** audio_encode_prop,
   3.238                           guint audio_rate,
   3.239 -                         const gchar* sink_name,
   3.240 -                         gchar** sink_prop)
   3.241 +                         const gchar* out_uri)
   3.242 +{
   3.243 +    GMencoderPrivate *priv = G_MENCODER_GET_PRIVATE (self);
   3.244 +    if (priv->ready == TRUE) {
   3.245 +        g_warning ("Stream already configured. You need close stream first.");
   3.246 +        return;
   3.247 +    }
   3.248 +
   3.249 +    priv->pipe = _create_pipeline (self,
   3.250 +            video_encode,
   3.251 +            mux_name,
   3.252 +            video_encode_prop,
   3.253 +            video_fps,
   3.254 +            video_rate,
   3.255 +            video_width,
   3.256 +            video_height,
   3.257 +            audio_encode,
   3.258 +            audio_encode_prop,
   3.259 +            audio_rate);
   3.260 +
   3.261 +    _close_output (self);
   3.262 +    _open_output (self, out_uri);
   3.263 +}
   3.264 +
   3.265 +
   3.266 +gboolean
   3.267 +g_mencoder_append_uri (GMencoder *self,
   3.268 +                     const gchar* uri)
   3.269 +{
   3.270 +    GstElement *ap;
   3.271 +    GstElement *vp;
   3.272 +    GstPad *pad_src;
   3.273 +    GstPad *pad_sink;
   3.274 +    GstElement *src;
   3.275 +    GMencoderPrivate *priv = G_MENCODER_GET_PRIVATE (self);
   3.276 +    gboolean ret = FALSE;
   3.277 +
   3.278 +    g_return_val_if_fail (priv->pipe != NULL, FALSE);
   3.279 +    g_return_val_if_fail (priv->ready == FALSE, FALSE);
   3.280 +
   3.281 +    src = _create_source (uri);
   3.282 +    if (src == NULL) 
   3.283 +        return FALSE;
   3.284 +
   3.285 +    gst_bin_add (GST_BIN (priv->pipe), src);
   3.286 +
   3.287 +    ap = gst_bin_get_by_name (GST_BIN (priv->pipe), "ap");
   3.288 +    vp = gst_bin_get_by_name (GST_BIN (priv->pipe), "vp");
   3.289 +    if ((vp == NULL)  || (ap == NULL))
   3.290 +        goto error;
   3.291 +
   3.292 +    pad_src = gst_element_get_pad (src, "src_audio");
   3.293 +    pad_sink = gst_element_get_compatible_pad (ap, 
   3.294 +            pad_src, 
   3.295 +            gst_pad_get_caps (pad_src));
   3.296 +
   3.297 +    if ((pad_sink == NULL) || (pad_src == NULL))
   3.298 +        goto error;
   3.299 +
   3.300 +    GstPadLinkReturn lret = gst_pad_link (pad_src, pad_sink);
   3.301 +    if (lret != GST_PAD_LINK_OK)
   3.302 +        goto error;
   3.303 +
   3.304 +    gst_object_unref (pad_src);
   3.305 +    gst_object_unref (pad_sink);
   3.306 +
   3.307 +    pad_src = gst_element_get_pad (src, "src_video");
   3.308 +    pad_sink = gst_element_get_compatible_pad (vp, 
   3.309 +            pad_src, 
   3.310 +            gst_pad_get_caps (pad_src));
   3.311 +
   3.312 +    if ((pad_src == NULL) || (pad_sink == NULL))
   3.313 +        goto error;
   3.314 +
   3.315 +    if (gst_pad_link (pad_src, pad_sink) != GST_PAD_LINK_OK) {
   3.316 +        g_warning ("invalid source. video");
   3.317 +        goto error;
   3.318 +    }
   3.319 +
   3.320 +    ret = TRUE;
   3.321 +error:
   3.322 +
   3.323 +    if ((src != NULL) && (ret == FALSE)) {
   3.324 +        gst_bin_remove (GST_BIN (priv->pipe), src);
   3.325 +        gst_object_unref (src);
   3.326 +    }
   3.327 +
   3.328 +    if (ap != NULL) 
   3.329 +        gst_object_unref (ap);
   3.330 +
   3.331 +    if (vp != NULL)
   3.332 +        gst_object_unref (vp);
   3.333 +
   3.334 +    if (pad_src != NULL)
   3.335 +        gst_object_unref (pad_src);
   3.336 +
   3.337 +    if (pad_sink != NULL)
   3.338 +        gst_object_unref (pad_sink);
   3.339 +
   3.340 +    return ret;
   3.341 +}
   3.342 +
   3.343 +
   3.344 +
   3.345 +void        
   3.346 +g_mencoder_remove_uri (GMencoder *self,
   3.347 +                        const gchar* uri)
   3.348 +{
   3.349 +    // GMencoderPrivate *priv = G_MENCODER_GET_PRIVATE (self);
   3.350 +    //TODO: remove src
   3.351 +}
   3.352 +
   3.353 +void
   3.354 +g_mencoder_play_stream (GMencoder *self)
   3.355 +{
   3.356 +    GMencoderPrivate *priv = G_MENCODER_GET_PRIVATE (self);
   3.357 +
   3.358 +    g_return_if_fail (priv->ready == FALSE);
   3.359 +    priv->ready = TRUE;
   3.360 +    gst_element_set_state (priv->pipe, GST_STATE_PLAYING);
   3.361 +}
   3.362 +
   3.363 +void
   3.364 +g_mencoder_pause_stream (GMencoder *self)
   3.365 +{
   3.366 +    GMencoderPrivate *priv = G_MENCODER_GET_PRIVATE (self);
   3.367 +
   3.368 +    g_return_if_fail (priv->ready == TRUE);
   3.369 +    gst_element_set_state (priv->pipe, GST_STATE_PAUSED);
   3.370 +}
   3.371 +
   3.372 +void
   3.373 +g_mencoder_close_stream (GMencoder *self)
   3.374 +{
   3.375 +
   3.376 +    GMencoderPrivate *priv = G_MENCODER_GET_PRIVATE (self);
   3.377 +
   3.378 +    if (priv->pipe != NULL) { 
   3.379 +        gst_element_set_state (priv->pipe, GST_STATE_NULL);
   3.380 +        gst_object_unref (priv->pipe);
   3.381 +        priv->pipe = NULL;
   3.382 +        priv->abin = NULL;
   3.383 +        priv->vbin = NULL;
   3.384 +        priv->sink = NULL;
   3.385 +    }
   3.386 +    priv->ready = FALSE;
   3.387 +}
   3.388 +
   3.389 +static void
   3.390 +_sink_handoff_cb (GstElement* object,
   3.391 +                  GstBuffer* buf,
   3.392 +                  GstPad* pad,
   3.393 +                  gpointer user_data)
   3.394 +{
   3.395 +    GMencoderPrivate *priv = G_MENCODER_GET_PRIVATE (user_data);
   3.396 +    gint size = 0;
   3.397 +
   3.398 +    size = write (priv->fd, GST_BUFFER_DATA (buf),  GST_BUFFER_SIZE (buf));
   3.399 +    if (size == -1) {
   3.400 +        g_signal_emit (user_data, g_mencoder_signals[ERROR], 0, "Fail to write output");
   3.401 +    }
   3.402 +}
   3.403 +
   3.404 +
   3.405 +static GstElement*
   3.406 +_create_pipeline (GMencoder *self,
   3.407 +                  const gchar* video_encode,
   3.408 +                  const gchar* mux_name,
   3.409 +                  gchar** video_encode_prop,
   3.410 +                  gdouble video_fps,
   3.411 +                  gdouble video_rate,
   3.412 +                  guint video_width, 
   3.413 +                  guint video_height,                         
   3.414 +                  const gchar* audio_encode,
   3.415 +                  gchar** audio_encode_prop,
   3.416 +                  guint audio_rate)
   3.417  {
   3.418  	GstBus *bus = NULL;
   3.419  	GstElement *pipe = NULL;
   3.420 -	GstElement *fdsink = NULL;
   3.421 +	GstElement *sink = NULL;
   3.422      GstElement *mux = NULL;
   3.423 -    GstElement *decode = NULL;
   3.424 -	GstElement *src = NULL;
   3.425      GstElement *abin = NULL;
   3.426 -    GstElement *vbin = NULL;
   3.427 +    GstElement *vbin = NULL;    
   3.428 +    GstElement *ap = NULL;
   3.429 +    GstElement *vp = NULL;    
   3.430      GstPad *aux_pad = NULL;
   3.431      GstPad *mux_pad = NULL;
   3.432  
   3.433 -	GMencoderPrivate *priv = G_MENCODER_GET_PRIVATE (self);
   3.434 +	pipe = gst_pipeline_new ("pipe");
   3.435  
   3.436 -	pipe = gst_pipeline_new ("pipe");
   3.437 -	src = gst_element_make_from_uri (GST_URI_SRC, uri, "src");
   3.438 -	if (src == NULL) 
   3.439 -		goto error;
   3.440 +    ap = gst_element_factory_make ("multipartmux", "ap");
   3.441 +    vp = gst_element_factory_make ("multipartmux", "vp");
   3.442  
   3.443 -	decode = gst_element_factory_make ("decodebin2", "decode");
   3.444 -	if (decode == NULL) 
   3.445 -		goto error;
   3.446 -
   3.447 -    mux = gst_element_factory_make ("ffmux_mpeg", "mux");
   3.448 +    mux = gst_element_factory_make ((mux_name ? mux_name : "ffmux_mpeg"), "mux");
   3.449      if (mux == NULL)
   3.450          goto error;
   3.451  
   3.452 -    fdsink = _create_element_with_prop (sink_name, "sink", sink_prop);
   3.453 -    if (fdsink == NULL)
   3.454 +    sink = gst_element_factory_make ("fakesink", "sink");
   3.455 +    if (sink == NULL)
   3.456          goto error;
   3.457  
   3.458 -    abin = _create_audio_bin (self, audio_encode, audio_encode_prop, audio_rate);
   3.459 +    g_object_set (G_OBJECT(sink), 
   3.460 +            "sync", FALSE,
   3.461 +            "signal-handoffs", TRUE, NULL);
   3.462 +
   3.463 +    abin = _create_audio_bin (audio_encode, audio_encode_prop, audio_rate);
   3.464      if (abin == NULL)
   3.465          goto error;
   3.466  
   3.467 -    vbin = _create_video_bin (self, video_encode, video_encode_prop, video_fps, video_rate, video_width, video_height);
   3.468 +    vbin = _create_video_bin (video_encode, video_encode_prop, video_fps, video_rate, video_width, video_height);
   3.469      if (vbin == NULL)
   3.470          goto error;
   3.471  
   3.472  	// Finish Pipe
   3.473 -    gst_bin_add_many (GST_BIN (pipe), src, decode, abin, vbin, mux, fdsink, NULL);
   3.474 -	gst_element_link (src, decode);
   3.475 +    gst_bin_add_many (GST_BIN (pipe), ap, abin, vp, vbin, mux, sink, NULL);
   3.476 +
   3.477 +    if (gst_element_link (ap, abin) == FALSE) {
   3.478 +        g_warning ("Fail to link multipart and abin");
   3.479 +        goto error;
   3.480 +    }
   3.481 +
   3.482 +    if (gst_element_link (vp, vbin) == FALSE) {
   3.483 +        g_warning ("Fail to link multipart and vbin");
   3.484 +    }
   3.485  
   3.486      //Link bins with mux
   3.487      aux_pad = gst_element_get_pad (abin, "src");
   3.488      mux_pad = gst_element_get_pad (mux, "audio_0");
   3.489 +    if (mux_pad == NULL) {
   3.490 +        g_warning ("Mux element no have audio_0 PAD");
   3.491 +        goto error;
   3.492 +    }
   3.493      GstPadLinkReturn ret = gst_pad_link (aux_pad, mux_pad);
   3.494      if (ret != GST_PAD_LINK_OK) {
   3.495          g_warning ("Fail link audio and mux: %d", ret);
   3.496 @@ -480,6 +703,10 @@
   3.497  
   3.498      aux_pad = gst_element_get_pad (vbin, "src");
   3.499      mux_pad = gst_element_get_pad (mux, "video_0");
   3.500 +    if (mux_pad == NULL) {
   3.501 +        g_warning ("Mux element no have video_0 PAD");
   3.502 +        goto error;
   3.503 +    }
   3.504      ret = gst_pad_link (aux_pad, mux_pad);
   3.505      if (ret != GST_PAD_LINK_OK) {
   3.506          g_warning ("Fail link video and mux: %d", ret);
   3.507 @@ -491,32 +718,17 @@
   3.508      mux_pad = NULL;
   3.509  
   3.510      //Link mux with sink
   3.511 -    gst_element_link (mux, fdsink);
   3.512 +    gst_element_link (mux, sink);
   3.513  
   3.514 -	g_signal_connect (G_OBJECT (decode), 
   3.515 -				"new-decoded-pad",
   3.516 -				G_CALLBACK (_decodebin_new_pad_cb),
   3.517 +    g_signal_connect (G_OBJECT (sink),
   3.518 +				"handoff",
   3.519 +				G_CALLBACK (_sink_handoff_cb),
   3.520  				self);
   3.521 -	
   3.522 -	g_signal_connect (G_OBJECT (decode),
   3.523 -				"unknown-type",
   3.524 -				G_CALLBACK (_decodebin_unknown_type_cb),
   3.525 -				self);
   3.526 -
   3.527  
   3.528  	bus = gst_pipeline_get_bus (GST_PIPELINE (pipe));
   3.529  	gst_bus_add_watch (bus, _pipeline_bus_cb, self);
   3.530  	gst_object_unref (bus);
   3.531 -
   3.532 -
   3.533 -	priv->pipe = pipe;
   3.534 -	priv->abin = abin;
   3.535 -	priv->vbin = vbin;
   3.536 -	priv->sink = fdsink;
   3.537 -	priv->ready = FALSE;
   3.538 -	
   3.539 -	gst_element_set_state (pipe, GST_STATE_PAUSED);	   	
   3.540 -	return  TRUE;
   3.541 +    return pipe;
   3.542  	
   3.543  error:
   3.544  	g_warning ("Invalid uri");
   3.545 @@ -525,9 +737,6 @@
   3.546  		gst_object_unref (pipe);
   3.547      }
   3.548  
   3.549 -	if (src != NULL) {
   3.550 -		gst_object_unref (src);
   3.551 -    }
   3.552  
   3.553      if (mux != NULL) {
   3.554          gst_object_unref (mux);
   3.555 @@ -541,8 +750,8 @@
   3.556          gst_object_unref (mux_pad);
   3.557      }
   3.558  
   3.559 -	if (fdsink != NULL) {
   3.560 -		gst_object_unref (fdsink);
   3.561 +	if (sink != NULL) {
   3.562 +		gst_object_unref (sink);
   3.563      }
   3.564  
   3.565      if (abin != NULL) {
   3.566 @@ -556,49 +765,104 @@
   3.567  	return FALSE;
   3.568  }
   3.569  
   3.570 -gboolean 
   3.571 -g_mencoder_play_stream (GMencoder *self)
   3.572 +
   3.573 +static void
   3.574 +_close_output (GMencoder *self)
   3.575  {
   3.576 +    
   3.577 +}
   3.578 +
   3.579 +static GstElement*
   3.580 +_create_source (const gchar* uri)
   3.581 +{
   3.582 +
   3.583 +    GstElement *bsrc;
   3.584 +    GstElement *src;
   3.585 +    GstElement *aqueue;
   3.586 +    GstElement *vqueue;
   3.587 +    GstElement *decode;
   3.588 +    GstPad *src_pad;
   3.589 +
   3.590 +
   3.591 +    bsrc = gst_bin_new (NULL);
   3.592 +
   3.593 +	src = gst_element_factory_make ("gnomevfssrc", "src");
   3.594 +    g_object_set (G_OBJECT (src), "location", uri, NULL);
   3.595 +	if (src == NULL) 
   3.596 +		goto error;
   3.597 +
   3.598 +	decode = gst_element_factory_make ("decodebin2", "decode");
   3.599 +	if (decode == NULL) 
   3.600 +		goto error;
   3.601 +
   3.602 +    aqueue = gst_element_factory_make ("queue", "aqueue");
   3.603 +    if (aqueue == NULL)
   3.604 +        goto error;
   3.605 +
   3.606 +    vqueue = gst_element_factory_make ("queue", "vqueue");
   3.607 +    if (vqueue == NULL)
   3.608 +        goto error;
   3.609 +
   3.610 +    gst_bin_add_many (GST_BIN (bsrc), src, decode, aqueue, vqueue, NULL);
   3.611 +    gst_element_link (src, decode);
   3.612 +
   3.613 +	g_signal_connect (G_OBJECT (decode), 
   3.614 +				"new-decoded-pad",
   3.615 +				G_CALLBACK (_decodebin_new_pad_cb),
   3.616 +				bsrc);
   3.617 +
   3.618 +	g_signal_connect (G_OBJECT (decode),
   3.619 +				"unknown-type",
   3.620 +				G_CALLBACK (_decodebin_unknown_type_cb),
   3.621 +				pipe);
   3.622 +
   3.623 +    src_pad = gst_element_get_pad (aqueue, "src");
   3.624 +   	gst_element_add_pad (bsrc, gst_ghost_pad_new("src_audio", src_pad));
   3.625 +    gst_object_unref (src_pad);
   3.626 +
   3.627 +    src_pad = gst_element_get_pad (vqueue, "src");
   3.628 +   	gst_element_add_pad (bsrc, gst_ghost_pad_new("src_video", src_pad));
   3.629 +    gst_object_unref (src_pad);
   3.630 +
   3.631 +    return bsrc;
   3.632 +
   3.633 +error:
   3.634 +	if (src != NULL) {
   3.635 +		gst_object_unref (src);
   3.636 +    }
   3.637 +
   3.638 +	if (decode != NULL) {
   3.639 +		gst_object_unref (decode);
   3.640 +    }
   3.641 +
   3.642 +	if (aqueue != NULL) {
   3.643 +		gst_object_unref (aqueue);
   3.644 +    }
   3.645 +
   3.646 +	if (vqueue != NULL) {
   3.647 +		gst_object_unref (vqueue);
   3.648 +    }
   3.649 +
   3.650 +    return NULL;
   3.651 +}
   3.652 +
   3.653 +static void
   3.654 +_open_output (GMencoder *self, 
   3.655 +              const gchar* uri)
   3.656 +{
   3.657 +    gchar** i;
   3.658      GMencoderPrivate *priv = G_MENCODER_GET_PRIVATE (self);
   3.659  
   3.660 -    g_return_val_if_fail (priv->ready == TRUE, FALSE);
   3.661 -    
   3.662 -    if (gst_element_set_state (priv->pipe, GST_STATE_PLAYING) != GST_STATE_CHANGE_FAILURE) {
   3.663 -			g_debug ("PLAYING");
   3.664 -			return TRUE;
   3.665 -	}
   3.666 -	return FALSE;
   3.667 -}
   3.668 +    i = g_strsplit (uri, "://", 0);
   3.669 +    if (strcmp (i[0], "fd") == 0) {
   3.670 +        priv->fd = atoi (i[1]);
   3.671 +    } else if (strcmp (i[0], "file") == 0) {
   3.672 +        priv->fd = open (i[1], O_WRONLY | O_CREAT | O_TRUNC);
   3.673 +    } else {
   3.674 +        g_warning ("Output uri not supported");
   3.675 +    }
   3.676  
   3.677 -gboolean
   3.678 -g_mencoder_pause_stream (GMencoder *self)
   3.679 -{
   3.680 -    GMencoderPrivate *priv = G_MENCODER_GET_PRIVATE (self);
   3.681 -
   3.682 -    g_return_val_if_fail (priv->ready == TRUE, FALSE);
   3.683 -    
   3.684 -    if (gst_element_set_state (priv->pipe, GST_STATE_PAUSED) != GST_STATE_CHANGE_FAILURE) {
   3.685 -			g_debug ("PAUSED");
   3.686 -			return TRUE;
   3.687 -	}
   3.688 -	return FALSE;
   3.689 -}
   3.690 -
   3.691 -void
   3.692 -g_mencoder_close_stream (GMencoder *self)
   3.693 -{
   3.694 -
   3.695 -    GMencoderPrivate *priv = G_MENCODER_GET_PRIVATE (self);
   3.696 -
   3.697 -    g_return_if_fail (priv->ready == TRUE);
   3.698 -    
   3.699 -    gst_element_set_state (priv->pipe, GST_STATE_NULL);
   3.700 -    gst_object_unref (priv->pipe);
   3.701 -    priv->pipe = NULL;
   3.702 -    priv->abin = NULL;
   3.703 -    priv->vbin = NULL;
   3.704 -    priv->sink = NULL;
   3.705 -    priv->ready = FALSE;
   3.706 +    g_strfreev (i);
   3.707  }
   3.708  
   3.709  static gboolean
   3.710 @@ -606,6 +870,8 @@
   3.711  		  GstMessage *msg,
   3.712  		  gpointer    user_data)
   3.713  {
   3.714 +	GMencoderPrivate *priv = G_MENCODER_GET_PRIVATE (user_data);
   3.715 +
   3.716  	switch (GST_MESSAGE_TYPE (msg)) 
   3.717  	{
   3.718  		case GST_MESSAGE_STATE_CHANGED:
   3.719 @@ -614,7 +880,6 @@
   3.720  			GstState newstate;
   3.721  			GstState pendingstate;
   3.722  
   3.723 -			GMencoderPrivate *priv = G_MENCODER_GET_PRIVATE (user_data);
   3.724  
   3.725  			gst_message_parse_state_changed (msg, &oldstate,
   3.726  				&newstate, &pendingstate);
   3.727 @@ -626,10 +891,6 @@
   3.728                  (newstate == GST_STATE_PAUSED)) {
   3.729                      if (priv->ready) 
   3.730                          g_signal_emit (user_data, g_mencoder_signals[PAUSED], 0);
   3.731 -                    else {
   3.732 -                        priv->ready = TRUE;
   3.733 -                        g_signal_emit (user_data, g_mencoder_signals[READY], 0);
   3.734 -                    }
   3.735              } else if ((oldstate == GST_STATE_PAUSED) &&
   3.736                         (newstate == GST_STATE_PLAYING)) {
   3.737                          g_signal_emit (user_data, g_mencoder_signals[PLAYING], 0);
   3.738 @@ -650,6 +911,7 @@
   3.739  		        error->message,
   3.740  		        debug);
   3.741  		    g_signal_emit (user_data, g_mencoder_signals[ERROR], 0, err_str);
   3.742 +            priv->ready = FALSE;
   3.743  		    g_free (err_str);
   3.744  		    g_clear_error (&error);
   3.745  		    g_free (debug);
   3.746 @@ -657,6 +919,7 @@
   3.747  		}
   3.748  		
   3.749  		case GST_MESSAGE_EOS:
   3.750 +            priv->ready = FALSE;
   3.751  		    g_signal_emit (user_data, g_mencoder_signals[EOS], 0);
   3.752  		    break;		
   3.753  		default:
   3.754 @@ -665,6 +928,8 @@
   3.755  	return TRUE;
   3.756  }
   3.757  
   3.758 +
   3.759 +
   3.760  static void 
   3.761  _decodebin_new_pad_cb (GstElement* object,
   3.762                         GstPad* pad,
   3.763 @@ -673,24 +938,24 @@
   3.764  {
   3.765  	GstCaps *caps;
   3.766  	gchar *str_caps = NULL;
   3.767 -    GMencoderPrivate *priv = G_MENCODER_GET_PRIVATE (user_data);
   3.768 +    GstElement *sink_element;
   3.769 +    GstPad *sink_pad;
   3.770  
   3.771  	caps = gst_pad_get_caps (pad);
   3.772  	str_caps = gst_caps_to_string (caps);
   3.773 -    g_debug ("CAPS : %s", str_caps);
   3.774 -
   3.775  	if (strstr (str_caps, "audio") != NULL) {
   3.776 -		GstPad *apad = gst_element_get_pad (priv->abin, "sink");
   3.777 -		gst_pad_link (pad, apad);
   3.778 -		gst_object_unref (apad);
   3.779 +        sink_element = gst_bin_get_by_name (GST_BIN (user_data), "aqueue");
   3.780  	} else if (strstr (str_caps, "video") != NULL) {
   3.781 -		GstPad *vpad = gst_element_get_pad (priv->vbin, "sink");
   3.782 -		gst_pad_link (pad, vpad);
   3.783 -		gst_object_unref (vpad);
   3.784 +        sink_element = gst_bin_get_by_name (GST_BIN (user_data), "vqueue");
   3.785  	} else {
   3.786  		g_warning ("invalid caps %s", str_caps);
   3.787  	}
   3.788  
   3.789 +    sink_pad = gst_element_get_pad (sink_element, "sink");
   3.790 +	gst_pad_link (pad, sink_pad);
   3.791 +
   3.792 +    gst_object_unref (sink_element);
   3.793 +	gst_object_unref (sink_pad);
   3.794  	g_free (str_caps);
   3.795  	gst_caps_unref (caps);
   3.796  }
   3.797 @@ -702,4 +967,5 @@
   3.798                              gpointer user_data)
   3.799  {
   3.800      g_warning  ("Unknown Type");
   3.801 +    //priv->ready = FALSE;
   3.802  }
     4.1 --- a/gmyth-stream/gmemcoder/src/gmencoder.h	Thu Apr 26 19:50:02 2007 +0100
     4.2 +++ b/gmyth-stream/gmemcoder/src/gmencoder.h	Thu Apr 26 22:33:00 2007 +0100
     4.3 @@ -33,9 +33,9 @@
     4.4  
     4.5  GType 		g_mencoder_get_type 	 	(void);
     4.6  GMencoder*  g_mencoder_new              (void);
     4.7 -gboolean    g_mencoder_setup_stream     (GMencoder *self, 
     4.8 -                                         const gchar* uri, 
     4.9 +void        g_mencoder_setup_stream     (GMencoder *self, 
    4.10                                           const gchar* video_encode,
    4.11 +                                         const gchar* mux_name,
    4.12                                           gchar** video_encode_prop,
    4.13                                           gdouble video_fps,
    4.14                                           gdouble video_rate,
    4.15 @@ -44,10 +44,13 @@
    4.16                                           const gchar* audio_encode,
    4.17                                           gchar** audio_encode_prop,
    4.18                                           guint audio_rate,
    4.19 -                                         const gchar* output_element,
    4.20 -                                         gchar** output_prop);
    4.21 -gboolean 	g_mencoder_play_stream      (GMencoder *self);
    4.22 -gboolean	g_mencoder_pause_stream 	(GMencoder *self);
    4.23 +                                         const gchar* output_uri);
    4.24 +gboolean    g_mencoder_append_uri       (GMencoder *self,
    4.25 +                                         const gchar* uri);
    4.26 +void        g_mencoder_remove_uri       (GMencoder *self,
    4.27 +                                         const gchar* uri);
    4.28 +void     	g_mencoder_play_stream      (GMencoder *self);
    4.29 +void    	g_mencoder_pause_stream 	(GMencoder *self);
    4.30  void        g_mencoder_close_stream 	(GMencoder *self);
    4.31  
    4.32  G_END_DECLS
     5.1 --- a/gmyth-stream/gmemcoder/src/main.c	Thu Apr 26 19:50:02 2007 +0100
     5.2 +++ b/gmyth-stream/gmemcoder/src/main.c	Thu Apr 26 22:33:00 2007 +0100
     5.3 @@ -22,14 +22,9 @@
     5.4  static gchar*   audio_encode    = NULL;
     5.5  static gchar*   audio_opts      = NULL;
     5.6  static double   audio_rate      = 0.0;
     5.7 -static gchar*   output_element  = NULL;
     5.8 -static gchar*   output_opts     = NULL;
     5.9 +static gchar*   mux_name        = NULL;
    5.10 +static gchar*   output_uri      = NULL;
    5.11  
    5.12 -static void
    5.13 -_mencoder_ready_cb (GMencoder *mencoder, gpointer data)
    5.14 -{
    5.15 -    g_mencoder_play_stream (mencoder);
    5.16 -}
    5.17  
    5.18  static void
    5.19  _mencoder_eos_cb (GMencoder *mencoder, gpointer data)
    5.20 @@ -70,15 +65,16 @@
    5.21  int 
    5.22  main (int argc, char** argv)
    5.23  {
    5.24 -    GMencoder *coder;
    5.25 +    GMencoder *coder = NULL;
    5.26      GIOChannel *ch;
    5.27 -    gchar **oopts;
    5.28      gchar **vopts;
    5.29      gchar **aopts;
    5.30 +    gchar **files;
    5.31 +    gint i;
    5.32  
    5.33      GOptionContext *context;
    5.34      static const GOptionEntry options []  = {
    5.35 -        {"input-file",    'i', 0, G_OPTION_ARG_STRING,          &input_file,    "Input File", NULL},
    5.36 +        {"input-files",    'i', 0, G_OPTION_ARG_STRING,          &input_file,    "Input File", NULL},
    5.37          {"video-encode",    0, 0, G_OPTION_ARG_STRING,          &video_encode,  "GstElementName for used to video encode", NULL},
    5.38          {"video-opts",      0, 0, G_OPTION_ARG_STRING,          &video_opts,    "Properties to set on video element", NULL},
    5.39          {"video-fps",       0, 0, G_OPTION_ARG_DOUBLE,          &video_fps,     "Video FPS", NULL},
    5.40 @@ -88,15 +84,16 @@
    5.41          {"audio-encode",    0, 0, G_OPTION_ARG_STRING,          &audio_encode,  "GstElementName for use to audio encode", NULL},
    5.42          {"audio-opts",      0, 0, G_OPTION_ARG_STRING,          &audio_opts,    "Properties to set on audio element", NULL},
    5.43          {"audio-rate",      0, 0, G_OPTION_ARG_INT,             &audio_rate,    "Audio rate", NULL},
    5.44 -        {"output-element",  0, 0, G_OPTION_ARG_STRING,          &output_element,"GstElementName for use to output", NULL},
    5.45 -        {"output-opts",     0, 0, G_OPTION_ARG_STRING,          &output_opts,   "Properties to set on output element", NULL},
    5.46 +        {"mux-element",     0, 0, G_OPTION_ARG_STRING,          &mux_name,      "GstElementName for use to mux file", NULL},
    5.47 +        {"output-uri",    'o', 0, G_OPTION_ARG_STRING,          &output_uri,    "Uri to output", NULL},
    5.48          { NULL }
    5.49      };
    5.50  
    5.51  	g_type_init ();
    5.52      g_thread_init (NULL);
    5.53 +	mainloop = g_main_loop_new (NULL, FALSE);
    5.54  
    5.55 -	//g_set_prgname ("gmemcoder");
    5.56 +	g_set_prgname ("gmemcoder");
    5.57      context = g_option_context_new (NULL);
    5.58      g_option_context_set_help_enabled (context, TRUE);
    5.59      g_option_context_add_main_entries (context, options, NULL);
    5.60 @@ -105,8 +102,8 @@
    5.61  
    5.62  	gst_init (&argc, &argv);
    5.63  
    5.64 -    if (output_element == NULL) {
    5.65 -        g_print ("You need specify output-element name.\nTry --help for more information.\n");
    5.66 +    if (output_uri == NULL) {
    5.67 +        g_print ("You need specify output-uri.\nTry --help for more information.\n");
    5.68          return 1; 
    5.69      }
    5.70  
    5.71 @@ -119,27 +116,27 @@
    5.72  
    5.73      aopts = g_strsplit (audio_opts, ",", 0);
    5.74      vopts = g_strsplit (video_opts, ",", 0);
    5.75 -    oopts = g_strsplit (output_opts, ",", 0);
    5.76  
    5.77      g_mencoder_setup_stream (coder, 
    5.78 -            input_file, 
    5.79 +            mux_name,
    5.80              video_encode, vopts, video_fps, video_rate, video_width, video_height,
    5.81              audio_encode, aopts, audio_rate, 
    5.82 -            output_element, oopts);
    5.83 +            output_uri);
    5.84  
    5.85 +    files = g_strsplit (input_file, ",", 0);
    5.86 +    for (i=0; i < g_strv_length (files); i++) {
    5.87 +        if (!g_mencoder_append_uri (coder, files[i])) {
    5.88 +            g_debug ("Invalid uri: %s", files[i]);
    5.89 +        } 
    5.90 +    }
    5.91 +                
    5.92 +    g_strfreev (files);
    5.93      g_strfreev (aopts);
    5.94      g_strfreev (vopts);
    5.95 -    g_strfreev (oopts);
    5.96  
    5.97 -	mainloop = g_main_loop_new (NULL, FALSE);
    5.98 +
    5.99      g_io_add_watch (ch, G_IO_IN, _io_channel_cb, coder);    
   5.100  
   5.101 -
   5.102 -    g_signal_connect (G_OBJECT (coder),
   5.103 -                        "ready",
   5.104 -                        G_CALLBACK (_mencoder_ready_cb),
   5.105 -                        NULL);
   5.106 -
   5.107      g_signal_connect (G_OBJECT (coder),
   5.108                          "eos",
   5.109                          G_CALLBACK (_mencoder_eos_cb),
   5.110 @@ -150,7 +147,14 @@
   5.111                          G_CALLBACK (_mencoder_error_cb),
   5.112                          mainloop);
   5.113  
   5.114 +    g_mencoder_play_stream (coder);
   5.115 +
   5.116 +    g_debug ("RUNNING..");
   5.117  	g_main_loop_run (mainloop);
   5.118  
   5.119 +    g_mencoder_close_stream (coder);
   5.120 +    g_object_unref (coder);
   5.121 +
   5.122 +
   5.123  	return 0;
   5.124  }