11 #include <sys/types.h>
12 #include <sys/socket.h>
13 #include <libgnomevfs/gnome-vfs.h>
14 #include <gst/interfaces/tuner.h>
16 #include "gmencoder.h"
18 #define G_MENCODER_GET_PRIVATE(obj) \
19 (G_TYPE_INSTANCE_GET_PRIVATE ((obj), G_TYPE_MENCODER, GMencoderPrivate))
21 #define USE_MANUAL_SINK
22 #define GMENCODER_TIMEOUT 5000
24 typedef struct _GMencoderPrivate GMencoderPrivate;
25 typedef struct _SetupInfo SetupInfo;
30 gchar **video_encode_prop;
36 gchar **audio_encode_prop;
41 struct _GMencoderPrivate {
48 GnomeVFSHandle *handle;
57 gboolean send_chunked;
76 static void g_mencoder_class_init(GMencoderClass * klass);
77 static void g_mencoder_init(GMencoder * object);
78 static void g_mencoder_dispose(GObject * object);
79 static void g_mencoder_finalize(GObject * object);
80 static GstElement *_create_audio_bin(const gchar * encode,
81 gchar ** encode_prop, gint rate);
82 static GstElement *_create_video_bin(const gchar * encode,
85 gint rate, guint width, guint height,
86 gboolean use_deinterlace);
89 _pipeline_bus_cb(GstBus * bus, GstMessage * msg, gpointer user_data);
91 static void _decodebin_new_pad_cb(GstElement * object,
93 gboolean flag, gpointer user_data);
95 static void _decodebin_unknown_type_cb(GstElement * object,
100 static void _close_output(GMencoder * self);
101 static gboolean _open_output(GMencoder * self, const gchar * uri);
103 static GstElement *_create_source(GMencoder *self, const gchar * uri);
104 static GstElement *_create_pipeline(GMencoder * self,
105 const gchar * video_encode,
106 const gchar * mux_name,
107 gchar ** video_encode_prop,
112 const gchar * audio_encode,
113 gchar ** audio_encode_prop,
115 gboolean deinterlace);
116 static gboolean _process_timeout_cb (gpointer user_data);
117 #ifdef USE_MANUAL_SINK
118 static void _flush_queue (GMencoder *self);
119 static void _buffer_arrive_cb (GstElement* object,
126 static gboolean _tick_cb(gpointer data);
128 static guint g_mencoder_signals[LAST_SIGNAL] = { 0 };
130 G_DEFINE_TYPE(GMencoder, g_mencoder, G_TYPE_OBJECT)
132 static void g_mencoder_class_init(GMencoderClass * klass)
134 GObjectClass *object_class;
135 object_class = (GObjectClass *) klass;
136 g_type_class_add_private(klass, sizeof(GMencoderPrivate));
138 object_class->dispose = g_mencoder_dispose;
139 object_class->finalize = g_mencoder_finalize;
141 g_mencoder_signals[PAUSED] =
142 g_signal_new("paused",
143 G_OBJECT_CLASS_TYPE(object_class),
146 g_cclosure_marshal_VOID__VOID, G_TYPE_NONE, 0);
148 g_mencoder_signals[PLAYING] =
149 g_signal_new("playing",
150 G_OBJECT_CLASS_TYPE(object_class),
153 g_cclosure_marshal_VOID__VOID, G_TYPE_NONE, 0);
155 g_mencoder_signals[STOPED] =
156 g_signal_new("stoped",
157 G_OBJECT_CLASS_TYPE(object_class),
160 g_cclosure_marshal_VOID__VOID, G_TYPE_NONE, 0);
162 g_mencoder_signals[EOS] =
164 G_OBJECT_CLASS_TYPE(object_class),
167 g_cclosure_marshal_VOID__VOID, G_TYPE_NONE, 0);
169 g_mencoder_signals[ERROR] =
170 g_signal_new("error",
171 G_OBJECT_CLASS_TYPE(object_class),
174 g_cclosure_marshal_VOID__STRING,
175 G_TYPE_NONE, 1, G_TYPE_STRING);
179 g_mencoder_init(GMencoder * self)
181 GMencoderPrivate *priv = G_MENCODER_GET_PRIVATE(self);
182 priv->info = g_new0(SetupInfo, 1);
186 g_mencoder_dispose(GObject * object)
191 g_mencoder_finalize(GObject * object)
193 GMencoderPrivate *priv = G_MENCODER_GET_PRIVATE(object);
196 g_mencoder_close_stream(G_MENCODER(object));
203 return g_object_new(G_TYPE_MENCODER, NULL);
208 _obj_set_prop(GObject * obj, const gchar * prop_name,
209 const gchar * prop_val)
213 GParamSpec *s = NULL;
214 GObjectClass *k = G_OBJECT_GET_CLASS(obj);
217 g_value_init(&v, G_TYPE_STRING);
218 g_value_set_string(&v, prop_val);
220 s = g_object_class_find_property(k, prop_name);
222 g_print("Invalid property name: %s\n", prop_name);
226 g_value_init(&p, s->value_type);
227 switch (s->value_type) {
229 g_value_set_int(&p, atoi(prop_val));
232 g_value_set_uint (&p, (guint) atoi(prop_val));
235 g_value_set_ulong (&p, atol(prop_val));
238 g_value_set_string(&p, prop_val);
241 g_value_set_boolean(&p, (gboolean) atoi (prop_val));
244 g_value_set_double(&p, atof (prop_val));
247 g_value_set_float(&p, (float) atof (prop_val));
250 g_value_set_enum(&p, atoi(prop_val));
251 g_warning ("Property %s of type %s. Not supported using default enum",
252 prop_name, g_type_name (s->value_type));
256 g_object_set_property(obj, prop_name, &p);
262 _create_element_with_prop(const gchar * factory_name,
263 const gchar * element_name, gchar ** prop)
268 ret = gst_element_factory_make(factory_name, element_name);
273 for (i = 0; i < g_strv_length(prop); i++) {
274 if (prop[i] != NULL) {
275 char **v = g_strsplit(prop[i], "=", 2);
276 if (g_strv_length(v) == 2) {
277 _obj_set_prop(G_OBJECT(ret), v[0], v[1]);
289 _create_audio_bin(const gchar * encode, gchar ** encode_prop, gint rate)
291 GstElement *abin = NULL;
292 GstElement *aqueue = NULL;
293 GstElement *aconvert = NULL;
294 GstElement *aencode = NULL;
295 GstElement *aqueue_src = NULL;
298 // audio/x-raw-int ! queue ! audioconvert ! faac ! rtpmp4gpay !
299 // udpsink name=upd_audio host=224.0.0.1 port=5002
300 abin = gst_bin_new("abin");
301 aqueue = gst_element_factory_make("queue", "aqueue");
302 aconvert = gst_element_factory_make("audioconvert", "aconvert");
304 _create_element_with_prop((encode ? encode : "lame"), "aencode",
306 aqueue_src = gst_element_factory_make("queue", "aqueue_src");
308 if ((abin == NULL) || (aqueue == NULL) || (aconvert == NULL)
309 || (aencode == NULL) || (aqueue_src == NULL)) {
310 g_warning("Audio elements not found");
316 gst_bin_add_many(GST_BIN(abin), aqueue, aconvert, aencode, aqueue_src,
319 if (!gst_element_link (aqueue, aconvert))
321 g_warning("Not Link audio elements");
328 caps = gst_caps_new_simple ("audio/x-raw-int",
329 "rate", G_TYPE_INT, rate, NULL);
330 if (!gst_element_link_filtered (aconvert, aencode, caps))
332 gst_caps_unref (caps);
333 g_warning("Not link rate filter");
337 gst_caps_unref (caps);
341 if (!gst_element_link (aconvert, aencode))
343 g_warning ("Fail to link audio elements");
349 if (!gst_element_link (aencode, aqueue_src))
351 g_warning("Not Link audio elements");
354 // TODO: apply audio rate
356 // ghost pad the audio bin
357 apad = gst_element_get_pad(aqueue, "sink");
358 gst_element_add_pad(abin, gst_ghost_pad_new("sink", apad));
359 gst_object_unref(apad);
361 apad = gst_element_get_pad(aqueue_src, "src");
362 gst_element_add_pad(abin, gst_ghost_pad_new("src", apad));
363 gst_object_unref(apad);
368 gst_object_unref(abin);
371 gst_object_unref(aqueue);
373 if (aconvert != NULL)
374 gst_object_unref(aconvert);
377 gst_object_unref(aencode);
379 if (aqueue_src != NULL)
380 gst_object_unref(aqueue_src);
383 gst_object_unref(apad);
391 // queue ! videoscale ! video/x-raw-yuv,width=240,height=144 ! colorspace
392 // ! rate ! encode ! queue
394 _create_video_bin(const gchar * encode,
395 gchar ** encode_prop,
396 gdouble fps, gint rate, guint width, guint height,
397 gboolean use_deinterlace)
399 GstElement *vbin = NULL;
400 GstElement *vqueue = NULL;
401 GstElement *vqueue_src = NULL;
402 GstElement *vcolorspace = NULL;
403 GstElement *vencode = NULL;
404 GstElement *vrate = NULL;
405 GstElement *deinterlace = NULL;
406 GstElement *walk = NULL;
409 vbin = gst_bin_new("vbin");
410 vqueue = gst_element_factory_make("queue", "vqueue");
412 gst_element_factory_make("ffmpegcolorspace", "colorspace");
414 if (use_deinterlace) {
415 deinterlace = gst_element_factory_make ("ffdeinterlace", "deinterlace");
416 if (deinterlace == NULL) {
417 g_warning ("Fail to create deinterlace element: Continue without deinterlace.");
422 vencode = _create_element_with_prop((encode !=
424 "ffenc_mpeg1video"), "vencode",
426 vqueue_src = gst_element_factory_make("queue", "queue_src");
428 if ((vbin == NULL) || (vqueue == NULL) || (vcolorspace == NULL)
429 || (vencode == NULL) || (vqueue_src == NULL)) {
430 g_warning("Video elements not found");
434 gst_bin_add_many(GST_BIN(vbin), vqueue, vcolorspace, vencode,
437 if (deinterlace != NULL) {
438 gst_bin_add(GST_BIN(vbin), deinterlace);
439 gst_element_link (vqueue, deinterlace);
445 if ((width > 0) && (height > 0)) {
450 vscale = gst_element_factory_make("videoscale", "vscale");
451 //g_object_set (G_OBJECT (vscale), "method", 1, NULL);
452 gst_bin_add(GST_BIN(vbin), vscale);
454 vcaps = gst_caps_new_simple("video/x-raw-yuv",
455 "width", G_TYPE_INT, width,
456 "height", G_TYPE_INT, height, NULL);
458 gst_element_link(walk, vscale);
460 if (gst_element_link_filtered(vscale, vcolorspace, vcaps) == FALSE) {
461 g_warning("Fail to resize video");
462 gst_object_unref(vcaps);
463 gst_object_unref(vscale);
466 gst_caps_unref(vcaps);
468 gst_element_link(walk, vcolorspace);
472 // Changing the video fps
474 vrate = gst_element_factory_make("videorate", "vrate");
476 gst_bin_add(GST_BIN(vbin), vrate);
478 if (gst_element_link(vcolorspace, vrate) == FALSE) {
479 g_warning("Fail to link video elements");
483 vcaps = gst_caps_new_simple("video/x-raw-yuv",
484 "framerate", GST_TYPE_FRACTION,
485 (int) (fps * 1000), 1000, NULL);
487 if (gst_element_link_filtered(vrate, vencode, vcaps) == FALSE) {
488 g_warning("Fail to link vrate with vencode.");
491 gst_caps_unref(vcaps);
493 if (gst_element_link(vcolorspace, vencode) == FALSE) {
494 g_warning("Fail to link colorspace and video encode element.");
499 gst_element_link(vencode, vqueue_src);
501 // ghost pad the video bin
502 vpad = gst_element_get_pad(vqueue, "sink");
503 gst_element_add_pad(vbin, gst_ghost_pad_new("sink", vpad));
504 gst_object_unref(vpad);
506 vpad = gst_element_get_pad(vqueue_src, "src");
507 gst_element_add_pad(vbin, gst_ghost_pad_new("src", vpad));
508 gst_object_unref(vpad);
514 gst_object_unref(vpad);
517 gst_object_unref(vbin);
520 gst_object_unref(vqueue);
523 gst_object_unref(vencode);
525 if (vqueue_src != NULL)
526 gst_object_unref(vqueue_src);
528 if (vcolorspace != NULL)
529 gst_object_unref(vcolorspace);
537 g_mencoder_setup_stream(GMencoder * self,
539 gboolean deinterlace,
540 const gchar * mux_name,
541 const gchar * video_encode,
542 gchar ** video_encode_prop,
547 const gchar * audio_encode,
548 gchar ** audio_encode_prop,
549 guint audio_rate, const gchar * out_uri)
551 GMencoderPrivate *priv = G_MENCODER_GET_PRIVATE(self);
552 if (priv->ready == TRUE) {
554 ("Stream already configured. You need close stream first.");
559 if (_open_output(self, out_uri) == FALSE) {
564 priv->send_chunked = chunked;
565 priv->pipe = _create_pipeline(self,
573 audio_encode, audio_encode_prop,
577 return (priv->pipe != NULL);
582 g_mencoder_append_uri(GMencoder * self, const gchar * uri)
587 GMencoderPrivate *priv = G_MENCODER_GET_PRIVATE(self);
588 gboolean ret = FALSE;
589 GstElement *ap = NULL;
590 GstElement *vp = NULL;
593 g_return_val_if_fail(priv->pipe != NULL, FALSE);
594 g_return_val_if_fail(priv->ready == FALSE, FALSE);
596 src = _create_source(self, uri);
600 priv->src = gst_bin_get_by_name(GST_BIN(src), "src");
602 gst_bin_add(GST_BIN(priv->pipe), src);
604 ap = gst_bin_get_by_name(GST_BIN(priv->pipe), "abin");
605 vp = gst_bin_get_by_name(GST_BIN(priv->pipe), "vbin");
607 if ((vp == NULL) || (ap == NULL)) {
608 g_warning("Fail to get output bin");
612 pad_src = gst_element_get_pad(src, "src_audio");
613 pad_sink = gst_element_get_compatible_pad(ap,
615 gst_pad_get_caps(pad_src));
617 if ((pad_sink == NULL) || (pad_src == NULL))
620 GstPadLinkReturn lret = gst_pad_link(pad_src, pad_sink);
621 if (lret != GST_PAD_LINK_OK)
624 gst_object_unref(pad_src);
625 gst_object_unref(pad_sink);
627 pad_src = gst_element_get_pad(src, "src_video");
628 pad_sink = gst_element_get_compatible_pad(vp,
630 gst_pad_get_caps(pad_src));
632 if ((pad_src == NULL) || (pad_sink == NULL))
635 if (gst_pad_link(pad_src, pad_sink) != GST_PAD_LINK_OK) {
636 g_warning("invalid source. video");
644 if ((src != NULL) && (ret == FALSE)) {
645 gst_bin_remove(GST_BIN(priv->pipe), src);
646 gst_object_unref(src);
650 gst_object_unref(ap);
653 gst_object_unref(vp);
656 gst_object_unref(pad_src);
658 if (pad_sink != NULL)
659 gst_object_unref(pad_sink);
667 g_mencoder_remove_uri(GMencoder * self, const gchar * uri)
669 // GMencoderPrivate *priv = G_MENCODER_GET_PRIVATE (self);
674 g_mencoder_play_stream(GMencoder * self)
676 GMencoderPrivate *priv = G_MENCODER_GET_PRIVATE(self);
677 g_return_if_fail(priv->ready == FALSE);
679 gst_element_set_state(priv->pipe, GST_STATE_PLAYING);
680 if (priv->tick_id != 0) {
681 g_source_remove (priv->tick_id);
683 priv->tick_id = g_timeout_add(500, _tick_cb, self);
685 if (priv->timeout_id != 0) {
686 g_source_remove (priv->timeout_id);
688 //priv->timeout_id = g_timeout_add(GMENCODER_TIMEOUT, _process_timeout_cb, self);
692 g_mencoder_pause_stream(GMencoder * self)
694 GMencoderPrivate *priv = G_MENCODER_GET_PRIVATE(self);
695 g_return_if_fail(priv->ready == TRUE);
696 gst_element_set_state(priv->pipe, GST_STATE_PAUSED);
700 g_mencoder_close_stream(GMencoder * self)
703 GMencoderPrivate *priv = G_MENCODER_GET_PRIVATE(self);
704 if (priv->tick_id != 0) {
705 g_source_remove(priv->tick_id);
709 if (priv->timeout_id != 0) {
710 g_source_remove (priv->timeout_id);
711 priv->timeout_id = 0;
714 if (priv->pipe != NULL) {
715 // TODO: fixe pipeline dispose
716 //gst_element_set_state (priv->pipe, GST_STATE_NULL);
717 // g_debug ("SETING STATE TO NULL: OK");
718 // gst_element_set_state (priv->pipe, GST_STATE_NULL);
719 //gst_object_unref (priv->pipe);
720 //gst_object_unref(priv->src);
731 _create_pipeline(GMencoder * self,
732 const gchar * video_encode,
733 const gchar * mux_name,
734 gchar ** video_encode_prop,
739 const gchar * audio_encode,
740 gchar ** audio_encode_prop, guint audio_rate,
741 gboolean deinterlace)
744 GstElement *pipe = NULL;
745 GstElement *sink = NULL;
746 GstElement *mux = NULL;
747 GstElement *abin = NULL;
748 GstElement *vbin = NULL;
749 GstElement *queue = NULL;
750 GstPad *aux_pad = NULL;
751 GstPad *mux_pad = NULL;
753 pipe = gst_pipeline_new("pipe");
756 gst_element_factory_make((mux_name ? mux_name : "ffmux_mpeg"),
761 queue = gst_element_factory_make("queue", "queueu_sink");
764 sink = gst_element_factory_make("fakesink", "sink");
765 g_object_set (G_OBJECT (sink), "signal-handoffs", TRUE, NULL);
766 g_signal_connect (G_OBJECT (sink),
768 G_CALLBACK (_buffer_arrive_cb),
771 abin = _create_audio_bin(audio_encode, audio_encode_prop, audio_rate);
776 _create_video_bin(video_encode, video_encode_prop, video_fps,
777 video_rate, video_width, video_height, deinterlace);
782 gst_bin_add_many(GST_BIN(pipe), abin, vbin, mux, queue, sink, NULL);
785 // Link bins with mux
786 aux_pad = gst_element_get_pad(abin, "src");
788 gst_element_get_compatible_pad(mux, aux_pad,
789 GST_PAD_CAPS(aux_pad));
790 if (mux_pad == NULL) {
791 g_warning("Mux element no have audio PAD");
794 GstPadLinkReturn ret = gst_pad_link(aux_pad, mux_pad);
795 if (ret != GST_PAD_LINK_OK) {
796 g_warning("Fail link audio and mux: %d", ret);
800 gst_object_unref(aux_pad);
801 gst_object_unref(mux_pad);
803 aux_pad = gst_element_get_pad(vbin, "src");
805 gst_element_get_compatible_pad(mux, aux_pad,
806 GST_PAD_CAPS(aux_pad));
807 if (mux_pad == NULL) {
808 g_warning("Mux element no have video PAD");
811 ret = gst_pad_link(aux_pad, mux_pad);
812 if (ret != GST_PAD_LINK_OK) {
813 g_warning("Fail link video and mux: %d", ret);
816 gst_object_unref(aux_pad);
817 gst_object_unref(mux_pad);
821 // Link mux with sink
822 gst_element_link_many(mux, queue, sink, NULL);
824 bus = gst_pipeline_get_bus(GST_PIPELINE(pipe));
825 gst_bus_add_watch(bus, _pipeline_bus_cb, self);
826 gst_object_unref(bus);
830 g_warning("Invalid uri");
833 gst_object_unref(pipe);
838 gst_object_unref(mux);
841 if (mux_pad != NULL) {
842 gst_object_unref(mux_pad);
845 if (aux_pad != NULL) {
846 gst_object_unref(mux_pad);
850 gst_object_unref(sink);
854 gst_object_unref(abin);
858 gst_object_unref(vbin);
866 _close_output(GMencoder * self)
871 _create_v4l_source (GMencoder *self, const gchar * uri)
874 GMencoderPrivate *priv = G_MENCODER_GET_PRIVATE(self);
877 info = g_strsplit (uri+6, ":", 3);
878 if (g_strv_length (info) != 3) {
882 priv->v4lsrc = gst_element_factory_make ("v4l2src", "src");
883 g_debug ("channel %s, norm %s, frequ %s", info[0], info[1], info[2]);
884 g_object_set (G_OBJECT (priv->v4lsrc),
887 "frequency", atoi (info[2]),
894 _create_source(GMencoder *self, const gchar * uri)
897 GstElement *bsrc = NULL;
898 GstElement *src = NULL;
899 GstElement *aqueue = NULL;
900 GstElement *vqueue = NULL;
901 GstElement *decode = NULL;
902 GstPad *src_pad = NULL;
905 bsrc = gst_bin_new(NULL);
907 // src = gst_element_factory_make ("gnomevfssrc", "src");
908 // g_object_set (G_OBJECT (src), "location", uri, NULL);
909 if (strncmp (uri, "v4l://", 6) == 0) {
911 src = _create_v4l_source (self, uri);
914 src = gst_element_make_from_uri(GST_URI_SRC, uri, "src");
921 if (g_getenv ("USE_DECODEBIN1"))
922 decode = gst_element_factory_make("decodebin", "decode");
924 decode = gst_element_factory_make("decodebin2", "decode");
928 aqueue = gst_element_factory_make("queue", "aqueue");
932 vqueue = gst_element_factory_make("queue", "vqueue");
936 gst_bin_add_many(GST_BIN(bsrc), src, decode, aqueue, vqueue,
938 gst_element_link (src, decode);
940 g_signal_connect(G_OBJECT(decode),
942 G_CALLBACK(_decodebin_new_pad_cb), bsrc);
944 g_signal_connect(G_OBJECT(decode),
946 G_CALLBACK(_decodebin_unknown_type_cb), pipe);
948 src_pad = gst_element_get_pad(aqueue, "src");
949 gst_element_add_pad(bsrc, gst_ghost_pad_new("src_audio", src_pad));
950 gst_object_unref(src_pad);
952 src_pad = gst_element_get_pad(vqueue, "src");
953 gst_element_add_pad(bsrc, gst_ghost_pad_new("src_video", src_pad));
954 gst_object_unref(src_pad);
959 g_debug ("Fail to create source element");
961 gst_object_unref(src);
964 if (decode != NULL) {
965 gst_object_unref(decode);
968 if (aqueue != NULL) {
969 gst_object_unref(aqueue);
972 if (vqueue != NULL) {
973 gst_object_unref(vqueue);
980 _open_output(GMencoder * self, const gchar * uri)
983 GnomeVFSResult result;
984 GMencoderPrivate *priv = G_MENCODER_GET_PRIVATE(self);
986 i = g_strsplit(uri, "://", 0);
987 if (strcmp(i[0], "fd") == 0) {
988 result = gnome_vfs_open_fd (&priv->handle, atoi(i[1]));
990 if (g_file_test (i[1], G_FILE_TEST_EXISTS) == FALSE) {
991 result = gnome_vfs_create (&priv->handle, uri, GNOME_VFS_OPEN_WRITE, FALSE,
992 GNOME_VFS_PERM_USER_WRITE | GNOME_VFS_PERM_USER_READ | GNOME_VFS_PERM_GROUP_READ);
994 result = gnome_vfs_open (&priv->handle, uri,
995 GNOME_VFS_OPEN_WRITE | GNOME_VFS_OPEN_TRUNCATE);
1000 return (result == GNOME_VFS_OK);
1004 _pipeline_bus_cb(GstBus * bus, GstMessage * msg, gpointer user_data)
1006 GMencoderPrivate *priv = G_MENCODER_GET_PRIVATE(user_data);
1008 switch (GST_MESSAGE_TYPE(msg)) {
1010 case GST_MESSAGE_STATE_CHANGED:
1014 GstState pendingstate;
1017 gst_message_parse_state_changed(msg, &oldstate,
1018 &newstate, &pendingstate);
1020 if (pendingstate != GST_STATE_VOID_PENDING)
1023 if ((oldstate == GST_STATE_READY)
1024 && (newstate == GST_STATE_PAUSED)) {
1026 g_signal_emit(user_data, g_mencoder_signals[PAUSED],
1028 } else if ((oldstate == GST_STATE_PAUSED)
1029 && (newstate == GST_STATE_PLAYING)) {
1030 g_signal_emit(user_data, g_mencoder_signals[PLAYING], 0);
1031 } else if ((oldstate == GST_STATE_READY) &&
1032 (newstate == GST_STATE_NULL)) {
1033 g_signal_emit(user_data, g_mencoder_signals[STOPED], 0);
1038 case GST_MESSAGE_ERROR:
1044 if (priv->tick_id != 0) {
1045 g_source_remove(priv->tick_id);
1049 gst_message_parse_error(msg, &error, &debug);
1050 err_str = g_strdup_printf("Error [%d] %s (%s)", error->code,
1051 error->message, debug);
1052 priv->ready = FALSE;
1054 g_signal_emit(user_data, g_mencoder_signals[ERROR], 0,
1058 g_clear_error(&error);
1063 case GST_MESSAGE_EOS:
1064 priv->ready = FALSE;
1065 #ifdef USE_MANUAL_SINK
1066 _flush_queue (G_MENCODER (user_data));
1068 g_signal_emit(user_data, g_mencoder_signals[EOS], 0);
1071 case GST_MESSAGE_DURATION:
1075 gst_message_parse_duration(msg, &format, &duration);
1076 if (format == GST_FORMAT_BYTES)
1077 priv->duration = duration;
1091 _decodebin_new_pad_cb(GstElement * object,
1092 GstPad * pad, gboolean flag, gpointer user_data)
1095 gchar *str_caps = NULL;
1096 GstElement *sink_element;
1099 caps = gst_pad_get_caps(pad);
1100 str_caps = gst_caps_to_string(caps);
1101 if (strstr(str_caps, "audio") != NULL) {
1102 sink_element = gst_bin_get_by_name(GST_BIN(user_data), "aqueue");
1103 } else if (strstr(str_caps, "video") != NULL) {
1104 sink_element = gst_bin_get_by_name(GST_BIN(user_data), "vqueue");
1106 g_warning("invalid caps %s", str_caps);
1109 sink_pad = gst_element_get_pad(sink_element, "sink");
1110 if (!gst_pad_is_linked (sink_pad))
1111 gst_pad_link(pad, sink_pad);
1113 gst_object_unref(sink_element);
1114 gst_object_unref(sink_pad);
1116 gst_caps_unref(caps);
1120 _decodebin_unknown_type_cb(GstElement * object,
1121 GstPad * pad, GstCaps * caps,
1124 g_warning("Unknown Type");
1125 // priv->ready = FALSE;
1129 _tick_cb(gpointer user_data)
1131 GstFormat format = GST_FORMAT_BYTES;
1134 GMencoderPrivate *priv = G_MENCODER_GET_PRIVATE(user_data);
1136 if (priv->duration == 0) {
1138 if (gst_element_query_duration(priv->src, &format, &d))
1142 if (priv->duration != 0) {
1143 gst_element_query_position(priv->src, &format, &cur);
1144 g_print("PROGRESS:%lli\n", (99 * cur) / priv->duration);
1151 _process_timeout_cb (gpointer user_data)
1153 GMencoderPrivate *priv = G_MENCODER_GET_PRIVATE(user_data);
1155 g_signal_emit(user_data, g_mencoder_signals[ERROR], 0, "timeout");
1156 priv->timeout_id = 0;
1161 #ifdef USE_MANUAL_SINK
1163 _send_buffer (GnomeVFSHandle *handle, gpointer buff, gint size)
1167 GnomeVFSResult result;
1168 GnomeVFSFileSize bytes_written;
1170 b_send = g_byte_array_new ();
1171 msg = g_strdup_printf ("%x\r\n", size);
1172 b_send = g_byte_array_append (b_send, (const guint8*) msg, strlen (msg) * sizeof (gchar));
1175 b_send = g_byte_array_append (b_send, buff, size);
1177 msg = g_strdup ("\r\n");
1178 b_send = g_byte_array_append (b_send, (const guint8*) msg, strlen (msg) * sizeof (gchar));
1181 result = gnome_vfs_write (handle, b_send->data, b_send->len, &bytes_written);
1182 g_byte_array_free (b_send, TRUE);
1184 return (result == GNOME_VFS_OK);
1188 _flush_queue (GMencoder *self)
1190 GMencoderPrivate *priv = G_MENCODER_GET_PRIVATE(self);
1192 if (priv->send_chunked) {
1193 GnomeVFSFileSize bytes_written;
1195 end_msg = g_strdup ("0\r\n\r\n");
1196 gnome_vfs_write (priv->handle,
1197 (const guint8*) end_msg,
1198 strlen(end_msg) * sizeof(gchar),
1205 _buffer_arrive_cb (GstElement* object,
1210 GMencoderPrivate *priv = G_MENCODER_GET_PRIVATE(user_data);
1212 if (priv->timeout_id != 0) {
1213 g_source_remove (priv->timeout_id);
1214 priv->timeout_id = 0;
1217 if (priv->send_chunked) {
1218 if (_send_buffer (priv->handle, GST_BUFFER_DATA (buff), GST_BUFFER_SIZE (buff)) == FALSE)
1221 GnomeVFSResult result;
1222 GnomeVFSFileSize bytes_written;
1224 result = gnome_vfs_write (priv->handle,
1225 GST_BUFFER_DATA (buff),
1226 GST_BUFFER_SIZE (buff),
1229 if (result != GNOME_VFS_OK)
1236 if (priv->tick_id != 0) {
1237 g_source_remove(priv->tick_id);
1240 g_signal_emit(user_data, g_mencoder_signals[ERROR], 0, "Fail to write on socket");
1241 gst_element_set_state (priv->pipe, GST_STATE_PAUSED);