11 #include <sys/types.h>
12 #include <sys/socket.h>
13 #include <libgnomevfs/gnome-vfs.h>
15 #include "gmencoder.h"
17 #define G_MENCODER_GET_PRIVATE(obj) \
18 (G_TYPE_INSTANCE_GET_PRIVATE ((obj), G_TYPE_MENCODER, GMencoderPrivate))
20 // #define SUPPORT_MULT_INPUT 0
21 #define USE_MANUAL_SINK
23 typedef struct _GMencoderPrivate GMencoderPrivate;
24 typedef struct _SetupInfo SetupInfo;
29 gchar **video_encode_prop;
35 gchar **audio_encode_prop;
40 struct _GMencoderPrivate {
47 GnomeVFSHandle *handle;
56 gboolean send_chunked;
68 static void g_mencoder_class_init(GMencoderClass * klass);
69 static void g_mencoder_init(GMencoder * object);
70 static void g_mencoder_dispose(GObject * object);
71 static void g_mencoder_finalize(GObject * object);
72 static GstElement *_create_audio_bin(const gchar * encode,
73 gchar ** encode_prop, gint rate);
74 static GstElement *_create_video_bin(const gchar * encode,
77 gint rate, guint width, guint height,
78 gboolean use_deinterlace);
81 _pipeline_bus_cb(GstBus * bus, GstMessage * msg, gpointer user_data);
83 static void _decodebin_new_pad_cb(GstElement * object,
85 gboolean flag, gpointer user_data);
87 static void _decodebin_unknown_type_cb(GstElement * object,
92 static void _close_output(GMencoder * self);
93 static gboolean _open_output(GMencoder * self, const gchar * uri);
95 static GstElement *_create_source(const gchar * uri);
96 static GstElement *_create_pipeline(GMencoder * self,
97 const gchar * video_encode,
98 const gchar * mux_name,
99 gchar ** video_encode_prop,
104 const gchar * audio_encode,
105 gchar ** audio_encode_prop,
107 gboolean deinterlace);
108 #ifdef USE_MANUAL_SINK
109 static void _flush_queue (GMencoder *self);
110 static void _buffer_arrive_cb (GstElement* object,
117 static gboolean _tick_cb(gpointer data);
119 static guint g_mencoder_signals[LAST_SIGNAL] = { 0 };
121 G_DEFINE_TYPE(GMencoder, g_mencoder, G_TYPE_OBJECT)
123 static void g_mencoder_class_init(GMencoderClass * klass)
125 GObjectClass *object_class;
126 object_class = (GObjectClass *) klass;
127 g_type_class_add_private(klass, sizeof(GMencoderPrivate));
129 object_class->dispose = g_mencoder_dispose;
130 object_class->finalize = g_mencoder_finalize;
132 g_mencoder_signals[PAUSED] =
133 g_signal_new("paused",
134 G_OBJECT_CLASS_TYPE(object_class),
137 g_cclosure_marshal_VOID__VOID, G_TYPE_NONE, 0);
139 g_mencoder_signals[PLAYING] =
140 g_signal_new("playing",
141 G_OBJECT_CLASS_TYPE(object_class),
144 g_cclosure_marshal_VOID__VOID, G_TYPE_NONE, 0);
146 g_mencoder_signals[STOPED] =
147 g_signal_new("stoped",
148 G_OBJECT_CLASS_TYPE(object_class),
151 g_cclosure_marshal_VOID__VOID, G_TYPE_NONE, 0);
153 g_mencoder_signals[EOS] =
155 G_OBJECT_CLASS_TYPE(object_class),
158 g_cclosure_marshal_VOID__VOID, G_TYPE_NONE, 0);
160 g_mencoder_signals[ERROR] =
161 g_signal_new("error",
162 G_OBJECT_CLASS_TYPE(object_class),
165 g_cclosure_marshal_VOID__STRING,
166 G_TYPE_NONE, 1, G_TYPE_STRING);
170 g_mencoder_init(GMencoder * self)
172 GMencoderPrivate *priv = G_MENCODER_GET_PRIVATE(self);
173 priv->info = g_new0(SetupInfo, 1);
177 g_mencoder_dispose(GObject * object)
182 g_mencoder_finalize(GObject * object)
184 GMencoderPrivate *priv = G_MENCODER_GET_PRIVATE(object);
187 g_mencoder_close_stream(G_MENCODER(object));
194 return g_object_new(G_TYPE_MENCODER, NULL);
199 _obj_set_prop(GObject * obj, const gchar * prop_name,
200 const gchar * prop_val)
204 GParamSpec *s = NULL;
205 GObjectClass *k = G_OBJECT_GET_CLASS(obj);
208 g_value_init(&v, G_TYPE_STRING);
209 g_value_set_string(&v, prop_val);
211 s = g_object_class_find_property(k, prop_name);
213 g_print("Invalid property name: %s\n", prop_name);
217 g_value_init(&p, s->value_type);
218 switch (s->value_type) {
220 g_value_set_int(&p, atoi(prop_val));
223 g_value_set_ulong (&p, atol(prop_val));
226 g_value_set_string(&p, prop_val);
229 g_value_set_boolean(&p, (gboolean) atoi (prop_val));
232 g_value_set_double(&p, atof (prop_val));
235 g_value_set_float(&p, (float) atof (prop_val));
238 g_value_set_enum(&p, atoi(prop_val));
239 g_warning ("Property %s of type %s. Not supported using default enum",
240 prop_name, g_type_name (s->value_type));
244 g_object_set_property(obj, prop_name, &p);
250 _create_element_with_prop(const gchar * factory_name,
251 const gchar * element_name, gchar ** prop)
256 ret = gst_element_factory_make(factory_name, element_name);
261 for (i = 0; i < g_strv_length(prop); i++) {
262 if (prop[i] != NULL) {
263 char **v = g_strsplit(prop[i], "=", 2);
264 if (g_strv_length(v) == 2) {
265 _obj_set_prop(G_OBJECT(ret), v[0], v[1]);
277 _create_audio_bin(const gchar * encode, gchar ** encode_prop, gint rate)
279 GstElement *abin = NULL;
280 GstElement *aqueue = NULL;
281 GstElement *aconvert = NULL;
282 GstElement *aencode = NULL;
283 GstElement *aqueue_src = NULL;
286 // audio/x-raw-int ! queue ! audioconvert ! faac ! rtpmp4gpay !
287 // udpsink name=upd_audio host=224.0.0.1 port=5002
288 abin = gst_bin_new("abin");
289 aqueue = gst_element_factory_make("queue", "aqueue");
290 aconvert = gst_element_factory_make("audioconvert", "aconvert");
292 _create_element_with_prop((encode ? encode : "lame"), "aencode",
294 aqueue_src = gst_element_factory_make("queue", "aqueue_src");
296 if ((abin == NULL) || (aqueue == NULL) || (aconvert == NULL)
297 || (aencode == NULL) || (aqueue_src == NULL)) {
298 g_warning("Audio elements not found");
302 g_object_set(G_OBJECT(aencode), "bitrate", 32, NULL);
304 * if (rate > 0) { g_object_set (G_OBJECT (aencode), "bitrate", 32,
308 gst_bin_add_many(GST_BIN(abin), aqueue, aconvert, aencode, aqueue_src,
310 if (gst_element_link_many(aqueue, aconvert, aencode, aqueue_src, NULL)
312 g_warning("Not Link audio elements");
314 // TODO: apply audio rate
316 // ghost pad the audio bin
317 apad = gst_element_get_pad(aqueue, "sink");
318 gst_element_add_pad(abin, gst_ghost_pad_new("sink", apad));
319 gst_object_unref(apad);
321 apad = gst_element_get_pad(aqueue_src, "src");
322 gst_element_add_pad(abin, gst_ghost_pad_new("src", apad));
323 gst_object_unref(apad);
328 gst_object_unref(abin);
331 gst_object_unref(aqueue);
333 if (aconvert != NULL)
334 gst_object_unref(aconvert);
337 gst_object_unref(aencode);
339 if (aqueue_src != NULL)
340 gst_object_unref(aqueue_src);
343 gst_object_unref(apad);
351 // queue ! videoscale ! video/x-raw-yuv,width=240,height=144 ! colorspace
352 // ! rate ! encode ! queue
354 _create_video_bin(const gchar * encode,
355 gchar ** encode_prop,
356 gdouble fps, gint rate, guint width, guint height,
357 gboolean use_deinterlace)
359 GstElement *vbin = NULL;
360 GstElement *vqueue = NULL;
361 GstElement *vqueue_src = NULL;
362 GstElement *vcolorspace = NULL;
363 GstElement *vencode = NULL;
364 GstElement *vrate = NULL;
365 GstElement *deinterlace = NULL;
366 GstElement *walk = NULL;
369 vbin = gst_bin_new("vbin");
370 vqueue = gst_element_factory_make("queue", "vqueue");
372 gst_element_factory_make("ffmpegcolorspace", "colorspace");
374 if (use_deinterlace) {
375 deinterlace = gst_element_factory_make ("ffdeinterlace", "deinterlace");
376 if (deinterlace == NULL) {
377 g_warning ("Fail to create deinterlace element: Continue without deinterlace.");
382 vencode = _create_element_with_prop((encode !=
384 "ffenc_mpeg1video"), "vencode",
386 vqueue_src = gst_element_factory_make("queue", "queue_src");
388 if ((vbin == NULL) || (vqueue == NULL) || (vcolorspace == NULL)
389 || (vencode == NULL) || (vqueue_src == NULL)) {
390 g_warning("Video elements not found");
394 gst_bin_add_many(GST_BIN(vbin), vqueue, vcolorspace, vencode,
397 if (deinterlace != NULL) {
398 gst_bin_add(GST_BIN(vbin), deinterlace);
399 gst_element_link (vqueue, deinterlace);
405 if ((width > 0) && (height > 0)) {
409 gst_element_factory_make("videoscale", "vscale");
411 g_object_set (G_OBJECT (vscale), "method", 1, NULL);
413 gst_bin_add(GST_BIN(vbin), vscale);
415 vcaps = gst_caps_new_simple("video/x-raw-yuv",
416 "width", G_TYPE_INT, width,
417 "height", G_TYPE_INT, height, NULL);
419 gst_element_link(walk, vscale);
421 if (gst_element_link_filtered(vscale, vcolorspace, vcaps) == FALSE) {
422 g_warning("Fail to resize video");
423 gst_object_unref(vcaps);
424 gst_object_unref(vscale);
427 gst_caps_unref(vcaps);
429 gst_element_link(walk, vcolorspace);
433 // Changing the video fps
435 vrate = gst_element_factory_make("videorate", "vrate");
437 gst_bin_add(GST_BIN(vbin), vrate);
439 if (gst_element_link(vcolorspace, vrate) == FALSE) {
440 g_warning("Fail to link video elements");
444 vcaps = gst_caps_new_simple("video/x-raw-yuv",
445 "framerate", GST_TYPE_FRACTION,
446 (int) (fps * 1000), 1000, NULL);
448 if (gst_element_link_filtered(vrate, vencode, vcaps) == FALSE) {
449 g_warning("Fail to link vrate with vencode.");
452 gst_caps_unref(vcaps);
454 if (gst_element_link(vcolorspace, vencode) == FALSE) {
455 g_warning("Fail to link colorspace and video encode element.");
460 gst_element_link(vencode, vqueue_src);
462 // ghost pad the video bin
463 vpad = gst_element_get_pad(vqueue, "sink");
464 gst_element_add_pad(vbin, gst_ghost_pad_new("sink", vpad));
465 gst_object_unref(vpad);
467 vpad = gst_element_get_pad(vqueue_src, "src");
468 gst_element_add_pad(vbin, gst_ghost_pad_new("src", vpad));
469 gst_object_unref(vpad);
475 gst_object_unref(vpad);
478 gst_object_unref(vbin);
481 gst_object_unref(vqueue);
484 gst_object_unref(vencode);
486 if (vqueue_src != NULL)
487 gst_object_unref(vqueue_src);
489 if (vcolorspace != NULL)
490 gst_object_unref(vcolorspace);
498 g_mencoder_setup_stream(GMencoder * self,
500 gboolean deinterlace,
501 const gchar * mux_name,
502 const gchar * video_encode,
503 gchar ** video_encode_prop,
508 const gchar * audio_encode,
509 gchar ** audio_encode_prop,
510 guint audio_rate, const gchar * out_uri)
512 GMencoderPrivate *priv = G_MENCODER_GET_PRIVATE(self);
513 if (priv->ready == TRUE) {
515 ("Stream already configured. You need close stream first.");
520 if (_open_output(self, out_uri) == FALSE)
524 priv->send_chunked = chunked;
525 priv->pipe = _create_pipeline(self,
533 audio_encode, audio_encode_prop,
537 return (priv->pipe != NULL);
542 g_mencoder_append_uri(GMencoder * self, const gchar * uri)
547 GMencoderPrivate *priv = G_MENCODER_GET_PRIVATE(self);
548 gboolean ret = FALSE;
549 GstElement *ap = NULL;
550 GstElement *vp = NULL;
553 g_return_val_if_fail(priv->pipe != NULL, FALSE);
554 g_return_val_if_fail(priv->ready == FALSE, FALSE);
556 #ifndef SUPPORT_MULT_INPUT
557 g_return_val_if_fail(priv->sources < 1, FALSE);
560 src = _create_source(uri);
564 priv->src = gst_bin_get_by_name(GST_BIN(src), "src");
566 gst_bin_add(GST_BIN(priv->pipe), src);
568 #ifdef SUPPORT_MULT_INPUT
569 ap = gst_bin_get_by_name(GST_BIN(priv->pipe), "ap");
570 vp = gst_bin_get_by_name(GST_BIN(priv->pipe), "vp");
572 ap = gst_bin_get_by_name(GST_BIN(priv->pipe), "abin");
573 vp = gst_bin_get_by_name(GST_BIN(priv->pipe), "vbin");
576 if ((vp == NULL) || (ap == NULL)) {
577 g_warning("Fail to get output bin");
581 pad_src = gst_element_get_pad(src, "src_audio");
582 pad_sink = gst_element_get_compatible_pad(ap,
584 gst_pad_get_caps(pad_src));
586 if ((pad_sink == NULL) || (pad_src == NULL))
589 GstPadLinkReturn lret = gst_pad_link(pad_src, pad_sink);
590 if (lret != GST_PAD_LINK_OK)
593 gst_object_unref(pad_src);
594 gst_object_unref(pad_sink);
596 pad_src = gst_element_get_pad(src, "src_video");
597 pad_sink = gst_element_get_compatible_pad(vp,
599 gst_pad_get_caps(pad_src));
601 if ((pad_src == NULL) || (pad_sink == NULL))
604 if (gst_pad_link(pad_src, pad_sink) != GST_PAD_LINK_OK) {
605 g_warning("invalid source. video");
613 if ((src != NULL) && (ret == FALSE)) {
614 gst_bin_remove(GST_BIN(priv->pipe), src);
615 gst_object_unref(src);
619 gst_object_unref(ap);
622 gst_object_unref(vp);
625 gst_object_unref(pad_src);
627 if (pad_sink != NULL)
628 gst_object_unref(pad_sink);
636 g_mencoder_remove_uri(GMencoder * self, const gchar * uri)
638 // GMencoderPrivate *priv = G_MENCODER_GET_PRIVATE (self);
643 g_mencoder_play_stream(GMencoder * self)
645 GMencoderPrivate *priv = G_MENCODER_GET_PRIVATE(self);
646 g_return_if_fail(priv->ready == FALSE);
648 gst_element_set_state(priv->pipe, GST_STATE_PLAYING);
649 priv->tick_id = g_timeout_add(500, _tick_cb, self);
653 g_mencoder_pause_stream(GMencoder * self)
655 GMencoderPrivate *priv = G_MENCODER_GET_PRIVATE(self);
656 g_return_if_fail(priv->ready == TRUE);
657 gst_element_set_state(priv->pipe, GST_STATE_PAUSED);
661 g_mencoder_close_stream(GMencoder * self)
664 GMencoderPrivate *priv = G_MENCODER_GET_PRIVATE(self);
665 if (priv->tick_id != 0) {
666 g_source_remove(priv->tick_id);
670 if (priv->pipe != NULL) {
671 // TODO: fixe pipeline dispose
672 //gst_element_set_state (priv->pipe, GST_STATE_NULL);
673 // g_debug ("SETING STATE TO NULL: OK");
674 // gst_element_set_state (priv->pipe, GST_STATE_NULL);
675 //gst_object_unref (priv->pipe);
676 //gst_object_unref(priv->src);
687 _create_pipeline(GMencoder * self,
688 const gchar * video_encode,
689 const gchar * mux_name,
690 gchar ** video_encode_prop,
695 const gchar * audio_encode,
696 gchar ** audio_encode_prop, guint audio_rate,
697 gboolean deinterlace)
700 GstElement *pipe = NULL;
701 GstElement *sink = NULL;
702 GstElement *mux = NULL;
703 GstElement *abin = NULL;
704 GstElement *vbin = NULL;
705 GstElement *queue = NULL;
706 GstPad *aux_pad = NULL;
707 GstPad *mux_pad = NULL;
708 #ifdef SUPPORT_MULT_INPUT
709 GstElement *ap = NULL;
710 GstElement *vp = NULL;
713 pipe = gst_pipeline_new("pipe");
715 #ifdef SUPPORT_MULT_INPUT
716 ap = gst_element_factory_make("concatmux", "ap");
717 vp = gst_element_factory_make("concatmux", "vp");
718 gst_bin_add_many(GST_BIN(pipe), ap, vp, NULL);
721 gst_element_factory_make((mux_name ? mux_name : "ffmux_mpeg"),
726 queue = gst_element_factory_make("queue", "queueu_sink");
729 sink = gst_element_factory_make("fakesink", "sink");
730 g_object_set (G_OBJECT (sink), "signal-handoffs", TRUE, NULL);
731 g_signal_connect (G_OBJECT (sink),
733 G_CALLBACK (_buffer_arrive_cb),
736 abin = _create_audio_bin(audio_encode, audio_encode_prop, audio_rate);
741 _create_video_bin(video_encode, video_encode_prop, video_fps,
742 video_rate, video_width, video_height, deinterlace);
747 gst_bin_add_many(GST_BIN(pipe), abin, vbin, mux, queue, sink, NULL);
750 #ifdef SUPPORT_MULT_INPUT
751 if (gst_element_link(ap, abin) == FALSE) {
752 g_warning("Fail to link concat and abin");
756 if (gst_element_link(vp, vbin) == FALSE) {
757 g_warning("Fail to link concat and vbin");
761 // Link bins with mux
762 aux_pad = gst_element_get_pad(abin, "src");
764 gst_element_get_compatible_pad(mux, aux_pad,
765 GST_PAD_CAPS(aux_pad));
766 if (mux_pad == NULL) {
767 g_warning("Mux element no have audio PAD");
770 GstPadLinkReturn ret = gst_pad_link(aux_pad, mux_pad);
771 if (ret != GST_PAD_LINK_OK) {
772 g_warning("Fail link audio and mux: %d", ret);
776 gst_object_unref(aux_pad);
777 gst_object_unref(mux_pad);
779 aux_pad = gst_element_get_pad(vbin, "src");
781 gst_element_get_compatible_pad(mux, aux_pad,
782 GST_PAD_CAPS(aux_pad));
783 if (mux_pad == NULL) {
784 g_warning("Mux element no have video PAD");
787 ret = gst_pad_link(aux_pad, mux_pad);
788 if (ret != GST_PAD_LINK_OK) {
789 g_warning("Fail link video and mux: %d", ret);
792 gst_object_unref(aux_pad);
793 gst_object_unref(mux_pad);
797 // Link mux with sink
798 gst_element_link_many(mux, queue, sink, NULL);
800 bus = gst_pipeline_get_bus(GST_PIPELINE(pipe));
801 gst_bus_add_watch(bus, _pipeline_bus_cb, self);
802 gst_object_unref(bus);
806 g_warning("Invalid uri");
809 gst_object_unref(pipe);
814 gst_object_unref(mux);
817 if (mux_pad != NULL) {
818 gst_object_unref(mux_pad);
821 if (aux_pad != NULL) {
822 gst_object_unref(mux_pad);
826 gst_object_unref(sink);
830 gst_object_unref(abin);
834 gst_object_unref(vbin);
842 _close_output(GMencoder * self)
847 _create_source(const gchar * uri)
850 GstElement *bsrc = NULL;
851 GstElement *src = NULL;
852 GstElement *queue = NULL;
853 GstElement *aqueue = NULL;
854 GstElement *vqueue = NULL;
855 GstElement *decode = NULL;
856 GstPad *src_pad = NULL;
859 bsrc = gst_bin_new(NULL);
861 // src = gst_element_factory_make ("gnomevfssrc", "src");
862 // g_object_set (G_OBJECT (src), "location", uri, NULL);
863 src = gst_element_make_from_uri(GST_URI_SRC, uri, "src");
867 decode = gst_element_factory_make("decodebin", "decode");
871 queue = gst_element_factory_make("queue", "queue_src");
872 aqueue = gst_element_factory_make("queue", "aqueue");
876 vqueue = gst_element_factory_make("queue", "vqueue");
880 gst_bin_add_many(GST_BIN(bsrc), src, queue, decode, aqueue, vqueue,
882 gst_element_link_many(src, queue, decode, NULL);
884 g_signal_connect(G_OBJECT(decode),
886 G_CALLBACK(_decodebin_new_pad_cb), bsrc);
888 g_signal_connect(G_OBJECT(decode),
890 G_CALLBACK(_decodebin_unknown_type_cb), pipe);
892 src_pad = gst_element_get_pad(aqueue, "src");
893 gst_element_add_pad(bsrc, gst_ghost_pad_new("src_audio", src_pad));
894 gst_object_unref(src_pad);
896 src_pad = gst_element_get_pad(vqueue, "src");
897 gst_element_add_pad(bsrc, gst_ghost_pad_new("src_video", src_pad));
898 gst_object_unref(src_pad);
904 gst_object_unref(src);
907 if (decode != NULL) {
908 gst_object_unref(decode);
911 if (aqueue != NULL) {
912 gst_object_unref(aqueue);
915 if (vqueue != NULL) {
916 gst_object_unref(vqueue);
923 _open_output(GMencoder * self, const gchar * uri)
926 GnomeVFSResult result;
927 GMencoderPrivate *priv = G_MENCODER_GET_PRIVATE(self);
929 i = g_strsplit(uri, "://", 0);
930 if (strcmp(i[0], "fd") == 0) {
931 result = gnome_vfs_open_fd (&priv->handle, atoi(i[1]));
933 result = gnome_vfs_open (&priv->handle, uri,
934 GNOME_VFS_OPEN_WRITE | GNOME_VFS_OPEN_TRUNCATE);
939 return (result == GNOME_VFS_OK);
943 _pipeline_bus_cb(GstBus * bus, GstMessage * msg, gpointer user_data)
945 GMencoderPrivate *priv = G_MENCODER_GET_PRIVATE(user_data);
947 switch (GST_MESSAGE_TYPE(msg)) {
949 case GST_MESSAGE_STATE_CHANGED:
953 GstState pendingstate;
956 gst_message_parse_state_changed(msg, &oldstate,
957 &newstate, &pendingstate);
959 if (pendingstate != GST_STATE_VOID_PENDING)
962 if ((oldstate == GST_STATE_READY)
963 && (newstate == GST_STATE_PAUSED)) {
965 g_signal_emit(user_data, g_mencoder_signals[PAUSED],
967 } else if ((oldstate == GST_STATE_PAUSED)
968 && (newstate == GST_STATE_PLAYING)) {
969 g_signal_emit(user_data, g_mencoder_signals[PLAYING], 0);
970 } else if ((oldstate == GST_STATE_READY) &&
971 (newstate == GST_STATE_NULL)) {
972 g_signal_emit(user_data, g_mencoder_signals[STOPED], 0);
977 case GST_MESSAGE_ERROR:
983 if (priv->tick_id != 0) {
984 g_source_remove(priv->tick_id);
988 gst_message_parse_error(msg, &error, &debug);
989 err_str = g_strdup_printf("Error [%d] %s (%s)", error->code,
990 error->message, debug);
992 g_signal_emit(user_data, g_mencoder_signals[ERROR], 0,
995 g_clear_error(&error);
1000 case GST_MESSAGE_EOS:
1001 priv->ready = FALSE;
1002 #ifdef USE_MANUAL_SINK
1003 _flush_queue (G_MENCODER (user_data));
1005 g_signal_emit(user_data, g_mencoder_signals[EOS], 0);
1008 case GST_MESSAGE_DURATION:
1012 gst_message_parse_duration(msg, &format, &duration);
1013 if (format == GST_FORMAT_BYTES)
1014 priv->duration = duration;
1028 _decodebin_new_pad_cb(GstElement * object,
1029 GstPad * pad, gboolean flag, gpointer user_data)
1032 gchar *str_caps = NULL;
1033 GstElement *sink_element;
1036 caps = gst_pad_get_caps(pad);
1037 str_caps = gst_caps_to_string(caps);
1038 if (strstr(str_caps, "audio") != NULL) {
1039 sink_element = gst_bin_get_by_name(GST_BIN(user_data), "aqueue");
1040 } else if (strstr(str_caps, "video") != NULL) {
1041 sink_element = gst_bin_get_by_name(GST_BIN(user_data), "vqueue");
1043 g_warning("invalid caps %s", str_caps);
1046 sink_pad = gst_element_get_pad(sink_element, "sink");
1047 gst_pad_link(pad, sink_pad);
1049 gst_object_unref(sink_element);
1050 gst_object_unref(sink_pad);
1052 gst_caps_unref(caps);
1056 _decodebin_unknown_type_cb(GstElement * object,
1057 GstPad * pad, GstCaps * caps,
1060 g_warning("Unknown Type");
1061 // priv->ready = FALSE;
1065 _tick_cb(gpointer user_data)
1067 GstFormat format = GST_FORMAT_BYTES;
1070 GMencoderPrivate *priv = G_MENCODER_GET_PRIVATE(user_data);
1072 if (priv->duration == 0) {
1074 if (gst_element_query_duration(priv->src, &format, &d))
1078 if (priv->duration != 0) {
1079 gst_element_query_position(priv->src, &format, &cur);
1080 g_print("PROGRESS:%lli\n", (99 * cur) / priv->duration);
1087 #ifdef USE_MANUAL_SINK
1089 _send_buffer (GnomeVFSHandle *handle, gpointer buff, gint size)
1093 GnomeVFSResult result;
1094 GnomeVFSFileSize bytes_written;
1096 b_send = g_byte_array_new ();
1097 msg = g_strdup_printf ("%x\r\n", size);
1098 b_send = g_byte_array_append (b_send, (const guint8*) msg, strlen (msg) * sizeof (gchar));
1101 b_send = g_byte_array_append (b_send, buff, size);
1103 msg = g_strdup ("\r\n");
1104 b_send = g_byte_array_append (b_send, (const guint8*) msg, strlen (msg) * sizeof (gchar));
1107 result = gnome_vfs_write (handle, b_send->data, b_send->len, &bytes_written);
1108 g_byte_array_free (b_send, TRUE);
1110 return (result == GNOME_VFS_OK);
1114 _flush_queue (GMencoder *self)
1116 GMencoderPrivate *priv = G_MENCODER_GET_PRIVATE(self);
1118 if (priv->send_chunked) {
1119 GnomeVFSFileSize bytes_written;
1121 end_msg = g_strdup ("0\r\n\r\n");
1122 gnome_vfs_write (priv->handle,
1123 (const guint8*) end_msg,
1124 strlen(end_msg) * sizeof(gchar),
1131 _buffer_arrive_cb (GstElement* object,
1136 GMencoderPrivate *priv = G_MENCODER_GET_PRIVATE(user_data);
1139 if (priv->send_chunked) {
1140 if (_send_buffer (priv->handle, GST_BUFFER_DATA (buff), GST_BUFFER_SIZE (buff)) == FALSE)
1143 GnomeVFSResult result;
1144 GnomeVFSFileSize bytes_written;
1146 result = gnome_vfs_write (priv->handle,
1147 GST_BUFFER_DATA (buff),
1148 GST_BUFFER_SIZE (buff),
1151 if (result != GNOME_VFS_OK)
1158 if (priv->tick_id != 0) {
1159 g_source_remove(priv->tick_id);
1162 g_signal_emit(user_data, g_mencoder_signals[ERROR], 0, "Fail to write on socket");
1163 gst_element_set_state (priv->pipe, GST_STATE_PAUSED);