1.1 --- a/gmyth-stream/gmemcoder/src/gmemcoder.c Mon Apr 23 19:16:24 2007 +0100
1.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
1.3 @@ -1,551 +0,0 @@
1.4 -#ifdef HAVE_CONFIG_H
1.5 -#include "config.h"
1.6 -#endif
1.7 -
1.8 -#include <glib.h>
1.9 -#include <gst/gst.h>
1.10 -#include <string.h>
1.11 -
1.12 -#include "gmemcoder.h"
1.13 -
1.14 -#define G_MENCODER_GET_PRIVATE(obj) \
1.15 - (G_TYPE_INSTANCE_GET_PRIVATE ((obj), G_TYPE_MENCODER, GMencoderPrivate))
1.16 -
1.17 -
1.18 -typedef struct _GMencoderPrivate GMencoderPrivate;
1.19 -
1.20 -struct _GMencoderPrivate
1.21 -{
1.22 - GstElement *pipe;
1.23 - GstElement *abin;
1.24 - GstElement *vbin;
1.25 - GstElement *sink;
1.26 - gboolean ready;
1.27 -};
1.28 -
1.29 -enum {
1.30 - READY,
1.31 - PAUSED,
1.32 - PLAYING,
1.33 - STOPED,
1.34 - EOS,
1.35 - ERROR,
1.36 - LAST_SIGNAL
1.37 -};
1.38 -
1.39 -static void g_mencoder_class_init (GMencoderClass *klass);
1.40 -static void g_mencoder_init (GMencoder *object);
1.41 -static void g_mencoder_dispose (GObject *object);
1.42 -static void g_mencoder_finalize (GObject *object);
1.43 -static gboolean
1.44 - _pipeline_bus_cb (GstBus *bus,
1.45 - GstMessage *msg,
1.46 - gpointer user_data);
1.47 -
1.48 -static void _decodebin_new_pad_cb (GstElement* object,
1.49 - GstPad* pad,
1.50 - gboolean flag,
1.51 - gpointer user_data);
1.52 -static void _decodebin_unknown_type_cb (GstElement* object,
1.53 - GstPad* pad,
1.54 - GstCaps* caps,
1.55 - gpointer user_data);
1.56 -
1.57 -static guint g_mencoder_signals[LAST_SIGNAL] = { 0 };
1.58 -
1.59 -G_DEFINE_TYPE(GMencoder, g_mencoder, G_TYPE_OBJECT)
1.60 -
1.61 -static void
1.62 -g_mencoder_class_init (GMencoderClass *klass)
1.63 -{
1.64 - GObjectClass *object_class;
1.65 -
1.66 - object_class = (GObjectClass *) klass;
1.67 -
1.68 - g_type_class_add_private (klass, sizeof (GMencoderPrivate));
1.69 -
1.70 - object_class->dispose = g_mencoder_dispose;
1.71 - object_class->finalize = g_mencoder_finalize;
1.72 -
1.73 - g_mencoder_signals[READY] =
1.74 - g_signal_new ("ready",
1.75 - G_OBJECT_CLASS_TYPE (object_class),
1.76 - G_SIGNAL_RUN_FIRST,
1.77 - 0, NULL, NULL,
1.78 - g_cclosure_marshal_VOID__VOID,
1.79 - G_TYPE_NONE, 0);
1.80 -
1.81 - g_mencoder_signals[PAUSED] =
1.82 - g_signal_new ("paused",
1.83 - G_OBJECT_CLASS_TYPE (object_class),
1.84 - G_SIGNAL_RUN_FIRST,
1.85 - 0, NULL, NULL,
1.86 - g_cclosure_marshal_VOID__VOID,
1.87 - G_TYPE_NONE, 0);
1.88 -
1.89 - g_mencoder_signals[PLAYING] =
1.90 - g_signal_new ("playing",
1.91 - G_OBJECT_CLASS_TYPE (object_class),
1.92 - G_SIGNAL_RUN_FIRST,
1.93 - 0, NULL, NULL,
1.94 - g_cclosure_marshal_VOID__VOID,
1.95 - G_TYPE_NONE, 0);
1.96 -
1.97 - g_mencoder_signals[STOPED] =
1.98 - g_signal_new ("stoped",
1.99 - G_OBJECT_CLASS_TYPE (object_class),
1.100 - G_SIGNAL_RUN_FIRST,
1.101 - 0, NULL, NULL,
1.102 - g_cclosure_marshal_VOID__VOID,
1.103 - G_TYPE_NONE, 0);
1.104 -
1.105 - g_mencoder_signals[EOS] =
1.106 - g_signal_new ("eos",
1.107 - G_OBJECT_CLASS_TYPE (object_class),
1.108 - G_SIGNAL_RUN_FIRST,
1.109 - 0, NULL, NULL,
1.110 - g_cclosure_marshal_VOID__VOID,
1.111 - G_TYPE_NONE, 0);
1.112 -
1.113 -
1.114 - g_mencoder_signals[ERROR] =
1.115 - g_signal_new ("error",
1.116 - G_OBJECT_CLASS_TYPE (object_class),
1.117 - G_SIGNAL_RUN_FIRST,
1.118 - 0, NULL, NULL,
1.119 - g_cclosure_marshal_VOID__STRING,
1.120 - G_TYPE_NONE, 1, G_TYPE_STRING);
1.121 -}
1.122 -
1.123 -static void
1.124 -g_mencoder_init (GMencoder *self)
1.125 -{
1.126 -}
1.127 -
1.128 -static void
1.129 -g_mencoder_dispose (GObject *object)
1.130 -{
1.131 -}
1.132 -
1.133 -static void
1.134 -g_mencoder_finalize (GObject *object)
1.135 -{
1.136 - g_mencoder_close_stream (G_MENCODER (object));
1.137 -}
1.138 -
1.139 -GMencoder*
1.140 -g_mencoder_new (void)
1.141 -{
1.142 - return g_object_new (G_TYPE_MENCODER, NULL);
1.143 -}
1.144 -
1.145 -
1.146 -gboolean
1.147 -g_mencoder_setup_stream (GMencoder *self,
1.148 - const gchar* uri,
1.149 - guint width, guint height,
1.150 - gint out_fd)
1.151 -{
1.152 - GstBus *bus = NULL;
1.153 - GstElement *pipe = NULL;
1.154 - GstElement *decode = NULL;
1.155 - GstElement *fdsink = NULL;
1.156 - GstElement *mux = NULL;
1.157 -
1.158 - GstCaps *vscale_caps = NULL;
1.159 - GstPad *asinkpad = NULL;
1.160 - GstPad *vsinkpad = NULL;
1.161 - GstPad *video_src_pad = NULL;
1.162 - GstPad *audio_src_pad = NULL;
1.163 - GstPad *mux_pad = NULL;
1.164 - GstElement *src = NULL;
1.165 - GstElement *vbin, *vqueue, *vcolorspace, *vscale, *vrate, *vencode, *vqueue_src;
1.166 - GstElement *abin, *aqueue, *aconvert, *aencode, *aqueue_src;
1.167 - GMencoderPrivate *priv = G_MENCODER_GET_PRIVATE (self);
1.168 -
1.169 - vbin = vqueue = vscale = vrate = vencode = vqueue_src = NULL;
1.170 - abin = aqueue = aconvert = aencode = aqueue_src = NULL;
1.171 -
1.172 - pipe = gst_pipeline_new ("pipe");
1.173 - src = gst_element_make_from_uri (GST_URI_SRC, uri, "src");
1.174 - if (src == NULL)
1.175 - goto error;
1.176 -
1.177 - decode = gst_element_factory_make ("decodebin", "decode");
1.178 - if (decode == NULL)
1.179 - goto error;
1.180 -
1.181 - mux = gst_element_factory_make ("ffmux_mpeg", "mux");
1.182 - if (mux == NULL)
1.183 - goto error;
1.184 -
1.185 - fdsink = gst_element_factory_make ("fdsink", "sink");
1.186 - if (fdsink == NULL)
1.187 - goto error;
1.188 -
1.189 - g_debug ("Setting fd to %d", out_fd);
1.190 - g_object_set (G_OBJECT (fdsink), "fd", out_fd, NULL);
1.191 -
1.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
1.193 -
1.194 - vbin = gst_bin_new ("vbin");
1.195 - vqueue = gst_element_factory_make ("queue", "vqueue");
1.196 - vscale = gst_element_factory_make ("videoscale", "vscale");
1.197 - vcolorspace = gst_element_factory_make ("ffmpegcolorspace", "colorspace");
1.198 - vrate = gst_element_factory_make ("videorate", "vrate");
1.199 - vencode = gst_element_factory_make ("ffenc_mpeg1video", "vencode");
1.200 - vqueue_src = gst_element_factory_make ("queue", "queue_src");
1.201 -
1.202 -
1.203 - if ((vbin == NULL) || (vqueue == NULL) || (vcolorspace == NULL)
1.204 - || (vscale == NULL) || (vrate == NULL)
1.205 - || (vencode == NULL) || (vqueue_src == NULL)) {
1.206 - g_warning ("Video elements not found");
1.207 - goto error;
1.208 - }
1.209 -
1.210 - g_object_set (G_OBJECT (vencode), "bitrate", 200, "pass", 2, "quantizer", 5, NULL);
1.211 -
1.212 - gst_bin_add_many (GST_BIN (vbin), vqueue, vscale, vcolorspace, vrate, vencode, vqueue_src, NULL);
1.213 - gst_element_link (vqueue, vscale);
1.214 -
1.215 -
1.216 - vscale_caps = gst_caps_new_simple ("video/x-raw-yuv",
1.217 - "width", G_TYPE_INT, 320,
1.218 - "height", G_TYPE_INT, 288,
1.219 - NULL);
1.220 -
1.221 - if (gst_element_link_filtered (vscale, vcolorspace, vscale_caps) == FALSE) {
1.222 - g_warning ("Fail to resize video");
1.223 - goto error;
1.224 - }
1.225 -
1.226 - if (gst_element_link (vcolorspace, vrate) == FALSE) {
1.227 - g_warning ("Fail to link video elements");
1.228 - goto error;
1.229 - }
1.230 -
1.231 - gst_caps_unref (vscale_caps);
1.232 -
1.233 - vscale_caps = gst_caps_new_simple ("video/x-raw-yuv",
1.234 - "framerate", GST_TYPE_FRACTION, 10, 1, NULL);
1.235 -
1.236 - if (gst_element_link_filtered (vrate, vencode, vscale_caps) == FALSE) {
1.237 - g_warning ("Fail to link vrate with vencode.");
1.238 - goto error;
1.239 -
1.240 - }
1.241 -
1.242 - gst_element_link (vencode, vqueue_src);
1.243 -
1.244 - // ghost pad the video bin
1.245 - vsinkpad = gst_element_get_pad (vqueue, "sink");
1.246 - gst_element_add_pad (vbin, gst_ghost_pad_new ("sink", vsinkpad));
1.247 - gst_object_unref (vsinkpad);
1.248 -
1.249 - video_src_pad = gst_element_get_pad (vqueue_src, "src");
1.250 - gst_element_add_pad (vbin, gst_ghost_pad_new ("src", video_src_pad));
1.251 - gst_object_unref (video_src_pad);
1.252 -
1.253 -
1.254 - //audio/x-raw-int ! queue ! audioconvert ! faac ! rtpmp4gpay ! udpsink name=upd_audio host=224.0.0.1 port=5002
1.255 - abin = gst_bin_new ("abin");
1.256 - aqueue = gst_element_factory_make ("queue", "aqueue");
1.257 - aconvert= gst_element_factory_make ("audioconvert", "aconvert");
1.258 - aencode = gst_element_factory_make ("lame", "aencode");
1.259 - aqueue_src= gst_element_factory_make ("queue", "aqueue_src");
1.260 -
1.261 - if ((abin == NULL) || (aqueue == NULL) || (aconvert == NULL)
1.262 - || (aencode == NULL) || (aqueue_src == NULL)) {
1.263 - g_warning ("Audio elements not found");
1.264 - goto error;
1.265 - }
1.266 -
1.267 - gst_bin_add_many (GST_BIN (abin), aqueue, aconvert, aencode, aqueue_src, NULL);
1.268 - gst_element_link_many (aqueue, aconvert, aencode, aqueue_src, NULL);
1.269 -
1.270 -
1.271 - // ghost pad the audio bin
1.272 - asinkpad = gst_element_get_pad (aqueue, "sink");
1.273 - gst_element_add_pad (abin, gst_ghost_pad_new("sink", asinkpad));
1.274 - gst_object_unref (asinkpad);
1.275 -
1.276 - audio_src_pad = gst_element_get_pad (aqueue_src, "src");
1.277 - gst_element_add_pad (abin, gst_ghost_pad_new("src", audio_src_pad));
1.278 - gst_object_unref (audio_src_pad);
1.279 -
1.280 -
1.281 - // Finish Pipe
1.282 - gst_bin_add_many (GST_BIN (pipe), src, decode, abin, vbin, mux, fdsink, NULL);
1.283 - gst_element_link (src, decode);
1.284 -
1.285 - //Link bins with mux
1.286 - audio_src_pad = gst_element_get_pad (abin, "src");
1.287 - mux_pad = gst_element_get_pad (mux, "audio_0");
1.288 - if (gst_pad_link (audio_src_pad, mux_pad) != GST_PAD_LINK_OK) {
1.289 - g_warning ("Fail link audio and mux");
1.290 - goto error;
1.291 -
1.292 - }
1.293 - gst_object_unref (audio_src_pad);
1.294 - gst_object_unref (mux_pad);
1.295 - audio_src_pad = NULL;
1.296 - mux_pad = NULL;
1.297 -
1.298 - video_src_pad = gst_element_get_pad (vbin, "src");
1.299 - mux_pad = gst_element_get_pad (mux, "video_0");
1.300 - if (gst_pad_link (video_src_pad, mux_pad) != GST_PAD_LINK_OK) {
1.301 - g_warning ("Fail link video and mux");
1.302 - goto error;
1.303 - }
1.304 - gst_object_unref (video_src_pad);
1.305 - gst_object_unref (mux_pad);
1.306 - video_src_pad = NULL;
1.307 - mux_pad = NULL;
1.308 -
1.309 - //Link mux with sink
1.310 - gst_element_link (mux, fdsink);
1.311 -
1.312 - bus = gst_pipeline_get_bus (GST_PIPELINE (pipe));
1.313 - gst_bus_add_watch (bus, _pipeline_bus_cb, self);
1.314 - gst_object_unref (bus);
1.315 -
1.316 - g_signal_connect (G_OBJECT (decode),
1.317 - "new-decoded-pad",
1.318 - G_CALLBACK (_decodebin_new_pad_cb),
1.319 - self);
1.320 -
1.321 - g_signal_connect (G_OBJECT (decode),
1.322 - "unknown-type",
1.323 - G_CALLBACK (_decodebin_unknown_type_cb),
1.324 - self);
1.325 -
1.326 - g_debug ("Setting pipe to PAUSE");
1.327 -
1.328 - priv->pipe = pipe;
1.329 - priv->abin = abin;
1.330 - priv->vbin = vbin;
1.331 - priv->sink = fdsink;
1.332 - priv->ready = FALSE;
1.333 -
1.334 - gst_element_set_state (pipe, GST_STATE_PAUSED);
1.335 - g_debug ("End SETUP");
1.336 - return TRUE;
1.337 -
1.338 -error:
1.339 - g_warning ("Invalid uri");
1.340 -
1.341 - if (pipe != NULL)
1.342 - gst_object_unref (pipe);
1.343 -
1.344 - if (src != NULL)
1.345 - gst_object_unref (src);
1.346 -
1.347 - if (decode != NULL)
1.348 - gst_object_unref (decode);
1.349 -
1.350 - if (vscale_caps != NULL)
1.351 - gst_caps_unref (vscale_caps);
1.352 -
1.353 - if (vbin != NULL)
1.354 - gst_object_unref (vbin);
1.355 -
1.356 - if (vqueue != NULL)
1.357 - gst_object_unref (vqueue);
1.358 -
1.359 - if (vrate != NULL)
1.360 - gst_object_unref (vrate);
1.361 -
1.362 - if (vencode != NULL)
1.363 - gst_object_unref (vencode);
1.364 -
1.365 - if (vqueue_src != NULL)
1.366 - gst_object_unref (vqueue_src);
1.367 -
1.368 - if (abin != NULL)
1.369 - gst_object_unref (abin);
1.370 -
1.371 - if (aqueue != NULL)
1.372 - gst_object_unref (aqueue);
1.373 -
1.374 - if (aconvert != NULL)
1.375 - gst_object_unref (aconvert);
1.376 -
1.377 - if (aencode != NULL)
1.378 - gst_object_unref (aencode);
1.379 -
1.380 - if (aqueue_src != NULL)
1.381 - gst_object_unref (aqueue_src);
1.382 -
1.383 - if (video_src_pad != NULL) {
1.384 - gst_object_unref (video_src_pad);
1.385 - }
1.386 -
1.387 - if (audio_src_pad != NULL) {
1.388 - gst_object_unref (audio_src_pad);
1.389 - }
1.390 -
1.391 - if (mux != NULL) {
1.392 - gst_object_unref (mux);
1.393 - }
1.394 -
1.395 - if (mux_pad != NULL) {
1.396 - gst_object_unref (mux_pad);
1.397 - }
1.398 -
1.399 - if (fdsink != NULL)
1.400 - gst_object_unref (fdsink);
1.401 -
1.402 - return FALSE;
1.403 -}
1.404 -
1.405 -gboolean
1.406 -g_mencoder_play_stream (GMencoder *self)
1.407 -{
1.408 - GMencoderPrivate *priv = G_MENCODER_GET_PRIVATE (self);
1.409 -
1.410 - g_return_val_if_fail (priv->ready == TRUE, FALSE);
1.411 -
1.412 - if (gst_element_set_state (priv->pipe, GST_STATE_PLAYING) != GST_STATE_CHANGE_FAILURE) {
1.413 - g_debug ("PLAYING");
1.414 - return TRUE;
1.415 - }
1.416 - return FALSE;
1.417 -}
1.418 -
1.419 -gboolean
1.420 -g_mencoder_pause_stream (GMencoder *self)
1.421 -{
1.422 - GMencoderPrivate *priv = G_MENCODER_GET_PRIVATE (self);
1.423 -
1.424 - g_return_val_if_fail (priv->ready == TRUE, FALSE);
1.425 -
1.426 - if (gst_element_set_state (priv->pipe, GST_STATE_PAUSED) != GST_STATE_CHANGE_FAILURE) {
1.427 - g_debug ("PAUSED");
1.428 - return TRUE;
1.429 - }
1.430 - return FALSE;
1.431 -}
1.432 -
1.433 -void
1.434 -g_mencoder_close_stream (GMencoder *self)
1.435 -{
1.436 -
1.437 - GMencoderPrivate *priv = G_MENCODER_GET_PRIVATE (self);
1.438 -
1.439 - g_return_if_fail (priv->ready == TRUE);
1.440 -
1.441 - gst_element_set_state (priv->pipe, GST_STATE_NULL);
1.442 - gst_object_unref (priv->pipe);
1.443 - priv->pipe = NULL;
1.444 - priv->abin = NULL;
1.445 - priv->vbin = NULL;
1.446 - priv->sink = NULL;
1.447 - priv->ready = FALSE;
1.448 -}
1.449 -
1.450 -static gboolean
1.451 -_pipeline_bus_cb (GstBus *bus,
1.452 - GstMessage *msg,
1.453 - gpointer user_data)
1.454 -{
1.455 - switch (GST_MESSAGE_TYPE (msg))
1.456 - {
1.457 - case GST_MESSAGE_STATE_CHANGED:
1.458 - {
1.459 - GstState oldstate;
1.460 - GstState newstate;
1.461 - GstState pendingstate;
1.462 -
1.463 - GMencoderPrivate *priv = G_MENCODER_GET_PRIVATE (user_data);
1.464 -
1.465 - gst_message_parse_state_changed (msg, &oldstate,
1.466 - &newstate, &pendingstate);
1.467 -
1.468 - if (pendingstate != GST_STATE_VOID_PENDING)
1.469 - break;
1.470 -
1.471 - if ((oldstate == GST_STATE_READY) &&
1.472 - (newstate == GST_STATE_PAUSED)) {
1.473 - if (priv->ready)
1.474 - g_signal_emit (user_data, g_mencoder_signals[PAUSED], 0);
1.475 - else {
1.476 - priv->ready = TRUE;
1.477 - g_signal_emit (user_data, g_mencoder_signals[READY], 0);
1.478 - }
1.479 - } else if ((oldstate == GST_STATE_PAUSED) &&
1.480 - (newstate == GST_STATE_PLAYING)) {
1.481 - g_signal_emit (user_data, g_mencoder_signals[PLAYING], 0);
1.482 - } else if ((oldstate == GST_STATE_READY) &&
1.483 - (newstate == GST_STATE_NULL)) {
1.484 - g_signal_emit (user_data, g_mencoder_signals[STOPED], 0);
1.485 - }
1.486 - break;
1.487 - }
1.488 - case GST_MESSAGE_ERROR:
1.489 - {
1.490 - GError *error;
1.491 - gchar *debug;
1.492 - gchar *err_str;
1.493 -
1.494 - gst_message_parse_error (msg, &error, &debug);
1.495 - err_str = g_strdup_printf ("Error [%d] %s (%s)", error->code,
1.496 - error->message,
1.497 - debug);
1.498 - g_signal_emit (user_data, g_mencoder_signals[ERROR], 0, err_str);
1.499 - g_free (err_str);
1.500 - g_clear_error (&error);
1.501 - g_free (debug);
1.502 - break;
1.503 - }
1.504 -
1.505 - case GST_MESSAGE_EOS:
1.506 - g_signal_emit (user_data, g_mencoder_signals[EOS], 0);
1.507 - break;
1.508 - default:
1.509 - break;
1.510 - }
1.511 - return TRUE;
1.512 -}
1.513 -
1.514 -static void
1.515 -_decodebin_new_pad_cb (GstElement* object,
1.516 - GstPad* pad,
1.517 - gboolean flag,
1.518 - gpointer user_data)
1.519 -{
1.520 - GstCaps *caps;
1.521 - gchar *str_caps = NULL;
1.522 - GMencoderPrivate *priv = G_MENCODER_GET_PRIVATE (user_data);
1.523 -
1.524 - caps = gst_pad_get_caps (pad);
1.525 - str_caps = gst_caps_to_string (caps);
1.526 - g_debug ("CAPS : %s", str_caps);
1.527 -
1.528 - if (strstr (str_caps, "audio") != NULL) {
1.529 - GstPad *apad = gst_element_get_pad (priv->abin, "sink");
1.530 - g_debug ("Linked with Audio");
1.531 - gst_pad_link (pad, apad);
1.532 - gst_object_unref (apad);
1.533 - } else if (strstr (str_caps, "video") != NULL) {
1.534 - GstPad *vpad = gst_element_get_pad (priv->vbin, "sink");
1.535 - g_debug ("Linked with Video");
1.536 - gst_pad_link (pad, vpad);
1.537 - gst_object_unref (vpad);
1.538 - } else {
1.539 - g_warning ("invalid caps %s", str_caps);
1.540 - }
1.541 -
1.542 - g_free (str_caps);
1.543 - gst_caps_unref (caps);
1.544 - g_debug ("OK");
1.545 -}
1.546 -
1.547 -static void
1.548 -_decodebin_unknown_type_cb (GstElement* object,
1.549 - GstPad* pad,
1.550 - GstCaps* caps,
1.551 - gpointer user_data)
1.552 -{
1.553 - g_warning ("Unknown Type");
1.554 -}