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
22 typedef struct _GMencoderPrivate GMencoderPrivate;
23 typedef struct _SetupInfo SetupInfo;
28 gchar **video_encode_prop;
34 gchar **audio_encode_prop;
39 struct _GMencoderPrivate {
53 gboolean send_chunked;
65 static void g_mencoder_class_init(GMencoderClass * klass);
66 static void g_mencoder_init(GMencoder * object);
67 static void g_mencoder_dispose(GObject * object);
68 static void g_mencoder_finalize(GObject * object);
69 static GstElement *_create_audio_bin(const gchar * encode,
70 gchar ** encode_prop, gint rate);
71 static GstElement *_create_video_bin(const gchar * encode,
74 gint rate, guint width, guint height,
75 gboolean use_deinterlace);
78 _pipeline_bus_cb(GstBus * bus, GstMessage * msg, gpointer user_data);
80 static void _decodebin_new_pad_cb(GstElement * object,
82 gboolean flag, gpointer user_data);
84 static void _decodebin_unknown_type_cb(GstElement * object,
89 static void _close_output(GMencoder * self);
90 static gboolean _open_output(GMencoder * self, const gchar * uri);
92 static GstElement *_create_source(const gchar * uri);
93 static GstElement *_create_pipeline(GMencoder * self,
94 const gchar * video_encode,
95 const gchar * mux_name,
96 gchar ** video_encode_prop,
101 const gchar * audio_encode,
102 gchar ** audio_encode_prop,
104 gboolean deinterlace);
105 #ifdef USE_MANUAL_SINK
106 static void _flush_queue (GMencoder *self);
107 static void _buffer_arrive_cb (GstElement* object,
114 static gboolean _tick_cb(gpointer data);
116 static guint g_mencoder_signals[LAST_SIGNAL] = { 0 };
118 G_DEFINE_TYPE(GMencoder, g_mencoder, G_TYPE_OBJECT)
120 static void g_mencoder_class_init(GMencoderClass * klass)
122 GObjectClass *object_class;
123 object_class = (GObjectClass *) klass;
124 g_type_class_add_private(klass, sizeof(GMencoderPrivate));
126 object_class->dispose = g_mencoder_dispose;
127 object_class->finalize = g_mencoder_finalize;
129 g_mencoder_signals[PAUSED] =
130 g_signal_new("paused",
131 G_OBJECT_CLASS_TYPE(object_class),
134 g_cclosure_marshal_VOID__VOID, G_TYPE_NONE, 0);
136 g_mencoder_signals[PLAYING] =
137 g_signal_new("playing",
138 G_OBJECT_CLASS_TYPE(object_class),
141 g_cclosure_marshal_VOID__VOID, G_TYPE_NONE, 0);
143 g_mencoder_signals[STOPED] =
144 g_signal_new("stoped",
145 G_OBJECT_CLASS_TYPE(object_class),
148 g_cclosure_marshal_VOID__VOID, G_TYPE_NONE, 0);
150 g_mencoder_signals[EOS] =
152 G_OBJECT_CLASS_TYPE(object_class),
155 g_cclosure_marshal_VOID__VOID, G_TYPE_NONE, 0);
157 g_mencoder_signals[ERROR] =
158 g_signal_new("error",
159 G_OBJECT_CLASS_TYPE(object_class),
162 g_cclosure_marshal_VOID__STRING,
163 G_TYPE_NONE, 1, G_TYPE_STRING);
167 g_mencoder_init(GMencoder * self)
169 GMencoderPrivate *priv = G_MENCODER_GET_PRIVATE(self);
170 priv->info = g_new0(SetupInfo, 1);
174 g_mencoder_dispose(GObject * object)
179 g_mencoder_finalize(GObject * object)
181 GMencoderPrivate *priv = G_MENCODER_GET_PRIVATE(object);
184 g_mencoder_close_stream(G_MENCODER(object));
191 return g_object_new(G_TYPE_MENCODER, NULL);
196 _obj_set_prop(GObject * obj, const gchar * prop_name,
197 const gchar * prop_val)
201 GParamSpec *s = NULL;
202 GObjectClass *k = G_OBJECT_GET_CLASS(obj);
205 g_value_init(&v, G_TYPE_STRING);
206 g_value_set_string(&v, prop_val);
208 s = g_object_class_find_property(k, prop_name);
210 g_print("Invalid property name: %s\n", prop_name);
214 g_value_init(&p, s->value_type);
215 switch (s->value_type) {
217 g_value_set_int(&p, atoi(prop_val));
220 g_value_set_ulong (&p, atol(prop_val));
223 g_value_set_string(&p, prop_val);
226 g_value_set_boolean(&p, (gboolean) atoi (prop_val));
229 g_value_set_double(&p, atof (prop_val));
232 g_value_set_float(&p, (float) atof (prop_val));
235 g_value_set_enum(&p, atoi(prop_val));
236 g_warning ("Property %s of type %s. Not supported using default enum",
237 prop_name, g_type_name (s->value_type));
241 g_object_set_property(obj, prop_name, &p);
247 _create_element_with_prop(const gchar * factory_name,
248 const gchar * element_name, gchar ** prop)
253 ret = gst_element_factory_make(factory_name, element_name);
258 for (i = 0; i < g_strv_length(prop); i++) {
259 if (prop[i] != NULL) {
260 char **v = g_strsplit(prop[i], "=", 2);
261 if (g_strv_length(v) == 2) {
262 _obj_set_prop(G_OBJECT(ret), v[0], v[1]);
274 _create_audio_bin(const gchar * encode, gchar ** encode_prop, gint rate)
276 GstElement *abin = NULL;
277 GstElement *aqueue = NULL;
278 GstElement *aconvert = NULL;
279 GstElement *aencode = NULL;
280 GstElement *aqueue_src = NULL;
283 // audio/x-raw-int ! queue ! audioconvert ! faac ! rtpmp4gpay !
284 // udpsink name=upd_audio host=224.0.0.1 port=5002
285 abin = gst_bin_new("abin");
286 aqueue = gst_element_factory_make("queue", "aqueue");
287 aconvert = gst_element_factory_make("audioconvert", "aconvert");
289 _create_element_with_prop((encode ? encode : "lame"), "aencode",
291 aqueue_src = gst_element_factory_make("queue", "aqueue_src");
293 if ((abin == NULL) || (aqueue == NULL) || (aconvert == NULL)
294 || (aencode == NULL) || (aqueue_src == NULL)) {
295 g_warning("Audio elements not found");
299 g_object_set(G_OBJECT(aencode), "bitrate", 32, NULL);
301 * if (rate > 0) { g_object_set (G_OBJECT (aencode), "bitrate", 32,
305 gst_bin_add_many(GST_BIN(abin), aqueue, aconvert, aencode, aqueue_src,
307 if (gst_element_link_many(aqueue, aconvert, aencode, aqueue_src, NULL)
309 g_warning("Not Link audio elements");
311 // TODO: apply audio rate
313 // ghost pad the audio bin
314 apad = gst_element_get_pad(aqueue, "sink");
315 gst_element_add_pad(abin, gst_ghost_pad_new("sink", apad));
316 gst_object_unref(apad);
318 apad = gst_element_get_pad(aqueue_src, "src");
319 gst_element_add_pad(abin, gst_ghost_pad_new("src", apad));
320 gst_object_unref(apad);
325 gst_object_unref(abin);
328 gst_object_unref(aqueue);
330 if (aconvert != NULL)
331 gst_object_unref(aconvert);
334 gst_object_unref(aencode);
336 if (aqueue_src != NULL)
337 gst_object_unref(aqueue_src);
340 gst_object_unref(apad);
348 // queue ! videoscale ! video/x-raw-yuv,width=240,height=144 ! colorspace
349 // ! rate ! encode ! queue
351 _create_video_bin(const gchar * encode,
352 gchar ** encode_prop,
353 gdouble fps, gint rate, guint width, guint height,
354 gboolean use_deinterlace)
356 GstElement *vbin = NULL;
357 GstElement *vqueue = NULL;
358 GstElement *vqueue_src = NULL;
359 GstElement *vcolorspace = NULL;
360 GstElement *vencode = NULL;
361 GstElement *vrate = NULL;
362 GstElement *deinterlace = NULL;
363 GstElement *walk = NULL;
366 vbin = gst_bin_new("vbin");
367 vqueue = gst_element_factory_make("queue", "vqueue");
369 gst_element_factory_make("ffmpegcolorspace", "colorspace");
371 if (use_deinterlace) {
372 deinterlace = gst_element_factory_make ("ffdeinterlace", "deinterlace");
373 if (deinterlace == NULL) {
374 g_warning ("Fail to create deinterlace element: Continue without deinterlace.");
379 vencode = _create_element_with_prop((encode !=
381 "ffenc_mpeg1video"), "vencode",
383 vqueue_src = gst_element_factory_make("queue", "queue_src");
385 if ((vbin == NULL) || (vqueue == NULL) || (vcolorspace == NULL)
386 || (vencode == NULL) || (vqueue_src == NULL)) {
387 g_warning("Video elements not found");
391 gst_bin_add_many(GST_BIN(vbin), vqueue, vcolorspace, vencode,
394 if (deinterlace != NULL) {
395 gst_bin_add(GST_BIN(vbin), deinterlace);
396 gst_element_link (vqueue, deinterlace);
402 if ((width > 0) && (height > 0)) {
406 gst_element_factory_make("videoscale", "vscale");
408 g_object_set (G_OBJECT (vscale), "method", 1, NULL);
410 gst_bin_add(GST_BIN(vbin), vscale);
412 vcaps = gst_caps_new_simple("video/x-raw-yuv",
413 "width", G_TYPE_INT, width,
414 "height", G_TYPE_INT, height, NULL);
416 gst_element_link(walk, vscale);
418 if (gst_element_link_filtered(vscale, vcolorspace, vcaps) == FALSE) {
419 g_warning("Fail to resize video");
420 gst_object_unref(vcaps);
421 gst_object_unref(vscale);
424 gst_caps_unref(vcaps);
426 gst_element_link(walk, vcolorspace);
430 // Changing the video fps
432 vrate = gst_element_factory_make("videorate", "vrate");
434 gst_bin_add(GST_BIN(vbin), vrate);
436 if (gst_element_link(vcolorspace, vrate) == FALSE) {
437 g_warning("Fail to link video elements");
441 vcaps = gst_caps_new_simple("video/x-raw-yuv",
442 "framerate", GST_TYPE_FRACTION,
443 (int) (fps * 1000), 1000, NULL);
445 if (gst_element_link_filtered(vrate, vencode, vcaps) == FALSE) {
446 g_warning("Fail to link vrate with vencode.");
449 gst_caps_unref(vcaps);
451 if (gst_element_link(vcolorspace, vencode) == FALSE) {
452 g_warning("Fail to link colorspace and video encode element.");
457 gst_element_link(vencode, vqueue_src);
459 // ghost pad the video bin
460 vpad = gst_element_get_pad(vqueue, "sink");
461 gst_element_add_pad(vbin, gst_ghost_pad_new("sink", vpad));
462 gst_object_unref(vpad);
464 vpad = gst_element_get_pad(vqueue_src, "src");
465 gst_element_add_pad(vbin, gst_ghost_pad_new("src", vpad));
466 gst_object_unref(vpad);
472 gst_object_unref(vpad);
475 gst_object_unref(vbin);
478 gst_object_unref(vqueue);
481 gst_object_unref(vencode);
483 if (vqueue_src != NULL)
484 gst_object_unref(vqueue_src);
486 if (vcolorspace != NULL)
487 gst_object_unref(vcolorspace);
495 g_mencoder_setup_stream(GMencoder * self,
497 gboolean deinterlace,
498 const gchar * mux_name,
499 const gchar * video_encode,
500 gchar ** video_encode_prop,
505 const gchar * audio_encode,
506 gchar ** audio_encode_prop,
507 guint audio_rate, const gchar * out_uri)
509 GMencoderPrivate *priv = G_MENCODER_GET_PRIVATE(self);
510 if (priv->ready == TRUE) {
512 ("Stream already configured. You need close stream first.");
517 if (_open_output(self, out_uri) == FALSE)
521 priv->send_chunked = chunked;
522 priv->pipe = _create_pipeline(self,
530 audio_encode, audio_encode_prop,
534 return (priv->pipe != NULL);
539 g_mencoder_append_uri(GMencoder * self, const gchar * uri)
544 GMencoderPrivate *priv = G_MENCODER_GET_PRIVATE(self);
545 gboolean ret = FALSE;
546 GstElement *ap = NULL;
547 GstElement *vp = NULL;
550 g_return_val_if_fail(priv->pipe != NULL, FALSE);
551 g_return_val_if_fail(priv->ready == FALSE, FALSE);
553 #ifndef SUPPORT_MULT_INPUT
554 g_return_val_if_fail(priv->sources < 1, FALSE);
557 src = _create_source(uri);
561 priv->src = gst_bin_get_by_name(GST_BIN(src), "src");
563 gst_bin_add(GST_BIN(priv->pipe), src);
565 #ifdef SUPPORT_MULT_INPUT
566 ap = gst_bin_get_by_name(GST_BIN(priv->pipe), "ap");
567 vp = gst_bin_get_by_name(GST_BIN(priv->pipe), "vp");
569 ap = gst_bin_get_by_name(GST_BIN(priv->pipe), "abin");
570 vp = gst_bin_get_by_name(GST_BIN(priv->pipe), "vbin");
573 if ((vp == NULL) || (ap == NULL)) {
574 g_warning("Fail to get output bin");
578 pad_src = gst_element_get_pad(src, "src_audio");
579 pad_sink = gst_element_get_compatible_pad(ap,
581 gst_pad_get_caps(pad_src));
583 if ((pad_sink == NULL) || (pad_src == NULL))
586 GstPadLinkReturn lret = gst_pad_link(pad_src, pad_sink);
587 if (lret != GST_PAD_LINK_OK)
590 gst_object_unref(pad_src);
591 gst_object_unref(pad_sink);
593 pad_src = gst_element_get_pad(src, "src_video");
594 pad_sink = gst_element_get_compatible_pad(vp,
596 gst_pad_get_caps(pad_src));
598 if ((pad_src == NULL) || (pad_sink == NULL))
601 if (gst_pad_link(pad_src, pad_sink) != GST_PAD_LINK_OK) {
602 g_warning("invalid source. video");
610 if ((src != NULL) && (ret == FALSE)) {
611 gst_bin_remove(GST_BIN(priv->pipe), src);
612 gst_object_unref(src);
616 gst_object_unref(ap);
619 gst_object_unref(vp);
622 gst_object_unref(pad_src);
624 if (pad_sink != NULL)
625 gst_object_unref(pad_sink);
633 g_mencoder_remove_uri(GMencoder * self, const gchar * uri)
635 // GMencoderPrivate *priv = G_MENCODER_GET_PRIVATE (self);
640 g_mencoder_play_stream(GMencoder * self)
642 GMencoderPrivate *priv = G_MENCODER_GET_PRIVATE(self);
643 g_return_if_fail(priv->ready == FALSE);
645 gst_element_set_state(priv->pipe, GST_STATE_PLAYING);
646 priv->tick_id = g_timeout_add(500, _tick_cb, self);
650 g_mencoder_pause_stream(GMencoder * self)
652 GMencoderPrivate *priv = G_MENCODER_GET_PRIVATE(self);
653 g_return_if_fail(priv->ready == TRUE);
654 gst_element_set_state(priv->pipe, GST_STATE_PAUSED);
658 g_mencoder_close_stream(GMencoder * self)
661 GMencoderPrivate *priv = G_MENCODER_GET_PRIVATE(self);
662 if (priv->tick_id != 0) {
663 g_source_remove(priv->tick_id);
667 if (priv->pipe != NULL) {
668 // TODO: fixe pipeline dispose
669 gst_element_set_state (priv->pipe, GST_STATE_NULL);
670 // g_debug ("SETING STATE TO NULL: OK");
671 // gst_element_set_state (priv->pipe, GST_STATE_NULL);
672 gst_object_unref (priv->pipe);
673 //gst_object_unref(priv->src);
684 _create_pipeline(GMencoder * self,
685 const gchar * video_encode,
686 const gchar * mux_name,
687 gchar ** video_encode_prop,
692 const gchar * audio_encode,
693 gchar ** audio_encode_prop, guint audio_rate,
694 gboolean deinterlace)
697 GstElement *pipe = NULL;
698 GstElement *sink = NULL;
699 GstElement *mux = NULL;
700 GstElement *abin = NULL;
701 GstElement *vbin = NULL;
702 GstElement *queue = NULL;
703 GstPad *aux_pad = NULL;
704 GstPad *mux_pad = NULL;
705 #ifdef SUPPORT_MULT_INPUT
706 GstElement *ap = NULL;
707 GstElement *vp = NULL;
710 pipe = gst_pipeline_new("pipe");
712 #ifdef SUPPORT_MULT_INPUT
713 ap = gst_element_factory_make("concatmux", "ap");
714 vp = gst_element_factory_make("concatmux", "vp");
715 gst_bin_add_many(GST_BIN(pipe), ap, vp, NULL);
717 GMencoderPrivate *priv = G_MENCODER_GET_PRIVATE(self);
720 gst_element_factory_make((mux_name ? mux_name : "ffmux_mpeg"),
725 queue = gst_element_factory_make("queue", "queueu_sink");
728 #ifdef USE_MANUAL_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 sink = gst_element_factory_make("fdsink", "sink");
740 g_object_set(G_OBJECT(sink), "fd", priv->fd, "sync", FALSE, NULL);
743 abin = _create_audio_bin(audio_encode, audio_encode_prop, audio_rate);
748 _create_video_bin(video_encode, video_encode_prop, video_fps,
749 video_rate, video_width, video_height, deinterlace);
754 gst_bin_add_many(GST_BIN(pipe), abin, vbin, mux, queue, sink, NULL);
757 #ifdef SUPPORT_MULT_INPUT
758 if (gst_element_link(ap, abin) == FALSE) {
759 g_warning("Fail to link concat and abin");
763 if (gst_element_link(vp, vbin) == FALSE) {
764 g_warning("Fail to link concat and vbin");
768 // Link bins with mux
769 aux_pad = gst_element_get_pad(abin, "src");
771 gst_element_get_compatible_pad(mux, aux_pad,
772 GST_PAD_CAPS(aux_pad));
773 if (mux_pad == NULL) {
774 g_warning("Mux element no have audio PAD");
777 GstPadLinkReturn ret = gst_pad_link(aux_pad, mux_pad);
778 if (ret != GST_PAD_LINK_OK) {
779 g_warning("Fail link audio and mux: %d", ret);
783 gst_object_unref(aux_pad);
784 gst_object_unref(mux_pad);
786 aux_pad = gst_element_get_pad(vbin, "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 video PAD");
794 ret = gst_pad_link(aux_pad, mux_pad);
795 if (ret != GST_PAD_LINK_OK) {
796 g_warning("Fail link video and mux: %d", ret);
799 gst_object_unref(aux_pad);
800 gst_object_unref(mux_pad);
804 // Link mux with sink
805 gst_element_link_many(mux, queue, sink, NULL);
807 bus = gst_pipeline_get_bus(GST_PIPELINE(pipe));
808 gst_bus_add_watch(bus, _pipeline_bus_cb, self);
809 gst_object_unref(bus);
813 g_warning("Invalid uri");
816 gst_object_unref(pipe);
821 gst_object_unref(mux);
824 if (mux_pad != NULL) {
825 gst_object_unref(mux_pad);
828 if (aux_pad != NULL) {
829 gst_object_unref(mux_pad);
833 gst_object_unref(sink);
837 gst_object_unref(abin);
841 gst_object_unref(vbin);
849 _close_output(GMencoder * self)
854 _create_source(const gchar * uri)
857 GstElement *bsrc = NULL;
858 GstElement *src = NULL;
859 GstElement *queue = NULL;
860 GstElement *aqueue = NULL;
861 GstElement *vqueue = NULL;
862 GstElement *decode = NULL;
863 GstPad *src_pad = NULL;
866 bsrc = gst_bin_new(NULL);
868 // src = gst_element_factory_make ("gnomevfssrc", "src");
869 // g_object_set (G_OBJECT (src), "location", uri, NULL);
870 src = gst_element_make_from_uri(GST_URI_SRC, uri, "src");
874 decode = gst_element_factory_make("decodebin", "decode");
878 queue = gst_element_factory_make("queue", "queue_src");
879 aqueue = gst_element_factory_make("queue", "aqueue");
883 vqueue = gst_element_factory_make("queue", "vqueue");
887 gst_bin_add_many(GST_BIN(bsrc), src, queue, decode, aqueue, vqueue,
889 gst_element_link_many(src, queue, decode, NULL);
891 g_signal_connect(G_OBJECT(decode),
893 G_CALLBACK(_decodebin_new_pad_cb), bsrc);
895 g_signal_connect(G_OBJECT(decode),
897 G_CALLBACK(_decodebin_unknown_type_cb), pipe);
899 src_pad = gst_element_get_pad(aqueue, "src");
900 gst_element_add_pad(bsrc, gst_ghost_pad_new("src_audio", src_pad));
901 gst_object_unref(src_pad);
903 src_pad = gst_element_get_pad(vqueue, "src");
904 gst_element_add_pad(bsrc, gst_ghost_pad_new("src_video", src_pad));
905 gst_object_unref(src_pad);
911 gst_object_unref(src);
914 if (decode != NULL) {
915 gst_object_unref(decode);
918 if (aqueue != NULL) {
919 gst_object_unref(aqueue);
922 if (vqueue != NULL) {
923 gst_object_unref(vqueue);
930 _open_output(GMencoder * self, const gchar * uri)
934 GMencoderPrivate *priv = G_MENCODER_GET_PRIVATE(self);
936 i = g_strsplit(uri, "://", 0);
937 if (strcmp(i[0], "fd") == 0) {
938 priv->fd = atoi(i[1]);
939 } else if (strcmp(i[0], "file") == 0) {
940 if (g_file_test (i[1], G_FILE_TEST_EXISTS)) {
941 if (unlink (i[1]) != 0) {
942 g_warning ("Fail to write in : %s", uri);
947 priv->fd = open(i[1], O_WRONLY | O_CREAT | O_TRUNC,
948 S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH);
950 if (priv->fd == -1) {
951 g_warning ("Fail to open : %s", uri);
955 g_warning("Output uri not supported");
965 _pipeline_bus_cb(GstBus * bus, GstMessage * msg, gpointer user_data)
967 GMencoderPrivate *priv = G_MENCODER_GET_PRIVATE(user_data);
969 switch (GST_MESSAGE_TYPE(msg)) {
971 case GST_MESSAGE_STATE_CHANGED:
975 GstState pendingstate;
978 gst_message_parse_state_changed(msg, &oldstate,
979 &newstate, &pendingstate);
981 if (pendingstate != GST_STATE_VOID_PENDING)
984 if ((oldstate == GST_STATE_READY)
985 && (newstate == GST_STATE_PAUSED)) {
987 g_signal_emit(user_data, g_mencoder_signals[PAUSED],
989 } else if ((oldstate == GST_STATE_PAUSED)
990 && (newstate == GST_STATE_PLAYING)) {
991 g_signal_emit(user_data, g_mencoder_signals[PLAYING], 0);
992 } else if ((oldstate == GST_STATE_READY) &&
993 (newstate == GST_STATE_NULL)) {
994 g_signal_emit(user_data, g_mencoder_signals[STOPED], 0);
999 case GST_MESSAGE_ERROR:
1005 if (priv->tick_id != 0) {
1006 g_source_remove(priv->tick_id);
1010 gst_message_parse_error(msg, &error, &debug);
1011 err_str = g_strdup_printf("Error [%d] %s (%s)", error->code,
1012 error->message, debug);
1013 priv->ready = FALSE;
1014 g_signal_emit(user_data, g_mencoder_signals[ERROR], 0,
1017 g_clear_error(&error);
1022 case GST_MESSAGE_EOS:
1023 priv->ready = FALSE;
1024 #ifdef USE_MANUAL_SINK
1025 _flush_queue (G_MENCODER (user_data));
1027 g_signal_emit(user_data, g_mencoder_signals[EOS], 0);
1030 case GST_MESSAGE_DURATION:
1034 gst_message_parse_duration(msg, &format, &duration);
1035 if (format == GST_FORMAT_BYTES)
1036 priv->duration = duration;
1050 _decodebin_new_pad_cb(GstElement * object,
1051 GstPad * pad, gboolean flag, gpointer user_data)
1054 gchar *str_caps = NULL;
1055 GstElement *sink_element;
1058 caps = gst_pad_get_caps(pad);
1059 str_caps = gst_caps_to_string(caps);
1060 if (strstr(str_caps, "audio") != NULL) {
1061 sink_element = gst_bin_get_by_name(GST_BIN(user_data), "aqueue");
1062 } else if (strstr(str_caps, "video") != NULL) {
1063 sink_element = gst_bin_get_by_name(GST_BIN(user_data), "vqueue");
1065 g_warning("invalid caps %s", str_caps);
1068 sink_pad = gst_element_get_pad(sink_element, "sink");
1069 gst_pad_link(pad, sink_pad);
1071 gst_object_unref(sink_element);
1072 gst_object_unref(sink_pad);
1074 gst_caps_unref(caps);
1078 _decodebin_unknown_type_cb(GstElement * object,
1079 GstPad * pad, GstCaps * caps,
1082 g_warning("Unknown Type");
1083 // priv->ready = FALSE;
1087 _tick_cb(gpointer user_data)
1089 GstFormat format = GST_FORMAT_BYTES;
1092 GMencoderPrivate *priv = G_MENCODER_GET_PRIVATE(user_data);
1094 if (priv->duration == 0) {
1096 if (gst_element_query_duration(priv->src, &format, &d))
1100 if (priv->duration != 0) {
1101 gst_element_query_position(priv->src, &format, &cur);
1102 g_print("PROGRESS:%lli\n", (99 * cur) / priv->duration);
1109 #ifdef USE_MANUAL_SINK
1111 _send_buffer (gint fd, gpointer buff, gint size)
1113 gboolean ret = TRUE;
1117 b_send = g_byte_array_new ();
1118 msg = g_strdup_printf ("%x\r\n", size);
1119 b_send = g_byte_array_append (b_send, (const guint8*) msg, strlen (msg) * sizeof (gchar));
1122 b_send = g_byte_array_append (b_send, buff, size);
1124 msg = g_strdup ("\r\n");
1125 b_send = g_byte_array_append (b_send, (const guint8*) msg, strlen (msg) * sizeof (gchar));
1128 if (send (fd, b_send->data, b_send->len, MSG_MORE) <= 0)
1130 g_byte_array_free (b_send, TRUE);
1136 _flush_queue (GMencoder *self)
1138 GMencoderPrivate *priv = G_MENCODER_GET_PRIVATE(self);
1140 if (priv->send_chunked) {
1142 end_msg = g_strdup ("0\r\n\r\n");
1143 write (priv->fd, (const guint8*) end_msg, strlen(end_msg) * sizeof(gchar));
1148 _buffer_arrive_cb (GstElement* object,
1153 GMencoderPrivate *priv = G_MENCODER_GET_PRIVATE(user_data);
1155 if (priv->send_chunked) {
1156 if (_send_buffer (priv->fd, GST_BUFFER_DATA (buff), GST_BUFFER_SIZE (buff)) == FALSE)
1159 if (write (priv->fd, GST_BUFFER_DATA (buff), GST_BUFFER_SIZE (buff)) < 0)
1166 if (priv->tick_id != 0) {
1167 g_source_remove(priv->tick_id);
1170 g_signal_emit(user_data, g_mencoder_signals[ERROR], 0, "Error on socket");