1.1 --- a/gmyth-stream/gmemcoder/src/Makefile.am Mon Apr 23 19:16:24 2007 +0100
1.2 +++ b/gmyth-stream/gmemcoder/src/Makefile.am Mon Apr 23 21:05:21 2007 +0100
1.3 @@ -3,8 +3,8 @@
1.4
1.5 gmencoder_SOURCES = \
1.6 main.c \
1.7 - gmemcoder.c \
1.8 - gmemcoder.h
1.9 + gmencoder.c \
1.10 + gmencoder.h
1.11
1.12 gmencoder_LDADD = \
1.13 $(GLIB_LIBS) \
2.1 --- a/gmyth-stream/gmemcoder/src/gmemcoder.c Mon Apr 23 19:16:24 2007 +0100
2.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
2.3 @@ -1,551 +0,0 @@
2.4 -#ifdef HAVE_CONFIG_H
2.5 -#include "config.h"
2.6 -#endif
2.7 -
2.8 -#include <glib.h>
2.9 -#include <gst/gst.h>
2.10 -#include <string.h>
2.11 -
2.12 -#include "gmemcoder.h"
2.13 -
2.14 -#define G_MENCODER_GET_PRIVATE(obj) \
2.15 - (G_TYPE_INSTANCE_GET_PRIVATE ((obj), G_TYPE_MENCODER, GMencoderPrivate))
2.16 -
2.17 -
2.18 -typedef struct _GMencoderPrivate GMencoderPrivate;
2.19 -
2.20 -struct _GMencoderPrivate
2.21 -{
2.22 - GstElement *pipe;
2.23 - GstElement *abin;
2.24 - GstElement *vbin;
2.25 - GstElement *sink;
2.26 - gboolean ready;
2.27 -};
2.28 -
2.29 -enum {
2.30 - READY,
2.31 - PAUSED,
2.32 - PLAYING,
2.33 - STOPED,
2.34 - EOS,
2.35 - ERROR,
2.36 - LAST_SIGNAL
2.37 -};
2.38 -
2.39 -static void g_mencoder_class_init (GMencoderClass *klass);
2.40 -static void g_mencoder_init (GMencoder *object);
2.41 -static void g_mencoder_dispose (GObject *object);
2.42 -static void g_mencoder_finalize (GObject *object);
2.43 -static gboolean
2.44 - _pipeline_bus_cb (GstBus *bus,
2.45 - GstMessage *msg,
2.46 - gpointer user_data);
2.47 -
2.48 -static void _decodebin_new_pad_cb (GstElement* object,
2.49 - GstPad* pad,
2.50 - gboolean flag,
2.51 - gpointer user_data);
2.52 -static void _decodebin_unknown_type_cb (GstElement* object,
2.53 - GstPad* pad,
2.54 - GstCaps* caps,
2.55 - gpointer user_data);
2.56 -
2.57 -static guint g_mencoder_signals[LAST_SIGNAL] = { 0 };
2.58 -
2.59 -G_DEFINE_TYPE(GMencoder, g_mencoder, G_TYPE_OBJECT)
2.60 -
2.61 -static void
2.62 -g_mencoder_class_init (GMencoderClass *klass)
2.63 -{
2.64 - GObjectClass *object_class;
2.65 -
2.66 - object_class = (GObjectClass *) klass;
2.67 -
2.68 - g_type_class_add_private (klass, sizeof (GMencoderPrivate));
2.69 -
2.70 - object_class->dispose = g_mencoder_dispose;
2.71 - object_class->finalize = g_mencoder_finalize;
2.72 -
2.73 - g_mencoder_signals[READY] =
2.74 - g_signal_new ("ready",
2.75 - G_OBJECT_CLASS_TYPE (object_class),
2.76 - G_SIGNAL_RUN_FIRST,
2.77 - 0, NULL, NULL,
2.78 - g_cclosure_marshal_VOID__VOID,
2.79 - G_TYPE_NONE, 0);
2.80 -
2.81 - g_mencoder_signals[PAUSED] =
2.82 - g_signal_new ("paused",
2.83 - G_OBJECT_CLASS_TYPE (object_class),
2.84 - G_SIGNAL_RUN_FIRST,
2.85 - 0, NULL, NULL,
2.86 - g_cclosure_marshal_VOID__VOID,
2.87 - G_TYPE_NONE, 0);
2.88 -
2.89 - g_mencoder_signals[PLAYING] =
2.90 - g_signal_new ("playing",
2.91 - G_OBJECT_CLASS_TYPE (object_class),
2.92 - G_SIGNAL_RUN_FIRST,
2.93 - 0, NULL, NULL,
2.94 - g_cclosure_marshal_VOID__VOID,
2.95 - G_TYPE_NONE, 0);
2.96 -
2.97 - g_mencoder_signals[STOPED] =
2.98 - g_signal_new ("stoped",
2.99 - G_OBJECT_CLASS_TYPE (object_class),
2.100 - G_SIGNAL_RUN_FIRST,
2.101 - 0, NULL, NULL,
2.102 - g_cclosure_marshal_VOID__VOID,
2.103 - G_TYPE_NONE, 0);
2.104 -
2.105 - g_mencoder_signals[EOS] =
2.106 - g_signal_new ("eos",
2.107 - G_OBJECT_CLASS_TYPE (object_class),
2.108 - G_SIGNAL_RUN_FIRST,
2.109 - 0, NULL, NULL,
2.110 - g_cclosure_marshal_VOID__VOID,
2.111 - G_TYPE_NONE, 0);
2.112 -
2.113 -
2.114 - g_mencoder_signals[ERROR] =
2.115 - g_signal_new ("error",
2.116 - G_OBJECT_CLASS_TYPE (object_class),
2.117 - G_SIGNAL_RUN_FIRST,
2.118 - 0, NULL, NULL,
2.119 - g_cclosure_marshal_VOID__STRING,
2.120 - G_TYPE_NONE, 1, G_TYPE_STRING);
2.121 -}
2.122 -
2.123 -static void
2.124 -g_mencoder_init (GMencoder *self)
2.125 -{
2.126 -}
2.127 -
2.128 -static void
2.129 -g_mencoder_dispose (GObject *object)
2.130 -{
2.131 -}
2.132 -
2.133 -static void
2.134 -g_mencoder_finalize (GObject *object)
2.135 -{
2.136 - g_mencoder_close_stream (G_MENCODER (object));
2.137 -}
2.138 -
2.139 -GMencoder*
2.140 -g_mencoder_new (void)
2.141 -{
2.142 - return g_object_new (G_TYPE_MENCODER, NULL);
2.143 -}
2.144 -
2.145 -
2.146 -gboolean
2.147 -g_mencoder_setup_stream (GMencoder *self,
2.148 - const gchar* uri,
2.149 - guint width, guint height,
2.150 - gint out_fd)
2.151 -{
2.152 - GstBus *bus = NULL;
2.153 - GstElement *pipe = NULL;
2.154 - GstElement *decode = NULL;
2.155 - GstElement *fdsink = NULL;
2.156 - GstElement *mux = NULL;
2.157 -
2.158 - GstCaps *vscale_caps = NULL;
2.159 - GstPad *asinkpad = NULL;
2.160 - GstPad *vsinkpad = NULL;
2.161 - GstPad *video_src_pad = NULL;
2.162 - GstPad *audio_src_pad = NULL;
2.163 - GstPad *mux_pad = NULL;
2.164 - GstElement *src = NULL;
2.165 - GstElement *vbin, *vqueue, *vcolorspace, *vscale, *vrate, *vencode, *vqueue_src;
2.166 - GstElement *abin, *aqueue, *aconvert, *aencode, *aqueue_src;
2.167 - GMencoderPrivate *priv = G_MENCODER_GET_PRIVATE (self);
2.168 -
2.169 - vbin = vqueue = vscale = vrate = vencode = vqueue_src = NULL;
2.170 - abin = aqueue = aconvert = aencode = aqueue_src = NULL;
2.171 -
2.172 - pipe = gst_pipeline_new ("pipe");
2.173 - src = gst_element_make_from_uri (GST_URI_SRC, uri, "src");
2.174 - if (src == NULL)
2.175 - goto error;
2.176 -
2.177 - decode = gst_element_factory_make ("decodebin", "decode");
2.178 - if (decode == NULL)
2.179 - goto error;
2.180 -
2.181 - mux = gst_element_factory_make ("ffmux_mpeg", "mux");
2.182 - if (mux == NULL)
2.183 - goto error;
2.184 -
2.185 - fdsink = gst_element_factory_make ("fdsink", "sink");
2.186 - if (fdsink == NULL)
2.187 - goto error;
2.188 -
2.189 - g_debug ("Setting fd to %d", out_fd);
2.190 - g_object_set (G_OBJECT (fdsink), "fd", out_fd, NULL);
2.191 -
2.192 - //queue ! videoscale ! video/x-raw-yuv,width=240,height=144 ! videorate ! ffenc_h263p bitrate=256000 me-method=2 ! rtph263ppay ! udpsink host=224.0.0.1 port=5000
2.193 -
2.194 - vbin = gst_bin_new ("vbin");
2.195 - vqueue = gst_element_factory_make ("queue", "vqueue");
2.196 - vscale = gst_element_factory_make ("videoscale", "vscale");
2.197 - vcolorspace = gst_element_factory_make ("ffmpegcolorspace", "colorspace");
2.198 - vrate = gst_element_factory_make ("videorate", "vrate");
2.199 - vencode = gst_element_factory_make ("ffenc_mpeg1video", "vencode");
2.200 - vqueue_src = gst_element_factory_make ("queue", "queue_src");
2.201 -
2.202 -
2.203 - if ((vbin == NULL) || (vqueue == NULL) || (vcolorspace == NULL)
2.204 - || (vscale == NULL) || (vrate == NULL)
2.205 - || (vencode == NULL) || (vqueue_src == NULL)) {
2.206 - g_warning ("Video elements not found");
2.207 - goto error;
2.208 - }
2.209 -
2.210 - g_object_set (G_OBJECT (vencode), "bitrate", 200, "pass", 2, "quantizer", 5, NULL);
2.211 -
2.212 - gst_bin_add_many (GST_BIN (vbin), vqueue, vscale, vcolorspace, vrate, vencode, vqueue_src, NULL);
2.213 - gst_element_link (vqueue, vscale);
2.214 -
2.215 -
2.216 - vscale_caps = gst_caps_new_simple ("video/x-raw-yuv",
2.217 - "width", G_TYPE_INT, 320,
2.218 - "height", G_TYPE_INT, 288,
2.219 - NULL);
2.220 -
2.221 - if (gst_element_link_filtered (vscale, vcolorspace, vscale_caps) == FALSE) {
2.222 - g_warning ("Fail to resize video");
2.223 - goto error;
2.224 - }
2.225 -
2.226 - if (gst_element_link (vcolorspace, vrate) == FALSE) {
2.227 - g_warning ("Fail to link video elements");
2.228 - goto error;
2.229 - }
2.230 -
2.231 - gst_caps_unref (vscale_caps);
2.232 -
2.233 - vscale_caps = gst_caps_new_simple ("video/x-raw-yuv",
2.234 - "framerate", GST_TYPE_FRACTION, 10, 1, NULL);
2.235 -
2.236 - if (gst_element_link_filtered (vrate, vencode, vscale_caps) == FALSE) {
2.237 - g_warning ("Fail to link vrate with vencode.");
2.238 - goto error;
2.239 -
2.240 - }
2.241 -
2.242 - gst_element_link (vencode, vqueue_src);
2.243 -
2.244 - // ghost pad the video bin
2.245 - vsinkpad = gst_element_get_pad (vqueue, "sink");
2.246 - gst_element_add_pad (vbin, gst_ghost_pad_new ("sink", vsinkpad));
2.247 - gst_object_unref (vsinkpad);
2.248 -
2.249 - video_src_pad = gst_element_get_pad (vqueue_src, "src");
2.250 - gst_element_add_pad (vbin, gst_ghost_pad_new ("src", video_src_pad));
2.251 - gst_object_unref (video_src_pad);
2.252 -
2.253 -
2.254 - //audio/x-raw-int ! queue ! audioconvert ! faac ! rtpmp4gpay ! udpsink name=upd_audio host=224.0.0.1 port=5002
2.255 - abin = gst_bin_new ("abin");
2.256 - aqueue = gst_element_factory_make ("queue", "aqueue");
2.257 - aconvert= gst_element_factory_make ("audioconvert", "aconvert");
2.258 - aencode = gst_element_factory_make ("lame", "aencode");
2.259 - aqueue_src= gst_element_factory_make ("queue", "aqueue_src");
2.260 -
2.261 - if ((abin == NULL) || (aqueue == NULL) || (aconvert == NULL)
2.262 - || (aencode == NULL) || (aqueue_src == NULL)) {
2.263 - g_warning ("Audio elements not found");
2.264 - goto error;
2.265 - }
2.266 -
2.267 - gst_bin_add_many (GST_BIN (abin), aqueue, aconvert, aencode, aqueue_src, NULL);
2.268 - gst_element_link_many (aqueue, aconvert, aencode, aqueue_src, NULL);
2.269 -
2.270 -
2.271 - // ghost pad the audio bin
2.272 - asinkpad = gst_element_get_pad (aqueue, "sink");
2.273 - gst_element_add_pad (abin, gst_ghost_pad_new("sink", asinkpad));
2.274 - gst_object_unref (asinkpad);
2.275 -
2.276 - audio_src_pad = gst_element_get_pad (aqueue_src, "src");
2.277 - gst_element_add_pad (abin, gst_ghost_pad_new("src", audio_src_pad));
2.278 - gst_object_unref (audio_src_pad);
2.279 -
2.280 -
2.281 - // Finish Pipe
2.282 - gst_bin_add_many (GST_BIN (pipe), src, decode, abin, vbin, mux, fdsink, NULL);
2.283 - gst_element_link (src, decode);
2.284 -
2.285 - //Link bins with mux
2.286 - audio_src_pad = gst_element_get_pad (abin, "src");
2.287 - mux_pad = gst_element_get_pad (mux, "audio_0");
2.288 - if (gst_pad_link (audio_src_pad, mux_pad) != GST_PAD_LINK_OK) {
2.289 - g_warning ("Fail link audio and mux");
2.290 - goto error;
2.291 -
2.292 - }
2.293 - gst_object_unref (audio_src_pad);
2.294 - gst_object_unref (mux_pad);
2.295 - audio_src_pad = NULL;
2.296 - mux_pad = NULL;
2.297 -
2.298 - video_src_pad = gst_element_get_pad (vbin, "src");
2.299 - mux_pad = gst_element_get_pad (mux, "video_0");
2.300 - if (gst_pad_link (video_src_pad, mux_pad) != GST_PAD_LINK_OK) {
2.301 - g_warning ("Fail link video and mux");
2.302 - goto error;
2.303 - }
2.304 - gst_object_unref (video_src_pad);
2.305 - gst_object_unref (mux_pad);
2.306 - video_src_pad = NULL;
2.307 - mux_pad = NULL;
2.308 -
2.309 - //Link mux with sink
2.310 - gst_element_link (mux, fdsink);
2.311 -
2.312 - bus = gst_pipeline_get_bus (GST_PIPELINE (pipe));
2.313 - gst_bus_add_watch (bus, _pipeline_bus_cb, self);
2.314 - gst_object_unref (bus);
2.315 -
2.316 - g_signal_connect (G_OBJECT (decode),
2.317 - "new-decoded-pad",
2.318 - G_CALLBACK (_decodebin_new_pad_cb),
2.319 - self);
2.320 -
2.321 - g_signal_connect (G_OBJECT (decode),
2.322 - "unknown-type",
2.323 - G_CALLBACK (_decodebin_unknown_type_cb),
2.324 - self);
2.325 -
2.326 - g_debug ("Setting pipe to PAUSE");
2.327 -
2.328 - priv->pipe = pipe;
2.329 - priv->abin = abin;
2.330 - priv->vbin = vbin;
2.331 - priv->sink = fdsink;
2.332 - priv->ready = FALSE;
2.333 -
2.334 - gst_element_set_state (pipe, GST_STATE_PAUSED);
2.335 - g_debug ("End SETUP");
2.336 - return TRUE;
2.337 -
2.338 -error:
2.339 - g_warning ("Invalid uri");
2.340 -
2.341 - if (pipe != NULL)
2.342 - gst_object_unref (pipe);
2.343 -
2.344 - if (src != NULL)
2.345 - gst_object_unref (src);
2.346 -
2.347 - if (decode != NULL)
2.348 - gst_object_unref (decode);
2.349 -
2.350 - if (vscale_caps != NULL)
2.351 - gst_caps_unref (vscale_caps);
2.352 -
2.353 - if (vbin != NULL)
2.354 - gst_object_unref (vbin);
2.355 -
2.356 - if (vqueue != NULL)
2.357 - gst_object_unref (vqueue);
2.358 -
2.359 - if (vrate != NULL)
2.360 - gst_object_unref (vrate);
2.361 -
2.362 - if (vencode != NULL)
2.363 - gst_object_unref (vencode);
2.364 -
2.365 - if (vqueue_src != NULL)
2.366 - gst_object_unref (vqueue_src);
2.367 -
2.368 - if (abin != NULL)
2.369 - gst_object_unref (abin);
2.370 -
2.371 - if (aqueue != NULL)
2.372 - gst_object_unref (aqueue);
2.373 -
2.374 - if (aconvert != NULL)
2.375 - gst_object_unref (aconvert);
2.376 -
2.377 - if (aencode != NULL)
2.378 - gst_object_unref (aencode);
2.379 -
2.380 - if (aqueue_src != NULL)
2.381 - gst_object_unref (aqueue_src);
2.382 -
2.383 - if (video_src_pad != NULL) {
2.384 - gst_object_unref (video_src_pad);
2.385 - }
2.386 -
2.387 - if (audio_src_pad != NULL) {
2.388 - gst_object_unref (audio_src_pad);
2.389 - }
2.390 -
2.391 - if (mux != NULL) {
2.392 - gst_object_unref (mux);
2.393 - }
2.394 -
2.395 - if (mux_pad != NULL) {
2.396 - gst_object_unref (mux_pad);
2.397 - }
2.398 -
2.399 - if (fdsink != NULL)
2.400 - gst_object_unref (fdsink);
2.401 -
2.402 - return FALSE;
2.403 -}
2.404 -
2.405 -gboolean
2.406 -g_mencoder_play_stream (GMencoder *self)
2.407 -{
2.408 - GMencoderPrivate *priv = G_MENCODER_GET_PRIVATE (self);
2.409 -
2.410 - g_return_val_if_fail (priv->ready == TRUE, FALSE);
2.411 -
2.412 - if (gst_element_set_state (priv->pipe, GST_STATE_PLAYING) != GST_STATE_CHANGE_FAILURE) {
2.413 - g_debug ("PLAYING");
2.414 - return TRUE;
2.415 - }
2.416 - return FALSE;
2.417 -}
2.418 -
2.419 -gboolean
2.420 -g_mencoder_pause_stream (GMencoder *self)
2.421 -{
2.422 - GMencoderPrivate *priv = G_MENCODER_GET_PRIVATE (self);
2.423 -
2.424 - g_return_val_if_fail (priv->ready == TRUE, FALSE);
2.425 -
2.426 - if (gst_element_set_state (priv->pipe, GST_STATE_PAUSED) != GST_STATE_CHANGE_FAILURE) {
2.427 - g_debug ("PAUSED");
2.428 - return TRUE;
2.429 - }
2.430 - return FALSE;
2.431 -}
2.432 -
2.433 -void
2.434 -g_mencoder_close_stream (GMencoder *self)
2.435 -{
2.436 -
2.437 - GMencoderPrivate *priv = G_MENCODER_GET_PRIVATE (self);
2.438 -
2.439 - g_return_if_fail (priv->ready == TRUE);
2.440 -
2.441 - gst_element_set_state (priv->pipe, GST_STATE_NULL);
2.442 - gst_object_unref (priv->pipe);
2.443 - priv->pipe = NULL;
2.444 - priv->abin = NULL;
2.445 - priv->vbin = NULL;
2.446 - priv->sink = NULL;
2.447 - priv->ready = FALSE;
2.448 -}
2.449 -
2.450 -static gboolean
2.451 -_pipeline_bus_cb (GstBus *bus,
2.452 - GstMessage *msg,
2.453 - gpointer user_data)
2.454 -{
2.455 - switch (GST_MESSAGE_TYPE (msg))
2.456 - {
2.457 - case GST_MESSAGE_STATE_CHANGED:
2.458 - {
2.459 - GstState oldstate;
2.460 - GstState newstate;
2.461 - GstState pendingstate;
2.462 -
2.463 - GMencoderPrivate *priv = G_MENCODER_GET_PRIVATE (user_data);
2.464 -
2.465 - gst_message_parse_state_changed (msg, &oldstate,
2.466 - &newstate, &pendingstate);
2.467 -
2.468 - if (pendingstate != GST_STATE_VOID_PENDING)
2.469 - break;
2.470 -
2.471 - if ((oldstate == GST_STATE_READY) &&
2.472 - (newstate == GST_STATE_PAUSED)) {
2.473 - if (priv->ready)
2.474 - g_signal_emit (user_data, g_mencoder_signals[PAUSED], 0);
2.475 - else {
2.476 - priv->ready = TRUE;
2.477 - g_signal_emit (user_data, g_mencoder_signals[READY], 0);
2.478 - }
2.479 - } else if ((oldstate == GST_STATE_PAUSED) &&
2.480 - (newstate == GST_STATE_PLAYING)) {
2.481 - g_signal_emit (user_data, g_mencoder_signals[PLAYING], 0);
2.482 - } else if ((oldstate == GST_STATE_READY) &&
2.483 - (newstate == GST_STATE_NULL)) {
2.484 - g_signal_emit (user_data, g_mencoder_signals[STOPED], 0);
2.485 - }
2.486 - break;
2.487 - }
2.488 - case GST_MESSAGE_ERROR:
2.489 - {
2.490 - GError *error;
2.491 - gchar *debug;
2.492 - gchar *err_str;
2.493 -
2.494 - gst_message_parse_error (msg, &error, &debug);
2.495 - err_str = g_strdup_printf ("Error [%d] %s (%s)", error->code,
2.496 - error->message,
2.497 - debug);
2.498 - g_signal_emit (user_data, g_mencoder_signals[ERROR], 0, err_str);
2.499 - g_free (err_str);
2.500 - g_clear_error (&error);
2.501 - g_free (debug);
2.502 - break;
2.503 - }
2.504 -
2.505 - case GST_MESSAGE_EOS:
2.506 - g_signal_emit (user_data, g_mencoder_signals[EOS], 0);
2.507 - break;
2.508 - default:
2.509 - break;
2.510 - }
2.511 - return TRUE;
2.512 -}
2.513 -
2.514 -static void
2.515 -_decodebin_new_pad_cb (GstElement* object,
2.516 - GstPad* pad,
2.517 - gboolean flag,
2.518 - gpointer user_data)
2.519 -{
2.520 - GstCaps *caps;
2.521 - gchar *str_caps = NULL;
2.522 - GMencoderPrivate *priv = G_MENCODER_GET_PRIVATE (user_data);
2.523 -
2.524 - caps = gst_pad_get_caps (pad);
2.525 - str_caps = gst_caps_to_string (caps);
2.526 - g_debug ("CAPS : %s", str_caps);
2.527 -
2.528 - if (strstr (str_caps, "audio") != NULL) {
2.529 - GstPad *apad = gst_element_get_pad (priv->abin, "sink");
2.530 - g_debug ("Linked with Audio");
2.531 - gst_pad_link (pad, apad);
2.532 - gst_object_unref (apad);
2.533 - } else if (strstr (str_caps, "video") != NULL) {
2.534 - GstPad *vpad = gst_element_get_pad (priv->vbin, "sink");
2.535 - g_debug ("Linked with Video");
2.536 - gst_pad_link (pad, vpad);
2.537 - gst_object_unref (vpad);
2.538 - } else {
2.539 - g_warning ("invalid caps %s", str_caps);
2.540 - }
2.541 -
2.542 - g_free (str_caps);
2.543 - gst_caps_unref (caps);
2.544 - g_debug ("OK");
2.545 -}
2.546 -
2.547 -static void
2.548 -_decodebin_unknown_type_cb (GstElement* object,
2.549 - GstPad* pad,
2.550 - GstCaps* caps,
2.551 - gpointer user_data)
2.552 -{
2.553 - g_warning ("Unknown Type");
2.554 -}
3.1 --- a/gmyth-stream/gmemcoder/src/gmemcoder.h Mon Apr 23 19:16:24 2007 +0100
3.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
3.3 @@ -1,46 +0,0 @@
3.4 -#ifndef __G_MENCODER_H__
3.5 -#define __G_MENCODER_H__
3.6 -
3.7 -#include <glib-object.h>
3.8 -
3.9 -G_BEGIN_DECLS
3.10 -
3.11 -typedef struct _GMencoder GMencoder;
3.12 -typedef struct _GMencoderClass GMencoderClass;
3.13 -
3.14 -struct _GMencoderClass {
3.15 - GObjectClass parent_class;
3.16 -};
3.17 -
3.18 -struct _GMencoder {
3.19 - GObject parent;
3.20 -};
3.21 -
3.22 -/* TYPE MACROS */
3.23 -#define G_TYPE_MENCODER \
3.24 - (g_mencoder_get_type())
3.25 -#define G_MENCODER(obj) \
3.26 - (G_TYPE_CHECK_INSTANCE_CAST((obj), G_TYPE_MENCODER, GMencoder))
3.27 -#define G_MENCODER_CLASS(klass) \
3.28 - (G_TYPE_CHECK_CLASS_CAST((klass), G_TYPE_MENCODER, GMencoderClass))
3.29 -#define G_IS_MENCODER(obj) \
3.30 - (G_TYPE_CHECK_INSTANCE_TYPE((obj), G_TYPE_MENCODER))
3.31 -#define G_IS_MENCODER_CLASS(klass) \
3.32 - (G_TYPE_CHECK_CLASS_TYPE((klass), G_TYPE_MENCODER))
3.33 -#define G_MENCODER_GET_CLASS(obj) \
3.34 - (G_TYPE_INSTANCE_GET_CLASS ((obj), G_TYPE_MENCODER, GMencoderClass))
3.35 -
3.36 -
3.37 -GType g_mencoder_get_type (void);
3.38 -GMencoder* g_mencoder_new (void);
3.39 -gboolean g_mencoder_setup_stream (GMencoder *self,
3.40 - const gchar* uri,
3.41 - guint width, guint height,
3.42 - gint out_fd);
3.43 -gboolean g_mencoder_play_stream (GMencoder *self);
3.44 -gboolean g_mencoder_pause_stream (GMencoder *self);
3.45 -void g_mencoder_close_stream (GMencoder *self);
3.46 -
3.47 -G_END_DECLS
3.48 -
3.49 -#endif
4.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
4.2 +++ b/gmyth-stream/gmemcoder/src/gmencoder.c Mon Apr 23 21:05:21 2007 +0100
4.3 @@ -0,0 +1,705 @@
4.4 +#ifdef HAVE_CONFIG_H
4.5 +#include "config.h"
4.6 +#endif
4.7 +
4.8 +#include <glib.h>
4.9 +#include <gst/gst.h>
4.10 +#include <string.h>
4.11 +
4.12 +#include "gmencoder.h"
4.13 +
4.14 +#define G_MENCODER_GET_PRIVATE(obj) \
4.15 + (G_TYPE_INSTANCE_GET_PRIVATE ((obj), G_TYPE_MENCODER, GMencoderPrivate))
4.16 +
4.17 +
4.18 +typedef struct _GMencoderPrivate GMencoderPrivate;
4.19 +
4.20 +struct _GMencoderPrivate
4.21 +{
4.22 + GstElement *pipe;
4.23 + GstElement *abin;
4.24 + GstElement *vbin;
4.25 + GstElement *sink;
4.26 + gboolean ready;
4.27 +};
4.28 +
4.29 +enum {
4.30 + READY,
4.31 + PAUSED,
4.32 + PLAYING,
4.33 + STOPED,
4.34 + EOS,
4.35 + ERROR,
4.36 + LAST_SIGNAL
4.37 +};
4.38 +
4.39 +static void g_mencoder_class_init (GMencoderClass *klass);
4.40 +static void g_mencoder_init (GMencoder *object);
4.41 +static void g_mencoder_dispose (GObject *object);
4.42 +static void g_mencoder_finalize (GObject *object);
4.43 +static GstElement*
4.44 + _create_audio_bin (GMencoder *self,
4.45 + const gchar* encode,
4.46 + gchar** encode_prop,
4.47 + gint rate);
4.48 +static GstElement*
4.49 + _create_video_bin (GMencoder* self,
4.50 + const gchar* encode,
4.51 + gchar** encode_prop,
4.52 + gdouble fps,
4.53 + gint rate,
4.54 + guint width,
4.55 + guint height);
4.56 +
4.57 +static gboolean
4.58 + _pipeline_bus_cb (GstBus *bus,
4.59 + GstMessage *msg,
4.60 + gpointer user_data);
4.61 +static void _decodebin_new_pad_cb (GstElement* object,
4.62 + GstPad* pad,
4.63 + gboolean flag,
4.64 + gpointer user_data);
4.65 +static void _decodebin_unknown_type_cb (GstElement* object,
4.66 + GstPad* pad,
4.67 + GstCaps* caps,
4.68 + gpointer user_data);
4.69 +
4.70 +
4.71 +static guint g_mencoder_signals[LAST_SIGNAL] = { 0 };
4.72 +
4.73 +G_DEFINE_TYPE(GMencoder, g_mencoder, G_TYPE_OBJECT)
4.74 +
4.75 +static void
4.76 +g_mencoder_class_init (GMencoderClass *klass)
4.77 +{
4.78 + GObjectClass *object_class;
4.79 +
4.80 + object_class = (GObjectClass *) klass;
4.81 +
4.82 + g_type_class_add_private (klass, sizeof (GMencoderPrivate));
4.83 +
4.84 + object_class->dispose = g_mencoder_dispose;
4.85 + object_class->finalize = g_mencoder_finalize;
4.86 +
4.87 + g_mencoder_signals[READY] =
4.88 + g_signal_new ("ready",
4.89 + G_OBJECT_CLASS_TYPE (object_class),
4.90 + G_SIGNAL_RUN_FIRST,
4.91 + 0, NULL, NULL,
4.92 + g_cclosure_marshal_VOID__VOID,
4.93 + G_TYPE_NONE, 0);
4.94 +
4.95 + g_mencoder_signals[PAUSED] =
4.96 + g_signal_new ("paused",
4.97 + G_OBJECT_CLASS_TYPE (object_class),
4.98 + G_SIGNAL_RUN_FIRST,
4.99 + 0, NULL, NULL,
4.100 + g_cclosure_marshal_VOID__VOID,
4.101 + G_TYPE_NONE, 0);
4.102 +
4.103 + g_mencoder_signals[PLAYING] =
4.104 + g_signal_new ("playing",
4.105 + G_OBJECT_CLASS_TYPE (object_class),
4.106 + G_SIGNAL_RUN_FIRST,
4.107 + 0, NULL, NULL,
4.108 + g_cclosure_marshal_VOID__VOID,
4.109 + G_TYPE_NONE, 0);
4.110 +
4.111 + g_mencoder_signals[STOPED] =
4.112 + g_signal_new ("stoped",
4.113 + G_OBJECT_CLASS_TYPE (object_class),
4.114 + G_SIGNAL_RUN_FIRST,
4.115 + 0, NULL, NULL,
4.116 + g_cclosure_marshal_VOID__VOID,
4.117 + G_TYPE_NONE, 0);
4.118 +
4.119 + g_mencoder_signals[EOS] =
4.120 + g_signal_new ("eos",
4.121 + G_OBJECT_CLASS_TYPE (object_class),
4.122 + G_SIGNAL_RUN_FIRST,
4.123 + 0, NULL, NULL,
4.124 + g_cclosure_marshal_VOID__VOID,
4.125 + G_TYPE_NONE, 0);
4.126 +
4.127 +
4.128 + g_mencoder_signals[ERROR] =
4.129 + g_signal_new ("error",
4.130 + G_OBJECT_CLASS_TYPE (object_class),
4.131 + G_SIGNAL_RUN_FIRST,
4.132 + 0, NULL, NULL,
4.133 + g_cclosure_marshal_VOID__STRING,
4.134 + G_TYPE_NONE, 1, G_TYPE_STRING);
4.135 +}
4.136 +
4.137 +static void
4.138 +g_mencoder_init (GMencoder *self)
4.139 +{
4.140 +}
4.141 +
4.142 +static void
4.143 +g_mencoder_dispose (GObject *object)
4.144 +{
4.145 +}
4.146 +
4.147 +static void
4.148 +g_mencoder_finalize (GObject *object)
4.149 +{
4.150 + g_mencoder_close_stream (G_MENCODER (object));
4.151 +}
4.152 +
4.153 +GMencoder*
4.154 +g_mencoder_new (void)
4.155 +{
4.156 + return g_object_new (G_TYPE_MENCODER, NULL);
4.157 +}
4.158 +
4.159 +static void
4.160 +_obj_set_prop (GObject *obj,
4.161 + const gchar *prop_name,
4.162 + const gchar *prop_val)
4.163 +{
4.164 + GValue p = {0};
4.165 + GValue v = {0};
4.166 + GParamSpec *s = NULL;
4.167 + GObjectClass *k = G_OBJECT_GET_CLASS (obj);
4.168 +
4.169 +
4.170 + g_value_init (&v, G_TYPE_STRING);
4.171 + g_value_set_string (&v, prop_val);
4.172 +
4.173 + g_debug ("PROP [%s] VAL [%s]", prop_name, prop_val);
4.174 +
4.175 + s = g_object_class_find_property (k, prop_name);
4.176 + if (s == NULL) {
4.177 + g_print ("Invalid property name: %s\n", prop_name);
4.178 + return;
4.179 + }
4.180 +
4.181 + g_value_init (&p, s->value_type);
4.182 + switch (s->value_type)
4.183 + {
4.184 + case G_TYPE_INT:
4.185 + g_value_set_int (&p, atoi (prop_val));
4.186 + break;
4.187 + case G_TYPE_STRING:
4.188 + g_value_set_string (&p, prop_val);
4.189 + break;
4.190 + default:
4.191 + return;
4.192 + }
4.193 +
4.194 + g_object_set_property (obj, prop_name, &p);
4.195 + g_value_unset (&v);
4.196 + g_value_unset (&p);
4.197 +}
4.198 +
4.199 +static GstElement*
4.200 +_create_element_with_prop (const gchar* factory_name,
4.201 + const gchar* element_name,
4.202 + gchar** prop)
4.203 +{
4.204 + GstElement *ret;
4.205 + int i;
4.206 +
4.207 +
4.208 + g_debug ("SET OBJ [%s]", factory_name);
4.209 + ret = gst_element_factory_make (factory_name, element_name);
4.210 + if (ret == NULL)
4.211 + return NULL;
4.212 +
4.213 + if (prop != NULL) {
4.214 + for (i=0; i < g_strv_length (prop); i++) {
4.215 + char** v = g_strsplit(prop[i], "=", 2);
4.216 + if (g_strv_length (v) == 2) {
4.217 + _obj_set_prop (G_OBJECT (ret), v[0], v[1]);
4.218 + }
4.219 + g_strfreev (v);
4.220 + }
4.221 + }
4.222 +
4.223 + return ret;
4.224 +
4.225 +}
4.226 +
4.227 +static GstElement*
4.228 +_create_audio_bin (GMencoder* self,
4.229 + const gchar* encode,
4.230 + gchar** encode_prop,
4.231 + gint rate)
4.232 +{
4.233 + GstElement *abin = NULL;
4.234 + GstElement *aqueue = NULL;
4.235 + GstElement *aconvert = NULL;
4.236 + GstElement *aencode = NULL;
4.237 + GstElement *aqueue_src = NULL;
4.238 + GstPad *apad = NULL;
4.239 +
4.240 + //audio/x-raw-int ! queue ! audioconvert ! faac ! rtpmp4gpay ! udpsink name=upd_audio host=224.0.0.1 port=5002
4.241 + abin = gst_bin_new ("abin");
4.242 + aqueue = gst_element_factory_make ("queue", "aqueue");
4.243 + aconvert= gst_element_factory_make ("audioconvert", "aconvert");
4.244 + aencode = _create_element_with_prop ((encode ? encode : "lame"), "aencode", encode_prop);
4.245 + aqueue_src= gst_element_factory_make ("queue", "aqueue_src");
4.246 +
4.247 + if ((abin == NULL) || (aqueue == NULL) || (aconvert == NULL)
4.248 + || (aencode == NULL) || (aqueue_src == NULL)) {
4.249 + g_warning ("Audio elements not found");
4.250 + goto error;
4.251 + }
4.252 +
4.253 + gst_bin_add_many (GST_BIN (abin), aqueue, aconvert, aencode, aqueue_src, NULL);
4.254 + gst_element_link_many (aqueue, aconvert, aencode, aqueue_src, NULL);
4.255 +
4.256 + //TODO: apply audio rate
4.257 +
4.258 + // ghost pad the audio bin
4.259 + apad = gst_element_get_pad (aqueue, "sink");
4.260 + gst_element_add_pad (abin, gst_ghost_pad_new("sink", apad));
4.261 + gst_object_unref (apad);
4.262 +
4.263 + apad = gst_element_get_pad (aqueue_src, "src");
4.264 + gst_element_add_pad (abin, gst_ghost_pad_new("src", apad));
4.265 + gst_object_unref (apad);
4.266 +
4.267 + return abin;
4.268 +error:
4.269 + if (abin != NULL)
4.270 + gst_object_unref (abin);
4.271 +
4.272 + if (aqueue != NULL)
4.273 + gst_object_unref (aqueue);
4.274 +
4.275 + if (aconvert != NULL)
4.276 + gst_object_unref (aconvert);
4.277 +
4.278 + if (aencode != NULL)
4.279 + gst_object_unref (aencode);
4.280 +
4.281 + if (aqueue_src != NULL)
4.282 + gst_object_unref (aqueue_src);
4.283 +
4.284 + if (apad != NULL)
4.285 + gst_object_unref (apad);
4.286 +
4.287 + return NULL;
4.288 +}
4.289 +
4.290 +
4.291 +
4.292 +
4.293 +//queue ! videoscale ! video/x-raw-yuv,width=240,height=144 ! colorspace ! rate ! encode ! queue
4.294 +static GstElement*
4.295 +_create_video_bin (GMencoder* self,
4.296 + const gchar* encode,
4.297 + gchar** encode_prop,
4.298 + gdouble fps,
4.299 + gint rate,
4.300 + guint width,
4.301 + guint height)
4.302 +{
4.303 + GstElement *vbin = NULL;
4.304 + GstElement *vqueue = NULL;
4.305 + GstElement* vqueue_src = NULL;
4.306 + GstElement *vcolorspace = NULL;
4.307 + GstElement *vencode = NULL;
4.308 + GstElement *vrate = NULL;
4.309 + GstPad *vpad = NULL;
4.310 +
4.311 + vbin = gst_bin_new ("vbin");
4.312 + vqueue = gst_element_factory_make ("queue", "vqueue");
4.313 + vcolorspace = gst_element_factory_make ("ffmpegcolorspace", "colorspace");
4.314 + vencode = _create_element_with_prop ((encode ? encode : "ffenc_mpeg1video"), "vencode", encode_prop);
4.315 + vrate = gst_element_factory_make ("videorate", "vrate");
4.316 + vqueue_src = gst_element_factory_make ("queue", "queue_src");
4.317 +
4.318 + if ((vbin == NULL) || (vqueue == NULL) || (vcolorspace == NULL)
4.319 + || (vencode == NULL) || (vqueue_src == NULL)) {
4.320 + g_warning ("Video elements not found");
4.321 + goto error;
4.322 + }
4.323 +
4.324 + gst_bin_add_many (GST_BIN (vbin), vqueue, vcolorspace, vencode, vqueue_src, NULL);
4.325 +
4.326 +
4.327 + if ((width > 0) && (height > 0)) {
4.328 + //Scalling video
4.329 + GstCaps *vcaps;
4.330 + GstElement *vscale = gst_element_factory_make ("videoscale", "vscale");
4.331 +
4.332 + gst_bin_add (GST_BIN (vbin), vscale);
4.333 +
4.334 + vcaps = gst_caps_new_simple ("video/x-raw-yuv",
4.335 + "width", G_TYPE_INT, width,
4.336 + "height", G_TYPE_INT, height,
4.337 + NULL);
4.338 +
4.339 + gst_element_link (vqueue, vscale);
4.340 +
4.341 + if (gst_element_link_filtered (vscale, vcolorspace, vcaps) == FALSE) {
4.342 + g_warning ("Fail to resize video");
4.343 + gst_object_unref (vcaps);
4.344 + gst_object_unref (vscale);
4.345 + goto error;
4.346 + }
4.347 + gst_caps_unref (vcaps);
4.348 + } else {
4.349 + gst_element_link (vqueue, vcolorspace);
4.350 + }
4.351 +
4.352 + if (fps > 0) {
4.353 + //Changing the video fps
4.354 + GstCaps *vcaps;
4.355 +
4.356 + gst_bin_add (GST_BIN (vbin), vrate);
4.357 +
4.358 + if (gst_element_link (vcolorspace, vrate) == FALSE) {
4.359 + g_warning ("Fail to link video elements");
4.360 + goto error;
4.361 + }
4.362 +
4.363 + vcaps = gst_caps_new_simple ("video/x-raw-yuv",
4.364 + "framerate", GST_TYPE_FRACTION, (int) (fps * 1000), 1000, NULL);
4.365 +
4.366 + if (gst_element_link_filtered (vrate, vencode, vcaps) == FALSE) {
4.367 + g_warning ("Fail to link vrate with vencode.");
4.368 + goto error;
4.369 + }
4.370 + gst_caps_unref (vcaps);
4.371 + } else {
4.372 + if (gst_element_link (vcolorspace, vencode) == FALSE) {
4.373 + g_warning ("Fail to link colorspace and video encode element.");
4.374 + goto error;
4.375 + }
4.376 + }
4.377 +
4.378 +
4.379 + gst_element_link (vencode, vqueue_src);
4.380 +
4.381 + // ghost pad the video bin
4.382 + vpad = gst_element_get_pad (vqueue, "sink");
4.383 + gst_element_add_pad (vbin, gst_ghost_pad_new ("sink", vpad));
4.384 + gst_object_unref (vpad);
4.385 +
4.386 + vpad = gst_element_get_pad (vqueue_src, "src");
4.387 + gst_element_add_pad (vbin, gst_ghost_pad_new ("src", vpad));
4.388 + gst_object_unref (vpad);
4.389 +
4.390 + return vbin;
4.391 +
4.392 +error:
4.393 + if (vpad != NULL)
4.394 + gst_object_unref (vpad);
4.395 +
4.396 + if (vbin != NULL)
4.397 + gst_object_unref (vbin);
4.398 +
4.399 + if (vqueue != NULL)
4.400 + gst_object_unref (vqueue);
4.401 +
4.402 + if (vencode != NULL)
4.403 + gst_object_unref (vencode);
4.404 +
4.405 + if (vqueue_src != NULL)
4.406 + gst_object_unref (vqueue_src);
4.407 +
4.408 + if (vcolorspace != NULL)
4.409 + gst_object_unref (vcolorspace);
4.410 +
4.411 + return NULL;
4.412 +}
4.413 +
4.414 +
4.415 +gboolean
4.416 +g_mencoder_setup_stream (GMencoder *self,
4.417 + const gchar* uri,
4.418 + const gchar* video_encode,
4.419 + gchar** video_encode_prop,
4.420 + gdouble video_fps,
4.421 + gdouble video_rate,
4.422 + guint video_width,
4.423 + guint video_height,
4.424 + const gchar* audio_encode,
4.425 + gchar** audio_encode_prop,
4.426 + guint audio_rate,
4.427 + const gchar* sink_name,
4.428 + gchar** sink_prop)
4.429 +{
4.430 + GstBus *bus = NULL;
4.431 + GstElement *pipe = NULL;
4.432 + GstElement *fdsink = NULL;
4.433 + GstElement *mux = NULL;
4.434 + GstElement *decode = NULL;
4.435 + GstElement *src = NULL;
4.436 + GstElement *abin = NULL;
4.437 + GstElement *vbin = NULL;
4.438 + GstPad *aux_pad = NULL;
4.439 + GstPad *mux_pad = NULL;
4.440 +
4.441 + GMencoderPrivate *priv = G_MENCODER_GET_PRIVATE (self);
4.442 +
4.443 + pipe = gst_pipeline_new ("pipe");
4.444 + src = gst_element_make_from_uri (GST_URI_SRC, uri, "src");
4.445 + if (src == NULL)
4.446 + goto error;
4.447 +
4.448 + decode = gst_element_factory_make ("decodebin2", "decode");
4.449 + if (decode == NULL)
4.450 + goto error;
4.451 +
4.452 + mux = gst_element_factory_make ("ffmux_mpeg", "mux");
4.453 + if (mux == NULL)
4.454 + goto error;
4.455 +
4.456 + fdsink = _create_element_with_prop (sink_name, "sink", sink_prop);
4.457 + if (fdsink == NULL)
4.458 + goto error;
4.459 +
4.460 + abin = _create_audio_bin (self, audio_encode, audio_encode_prop, audio_rate);
4.461 + if (abin == NULL)
4.462 + goto error;
4.463 +
4.464 + vbin = _create_video_bin (self, video_encode, video_encode_prop, video_fps, video_rate, video_width, video_height);
4.465 + if (vbin == NULL)
4.466 + goto error;
4.467 +
4.468 + // Finish Pipe
4.469 + gst_bin_add_many (GST_BIN (pipe), src, decode, abin, vbin, mux, fdsink, NULL);
4.470 + gst_element_link (src, decode);
4.471 +
4.472 + //Link bins with mux
4.473 + aux_pad = gst_element_get_pad (abin, "src");
4.474 + mux_pad = gst_element_get_pad (mux, "audio_0");
4.475 + GstPadLinkReturn ret = gst_pad_link (aux_pad, mux_pad);
4.476 + if (ret != GST_PAD_LINK_OK) {
4.477 + g_warning ("Fail link audio and mux: %d", ret);
4.478 + goto error;
4.479 +
4.480 + }
4.481 + gst_object_unref (aux_pad);
4.482 + gst_object_unref (mux_pad);
4.483 +
4.484 + aux_pad = gst_element_get_pad (vbin, "src");
4.485 + mux_pad = gst_element_get_pad (mux, "video_0");
4.486 + ret = gst_pad_link (aux_pad, mux_pad);
4.487 + if (ret != GST_PAD_LINK_OK) {
4.488 + g_warning ("Fail link video and mux: %d", ret);
4.489 + goto error;
4.490 + }
4.491 + gst_object_unref (aux_pad);
4.492 + gst_object_unref (mux_pad);
4.493 + aux_pad = NULL;
4.494 + mux_pad = NULL;
4.495 +
4.496 + //Link mux with sink
4.497 + gst_element_link (mux, fdsink);
4.498 +
4.499 + g_signal_connect (G_OBJECT (decode),
4.500 + "new-decoded-pad",
4.501 + G_CALLBACK (_decodebin_new_pad_cb),
4.502 + self);
4.503 +
4.504 + g_signal_connect (G_OBJECT (decode),
4.505 + "unknown-type",
4.506 + G_CALLBACK (_decodebin_unknown_type_cb),
4.507 + self);
4.508 +
4.509 +
4.510 + bus = gst_pipeline_get_bus (GST_PIPELINE (pipe));
4.511 + gst_bus_add_watch (bus, _pipeline_bus_cb, self);
4.512 + gst_object_unref (bus);
4.513 +
4.514 +
4.515 + priv->pipe = pipe;
4.516 + priv->abin = abin;
4.517 + priv->vbin = vbin;
4.518 + priv->sink = fdsink;
4.519 + priv->ready = FALSE;
4.520 +
4.521 + gst_element_set_state (pipe, GST_STATE_PAUSED);
4.522 + return TRUE;
4.523 +
4.524 +error:
4.525 + g_warning ("Invalid uri");
4.526 +
4.527 + if (pipe != NULL) {
4.528 + gst_object_unref (pipe);
4.529 + }
4.530 +
4.531 + if (src != NULL) {
4.532 + gst_object_unref (src);
4.533 + }
4.534 +
4.535 + if (mux != NULL) {
4.536 + gst_object_unref (mux);
4.537 + }
4.538 +
4.539 + if (mux_pad != NULL) {
4.540 + gst_object_unref (mux_pad);
4.541 + }
4.542 +
4.543 + if (aux_pad != NULL) {
4.544 + gst_object_unref (mux_pad);
4.545 + }
4.546 +
4.547 + if (fdsink != NULL) {
4.548 + gst_object_unref (fdsink);
4.549 + }
4.550 +
4.551 + if (abin != NULL) {
4.552 + gst_object_unref (abin);
4.553 + }
4.554 +
4.555 + if (vbin != NULL) {
4.556 + gst_object_unref (vbin);
4.557 + }
4.558 +
4.559 + return FALSE;
4.560 +}
4.561 +
4.562 +gboolean
4.563 +g_mencoder_play_stream (GMencoder *self)
4.564 +{
4.565 + GMencoderPrivate *priv = G_MENCODER_GET_PRIVATE (self);
4.566 +
4.567 + g_return_val_if_fail (priv->ready == TRUE, FALSE);
4.568 +
4.569 + if (gst_element_set_state (priv->pipe, GST_STATE_PLAYING) != GST_STATE_CHANGE_FAILURE) {
4.570 + g_debug ("PLAYING");
4.571 + return TRUE;
4.572 + }
4.573 + return FALSE;
4.574 +}
4.575 +
4.576 +gboolean
4.577 +g_mencoder_pause_stream (GMencoder *self)
4.578 +{
4.579 + GMencoderPrivate *priv = G_MENCODER_GET_PRIVATE (self);
4.580 +
4.581 + g_return_val_if_fail (priv->ready == TRUE, FALSE);
4.582 +
4.583 + if (gst_element_set_state (priv->pipe, GST_STATE_PAUSED) != GST_STATE_CHANGE_FAILURE) {
4.584 + g_debug ("PAUSED");
4.585 + return TRUE;
4.586 + }
4.587 + return FALSE;
4.588 +}
4.589 +
4.590 +void
4.591 +g_mencoder_close_stream (GMencoder *self)
4.592 +{
4.593 +
4.594 + GMencoderPrivate *priv = G_MENCODER_GET_PRIVATE (self);
4.595 +
4.596 + g_return_if_fail (priv->ready == TRUE);
4.597 +
4.598 + gst_element_set_state (priv->pipe, GST_STATE_NULL);
4.599 + gst_object_unref (priv->pipe);
4.600 + priv->pipe = NULL;
4.601 + priv->abin = NULL;
4.602 + priv->vbin = NULL;
4.603 + priv->sink = NULL;
4.604 + priv->ready = FALSE;
4.605 +}
4.606 +
4.607 +static gboolean
4.608 +_pipeline_bus_cb (GstBus *bus,
4.609 + GstMessage *msg,
4.610 + gpointer user_data)
4.611 +{
4.612 + switch (GST_MESSAGE_TYPE (msg))
4.613 + {
4.614 + case GST_MESSAGE_STATE_CHANGED:
4.615 + {
4.616 + GstState oldstate;
4.617 + GstState newstate;
4.618 + GstState pendingstate;
4.619 +
4.620 + GMencoderPrivate *priv = G_MENCODER_GET_PRIVATE (user_data);
4.621 +
4.622 + gst_message_parse_state_changed (msg, &oldstate,
4.623 + &newstate, &pendingstate);
4.624 +
4.625 + if (pendingstate != GST_STATE_VOID_PENDING)
4.626 + break;
4.627 +
4.628 + if ((oldstate == GST_STATE_READY) &&
4.629 + (newstate == GST_STATE_PAUSED)) {
4.630 + if (priv->ready)
4.631 + g_signal_emit (user_data, g_mencoder_signals[PAUSED], 0);
4.632 + else {
4.633 + priv->ready = TRUE;
4.634 + g_signal_emit (user_data, g_mencoder_signals[READY], 0);
4.635 + }
4.636 + } else if ((oldstate == GST_STATE_PAUSED) &&
4.637 + (newstate == GST_STATE_PLAYING)) {
4.638 + g_signal_emit (user_data, g_mencoder_signals[PLAYING], 0);
4.639 + } else if ((oldstate == GST_STATE_READY) &&
4.640 + (newstate == GST_STATE_NULL)) {
4.641 + g_signal_emit (user_data, g_mencoder_signals[STOPED], 0);
4.642 + }
4.643 + break;
4.644 + }
4.645 + case GST_MESSAGE_ERROR:
4.646 + {
4.647 + GError *error;
4.648 + gchar *debug;
4.649 + gchar *err_str;
4.650 +
4.651 + gst_message_parse_error (msg, &error, &debug);
4.652 + err_str = g_strdup_printf ("Error [%d] %s (%s)", error->code,
4.653 + error->message,
4.654 + debug);
4.655 + g_signal_emit (user_data, g_mencoder_signals[ERROR], 0, err_str);
4.656 + g_free (err_str);
4.657 + g_clear_error (&error);
4.658 + g_free (debug);
4.659 + break;
4.660 + }
4.661 +
4.662 + case GST_MESSAGE_EOS:
4.663 + g_signal_emit (user_data, g_mencoder_signals[EOS], 0);
4.664 + break;
4.665 + default:
4.666 + break;
4.667 + }
4.668 + return TRUE;
4.669 +}
4.670 +
4.671 +static void
4.672 +_decodebin_new_pad_cb (GstElement* object,
4.673 + GstPad* pad,
4.674 + gboolean flag,
4.675 + gpointer user_data)
4.676 +{
4.677 + GstCaps *caps;
4.678 + gchar *str_caps = NULL;
4.679 + GMencoderPrivate *priv = G_MENCODER_GET_PRIVATE (user_data);
4.680 +
4.681 + caps = gst_pad_get_caps (pad);
4.682 + str_caps = gst_caps_to_string (caps);
4.683 + g_debug ("CAPS : %s", str_caps);
4.684 +
4.685 + if (strstr (str_caps, "audio") != NULL) {
4.686 + GstPad *apad = gst_element_get_pad (priv->abin, "sink");
4.687 + gst_pad_link (pad, apad);
4.688 + gst_object_unref (apad);
4.689 + } else if (strstr (str_caps, "video") != NULL) {
4.690 + GstPad *vpad = gst_element_get_pad (priv->vbin, "sink");
4.691 + gst_pad_link (pad, vpad);
4.692 + gst_object_unref (vpad);
4.693 + } else {
4.694 + g_warning ("invalid caps %s", str_caps);
4.695 + }
4.696 +
4.697 + g_free (str_caps);
4.698 + gst_caps_unref (caps);
4.699 +}
4.700 +
4.701 +static void
4.702 +_decodebin_unknown_type_cb (GstElement* object,
4.703 + GstPad* pad,
4.704 + GstCaps* caps,
4.705 + gpointer user_data)
4.706 +{
4.707 + g_warning ("Unknown Type");
4.708 +}
5.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
5.2 +++ b/gmyth-stream/gmemcoder/src/gmencoder.h Mon Apr 23 21:05:21 2007 +0100
5.3 @@ -0,0 +1,55 @@
5.4 +#ifndef __G_MENCODER_H__
5.5 +#define __G_MENCODER_H__
5.6 +
5.7 +#include <glib-object.h>
5.8 +
5.9 +G_BEGIN_DECLS
5.10 +
5.11 +typedef struct _GMencoder GMencoder;
5.12 +typedef struct _GMencoderClass GMencoderClass;
5.13 +
5.14 +struct _GMencoderClass {
5.15 + GObjectClass parent_class;
5.16 +};
5.17 +
5.18 +struct _GMencoder {
5.19 + GObject parent;
5.20 +};
5.21 +
5.22 +/* TYPE MACROS */
5.23 +#define G_TYPE_MENCODER \
5.24 + (g_mencoder_get_type())
5.25 +#define G_MENCODER(obj) \
5.26 + (G_TYPE_CHECK_INSTANCE_CAST((obj), G_TYPE_MENCODER, GMencoder))
5.27 +#define G_MENCODER_CLASS(klass) \
5.28 + (G_TYPE_CHECK_CLASS_CAST((klass), G_TYPE_MENCODER, GMencoderClass))
5.29 +#define G_IS_MENCODER(obj) \
5.30 + (G_TYPE_CHECK_INSTANCE_TYPE((obj), G_TYPE_MENCODER))
5.31 +#define G_IS_MENCODER_CLASS(klass) \
5.32 + (G_TYPE_CHECK_CLASS_TYPE((klass), G_TYPE_MENCODER))
5.33 +#define G_MENCODER_GET_CLASS(obj) \
5.34 + (G_TYPE_INSTANCE_GET_CLASS ((obj), G_TYPE_MENCODER, GMencoderClass))
5.35 +
5.36 +
5.37 +GType g_mencoder_get_type (void);
5.38 +GMencoder* g_mencoder_new (void);
5.39 +gboolean g_mencoder_setup_stream (GMencoder *self,
5.40 + const gchar* uri,
5.41 + const gchar* video_encode,
5.42 + gchar** video_encode_prop,
5.43 + gdouble video_fps,
5.44 + gdouble video_rate,
5.45 + guint video_width,
5.46 + guint video_height,
5.47 + const gchar* audio_encode,
5.48 + gchar** audio_encode_prop,
5.49 + guint audio_rate,
5.50 + const gchar* output_element,
5.51 + gchar** output_prop);
5.52 +gboolean g_mencoder_play_stream (GMencoder *self);
5.53 +gboolean g_mencoder_pause_stream (GMencoder *self);
5.54 +void g_mencoder_close_stream (GMencoder *self);
5.55 +
5.56 +G_END_DECLS
5.57 +
5.58 +#endif
6.1 --- a/gmyth-stream/gmemcoder/src/main.c Mon Apr 23 19:16:24 2007 +0100
6.2 +++ b/gmyth-stream/gmemcoder/src/main.c Mon Apr 23 21:05:21 2007 +0100
6.3 @@ -6,11 +6,24 @@
6.4 #include <gst/gst.h>
6.5 #include <glib.h>
6.6
6.7 -#include "gmemcoder.h"
6.8 +#include "gmencoder.h"
6.9
6.10 -//#define FILE_OUT 1
6.11 +#define FILE_OUT 1
6.12
6.13 static GMainLoop *mainloop = NULL;
6.14 +/* Options */
6.15 +static gchar* input_file = NULL;
6.16 +static gchar* video_encode = NULL;
6.17 +static gchar* video_opts = NULL;
6.18 +static gdouble video_fps = 0.0;
6.19 +static gint video_rate = 0;
6.20 +static gint video_width = 0;
6.21 +static gint video_height = 0;
6.22 +static gchar* audio_encode = NULL;
6.23 +static gchar* audio_opts = NULL;
6.24 +static double audio_rate = 0.0;
6.25 +static gchar* output_element = NULL;
6.26 +static gchar* output_opts = NULL;
6.27
6.28 static void
6.29 _mencoder_ready_cb (GMencoder *mencoder, gpointer data)
6.30 @@ -59,22 +72,64 @@
6.31 {
6.32 GMencoder *coder;
6.33 GIOChannel *ch;
6.34 + gchar **oopts;
6.35 + gchar **vopts;
6.36 + gchar **aopts;
6.37 +
6.38 + GOptionContext *context;
6.39 + static const GOptionEntry options [] = {
6.40 + {"input-file", 'i', 0, G_OPTION_ARG_STRING, &input_file, "Input File", NULL},
6.41 + {"video-encode", 0, 0, G_OPTION_ARG_STRING, &video_encode, "GstElementName for used to video encode", NULL},
6.42 + {"video-opts", 0, 0, G_OPTION_ARG_STRING, &video_opts, "Properties to set on video element", NULL},
6.43 + {"video-fps", 0, 0, G_OPTION_ARG_DOUBLE, &video_fps, "Video FPS", NULL},
6.44 + {"video-rate", 0, 0, G_OPTION_ARG_INT, &video_rate, "Video rate", NULL},
6.45 + {"video-width", 0, 0, G_OPTION_ARG_INT, &video_width, "Video width", NULL},
6.46 + {"video-height", 0, 0, G_OPTION_ARG_INT, &video_height, "Video height", NULL},
6.47 + {"audio-encode", 0, 0, G_OPTION_ARG_STRING, &audio_encode, "GstElementName for use to audio encode", NULL},
6.48 + {"audio-opts", 0, 0, G_OPTION_ARG_STRING, &audio_opts, "Properties to set on audio element", NULL},
6.49 + {"audio-rate", 0, 0, G_OPTION_ARG_INT, &audio_rate, "Audio rate", NULL},
6.50 + {"output-element", 0, 0, G_OPTION_ARG_STRING, &output_element,"GstElementName for use to output", NULL},
6.51 + {"output-opts", 0, 0, G_OPTION_ARG_STRING, &output_opts, "Properties to set on output element", NULL},
6.52 + { NULL }
6.53 + };
6.54
6.55 g_type_init ();
6.56 + g_thread_init (NULL);
6.57 +
6.58 + //g_set_prgname ("gmemcoder");
6.59 + context = g_option_context_new (NULL);
6.60 + g_option_context_set_help_enabled (context, TRUE);
6.61 + g_option_context_add_main_entries (context, options, NULL);
6.62 + g_option_context_add_group (context, gst_init_get_option_group ());
6.63 + g_option_context_parse (context, &argc, &argv, NULL);
6.64 +
6.65 gst_init (&argc, &argv);
6.66
6.67 - g_set_prgname ("gmemcoder");
6.68 + if (output_element == NULL) {
6.69 + g_print ("You need specify output-element name.\nTry --help for more information.\n");
6.70 + return 1;
6.71 + }
6.72 +
6.73 + if (input_file == NULL) {
6.74 + g_print ("You need specify input file\nTry --help for more information.\n");
6.75 + }
6.76
6.77 coder = g_mencoder_new ();
6.78 ch = g_io_channel_unix_new (0);
6.79
6.80 -#ifdef FILE_OUT
6.81 - int fd = open (argv[2], O_WRONLY | O_CREAT | O_TRUNC);
6.82 - g_debug ("FD %d", fd);
6.83 - g_mencoder_setup_stream (coder, argv[1], 320, 288, fd);
6.84 -#else
6.85 - g_mencoder_setup_stream (coder, argv[1], 320, 288, atoi (argv[2]));
6.86 -#endif
6.87 + aopts = g_strsplit (audio_opts, ",", 0);
6.88 + vopts = g_strsplit (video_opts, ",", 0);
6.89 + oopts = g_strsplit (output_opts, ",", 0);
6.90 +
6.91 + g_mencoder_setup_stream (coder,
6.92 + input_file,
6.93 + video_encode, vopts, video_fps, video_rate, video_width, video_height,
6.94 + audio_encode, aopts, audio_rate,
6.95 + output_element, oopts);
6.96 +
6.97 + g_strfreev (aopts);
6.98 + g_strfreev (vopts);
6.99 + g_strfreev (oopts);
6.100
6.101 mainloop = g_main_loop_new (NULL, FALSE);
6.102 g_io_add_watch (ch, G_IO_IN, _io_channel_cb, coder);
6.103 @@ -97,9 +152,5 @@
6.104
6.105 g_main_loop_run (mainloop);
6.106
6.107 -#if FILE_OUT
6.108 - close (fd);
6.109 -#endif
6.110 -
6.111 return 0;
6.112 }