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 }