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 }