11 #include <sys/types.h>
12 #include <sys/socket.h>
14 #include "gmencoder.h"
16 #define G_MENCODER_GET_PRIVATE(obj) \
17 (G_TYPE_INSTANCE_GET_PRIVATE ((obj), G_TYPE_MENCODER, GMencoderPrivate))
19 // #define SUPPORT_MULT_INPUT 0
20 #define USE_MANUAL_SINK
21 #define BUFFER_SIZE (1024 * 64)
23 typedef struct _GMencoderPrivate GMencoderPrivate;
24 typedef struct _SetupInfo SetupInfo;
29 gchar **video_encode_prop;
35 gchar **audio_encode_prop;
40 struct _GMencoderPrivate {
54 gboolean send_chunked;
55 #ifdef USE_MANUAL_SINK
69 static void g_mencoder_class_init(GMencoderClass * klass);
70 static void g_mencoder_init(GMencoder * object);
71 static void g_mencoder_dispose(GObject * object);
72 static void g_mencoder_finalize(GObject * object);
73 static GstElement *_create_audio_bin(const gchar * encode,
74 gchar ** encode_prop, gint rate);
75 static GstElement *_create_video_bin(const gchar * encode,
78 gint rate, guint width, guint height);
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 #ifdef USE_MANUAL_SINK
108 static void _flush_queue (GMencoder *self);
109 static void _buffer_arrive_cb (GstElement* object,
116 static gboolean _tick_cb(gpointer data);
118 static guint g_mencoder_signals[LAST_SIGNAL] = { 0 };
120 G_DEFINE_TYPE(GMencoder, g_mencoder, G_TYPE_OBJECT)
122 static void g_mencoder_class_init(GMencoderClass * klass)
124 GObjectClass *object_class;
125 object_class = (GObjectClass *) klass;
126 g_type_class_add_private(klass, sizeof(GMencoderPrivate));
128 object_class->dispose = g_mencoder_dispose;
129 object_class->finalize = g_mencoder_finalize;
131 g_mencoder_signals[PAUSED] =
132 g_signal_new("paused",
133 G_OBJECT_CLASS_TYPE(object_class),
136 g_cclosure_marshal_VOID__VOID, G_TYPE_NONE, 0);
138 g_mencoder_signals[PLAYING] =
139 g_signal_new("playing",
140 G_OBJECT_CLASS_TYPE(object_class),
143 g_cclosure_marshal_VOID__VOID, G_TYPE_NONE, 0);
145 g_mencoder_signals[STOPED] =
146 g_signal_new("stoped",
147 G_OBJECT_CLASS_TYPE(object_class),
150 g_cclosure_marshal_VOID__VOID, G_TYPE_NONE, 0);
152 g_mencoder_signals[EOS] =
154 G_OBJECT_CLASS_TYPE(object_class),
157 g_cclosure_marshal_VOID__VOID, G_TYPE_NONE, 0);
159 g_mencoder_signals[ERROR] =
160 g_signal_new("error",
161 G_OBJECT_CLASS_TYPE(object_class),
164 g_cclosure_marshal_VOID__STRING,
165 G_TYPE_NONE, 1, G_TYPE_STRING);
169 g_mencoder_init(GMencoder * self)
171 GMencoderPrivate *priv = G_MENCODER_GET_PRIVATE(self);
172 priv->info = g_new0(SetupInfo, 1);
173 #ifdef USE_MANUAL_SINK
174 priv->queue = g_byte_array_new ();
179 g_mencoder_dispose(GObject * object)
184 g_mencoder_finalize(GObject * object)
186 GMencoderPrivate *priv = G_MENCODER_GET_PRIVATE(object);
189 g_mencoder_close_stream(G_MENCODER(object));
191 #ifdef USE_MANUAL_SINK
192 g_byte_array_free (priv->queue, TRUE);
199 return g_object_new(G_TYPE_MENCODER, NULL);
204 _obj_set_prop(GObject * obj, const gchar * prop_name,
205 const gchar * prop_val)
209 GParamSpec *s = NULL;
210 GObjectClass *k = G_OBJECT_GET_CLASS(obj);
213 g_value_init(&v, G_TYPE_STRING);
214 g_value_set_string(&v, prop_val);
216 s = g_object_class_find_property(k, prop_name);
218 g_print("Invalid property name: %s\n", prop_name);
222 g_value_init(&p, s->value_type);
223 switch (s->value_type) {
225 g_value_set_int(&p, atoi(prop_val));
228 g_value_set_string(&p, prop_val);
234 g_object_set_property(obj, prop_name, &p);
240 _create_element_with_prop(const gchar * factory_name,
241 const gchar * element_name, gchar ** prop)
246 ret = gst_element_factory_make(factory_name, element_name);
251 for (i = 0; i < g_strv_length(prop); i++) {
252 if (prop[i] != NULL) {
253 char **v = g_strsplit(prop[i], "=", 2);
254 if (g_strv_length(v) == 2) {
255 _obj_set_prop(G_OBJECT(ret), v[0], v[1]);
267 _create_audio_bin(const gchar * encode, gchar ** encode_prop, gint rate)
269 GstElement *abin = NULL;
270 GstElement *aqueue = NULL;
271 GstElement *aconvert = NULL;
272 GstElement *aencode = NULL;
273 GstElement *aqueue_src = NULL;
276 // audio/x-raw-int ! queue ! audioconvert ! faac ! rtpmp4gpay !
277 // udpsink name=upd_audio host=224.0.0.1 port=5002
278 abin = gst_bin_new("abin");
279 aqueue = gst_element_factory_make("queue", "aqueue");
280 aconvert = gst_element_factory_make("audioconvert", "aconvert");
282 _create_element_with_prop((encode ? encode : "lame"), "aencode",
284 aqueue_src = gst_element_factory_make("queue", "aqueue_src");
286 if ((abin == NULL) || (aqueue == NULL) || (aconvert == NULL)
287 || (aencode == NULL) || (aqueue_src == NULL)) {
288 g_warning("Audio elements not found");
292 g_object_set(G_OBJECT(aencode), "bitrate", 32, NULL);
294 * if (rate > 0) { g_object_set (G_OBJECT (aencode), "bitrate", 32,
298 gst_bin_add_many(GST_BIN(abin), aqueue, aconvert, aencode, aqueue_src,
300 if (gst_element_link_many(aqueue, aconvert, aencode, aqueue_src, NULL)
302 g_warning("Not Link audio elements");
304 // TODO: apply audio rate
306 // ghost pad the audio bin
307 apad = gst_element_get_pad(aqueue, "sink");
308 gst_element_add_pad(abin, gst_ghost_pad_new("sink", apad));
309 gst_object_unref(apad);
311 apad = gst_element_get_pad(aqueue_src, "src");
312 gst_element_add_pad(abin, gst_ghost_pad_new("src", apad));
313 gst_object_unref(apad);
318 gst_object_unref(abin);
321 gst_object_unref(aqueue);
323 if (aconvert != NULL)
324 gst_object_unref(aconvert);
327 gst_object_unref(aencode);
329 if (aqueue_src != NULL)
330 gst_object_unref(aqueue_src);
333 gst_object_unref(apad);
341 // queue ! videoscale ! video/x-raw-yuv,width=240,height=144 ! colorspace
342 // ! rate ! encode ! queue
344 _create_video_bin(const gchar * encode,
345 gchar ** encode_prop,
346 gdouble fps, gint rate, guint width, guint height)
348 GstElement *vbin = NULL;
349 GstElement *vqueue = NULL;
350 GstElement *vqueue_src = NULL;
351 GstElement *vcolorspace = NULL;
352 GstElement *vencode = NULL;
353 GstElement *vrate = NULL;
356 vbin = gst_bin_new("vbin");
357 vqueue = gst_element_factory_make("queue", "vqueue");
359 gst_element_factory_make("ffmpegcolorspace", "colorspace");
361 vencode = _create_element_with_prop((encode !=
363 "ffenc_mpeg1video"), "vencode",
365 vqueue_src = gst_element_factory_make("queue", "queue_src");
367 if ((vbin == NULL) || (vqueue == NULL) || (vcolorspace == NULL)
368 || (vencode == NULL) || (vqueue_src == NULL)) {
369 g_warning("Video elements not found");
373 gst_bin_add_many(GST_BIN(vbin), vqueue, vcolorspace, vencode,
376 if ((width > 0) && (height > 0)) {
380 gst_element_factory_make("videoscale", "vscale");
382 gst_bin_add(GST_BIN(vbin), vscale);
384 vcaps = gst_caps_new_simple("video/x-raw-yuv",
385 "width", G_TYPE_INT, width,
386 "height", G_TYPE_INT, height, NULL);
388 gst_element_link(vqueue, vscale);
390 if (gst_element_link_filtered(vscale, vcolorspace, vcaps) == FALSE) {
391 g_warning("Fail to resize video");
392 gst_object_unref(vcaps);
393 gst_object_unref(vscale);
396 gst_caps_unref(vcaps);
398 gst_element_link(vqueue, vcolorspace);
402 // Changing the video fps
404 vrate = gst_element_factory_make("videorate", "vrate");
406 gst_bin_add(GST_BIN(vbin), vrate);
408 if (gst_element_link(vcolorspace, vrate) == FALSE) {
409 g_warning("Fail to link video elements");
413 vcaps = gst_caps_new_simple("video/x-raw-yuv",
414 "framerate", GST_TYPE_FRACTION,
415 (int) (fps * 1000), 1000, NULL);
417 if (gst_element_link_filtered(vrate, vencode, vcaps) == FALSE) {
418 g_warning("Fail to link vrate with vencode.");
421 gst_caps_unref(vcaps);
423 if (gst_element_link(vcolorspace, vencode) == FALSE) {
424 g_warning("Fail to link colorspace and video encode element.");
429 gst_element_link(vencode, vqueue_src);
431 // ghost pad the video bin
432 vpad = gst_element_get_pad(vqueue, "sink");
433 gst_element_add_pad(vbin, gst_ghost_pad_new("sink", vpad));
434 gst_object_unref(vpad);
436 vpad = gst_element_get_pad(vqueue_src, "src");
437 gst_element_add_pad(vbin, gst_ghost_pad_new("src", vpad));
438 gst_object_unref(vpad);
444 gst_object_unref(vpad);
447 gst_object_unref(vbin);
450 gst_object_unref(vqueue);
453 gst_object_unref(vencode);
455 if (vqueue_src != NULL)
456 gst_object_unref(vqueue_src);
458 if (vcolorspace != NULL)
459 gst_object_unref(vcolorspace);
467 g_mencoder_setup_stream(GMencoder * self,
469 const gchar * mux_name,
470 const gchar * video_encode,
471 gchar ** video_encode_prop,
476 const gchar * audio_encode,
477 gchar ** audio_encode_prop,
478 guint audio_rate, const gchar * out_uri)
480 GMencoderPrivate *priv = G_MENCODER_GET_PRIVATE(self);
481 if (priv->ready == TRUE) {
483 ("Stream already configured. You need close stream first.");
488 if (_open_output(self, out_uri) == FALSE)
492 priv->send_chunked = chunked;
493 priv->pipe = _create_pipeline(self,
501 audio_encode, audio_encode_prop,
504 return (priv->pipe != NULL);
509 g_mencoder_append_uri(GMencoder * self, const gchar * uri)
514 GMencoderPrivate *priv = G_MENCODER_GET_PRIVATE(self);
515 gboolean ret = FALSE;
516 GstElement *ap = NULL;
517 GstElement *vp = NULL;
520 g_return_val_if_fail(priv->pipe != NULL, FALSE);
521 g_return_val_if_fail(priv->ready == FALSE, FALSE);
523 #ifndef SUPPORT_MULT_INPUT
524 g_return_val_if_fail(priv->sources < 1, FALSE);
527 src = _create_source(uri);
531 priv->src = gst_bin_get_by_name(GST_BIN(src), "src");
533 gst_bin_add(GST_BIN(priv->pipe), src);
535 #ifdef SUPPORT_MULT_INPUT
536 ap = gst_bin_get_by_name(GST_BIN(priv->pipe), "ap");
537 vp = gst_bin_get_by_name(GST_BIN(priv->pipe), "vp");
539 ap = gst_bin_get_by_name(GST_BIN(priv->pipe), "abin");
540 vp = gst_bin_get_by_name(GST_BIN(priv->pipe), "vbin");
543 if ((vp == NULL) || (ap == NULL)) {
544 g_warning("Fail to get output bin");
548 pad_src = gst_element_get_pad(src, "src_audio");
549 pad_sink = gst_element_get_compatible_pad(ap,
551 gst_pad_get_caps(pad_src));
553 if ((pad_sink == NULL) || (pad_src == NULL))
556 GstPadLinkReturn lret = gst_pad_link(pad_src, pad_sink);
557 if (lret != GST_PAD_LINK_OK)
560 gst_object_unref(pad_src);
561 gst_object_unref(pad_sink);
563 pad_src = gst_element_get_pad(src, "src_video");
564 pad_sink = gst_element_get_compatible_pad(vp,
566 gst_pad_get_caps(pad_src));
568 if ((pad_src == NULL) || (pad_sink == NULL))
571 if (gst_pad_link(pad_src, pad_sink) != GST_PAD_LINK_OK) {
572 g_warning("invalid source. video");
580 if ((src != NULL) && (ret == FALSE)) {
581 gst_bin_remove(GST_BIN(priv->pipe), src);
582 gst_object_unref(src);
586 gst_object_unref(ap);
589 gst_object_unref(vp);
592 gst_object_unref(pad_src);
594 if (pad_sink != NULL)
595 gst_object_unref(pad_sink);
603 g_mencoder_remove_uri(GMencoder * self, const gchar * uri)
605 // GMencoderPrivate *priv = G_MENCODER_GET_PRIVATE (self);
610 g_mencoder_play_stream(GMencoder * self)
612 GMencoderPrivate *priv = G_MENCODER_GET_PRIVATE(self);
613 g_return_if_fail(priv->ready == FALSE);
615 gst_element_set_state(priv->pipe, GST_STATE_PLAYING);
616 priv->tick_id = g_timeout_add(500, _tick_cb, self);
620 g_mencoder_pause_stream(GMencoder * self)
622 GMencoderPrivate *priv = G_MENCODER_GET_PRIVATE(self);
623 g_return_if_fail(priv->ready == TRUE);
624 gst_element_set_state(priv->pipe, GST_STATE_PAUSED);
628 g_mencoder_close_stream(GMencoder * self)
631 GMencoderPrivate *priv = G_MENCODER_GET_PRIVATE(self);
632 if (priv->tick_id != 0) {
633 g_source_remove(priv->tick_id);
637 if (priv->pipe != NULL) {
638 // TODO: fixe pipeline dispose
639 // gst_element_set_state (priv->pipe, GST_STATE_NULL);
640 // g_debug ("SETING STATE TO NULL: OK");
641 // gst_element_set_state (priv->pipe, GST_STATE_NULL);
642 // gst_object_unref (priv->pipe);
643 gst_object_unref(priv->src);
654 _create_pipeline(GMencoder * self,
655 const gchar * video_encode,
656 const gchar * mux_name,
657 gchar ** video_encode_prop,
662 const gchar * audio_encode,
663 gchar ** audio_encode_prop, guint audio_rate)
666 GstElement *pipe = NULL;
667 GstElement *sink = NULL;
668 GstElement *mux = NULL;
669 GstElement *abin = NULL;
670 GstElement *vbin = NULL;
671 GstElement *queue = NULL;
672 GstPad *aux_pad = NULL;
673 GstPad *mux_pad = NULL;
674 #ifdef SUPPORT_MULT_INPUT
675 GstElement *ap = NULL;
676 GstElement *vp = NULL;
679 pipe = gst_pipeline_new("pipe");
681 #ifdef SUPPORT_MULT_INPUT
682 ap = gst_element_factory_make("concatmux", "ap");
683 vp = gst_element_factory_make("concatmux", "vp");
684 gst_bin_add_many(GST_BIN(pipe), ap, vp, NULL);
686 GMencoderPrivate *priv = G_MENCODER_GET_PRIVATE(self);
689 gst_element_factory_make((mux_name ? mux_name : "ffmux_mpeg"),
694 queue = gst_element_factory_make("queue", "queueu_sink");
697 #ifdef USE_MANUAL_SINK
698 sink = gst_element_factory_make("fakesink", "sink");
699 g_object_set (G_OBJECT (sink), "signal-handoffs", TRUE, NULL);
700 g_signal_connect (G_OBJECT (sink),
702 G_CALLBACK (_buffer_arrive_cb),
705 sink = gst_element_factory_make("fdsink", "sink");
709 g_object_set(G_OBJECT(sink), "fd", priv->fd, "sync", FALSE, NULL);
712 abin = _create_audio_bin(audio_encode, audio_encode_prop, audio_rate);
717 _create_video_bin(video_encode, video_encode_prop, video_fps,
718 video_rate, video_width, video_height);
723 gst_bin_add_many(GST_BIN(pipe), abin, vbin, mux, queue, sink, NULL);
726 #ifdef SUPPORT_MULT_INPUT
727 if (gst_element_link(ap, abin) == FALSE) {
728 g_warning("Fail to link concat and abin");
732 if (gst_element_link(vp, vbin) == FALSE) {
733 g_warning("Fail to link concat and vbin");
737 // Link bins with mux
738 aux_pad = gst_element_get_pad(abin, "src");
740 gst_element_get_compatible_pad(mux, aux_pad,
741 GST_PAD_CAPS(aux_pad));
742 if (mux_pad == NULL) {
743 g_warning("Mux element no have audio PAD");
746 GstPadLinkReturn ret = gst_pad_link(aux_pad, mux_pad);
747 if (ret != GST_PAD_LINK_OK) {
748 g_warning("Fail link audio and mux: %d", ret);
752 gst_object_unref(aux_pad);
753 gst_object_unref(mux_pad);
755 aux_pad = gst_element_get_pad(vbin, "src");
757 gst_element_get_compatible_pad(mux, aux_pad,
758 GST_PAD_CAPS(aux_pad));
759 if (mux_pad == NULL) {
760 g_warning("Mux element no have video PAD");
763 ret = gst_pad_link(aux_pad, mux_pad);
764 if (ret != GST_PAD_LINK_OK) {
765 g_warning("Fail link video and mux: %d", ret);
768 gst_object_unref(aux_pad);
769 gst_object_unref(mux_pad);
773 // Link mux with sink
774 gst_element_link_many(mux, queue, sink, NULL);
776 bus = gst_pipeline_get_bus(GST_PIPELINE(pipe));
777 gst_bus_add_watch(bus, _pipeline_bus_cb, self);
778 gst_object_unref(bus);
782 g_warning("Invalid uri");
785 gst_object_unref(pipe);
790 gst_object_unref(mux);
793 if (mux_pad != NULL) {
794 gst_object_unref(mux_pad);
797 if (aux_pad != NULL) {
798 gst_object_unref(mux_pad);
802 gst_object_unref(sink);
806 gst_object_unref(abin);
810 gst_object_unref(vbin);
818 _close_output(GMencoder * self)
823 _create_source(const gchar * uri)
826 GstElement *bsrc = NULL;
827 GstElement *src = NULL;
828 GstElement *queue = NULL;
829 GstElement *aqueue = NULL;
830 GstElement *vqueue = NULL;
831 GstElement *decode = NULL;
832 GstPad *src_pad = NULL;
835 bsrc = gst_bin_new(NULL);
837 // src = gst_element_factory_make ("gnomevfssrc", "src");
838 // g_object_set (G_OBJECT (src), "location", uri, NULL);
839 src = gst_element_make_from_uri(GST_URI_SRC, uri, "src");
843 decode = gst_element_factory_make("decodebin", "decode");
847 queue = gst_element_factory_make("queue", "queue_src");
848 aqueue = gst_element_factory_make("queue", "aqueue");
852 vqueue = gst_element_factory_make("queue", "vqueue");
856 gst_bin_add_many(GST_BIN(bsrc), src, queue, decode, aqueue, vqueue,
858 gst_element_link_many(src, queue, decode, NULL);
860 g_signal_connect(G_OBJECT(decode),
862 G_CALLBACK(_decodebin_new_pad_cb), bsrc);
864 g_signal_connect(G_OBJECT(decode),
866 G_CALLBACK(_decodebin_unknown_type_cb), pipe);
868 src_pad = gst_element_get_pad(aqueue, "src");
869 gst_element_add_pad(bsrc, gst_ghost_pad_new("src_audio", src_pad));
870 gst_object_unref(src_pad);
872 src_pad = gst_element_get_pad(vqueue, "src");
873 gst_element_add_pad(bsrc, gst_ghost_pad_new("src_video", src_pad));
874 gst_object_unref(src_pad);
880 gst_object_unref(src);
883 if (decode != NULL) {
884 gst_object_unref(decode);
887 if (aqueue != NULL) {
888 gst_object_unref(aqueue);
891 if (vqueue != NULL) {
892 gst_object_unref(vqueue);
899 _open_output(GMencoder * self, const gchar * uri)
903 GMencoderPrivate *priv = G_MENCODER_GET_PRIVATE(self);
905 i = g_strsplit(uri, "://", 0);
906 if (strcmp(i[0], "fd") == 0) {
907 priv->fd = atoi(i[1]);
908 if (priv->send_chunked)
909 fcntl (priv->fd, F_SETFL, O_ASYNC);
910 } else if (strcmp(i[0], "file") == 0) {
911 if (g_file_test (i[1], G_FILE_TEST_EXISTS)) {
912 if (unlink (i[1]) != 0) {
913 g_warning ("Fail to write in : %s", uri);
918 priv->fd = open(i[1], O_WRONLY | O_CREAT | O_TRUNC,
919 S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH);
921 if (priv->fd == -1) {
922 g_warning ("Fail to open : %s", uri);
926 g_warning("Output uri not supported");
936 _pipeline_bus_cb(GstBus * bus, GstMessage * msg, gpointer user_data)
938 GMencoderPrivate *priv = G_MENCODER_GET_PRIVATE(user_data);
940 switch (GST_MESSAGE_TYPE(msg)) {
942 case GST_MESSAGE_STATE_CHANGED:
946 GstState pendingstate;
949 gst_message_parse_state_changed(msg, &oldstate,
950 &newstate, &pendingstate);
952 if (pendingstate != GST_STATE_VOID_PENDING)
955 if ((oldstate == GST_STATE_READY)
956 && (newstate == GST_STATE_PAUSED)) {
958 g_signal_emit(user_data, g_mencoder_signals[PAUSED],
960 } else if ((oldstate == GST_STATE_PAUSED)
961 && (newstate == GST_STATE_PLAYING)) {
962 g_signal_emit(user_data, g_mencoder_signals[PLAYING], 0);
963 } else if ((oldstate == GST_STATE_READY) &&
964 (newstate == GST_STATE_NULL)) {
965 g_signal_emit(user_data, g_mencoder_signals[STOPED], 0);
970 case GST_MESSAGE_ERROR:
976 if (priv->tick_id != 0) {
977 g_source_remove(priv->tick_id);
981 gst_message_parse_error(msg, &error, &debug);
982 err_str = g_strdup_printf("Error [%d] %s (%s)", error->code,
983 error->message, debug);
985 g_signal_emit(user_data, g_mencoder_signals[ERROR], 0,
988 g_clear_error(&error);
993 case GST_MESSAGE_EOS:
995 #ifdef USE_MANUAL_SINK
996 _flush_queue (G_MENCODER (user_data));
998 g_signal_emit(user_data, g_mencoder_signals[EOS], 0);
1001 case GST_MESSAGE_DURATION:
1005 gst_message_parse_duration(msg, &format, &duration);
1006 if (format == GST_FORMAT_BYTES)
1007 priv->duration = duration;
1021 _decodebin_new_pad_cb(GstElement * object,
1022 GstPad * pad, gboolean flag, gpointer user_data)
1025 gchar *str_caps = NULL;
1026 GstElement *sink_element;
1029 caps = gst_pad_get_caps(pad);
1030 str_caps = gst_caps_to_string(caps);
1031 if (strstr(str_caps, "audio") != NULL) {
1032 sink_element = gst_bin_get_by_name(GST_BIN(user_data), "aqueue");
1033 } else if (strstr(str_caps, "video") != NULL) {
1034 sink_element = gst_bin_get_by_name(GST_BIN(user_data), "vqueue");
1036 g_warning("invalid caps %s", str_caps);
1039 sink_pad = gst_element_get_pad(sink_element, "sink");
1040 gst_pad_link(pad, sink_pad);
1042 gst_object_unref(sink_element);
1043 gst_object_unref(sink_pad);
1045 gst_caps_unref(caps);
1049 _decodebin_unknown_type_cb(GstElement * object,
1050 GstPad * pad, GstCaps * caps,
1053 g_warning("Unknown Type");
1054 // priv->ready = FALSE;
1058 _tick_cb(gpointer user_data)
1060 GstFormat format = GST_FORMAT_BYTES;
1063 GMencoderPrivate *priv = G_MENCODER_GET_PRIVATE(user_data);
1065 if (priv->duration == 0) {
1067 if (gst_element_query_duration(priv->src, &format, &d))
1071 if (priv->duration != 0) {
1072 gst_element_query_position(priv->src, &format, &cur);
1073 g_print("PROGRESS:%lli\n", (99 * cur) / priv->duration);
1080 #ifdef USE_MANUAL_SINK
1082 _send_buffer (gint fd, gpointer buff, gint size)
1084 gboolean ret = TRUE;
1088 b_send = g_byte_array_new ();
1089 msg = g_strdup_printf ("%x\r\n", size);
1090 b_send = g_byte_array_append (b_send, (const guint8*) msg, strlen (msg) * sizeof (gchar));
1093 b_send = g_byte_array_append (b_send, buff, size);
1095 msg = g_strdup ("\r\n");
1096 b_send = g_byte_array_append (b_send, (const guint8*) msg, strlen (msg) * sizeof (gchar));
1099 if (send (fd, b_send->data, b_send->len, MSG_MORE) <= 0)
1101 g_byte_array_free (b_send, TRUE);
1107 _flush_queue (GMencoder *self)
1110 GMencoderPrivate *priv = G_MENCODER_GET_PRIVATE(self);
1112 if (BUFFER_SIZE == 0)
1115 if (priv->queue->len > 0) {
1116 _send_buffer (priv->fd, priv->queue->data, priv->queue->len);
1117 priv->queue = g_byte_array_remove_range (priv->queue, 0, priv->queue->len);
1120 end_msg = g_strdup ("0\r\n\r\n");
1121 write (priv->fd, (const guint8*) end_msg, strlen(end_msg) * sizeof(gchar));
1126 _buffer_arrive_cb (GstElement* object,
1131 GMencoderPrivate *priv = G_MENCODER_GET_PRIVATE(user_data);
1133 if (BUFFER_SIZE == 0) {
1134 if (_send_buffer (priv->fd, GST_BUFFER_DATA (buff), GST_BUFFER_SIZE (buff)) == FALSE)
1139 priv->queue = g_byte_array_append (priv->queue, GST_BUFFER_DATA (buff), GST_BUFFER_SIZE (buff));
1140 while (priv->queue->len >= BUFFER_SIZE) {
1141 //g_usleep (0.2 * G_USEC_PER_SEC);
1142 if (priv->send_chunked) {
1143 if (_send_buffer (priv->fd, priv->queue->data, BUFFER_SIZE) == FALSE)
1146 if (write (priv->fd, priv->queue->data, BUFFER_SIZE) == -1)
1149 priv->queue = g_byte_array_remove_range (priv->queue, 0, BUFFER_SIZE);
1154 if (priv->tick_id != 0) {
1155 g_source_remove(priv->tick_id);
1158 priv->queue = g_byte_array_remove_range (priv->queue, 0, priv->queue->len);
1159 g_signal_emit(user_data, g_mencoder_signals[ERROR], 0, "Error on socket");