gmyth-stream/gmemcoder/src/gmencoder.c
branchtrunk
changeset 611 aa1f309ec686
parent 588 3219eb5401c0
child 614 24c3dd0bc57e
     1.1 --- a/gmyth-stream/gmemcoder/src/gmencoder.c	Mon Apr 23 21:05:21 2007 +0100
     1.2 +++ b/gmyth-stream/gmemcoder/src/gmencoder.c	Tue May 01 17:03:38 2007 +0100
     1.3 @@ -2,6 +2,9 @@
     1.4  #include "config.h"
     1.5  #endif
     1.6  
     1.7 +#include <sys/stat.h>
     1.8 +#include <fcntl.h>
     1.9 +#include <unistd.h>
    1.10  #include <glib.h>
    1.11  #include <gst/gst.h>
    1.12  #include <string.h>
    1.13 @@ -13,6 +16,22 @@
    1.14  
    1.15  
    1.16  typedef struct _GMencoderPrivate GMencoderPrivate;
    1.17 +typedef struct _SetupInfo SetupInfo;
    1.18 +
    1.19 +struct _SetupInfo
    1.20 +{
    1.21 +    gchar* video_encode;
    1.22 +    gchar* mux_name;
    1.23 +    gchar** video_encode_prop;
    1.24 +    gdouble video_fps;
    1.25 +    gdouble video_rate;
    1.26 +    guint video_width;
    1.27 +    guint video_height;                        
    1.28 +    gchar* audio_encode;
    1.29 +    gchar** audio_encode_prop;
    1.30 +    guint audio_rate;
    1.31 +};
    1.32 +
    1.33  
    1.34  struct _GMencoderPrivate
    1.35  {    
    1.36 @@ -21,10 +40,13 @@
    1.37  	GstElement *vbin;
    1.38  	GstElement *sink;
    1.39  	gboolean ready;
    1.40 +    SetupInfo *info;
    1.41 +    GstClockTime videot;
    1.42 +    GstClockTime audiot;
    1.43 +    gint fd;
    1.44  };
    1.45  
    1.46  enum {
    1.47 -  READY,
    1.48    PAUSED,
    1.49    PLAYING,
    1.50    STOPED,
    1.51 @@ -38,13 +60,11 @@
    1.52  static void g_mencoder_dispose  	    (GObject *object);
    1.53  static void g_mencoder_finalize 	    (GObject *object);
    1.54  static GstElement*
    1.55 -            _create_audio_bin           (GMencoder *self,
    1.56 -                                        const gchar* encode,
    1.57 -                                        gchar** encode_prop,
    1.58 -                                        gint rate);
    1.59 +            _create_audio_bin           (const gchar* encode,
    1.60 +                                         gchar** encode_prop,
    1.61 +                                         gint rate);
    1.62  static GstElement*
    1.63 -            _create_video_bin           (GMencoder* self, 
    1.64 -                                        const gchar* encode,
    1.65 +            _create_video_bin           (const gchar* encode,
    1.66                                          gchar** encode_prop,
    1.67                                          gdouble fps,
    1.68                                          gint rate,
    1.69 @@ -63,6 +83,24 @@
    1.70  		                         	     GstPad* pad,
    1.71                                           GstCaps* caps,
    1.72                                           gpointer user_data);
    1.73 +static void _close_output              (GMencoder *self);
    1.74 +static void _open_output               (GMencoder *self,
    1.75 +                                         const gchar* uri);
    1.76 +static GstElement* _create_source       (const gchar* uri);
    1.77 +static GstElement*_create_pipeline      (GMencoder *self,
    1.78 +                                          const gchar* video_encode,
    1.79 +                                          const gchar* mux_name,
    1.80 +                                          gchar** video_encode_prop,
    1.81 +                                          gdouble video_fps,
    1.82 +                                          gdouble video_rate,
    1.83 +                                          guint video_width, 
    1.84 +                                          guint video_height,                         
    1.85 +                                          const gchar* audio_encode,
    1.86 +                                          gchar** audio_encode_prop,
    1.87 +                                          guint audio_rate);
    1.88 +
    1.89 +
    1.90 +
    1.91  
    1.92  
    1.93  static guint g_mencoder_signals[LAST_SIGNAL] = { 0 };
    1.94 @@ -81,14 +119,6 @@
    1.95  	object_class->dispose  = g_mencoder_dispose;
    1.96  	object_class->finalize = g_mencoder_finalize;	
    1.97  	
    1.98 -    g_mencoder_signals[READY] =
    1.99 -        g_signal_new ("ready",
   1.100 -    		  G_OBJECT_CLASS_TYPE (object_class),
   1.101 -    		  G_SIGNAL_RUN_FIRST,
   1.102 -    		  0, NULL, NULL,
   1.103 -    		  g_cclosure_marshal_VOID__VOID,
   1.104 -    		  G_TYPE_NONE, 0);
   1.105 -
   1.106      g_mencoder_signals[PAUSED] =
   1.107          g_signal_new ("paused",
   1.108      		  G_OBJECT_CLASS_TYPE (object_class),
   1.109 @@ -134,6 +164,8 @@
   1.110  static void
   1.111  g_mencoder_init (GMencoder *self)
   1.112  {
   1.113 +	GMencoderPrivate *priv = G_MENCODER_GET_PRIVATE (self);
   1.114 +    priv->info = g_new0 (SetupInfo, 1);
   1.115  }
   1.116  
   1.117  static void 
   1.118 @@ -144,6 +176,7 @@
   1.119  static void 
   1.120  g_mencoder_finalize (GObject *object)
   1.121  {
   1.122 +    //TODO: clear vars
   1.123  	g_mencoder_close_stream (G_MENCODER (object));
   1.124  }
   1.125  
   1.126 @@ -153,6 +186,7 @@
   1.127      return g_object_new (G_TYPE_MENCODER, NULL);
   1.128  }
   1.129  
   1.130 +
   1.131  static void
   1.132  _obj_set_prop (GObject *obj, 
   1.133                  const gchar *prop_name,
   1.134 @@ -167,8 +201,6 @@
   1.135      g_value_init (&v, G_TYPE_STRING);
   1.136      g_value_set_string (&v, prop_val);
   1.137  
   1.138 -    g_debug ("PROP [%s] VAL [%s]", prop_name, prop_val);
   1.139 -
   1.140      s = g_object_class_find_property (k, prop_name);
   1.141      if (s == NULL) {
   1.142          g_print ("Invalid property name: %s\n", prop_name);
   1.143 @@ -201,8 +233,6 @@
   1.144      GstElement *ret;
   1.145      int i;
   1.146  
   1.147 -
   1.148 -    g_debug ("SET OBJ [%s]", factory_name);
   1.149      ret = gst_element_factory_make (factory_name, element_name);
   1.150      if (ret == NULL)
   1.151          return NULL;
   1.152 @@ -222,10 +252,9 @@
   1.153  }
   1.154  
   1.155  static GstElement*
   1.156 -_create_audio_bin (GMencoder* self,
   1.157 -                    const gchar* encode,
   1.158 -                    gchar** encode_prop,
   1.159 -                    gint rate)
   1.160 +_create_audio_bin (const gchar* encode,
   1.161 +                   gchar** encode_prop,
   1.162 +                   gint rate)
   1.163  {
   1.164      GstElement *abin = NULL;
   1.165      GstElement *aqueue = NULL;
   1.166 @@ -247,8 +276,17 @@
   1.167  		goto error;
   1.168  	}
   1.169  
   1.170 +    g_object_set (G_OBJECT (aencode), "bitrate", 32, NULL);
   1.171 +    /*
   1.172 +    if (rate > 0) {
   1.173 +        g_object_set (G_OBJECT (aencode), "bitrate", 32, NULL);
   1.174 +    }
   1.175 +    */
   1.176 +
   1.177  	gst_bin_add_many (GST_BIN (abin), aqueue, aconvert, aencode, aqueue_src, NULL);
   1.178 -	gst_element_link_many (aqueue, aconvert, aencode, aqueue_src, NULL);
   1.179 +	if (gst_element_link_many (aqueue, aconvert, aencode, aqueue_src, NULL) == FALSE) {
   1.180 +        g_warning ("Not Link audio elements");
   1.181 +    }
   1.182  
   1.183      //TODO: apply audio rate 
   1.184  
   1.185 @@ -289,8 +327,7 @@
   1.186  
   1.187  //queue ! videoscale ! video/x-raw-yuv,width=240,height=144 ! colorspace ! rate ! encode ! queue
   1.188  static GstElement*
   1.189 -_create_video_bin (GMencoder* self, 
   1.190 -                    const gchar* encode,
   1.191 +_create_video_bin (const gchar* encode,
   1.192                      gchar** encode_prop,
   1.193                      gdouble fps,
   1.194                      gint rate,
   1.195 @@ -320,6 +357,7 @@
   1.196  		
   1.197  	gst_bin_add_many (GST_BIN (vbin), vqueue, vcolorspace, vencode, vqueue_src, NULL);
   1.198  
   1.199 +
   1.200  	
   1.201      if ((width > 0) && (height > 0)) {        
   1.202          //Scalling video
   1.203 @@ -345,6 +383,7 @@
   1.204      } else {
   1.205          gst_element_link (vqueue, vcolorspace);
   1.206      }
   1.207 +    
   1.208  
   1.209      if (fps > 0) {
   1.210          //Changing the video fps
   1.211 @@ -371,7 +410,6 @@
   1.212              goto error;
   1.213          }
   1.214      }
   1.215 -
   1.216      
   1.217      gst_element_link (vencode, vqueue_src);
   1.218  
   1.219 @@ -409,66 +447,251 @@
   1.220  }
   1.221  
   1.222  
   1.223 -gboolean
   1.224 +
   1.225 +void
   1.226  g_mencoder_setup_stream (GMencoder *self, 
   1.227 -                         const gchar* uri, 
   1.228                           const gchar* video_encode,
   1.229 +                         const gchar* mux_name,
   1.230                           gchar** video_encode_prop,
   1.231                           gdouble video_fps,
   1.232                           gdouble video_rate,
   1.233                           guint video_width, 
   1.234 -                         guint video_height,
   1.235 +                         guint video_height,                         
   1.236                           const gchar* audio_encode,
   1.237                           gchar** audio_encode_prop,
   1.238                           guint audio_rate,
   1.239 -                         const gchar* sink_name,
   1.240 -                         gchar** sink_prop)
   1.241 +                         const gchar* out_uri)
   1.242 +{
   1.243 +    GMencoderPrivate *priv = G_MENCODER_GET_PRIVATE (self);
   1.244 +    if (priv->ready == TRUE) {
   1.245 +        g_warning ("Stream already configured. You need close stream first.");
   1.246 +        return;
   1.247 +    }
   1.248 +
   1.249 +    priv->pipe = _create_pipeline (self,
   1.250 +            video_encode,
   1.251 +            mux_name,
   1.252 +            video_encode_prop,
   1.253 +            video_fps,
   1.254 +            video_rate,
   1.255 +            video_width,
   1.256 +            video_height,
   1.257 +            audio_encode,
   1.258 +            audio_encode_prop,
   1.259 +            audio_rate);
   1.260 +
   1.261 +    _close_output (self);
   1.262 +    _open_output (self, out_uri);
   1.263 +}
   1.264 +
   1.265 +
   1.266 +gboolean
   1.267 +g_mencoder_append_uri (GMencoder *self,
   1.268 +                     const gchar* uri)
   1.269 +{
   1.270 +    GstElement *ap;
   1.271 +    GstElement *vp;
   1.272 +    GstPad *pad_src;
   1.273 +    GstPad *pad_sink;
   1.274 +    GstElement *src;
   1.275 +    GMencoderPrivate *priv = G_MENCODER_GET_PRIVATE (self);
   1.276 +    gboolean ret = FALSE;
   1.277 +
   1.278 +    g_return_val_if_fail (priv->pipe != NULL, FALSE);
   1.279 +    g_return_val_if_fail (priv->ready == FALSE, FALSE);
   1.280 +
   1.281 +    src = _create_source (uri);
   1.282 +    if (src == NULL) 
   1.283 +        return FALSE;
   1.284 +
   1.285 +    gst_bin_add (GST_BIN (priv->pipe), src);
   1.286 +
   1.287 +    ap = gst_bin_get_by_name (GST_BIN (priv->pipe), "ap");
   1.288 +    vp = gst_bin_get_by_name (GST_BIN (priv->pipe), "vp");
   1.289 +    if ((vp == NULL)  || (ap == NULL))
   1.290 +        goto error;
   1.291 +
   1.292 +    pad_src = gst_element_get_pad (src, "src_audio");
   1.293 +    pad_sink = gst_element_get_compatible_pad (ap, 
   1.294 +            pad_src, 
   1.295 +            gst_pad_get_caps (pad_src));
   1.296 +
   1.297 +    if ((pad_sink == NULL) || (pad_src == NULL))
   1.298 +        goto error;
   1.299 +
   1.300 +    GstPadLinkReturn lret = gst_pad_link (pad_src, pad_sink);
   1.301 +    if (lret != GST_PAD_LINK_OK)
   1.302 +        goto error;
   1.303 +
   1.304 +    gst_object_unref (pad_src);
   1.305 +    gst_object_unref (pad_sink);
   1.306 +
   1.307 +    pad_src = gst_element_get_pad (src, "src_video");
   1.308 +    pad_sink = gst_element_get_compatible_pad (vp, 
   1.309 +            pad_src, 
   1.310 +            gst_pad_get_caps (pad_src));
   1.311 +
   1.312 +    if ((pad_src == NULL) || (pad_sink == NULL))
   1.313 +        goto error;
   1.314 +
   1.315 +    if (gst_pad_link (pad_src, pad_sink) != GST_PAD_LINK_OK) {
   1.316 +        g_warning ("invalid source. video");
   1.317 +        goto error;
   1.318 +    }
   1.319 +
   1.320 +    ret = TRUE;
   1.321 +error:
   1.322 +
   1.323 +    if ((src != NULL) && (ret == FALSE)) {
   1.324 +        gst_bin_remove (GST_BIN (priv->pipe), src);
   1.325 +        gst_object_unref (src);
   1.326 +    }
   1.327 +
   1.328 +    if (ap != NULL) 
   1.329 +        gst_object_unref (ap);
   1.330 +
   1.331 +    if (vp != NULL)
   1.332 +        gst_object_unref (vp);
   1.333 +
   1.334 +    if (pad_src != NULL)
   1.335 +        gst_object_unref (pad_src);
   1.336 +
   1.337 +    if (pad_sink != NULL)
   1.338 +        gst_object_unref (pad_sink);
   1.339 +
   1.340 +    return ret;
   1.341 +}
   1.342 +
   1.343 +
   1.344 +
   1.345 +void        
   1.346 +g_mencoder_remove_uri (GMencoder *self,
   1.347 +                        const gchar* uri)
   1.348 +{
   1.349 +    // GMencoderPrivate *priv = G_MENCODER_GET_PRIVATE (self);
   1.350 +    //TODO: remove src
   1.351 +}
   1.352 +
   1.353 +void
   1.354 +g_mencoder_play_stream (GMencoder *self)
   1.355 +{
   1.356 +    GMencoderPrivate *priv = G_MENCODER_GET_PRIVATE (self);
   1.357 +
   1.358 +    g_return_if_fail (priv->ready == FALSE);
   1.359 +    priv->ready = TRUE;
   1.360 +    gst_element_set_state (priv->pipe, GST_STATE_PLAYING);
   1.361 +}
   1.362 +
   1.363 +void
   1.364 +g_mencoder_pause_stream (GMencoder *self)
   1.365 +{
   1.366 +    GMencoderPrivate *priv = G_MENCODER_GET_PRIVATE (self);
   1.367 +
   1.368 +    g_return_if_fail (priv->ready == TRUE);
   1.369 +    gst_element_set_state (priv->pipe, GST_STATE_PAUSED);
   1.370 +}
   1.371 +
   1.372 +void
   1.373 +g_mencoder_close_stream (GMencoder *self)
   1.374 +{
   1.375 +
   1.376 +    GMencoderPrivate *priv = G_MENCODER_GET_PRIVATE (self);
   1.377 +
   1.378 +    if (priv->pipe != NULL) { 
   1.379 +        gst_element_set_state (priv->pipe, GST_STATE_NULL);
   1.380 +        gst_object_unref (priv->pipe);
   1.381 +        priv->pipe = NULL;
   1.382 +        priv->abin = NULL;
   1.383 +        priv->vbin = NULL;
   1.384 +        priv->sink = NULL;
   1.385 +    }
   1.386 +    priv->ready = FALSE;
   1.387 +}
   1.388 +
   1.389 +static void
   1.390 +_sink_handoff_cb (GstElement* object,
   1.391 +                  GstBuffer* buf,
   1.392 +                  GstPad* pad,
   1.393 +                  gpointer user_data)
   1.394 +{
   1.395 +    GMencoderPrivate *priv = G_MENCODER_GET_PRIVATE (user_data);
   1.396 +    gint size = 0;
   1.397 +
   1.398 +    size = write (priv->fd, GST_BUFFER_DATA (buf),  GST_BUFFER_SIZE (buf));
   1.399 +    if (size == -1) {
   1.400 +        g_signal_emit (user_data, g_mencoder_signals[ERROR], 0, "Fail to write output");
   1.401 +    }
   1.402 +}
   1.403 +
   1.404 +
   1.405 +static GstElement*
   1.406 +_create_pipeline (GMencoder *self,
   1.407 +                  const gchar* video_encode,
   1.408 +                  const gchar* mux_name,
   1.409 +                  gchar** video_encode_prop,
   1.410 +                  gdouble video_fps,
   1.411 +                  gdouble video_rate,
   1.412 +                  guint video_width, 
   1.413 +                  guint video_height,                         
   1.414 +                  const gchar* audio_encode,
   1.415 +                  gchar** audio_encode_prop,
   1.416 +                  guint audio_rate)
   1.417  {
   1.418  	GstBus *bus = NULL;
   1.419  	GstElement *pipe = NULL;
   1.420 -	GstElement *fdsink = NULL;
   1.421 +	GstElement *sink = NULL;
   1.422      GstElement *mux = NULL;
   1.423 -    GstElement *decode = NULL;
   1.424 -	GstElement *src = NULL;
   1.425      GstElement *abin = NULL;
   1.426 -    GstElement *vbin = NULL;
   1.427 +    GstElement *vbin = NULL;    
   1.428 +    GstElement *ap = NULL;
   1.429 +    GstElement *vp = NULL;    
   1.430      GstPad *aux_pad = NULL;
   1.431      GstPad *mux_pad = NULL;
   1.432  
   1.433 -	GMencoderPrivate *priv = G_MENCODER_GET_PRIVATE (self);
   1.434 +	pipe = gst_pipeline_new ("pipe");
   1.435  
   1.436 -	pipe = gst_pipeline_new ("pipe");
   1.437 -	src = gst_element_make_from_uri (GST_URI_SRC, uri, "src");
   1.438 -	if (src == NULL) 
   1.439 -		goto error;
   1.440 +    ap = gst_element_factory_make ("multipartmux", "ap");
   1.441 +    vp = gst_element_factory_make ("multipartmux", "vp");
   1.442  
   1.443 -	decode = gst_element_factory_make ("decodebin2", "decode");
   1.444 -	if (decode == NULL) 
   1.445 -		goto error;
   1.446 -
   1.447 -    mux = gst_element_factory_make ("ffmux_mpeg", "mux");
   1.448 +    mux = gst_element_factory_make ((mux_name ? mux_name : "ffmux_mpeg"), "mux");
   1.449      if (mux == NULL)
   1.450          goto error;
   1.451  
   1.452 -    fdsink = _create_element_with_prop (sink_name, "sink", sink_prop);
   1.453 -    if (fdsink == NULL)
   1.454 +    sink = gst_element_factory_make ("fakesink", "sink");
   1.455 +    if (sink == NULL)
   1.456          goto error;
   1.457  
   1.458 -    abin = _create_audio_bin (self, audio_encode, audio_encode_prop, audio_rate);
   1.459 +    g_object_set (G_OBJECT(sink), 
   1.460 +            "sync", FALSE,
   1.461 +            "signal-handoffs", TRUE, NULL);
   1.462 +
   1.463 +    abin = _create_audio_bin (audio_encode, audio_encode_prop, audio_rate);
   1.464      if (abin == NULL)
   1.465          goto error;
   1.466  
   1.467 -    vbin = _create_video_bin (self, video_encode, video_encode_prop, video_fps, video_rate, video_width, video_height);
   1.468 +    vbin = _create_video_bin (video_encode, video_encode_prop, video_fps, video_rate, video_width, video_height);
   1.469      if (vbin == NULL)
   1.470          goto error;
   1.471  
   1.472  	// Finish Pipe
   1.473 -    gst_bin_add_many (GST_BIN (pipe), src, decode, abin, vbin, mux, fdsink, NULL);
   1.474 -	gst_element_link (src, decode);
   1.475 +    gst_bin_add_many (GST_BIN (pipe), ap, abin, vp, vbin, mux, sink, NULL);
   1.476 +
   1.477 +    if (gst_element_link (ap, abin) == FALSE) {
   1.478 +        g_warning ("Fail to link multipart and abin");
   1.479 +        goto error;
   1.480 +    }
   1.481 +
   1.482 +    if (gst_element_link (vp, vbin) == FALSE) {
   1.483 +        g_warning ("Fail to link multipart and vbin");
   1.484 +    }
   1.485  
   1.486      //Link bins with mux
   1.487      aux_pad = gst_element_get_pad (abin, "src");
   1.488      mux_pad = gst_element_get_pad (mux, "audio_0");
   1.489 +    if (mux_pad == NULL) {
   1.490 +        g_warning ("Mux element no have audio_0 PAD");
   1.491 +        goto error;
   1.492 +    }
   1.493      GstPadLinkReturn ret = gst_pad_link (aux_pad, mux_pad);
   1.494      if (ret != GST_PAD_LINK_OK) {
   1.495          g_warning ("Fail link audio and mux: %d", ret);
   1.496 @@ -480,6 +703,10 @@
   1.497  
   1.498      aux_pad = gst_element_get_pad (vbin, "src");
   1.499      mux_pad = gst_element_get_pad (mux, "video_0");
   1.500 +    if (mux_pad == NULL) {
   1.501 +        g_warning ("Mux element no have video_0 PAD");
   1.502 +        goto error;
   1.503 +    }
   1.504      ret = gst_pad_link (aux_pad, mux_pad);
   1.505      if (ret != GST_PAD_LINK_OK) {
   1.506          g_warning ("Fail link video and mux: %d", ret);
   1.507 @@ -491,32 +718,17 @@
   1.508      mux_pad = NULL;
   1.509  
   1.510      //Link mux with sink
   1.511 -    gst_element_link (mux, fdsink);
   1.512 +    gst_element_link (mux, sink);
   1.513  
   1.514 -	g_signal_connect (G_OBJECT (decode), 
   1.515 -				"new-decoded-pad",
   1.516 -				G_CALLBACK (_decodebin_new_pad_cb),
   1.517 +    g_signal_connect (G_OBJECT (sink),
   1.518 +				"handoff",
   1.519 +				G_CALLBACK (_sink_handoff_cb),
   1.520  				self);
   1.521 -	
   1.522 -	g_signal_connect (G_OBJECT (decode),
   1.523 -				"unknown-type",
   1.524 -				G_CALLBACK (_decodebin_unknown_type_cb),
   1.525 -				self);
   1.526 -
   1.527  
   1.528  	bus = gst_pipeline_get_bus (GST_PIPELINE (pipe));
   1.529  	gst_bus_add_watch (bus, _pipeline_bus_cb, self);
   1.530  	gst_object_unref (bus);
   1.531 -
   1.532 -
   1.533 -	priv->pipe = pipe;
   1.534 -	priv->abin = abin;
   1.535 -	priv->vbin = vbin;
   1.536 -	priv->sink = fdsink;
   1.537 -	priv->ready = FALSE;
   1.538 -	
   1.539 -	gst_element_set_state (pipe, GST_STATE_PAUSED);	   	
   1.540 -	return  TRUE;
   1.541 +    return pipe;
   1.542  	
   1.543  error:
   1.544  	g_warning ("Invalid uri");
   1.545 @@ -525,9 +737,6 @@
   1.546  		gst_object_unref (pipe);
   1.547      }
   1.548  
   1.549 -	if (src != NULL) {
   1.550 -		gst_object_unref (src);
   1.551 -    }
   1.552  
   1.553      if (mux != NULL) {
   1.554          gst_object_unref (mux);
   1.555 @@ -541,8 +750,8 @@
   1.556          gst_object_unref (mux_pad);
   1.557      }
   1.558  
   1.559 -	if (fdsink != NULL) {
   1.560 -		gst_object_unref (fdsink);
   1.561 +	if (sink != NULL) {
   1.562 +		gst_object_unref (sink);
   1.563      }
   1.564  
   1.565      if (abin != NULL) {
   1.566 @@ -556,49 +765,104 @@
   1.567  	return FALSE;
   1.568  }
   1.569  
   1.570 -gboolean 
   1.571 -g_mencoder_play_stream (GMencoder *self)
   1.572 +
   1.573 +static void
   1.574 +_close_output (GMencoder *self)
   1.575  {
   1.576 +    
   1.577 +}
   1.578 +
   1.579 +static GstElement*
   1.580 +_create_source (const gchar* uri)
   1.581 +{
   1.582 +
   1.583 +    GstElement *bsrc;
   1.584 +    GstElement *src;
   1.585 +    GstElement *aqueue;
   1.586 +    GstElement *vqueue;
   1.587 +    GstElement *decode;
   1.588 +    GstPad *src_pad;
   1.589 +
   1.590 +
   1.591 +    bsrc = gst_bin_new (NULL);
   1.592 +
   1.593 +	src = gst_element_factory_make ("gnomevfssrc", "src");
   1.594 +    g_object_set (G_OBJECT (src), "location", uri, NULL);
   1.595 +	if (src == NULL) 
   1.596 +		goto error;
   1.597 +
   1.598 +	decode = gst_element_factory_make ("decodebin2", "decode");
   1.599 +	if (decode == NULL) 
   1.600 +		goto error;
   1.601 +
   1.602 +    aqueue = gst_element_factory_make ("queue", "aqueue");
   1.603 +    if (aqueue == NULL)
   1.604 +        goto error;
   1.605 +
   1.606 +    vqueue = gst_element_factory_make ("queue", "vqueue");
   1.607 +    if (vqueue == NULL)
   1.608 +        goto error;
   1.609 +
   1.610 +    gst_bin_add_many (GST_BIN (bsrc), src, decode, aqueue, vqueue, NULL);
   1.611 +    gst_element_link (src, decode);
   1.612 +
   1.613 +	g_signal_connect (G_OBJECT (decode), 
   1.614 +				"new-decoded-pad",
   1.615 +				G_CALLBACK (_decodebin_new_pad_cb),
   1.616 +				bsrc);
   1.617 +
   1.618 +	g_signal_connect (G_OBJECT (decode),
   1.619 +				"unknown-type",
   1.620 +				G_CALLBACK (_decodebin_unknown_type_cb),
   1.621 +				pipe);
   1.622 +
   1.623 +    src_pad = gst_element_get_pad (aqueue, "src");
   1.624 +   	gst_element_add_pad (bsrc, gst_ghost_pad_new("src_audio", src_pad));
   1.625 +    gst_object_unref (src_pad);
   1.626 +
   1.627 +    src_pad = gst_element_get_pad (vqueue, "src");
   1.628 +   	gst_element_add_pad (bsrc, gst_ghost_pad_new("src_video", src_pad));
   1.629 +    gst_object_unref (src_pad);
   1.630 +
   1.631 +    return bsrc;
   1.632 +
   1.633 +error:
   1.634 +	if (src != NULL) {
   1.635 +		gst_object_unref (src);
   1.636 +    }
   1.637 +
   1.638 +	if (decode != NULL) {
   1.639 +		gst_object_unref (decode);
   1.640 +    }
   1.641 +
   1.642 +	if (aqueue != NULL) {
   1.643 +		gst_object_unref (aqueue);
   1.644 +    }
   1.645 +
   1.646 +	if (vqueue != NULL) {
   1.647 +		gst_object_unref (vqueue);
   1.648 +    }
   1.649 +
   1.650 +    return NULL;
   1.651 +}
   1.652 +
   1.653 +static void
   1.654 +_open_output (GMencoder *self, 
   1.655 +              const gchar* uri)
   1.656 +{
   1.657 +    gchar** i;
   1.658      GMencoderPrivate *priv = G_MENCODER_GET_PRIVATE (self);
   1.659  
   1.660 -    g_return_val_if_fail (priv->ready == TRUE, FALSE);
   1.661 -    
   1.662 -    if (gst_element_set_state (priv->pipe, GST_STATE_PLAYING) != GST_STATE_CHANGE_FAILURE) {
   1.663 -			g_debug ("PLAYING");
   1.664 -			return TRUE;
   1.665 -	}
   1.666 -	return FALSE;
   1.667 -}
   1.668 +    i = g_strsplit (uri, "://", 0);
   1.669 +    if (strcmp (i[0], "fd") == 0) {
   1.670 +        priv->fd = atoi (i[1]);
   1.671 +    } else if (strcmp (i[0], "file") == 0) {
   1.672 +        priv->fd = open (i[1], O_WRONLY | O_CREAT | O_TRUNC);
   1.673 +    } else {
   1.674 +        g_warning ("Output uri not supported");
   1.675 +    }
   1.676  
   1.677 -gboolean
   1.678 -g_mencoder_pause_stream (GMencoder *self)
   1.679 -{
   1.680 -    GMencoderPrivate *priv = G_MENCODER_GET_PRIVATE (self);
   1.681 -
   1.682 -    g_return_val_if_fail (priv->ready == TRUE, FALSE);
   1.683 -    
   1.684 -    if (gst_element_set_state (priv->pipe, GST_STATE_PAUSED) != GST_STATE_CHANGE_FAILURE) {
   1.685 -			g_debug ("PAUSED");
   1.686 -			return TRUE;
   1.687 -	}
   1.688 -	return FALSE;
   1.689 -}
   1.690 -
   1.691 -void
   1.692 -g_mencoder_close_stream (GMencoder *self)
   1.693 -{
   1.694 -
   1.695 -    GMencoderPrivate *priv = G_MENCODER_GET_PRIVATE (self);
   1.696 -
   1.697 -    g_return_if_fail (priv->ready == TRUE);
   1.698 -    
   1.699 -    gst_element_set_state (priv->pipe, GST_STATE_NULL);
   1.700 -    gst_object_unref (priv->pipe);
   1.701 -    priv->pipe = NULL;
   1.702 -    priv->abin = NULL;
   1.703 -    priv->vbin = NULL;
   1.704 -    priv->sink = NULL;
   1.705 -    priv->ready = FALSE;
   1.706 +    g_strfreev (i);
   1.707  }
   1.708  
   1.709  static gboolean
   1.710 @@ -606,6 +870,8 @@
   1.711  		  GstMessage *msg,
   1.712  		  gpointer    user_data)
   1.713  {
   1.714 +	GMencoderPrivate *priv = G_MENCODER_GET_PRIVATE (user_data);
   1.715 +
   1.716  	switch (GST_MESSAGE_TYPE (msg)) 
   1.717  	{
   1.718  		case GST_MESSAGE_STATE_CHANGED:
   1.719 @@ -614,7 +880,6 @@
   1.720  			GstState newstate;
   1.721  			GstState pendingstate;
   1.722  
   1.723 -			GMencoderPrivate *priv = G_MENCODER_GET_PRIVATE (user_data);
   1.724  
   1.725  			gst_message_parse_state_changed (msg, &oldstate,
   1.726  				&newstate, &pendingstate);
   1.727 @@ -626,10 +891,6 @@
   1.728                  (newstate == GST_STATE_PAUSED)) {
   1.729                      if (priv->ready) 
   1.730                          g_signal_emit (user_data, g_mencoder_signals[PAUSED], 0);
   1.731 -                    else {
   1.732 -                        priv->ready = TRUE;
   1.733 -                        g_signal_emit (user_data, g_mencoder_signals[READY], 0);
   1.734 -                    }
   1.735              } else if ((oldstate == GST_STATE_PAUSED) &&
   1.736                         (newstate == GST_STATE_PLAYING)) {
   1.737                          g_signal_emit (user_data, g_mencoder_signals[PLAYING], 0);
   1.738 @@ -650,6 +911,7 @@
   1.739  		        error->message,
   1.740  		        debug);
   1.741  		    g_signal_emit (user_data, g_mencoder_signals[ERROR], 0, err_str);
   1.742 +            priv->ready = FALSE;
   1.743  		    g_free (err_str);
   1.744  		    g_clear_error (&error);
   1.745  		    g_free (debug);
   1.746 @@ -657,6 +919,7 @@
   1.747  		}
   1.748  		
   1.749  		case GST_MESSAGE_EOS:
   1.750 +            priv->ready = FALSE;
   1.751  		    g_signal_emit (user_data, g_mencoder_signals[EOS], 0);
   1.752  		    break;		
   1.753  		default:
   1.754 @@ -665,6 +928,8 @@
   1.755  	return TRUE;
   1.756  }
   1.757  
   1.758 +
   1.759 +
   1.760  static void 
   1.761  _decodebin_new_pad_cb (GstElement* object,
   1.762                         GstPad* pad,
   1.763 @@ -673,24 +938,24 @@
   1.764  {
   1.765  	GstCaps *caps;
   1.766  	gchar *str_caps = NULL;
   1.767 -    GMencoderPrivate *priv = G_MENCODER_GET_PRIVATE (user_data);
   1.768 +    GstElement *sink_element;
   1.769 +    GstPad *sink_pad;
   1.770  
   1.771  	caps = gst_pad_get_caps (pad);
   1.772  	str_caps = gst_caps_to_string (caps);
   1.773 -    g_debug ("CAPS : %s", str_caps);
   1.774 -
   1.775  	if (strstr (str_caps, "audio") != NULL) {
   1.776 -		GstPad *apad = gst_element_get_pad (priv->abin, "sink");
   1.777 -		gst_pad_link (pad, apad);
   1.778 -		gst_object_unref (apad);
   1.779 +        sink_element = gst_bin_get_by_name (GST_BIN (user_data), "aqueue");
   1.780  	} else if (strstr (str_caps, "video") != NULL) {
   1.781 -		GstPad *vpad = gst_element_get_pad (priv->vbin, "sink");
   1.782 -		gst_pad_link (pad, vpad);
   1.783 -		gst_object_unref (vpad);
   1.784 +        sink_element = gst_bin_get_by_name (GST_BIN (user_data), "vqueue");
   1.785  	} else {
   1.786  		g_warning ("invalid caps %s", str_caps);
   1.787  	}
   1.788  
   1.789 +    sink_pad = gst_element_get_pad (sink_element, "sink");
   1.790 +	gst_pad_link (pad, sink_pad);
   1.791 +
   1.792 +    gst_object_unref (sink_element);
   1.793 +	gst_object_unref (sink_pad);
   1.794  	g_free (str_caps);
   1.795  	gst_caps_unref (caps);
   1.796  }
   1.797 @@ -702,4 +967,5 @@
   1.798                              gpointer user_data)
   1.799  {
   1.800      g_warning  ("Unknown Type");
   1.801 +    //priv->ready = FALSE;
   1.802  }