1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
1.2 +++ b/gmyth-stream/gmemcoder/src/Makefile.am Mon Apr 23 18:50:32 2007 +0100
1.3 @@ -0,0 +1,17 @@
1.4 +bin_PROGRAMS = \
1.5 + gmencoder
1.6 +
1.7 +gmencoder_SOURCES = \
1.8 + main.c \
1.9 + gmemcoder.c \
1.10 + gmemcoder.h
1.11 +
1.12 +gmencoder_LDADD = \
1.13 + $(GLIB_LIBS) \
1.14 + $(GST_LIBS)
1.15 +
1.16 +AM_CPPFLAGS = \
1.17 + $(GLIB_CFLAGS) \
1.18 + $(GST_CFLAGS)
1.19 +
1.20 +CLEANFILES =
2.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
2.2 +++ b/gmyth-stream/gmemcoder/src/gmemcoder.c Mon Apr 23 18:50:32 2007 +0100
2.3 @@ -0,0 +1,551 @@
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 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
3.2 +++ b/gmyth-stream/gmemcoder/src/gmemcoder.h Mon Apr 23 18:50:32 2007 +0100
3.3 @@ -0,0 +1,46 @@
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/main.c Mon Apr 23 18:50:32 2007 +0100
4.3 @@ -0,0 +1,105 @@
4.4 +#include <sys/stat.h>
4.5 +#include <fcntl.h>
4.6 +#include <unistd.h>
4.7 +#include <string.h>
4.8 +
4.9 +#include <gst/gst.h>
4.10 +#include <glib.h>
4.11 +
4.12 +#include "gmemcoder.h"
4.13 +
4.14 +//#define FILE_OUT 1
4.15 +
4.16 +static GMainLoop *mainloop = NULL;
4.17 +
4.18 +static void
4.19 +_mencoder_ready_cb (GMencoder *mencoder, gpointer data)
4.20 +{
4.21 + g_mencoder_play_stream (mencoder);
4.22 +}
4.23 +
4.24 +static void
4.25 +_mencoder_eos_cb (GMencoder *mencoder, gpointer data)
4.26 +{
4.27 + g_print ("EOS\n");
4.28 + g_main_loop_quit ((GMainLoop *) data);
4.29 +}
4.30 +
4.31 +static void
4.32 +_mencoder_error_cb (GMencoder *mencoder, const gchar* msg, gpointer data)
4.33 +{
4.34 + g_print ("Error: %s\n", msg);
4.35 + g_main_loop_quit ((GMainLoop *) data);
4.36 +}
4.37 +
4.38 +static gboolean
4.39 +_io_channel_cb (GIOChannel *ch,
4.40 + GIOCondition condition,
4.41 + gpointer data)
4.42 +{
4.43 + GString *cmd = g_string_new ("");
4.44 + g_io_channel_read_line_string (ch, cmd, NULL, NULL);
4.45 +
4.46 + if (strcmp (cmd->str, "PLAY\n") == 0) {
4.47 + g_mencoder_play_stream (G_MENCODER (data));
4.48 + } else if (strcmp (cmd->str, "PAUSE\n") == 0) {
4.49 + g_mencoder_pause_stream (G_MENCODER (data));
4.50 + } else if (strcmp (cmd->str, "STOP\n") == 0) {
4.51 + g_mencoder_close_stream (G_MENCODER (data));
4.52 + } else if (strcmp (cmd->str, "QUIT\n") == 0) {
4.53 + g_mencoder_close_stream (G_MENCODER (data));
4.54 + g_main_loop_quit (mainloop);
4.55 + }
4.56 + g_string_free (cmd, TRUE);
4.57 + return TRUE;
4.58 +}
4.59 +
4.60 +int
4.61 +main (int argc, char** argv)
4.62 +{
4.63 + GMencoder *coder;
4.64 + GIOChannel *ch;
4.65 +
4.66 + g_type_init ();
4.67 + gst_init (&argc, &argv);
4.68 +
4.69 + g_set_prgname ("gmemcoder");
4.70 +
4.71 + coder = g_mencoder_new ();
4.72 + ch = g_io_channel_unix_new (0);
4.73 +
4.74 +#ifdef FILE_OUT
4.75 + int fd = open (argv[2], O_WRONLY | O_CREAT | O_TRUNC);
4.76 + g_debug ("FD %d", fd);
4.77 + g_mencoder_setup_stream (coder, argv[1], 320, 288, fd);
4.78 +#else
4.79 + g_mencoder_setup_stream (coder, argv[1], 320, 288, atoi (argv[2]));
4.80 +#endif
4.81 +
4.82 + mainloop = g_main_loop_new (NULL, FALSE);
4.83 + g_io_add_watch (ch, G_IO_IN, _io_channel_cb, coder);
4.84 +
4.85 +
4.86 + g_signal_connect (G_OBJECT (coder),
4.87 + "ready",
4.88 + G_CALLBACK (_mencoder_ready_cb),
4.89 + NULL);
4.90 +
4.91 + g_signal_connect (G_OBJECT (coder),
4.92 + "eos",
4.93 + G_CALLBACK (_mencoder_eos_cb),
4.94 + mainloop);
4.95 +
4.96 + g_signal_connect (G_OBJECT (coder),
4.97 + "error",
4.98 + G_CALLBACK (_mencoder_error_cb),
4.99 + mainloop);
4.100 +
4.101 + g_main_loop_run (mainloop);
4.102 +
4.103 +#if FILE_OUT
4.104 + close (fd);
4.105 +#endif
4.106 +
4.107 + return 0;
4.108 +}