renatofilho@586: #ifdef HAVE_CONFIG_H renatofilho@586: #include "config.h" renatofilho@586: #endif renatofilho@586: renatofilho@586: #include renatofilho@586: #include renatofilho@586: #include renatofilho@586: renatofilho@586: #include "gmemcoder.h" renatofilho@586: renatofilho@586: #define G_MENCODER_GET_PRIVATE(obj) \ renatofilho@586: (G_TYPE_INSTANCE_GET_PRIVATE ((obj), G_TYPE_MENCODER, GMencoderPrivate)) renatofilho@586: renatofilho@586: renatofilho@586: typedef struct _GMencoderPrivate GMencoderPrivate; renatofilho@586: renatofilho@586: struct _GMencoderPrivate renatofilho@586: { renatofilho@586: GstElement *pipe; renatofilho@586: GstElement *abin; renatofilho@586: GstElement *vbin; renatofilho@586: GstElement *sink; renatofilho@586: gboolean ready; renatofilho@586: }; renatofilho@586: renatofilho@586: enum { renatofilho@586: READY, renatofilho@586: PAUSED, renatofilho@586: PLAYING, renatofilho@586: STOPED, renatofilho@586: EOS, renatofilho@586: ERROR, renatofilho@586: LAST_SIGNAL renatofilho@586: }; renatofilho@586: renatofilho@586: static void g_mencoder_class_init (GMencoderClass *klass); renatofilho@586: static void g_mencoder_init (GMencoder *object); renatofilho@586: static void g_mencoder_dispose (GObject *object); renatofilho@586: static void g_mencoder_finalize (GObject *object); renatofilho@586: static gboolean renatofilho@586: _pipeline_bus_cb (GstBus *bus, renatofilho@586: GstMessage *msg, renatofilho@586: gpointer user_data); renatofilho@586: renatofilho@586: static void _decodebin_new_pad_cb (GstElement* object, renatofilho@586: GstPad* pad, renatofilho@586: gboolean flag, renatofilho@586: gpointer user_data); renatofilho@586: static void _decodebin_unknown_type_cb (GstElement* object, renatofilho@586: GstPad* pad, renatofilho@586: GstCaps* caps, renatofilho@586: gpointer user_data); renatofilho@586: renatofilho@586: static guint g_mencoder_signals[LAST_SIGNAL] = { 0 }; renatofilho@586: renatofilho@586: G_DEFINE_TYPE(GMencoder, g_mencoder, G_TYPE_OBJECT) renatofilho@586: renatofilho@586: static void renatofilho@586: g_mencoder_class_init (GMencoderClass *klass) renatofilho@586: { renatofilho@586: GObjectClass *object_class; renatofilho@586: renatofilho@586: object_class = (GObjectClass *) klass; renatofilho@586: renatofilho@586: g_type_class_add_private (klass, sizeof (GMencoderPrivate)); renatofilho@586: renatofilho@586: object_class->dispose = g_mencoder_dispose; renatofilho@586: object_class->finalize = g_mencoder_finalize; renatofilho@586: renatofilho@586: g_mencoder_signals[READY] = renatofilho@586: g_signal_new ("ready", renatofilho@586: G_OBJECT_CLASS_TYPE (object_class), renatofilho@586: G_SIGNAL_RUN_FIRST, renatofilho@586: 0, NULL, NULL, renatofilho@586: g_cclosure_marshal_VOID__VOID, renatofilho@586: G_TYPE_NONE, 0); renatofilho@586: renatofilho@586: g_mencoder_signals[PAUSED] = renatofilho@586: g_signal_new ("paused", renatofilho@586: G_OBJECT_CLASS_TYPE (object_class), renatofilho@586: G_SIGNAL_RUN_FIRST, renatofilho@586: 0, NULL, NULL, renatofilho@586: g_cclosure_marshal_VOID__VOID, renatofilho@586: G_TYPE_NONE, 0); renatofilho@586: renatofilho@586: g_mencoder_signals[PLAYING] = renatofilho@586: g_signal_new ("playing", renatofilho@586: G_OBJECT_CLASS_TYPE (object_class), renatofilho@586: G_SIGNAL_RUN_FIRST, renatofilho@586: 0, NULL, NULL, renatofilho@586: g_cclosure_marshal_VOID__VOID, renatofilho@586: G_TYPE_NONE, 0); renatofilho@586: renatofilho@586: g_mencoder_signals[STOPED] = renatofilho@586: g_signal_new ("stoped", renatofilho@586: G_OBJECT_CLASS_TYPE (object_class), renatofilho@586: G_SIGNAL_RUN_FIRST, renatofilho@586: 0, NULL, NULL, renatofilho@586: g_cclosure_marshal_VOID__VOID, renatofilho@586: G_TYPE_NONE, 0); renatofilho@586: renatofilho@586: g_mencoder_signals[EOS] = renatofilho@586: g_signal_new ("eos", renatofilho@586: G_OBJECT_CLASS_TYPE (object_class), renatofilho@586: G_SIGNAL_RUN_FIRST, renatofilho@586: 0, NULL, NULL, renatofilho@586: g_cclosure_marshal_VOID__VOID, renatofilho@586: G_TYPE_NONE, 0); renatofilho@586: renatofilho@586: renatofilho@586: g_mencoder_signals[ERROR] = renatofilho@586: g_signal_new ("error", renatofilho@586: G_OBJECT_CLASS_TYPE (object_class), renatofilho@586: G_SIGNAL_RUN_FIRST, renatofilho@586: 0, NULL, NULL, renatofilho@586: g_cclosure_marshal_VOID__STRING, renatofilho@586: G_TYPE_NONE, 1, G_TYPE_STRING); renatofilho@586: } renatofilho@586: renatofilho@586: static void renatofilho@586: g_mencoder_init (GMencoder *self) renatofilho@586: { renatofilho@586: } renatofilho@586: renatofilho@586: static void renatofilho@586: g_mencoder_dispose (GObject *object) renatofilho@586: { renatofilho@586: } renatofilho@586: renatofilho@586: static void renatofilho@586: g_mencoder_finalize (GObject *object) renatofilho@586: { renatofilho@586: g_mencoder_close_stream (G_MENCODER (object)); renatofilho@586: } renatofilho@586: renatofilho@586: GMencoder* renatofilho@586: g_mencoder_new (void) renatofilho@586: { renatofilho@586: return g_object_new (G_TYPE_MENCODER, NULL); renatofilho@586: } renatofilho@586: renatofilho@586: renatofilho@586: gboolean renatofilho@586: g_mencoder_setup_stream (GMencoder *self, renatofilho@586: const gchar* uri, renatofilho@586: guint width, guint height, renatofilho@586: gint out_fd) renatofilho@586: { renatofilho@586: GstBus *bus = NULL; renatofilho@586: GstElement *pipe = NULL; renatofilho@586: GstElement *decode = NULL; renatofilho@586: GstElement *fdsink = NULL; renatofilho@586: GstElement *mux = NULL; renatofilho@586: renatofilho@586: GstCaps *vscale_caps = NULL; renatofilho@586: GstPad *asinkpad = NULL; renatofilho@586: GstPad *vsinkpad = NULL; renatofilho@586: GstPad *video_src_pad = NULL; renatofilho@586: GstPad *audio_src_pad = NULL; renatofilho@586: GstPad *mux_pad = NULL; renatofilho@586: GstElement *src = NULL; renatofilho@586: GstElement *vbin, *vqueue, *vcolorspace, *vscale, *vrate, *vencode, *vqueue_src; renatofilho@586: GstElement *abin, *aqueue, *aconvert, *aencode, *aqueue_src; renatofilho@586: GMencoderPrivate *priv = G_MENCODER_GET_PRIVATE (self); renatofilho@586: renatofilho@586: vbin = vqueue = vscale = vrate = vencode = vqueue_src = NULL; renatofilho@586: abin = aqueue = aconvert = aencode = aqueue_src = NULL; renatofilho@586: renatofilho@586: pipe = gst_pipeline_new ("pipe"); renatofilho@586: src = gst_element_make_from_uri (GST_URI_SRC, uri, "src"); renatofilho@586: if (src == NULL) renatofilho@586: goto error; renatofilho@586: renatofilho@586: decode = gst_element_factory_make ("decodebin", "decode"); renatofilho@586: if (decode == NULL) renatofilho@586: goto error; renatofilho@586: renatofilho@586: mux = gst_element_factory_make ("ffmux_mpeg", "mux"); renatofilho@586: if (mux == NULL) renatofilho@586: goto error; renatofilho@586: renatofilho@586: fdsink = gst_element_factory_make ("fdsink", "sink"); renatofilho@586: if (fdsink == NULL) renatofilho@586: goto error; renatofilho@586: renatofilho@586: g_debug ("Setting fd to %d", out_fd); renatofilho@586: g_object_set (G_OBJECT (fdsink), "fd", out_fd, NULL); renatofilho@586: renatofilho@586: //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 renatofilho@586: renatofilho@586: vbin = gst_bin_new ("vbin"); renatofilho@586: vqueue = gst_element_factory_make ("queue", "vqueue"); renatofilho@586: vscale = gst_element_factory_make ("videoscale", "vscale"); renatofilho@586: vcolorspace = gst_element_factory_make ("ffmpegcolorspace", "colorspace"); renatofilho@586: vrate = gst_element_factory_make ("videorate", "vrate"); renatofilho@586: vencode = gst_element_factory_make ("ffenc_mpeg1video", "vencode"); renatofilho@586: vqueue_src = gst_element_factory_make ("queue", "queue_src"); renatofilho@586: renatofilho@586: renatofilho@586: if ((vbin == NULL) || (vqueue == NULL) || (vcolorspace == NULL) renatofilho@586: || (vscale == NULL) || (vrate == NULL) renatofilho@586: || (vencode == NULL) || (vqueue_src == NULL)) { renatofilho@586: g_warning ("Video elements not found"); renatofilho@586: goto error; renatofilho@586: } renatofilho@586: renatofilho@586: g_object_set (G_OBJECT (vencode), "bitrate", 200, "pass", 2, "quantizer", 5, NULL); renatofilho@586: renatofilho@586: gst_bin_add_many (GST_BIN (vbin), vqueue, vscale, vcolorspace, vrate, vencode, vqueue_src, NULL); renatofilho@586: gst_element_link (vqueue, vscale); renatofilho@586: renatofilho@586: renatofilho@586: vscale_caps = gst_caps_new_simple ("video/x-raw-yuv", renatofilho@586: "width", G_TYPE_INT, 320, renatofilho@586: "height", G_TYPE_INT, 288, renatofilho@586: NULL); renatofilho@586: renatofilho@586: if (gst_element_link_filtered (vscale, vcolorspace, vscale_caps) == FALSE) { renatofilho@586: g_warning ("Fail to resize video"); renatofilho@586: goto error; renatofilho@586: } renatofilho@586: renatofilho@586: if (gst_element_link (vcolorspace, vrate) == FALSE) { renatofilho@586: g_warning ("Fail to link video elements"); renatofilho@586: goto error; renatofilho@586: } renatofilho@586: renatofilho@586: gst_caps_unref (vscale_caps); renatofilho@586: renatofilho@586: vscale_caps = gst_caps_new_simple ("video/x-raw-yuv", renatofilho@586: "framerate", GST_TYPE_FRACTION, 10, 1, NULL); renatofilho@586: renatofilho@586: if (gst_element_link_filtered (vrate, vencode, vscale_caps) == FALSE) { renatofilho@586: g_warning ("Fail to link vrate with vencode."); renatofilho@586: goto error; renatofilho@586: renatofilho@586: } renatofilho@586: renatofilho@586: gst_element_link (vencode, vqueue_src); renatofilho@586: renatofilho@586: // ghost pad the video bin renatofilho@586: vsinkpad = gst_element_get_pad (vqueue, "sink"); renatofilho@586: gst_element_add_pad (vbin, gst_ghost_pad_new ("sink", vsinkpad)); renatofilho@586: gst_object_unref (vsinkpad); renatofilho@586: renatofilho@586: video_src_pad = gst_element_get_pad (vqueue_src, "src"); renatofilho@586: gst_element_add_pad (vbin, gst_ghost_pad_new ("src", video_src_pad)); renatofilho@586: gst_object_unref (video_src_pad); renatofilho@586: renatofilho@586: renatofilho@586: //audio/x-raw-int ! queue ! audioconvert ! faac ! rtpmp4gpay ! udpsink name=upd_audio host=224.0.0.1 port=5002 renatofilho@586: abin = gst_bin_new ("abin"); renatofilho@586: aqueue = gst_element_factory_make ("queue", "aqueue"); renatofilho@586: aconvert= gst_element_factory_make ("audioconvert", "aconvert"); renatofilho@586: aencode = gst_element_factory_make ("lame", "aencode"); renatofilho@586: aqueue_src= gst_element_factory_make ("queue", "aqueue_src"); renatofilho@586: renatofilho@586: if ((abin == NULL) || (aqueue == NULL) || (aconvert == NULL) renatofilho@586: || (aencode == NULL) || (aqueue_src == NULL)) { renatofilho@586: g_warning ("Audio elements not found"); renatofilho@586: goto error; renatofilho@586: } renatofilho@586: renatofilho@586: gst_bin_add_many (GST_BIN (abin), aqueue, aconvert, aencode, aqueue_src, NULL); renatofilho@586: gst_element_link_many (aqueue, aconvert, aencode, aqueue_src, NULL); renatofilho@586: renatofilho@586: renatofilho@586: // ghost pad the audio bin renatofilho@586: asinkpad = gst_element_get_pad (aqueue, "sink"); renatofilho@586: gst_element_add_pad (abin, gst_ghost_pad_new("sink", asinkpad)); renatofilho@586: gst_object_unref (asinkpad); renatofilho@586: renatofilho@586: audio_src_pad = gst_element_get_pad (aqueue_src, "src"); renatofilho@586: gst_element_add_pad (abin, gst_ghost_pad_new("src", audio_src_pad)); renatofilho@586: gst_object_unref (audio_src_pad); renatofilho@586: renatofilho@586: renatofilho@586: // Finish Pipe renatofilho@586: gst_bin_add_many (GST_BIN (pipe), src, decode, abin, vbin, mux, fdsink, NULL); renatofilho@586: gst_element_link (src, decode); renatofilho@586: renatofilho@586: //Link bins with mux renatofilho@586: audio_src_pad = gst_element_get_pad (abin, "src"); renatofilho@586: mux_pad = gst_element_get_pad (mux, "audio_0"); renatofilho@586: if (gst_pad_link (audio_src_pad, mux_pad) != GST_PAD_LINK_OK) { renatofilho@586: g_warning ("Fail link audio and mux"); renatofilho@586: goto error; renatofilho@586: renatofilho@586: } renatofilho@586: gst_object_unref (audio_src_pad); renatofilho@586: gst_object_unref (mux_pad); renatofilho@586: audio_src_pad = NULL; renatofilho@586: mux_pad = NULL; renatofilho@586: renatofilho@586: video_src_pad = gst_element_get_pad (vbin, "src"); renatofilho@586: mux_pad = gst_element_get_pad (mux, "video_0"); renatofilho@586: if (gst_pad_link (video_src_pad, mux_pad) != GST_PAD_LINK_OK) { renatofilho@586: g_warning ("Fail link video and mux"); renatofilho@586: goto error; renatofilho@586: } renatofilho@586: gst_object_unref (video_src_pad); renatofilho@586: gst_object_unref (mux_pad); renatofilho@586: video_src_pad = NULL; renatofilho@586: mux_pad = NULL; renatofilho@586: renatofilho@586: //Link mux with sink renatofilho@586: gst_element_link (mux, fdsink); renatofilho@586: renatofilho@586: bus = gst_pipeline_get_bus (GST_PIPELINE (pipe)); renatofilho@586: gst_bus_add_watch (bus, _pipeline_bus_cb, self); renatofilho@586: gst_object_unref (bus); renatofilho@586: renatofilho@586: g_signal_connect (G_OBJECT (decode), renatofilho@586: "new-decoded-pad", renatofilho@586: G_CALLBACK (_decodebin_new_pad_cb), renatofilho@586: self); renatofilho@586: renatofilho@586: g_signal_connect (G_OBJECT (decode), renatofilho@586: "unknown-type", renatofilho@586: G_CALLBACK (_decodebin_unknown_type_cb), renatofilho@586: self); renatofilho@586: renatofilho@586: g_debug ("Setting pipe to PAUSE"); renatofilho@586: renatofilho@586: priv->pipe = pipe; renatofilho@586: priv->abin = abin; renatofilho@586: priv->vbin = vbin; renatofilho@586: priv->sink = fdsink; renatofilho@586: priv->ready = FALSE; renatofilho@586: renatofilho@586: gst_element_set_state (pipe, GST_STATE_PAUSED); renatofilho@586: g_debug ("End SETUP"); renatofilho@586: return TRUE; renatofilho@586: renatofilho@586: error: renatofilho@586: g_warning ("Invalid uri"); renatofilho@586: renatofilho@586: if (pipe != NULL) renatofilho@586: gst_object_unref (pipe); renatofilho@586: renatofilho@586: if (src != NULL) renatofilho@586: gst_object_unref (src); renatofilho@586: renatofilho@586: if (decode != NULL) renatofilho@586: gst_object_unref (decode); renatofilho@586: renatofilho@586: if (vscale_caps != NULL) renatofilho@586: gst_caps_unref (vscale_caps); renatofilho@586: renatofilho@586: if (vbin != NULL) renatofilho@586: gst_object_unref (vbin); renatofilho@586: renatofilho@586: if (vqueue != NULL) renatofilho@586: gst_object_unref (vqueue); renatofilho@586: renatofilho@586: if (vrate != NULL) renatofilho@586: gst_object_unref (vrate); renatofilho@586: renatofilho@586: if (vencode != NULL) renatofilho@586: gst_object_unref (vencode); renatofilho@586: renatofilho@586: if (vqueue_src != NULL) renatofilho@586: gst_object_unref (vqueue_src); renatofilho@586: renatofilho@586: if (abin != NULL) renatofilho@586: gst_object_unref (abin); renatofilho@586: renatofilho@586: if (aqueue != NULL) renatofilho@586: gst_object_unref (aqueue); renatofilho@586: renatofilho@586: if (aconvert != NULL) renatofilho@586: gst_object_unref (aconvert); renatofilho@586: renatofilho@586: if (aencode != NULL) renatofilho@586: gst_object_unref (aencode); renatofilho@586: renatofilho@586: if (aqueue_src != NULL) renatofilho@586: gst_object_unref (aqueue_src); renatofilho@586: renatofilho@586: if (video_src_pad != NULL) { renatofilho@586: gst_object_unref (video_src_pad); renatofilho@586: } renatofilho@586: renatofilho@586: if (audio_src_pad != NULL) { renatofilho@586: gst_object_unref (audio_src_pad); renatofilho@586: } renatofilho@586: renatofilho@586: if (mux != NULL) { renatofilho@586: gst_object_unref (mux); renatofilho@586: } renatofilho@586: renatofilho@586: if (mux_pad != NULL) { renatofilho@586: gst_object_unref (mux_pad); renatofilho@586: } renatofilho@586: renatofilho@586: if (fdsink != NULL) renatofilho@586: gst_object_unref (fdsink); renatofilho@586: renatofilho@586: return FALSE; renatofilho@586: } renatofilho@586: renatofilho@586: gboolean renatofilho@586: g_mencoder_play_stream (GMencoder *self) renatofilho@586: { renatofilho@586: GMencoderPrivate *priv = G_MENCODER_GET_PRIVATE (self); renatofilho@586: renatofilho@586: g_return_val_if_fail (priv->ready == TRUE, FALSE); renatofilho@586: renatofilho@586: if (gst_element_set_state (priv->pipe, GST_STATE_PLAYING) != GST_STATE_CHANGE_FAILURE) { renatofilho@586: g_debug ("PLAYING"); renatofilho@586: return TRUE; renatofilho@586: } renatofilho@586: return FALSE; renatofilho@586: } renatofilho@586: renatofilho@586: gboolean renatofilho@586: g_mencoder_pause_stream (GMencoder *self) renatofilho@586: { renatofilho@586: GMencoderPrivate *priv = G_MENCODER_GET_PRIVATE (self); renatofilho@586: renatofilho@586: g_return_val_if_fail (priv->ready == TRUE, FALSE); renatofilho@586: renatofilho@586: if (gst_element_set_state (priv->pipe, GST_STATE_PAUSED) != GST_STATE_CHANGE_FAILURE) { renatofilho@586: g_debug ("PAUSED"); renatofilho@586: return TRUE; renatofilho@586: } renatofilho@586: return FALSE; renatofilho@586: } renatofilho@586: renatofilho@586: void renatofilho@586: g_mencoder_close_stream (GMencoder *self) renatofilho@586: { renatofilho@586: renatofilho@586: GMencoderPrivate *priv = G_MENCODER_GET_PRIVATE (self); renatofilho@586: renatofilho@586: g_return_if_fail (priv->ready == TRUE); renatofilho@586: renatofilho@586: gst_element_set_state (priv->pipe, GST_STATE_NULL); renatofilho@586: gst_object_unref (priv->pipe); renatofilho@586: priv->pipe = NULL; renatofilho@586: priv->abin = NULL; renatofilho@586: priv->vbin = NULL; renatofilho@586: priv->sink = NULL; renatofilho@586: priv->ready = FALSE; renatofilho@586: } renatofilho@586: renatofilho@586: static gboolean renatofilho@586: _pipeline_bus_cb (GstBus *bus, renatofilho@586: GstMessage *msg, renatofilho@586: gpointer user_data) renatofilho@586: { renatofilho@586: switch (GST_MESSAGE_TYPE (msg)) renatofilho@586: { renatofilho@586: case GST_MESSAGE_STATE_CHANGED: renatofilho@586: { renatofilho@586: GstState oldstate; renatofilho@586: GstState newstate; renatofilho@586: GstState pendingstate; renatofilho@586: renatofilho@586: GMencoderPrivate *priv = G_MENCODER_GET_PRIVATE (user_data); renatofilho@586: renatofilho@586: gst_message_parse_state_changed (msg, &oldstate, renatofilho@586: &newstate, &pendingstate); renatofilho@586: renatofilho@586: if (pendingstate != GST_STATE_VOID_PENDING) renatofilho@586: break; renatofilho@586: renatofilho@586: if ((oldstate == GST_STATE_READY) && renatofilho@586: (newstate == GST_STATE_PAUSED)) { renatofilho@586: if (priv->ready) renatofilho@586: g_signal_emit (user_data, g_mencoder_signals[PAUSED], 0); renatofilho@586: else { renatofilho@586: priv->ready = TRUE; renatofilho@586: g_signal_emit (user_data, g_mencoder_signals[READY], 0); renatofilho@586: } renatofilho@586: } else if ((oldstate == GST_STATE_PAUSED) && renatofilho@586: (newstate == GST_STATE_PLAYING)) { renatofilho@586: g_signal_emit (user_data, g_mencoder_signals[PLAYING], 0); renatofilho@586: } else if ((oldstate == GST_STATE_READY) && renatofilho@586: (newstate == GST_STATE_NULL)) { renatofilho@586: g_signal_emit (user_data, g_mencoder_signals[STOPED], 0); renatofilho@586: } renatofilho@586: break; renatofilho@586: } renatofilho@586: case GST_MESSAGE_ERROR: renatofilho@586: { renatofilho@586: GError *error; renatofilho@586: gchar *debug; renatofilho@586: gchar *err_str; renatofilho@586: renatofilho@586: gst_message_parse_error (msg, &error, &debug); renatofilho@586: err_str = g_strdup_printf ("Error [%d] %s (%s)", error->code, renatofilho@586: error->message, renatofilho@586: debug); renatofilho@586: g_signal_emit (user_data, g_mencoder_signals[ERROR], 0, err_str); renatofilho@586: g_free (err_str); renatofilho@586: g_clear_error (&error); renatofilho@586: g_free (debug); renatofilho@586: break; renatofilho@586: } renatofilho@586: renatofilho@586: case GST_MESSAGE_EOS: renatofilho@586: g_signal_emit (user_data, g_mencoder_signals[EOS], 0); renatofilho@586: break; renatofilho@586: default: renatofilho@586: break; renatofilho@586: } renatofilho@586: return TRUE; renatofilho@586: } renatofilho@586: renatofilho@586: static void renatofilho@586: _decodebin_new_pad_cb (GstElement* object, renatofilho@586: GstPad* pad, renatofilho@586: gboolean flag, renatofilho@586: gpointer user_data) renatofilho@586: { renatofilho@586: GstCaps *caps; renatofilho@586: gchar *str_caps = NULL; renatofilho@586: GMencoderPrivate *priv = G_MENCODER_GET_PRIVATE (user_data); renatofilho@586: renatofilho@586: caps = gst_pad_get_caps (pad); renatofilho@586: str_caps = gst_caps_to_string (caps); renatofilho@586: g_debug ("CAPS : %s", str_caps); renatofilho@586: renatofilho@586: if (strstr (str_caps, "audio") != NULL) { renatofilho@586: GstPad *apad = gst_element_get_pad (priv->abin, "sink"); renatofilho@586: g_debug ("Linked with Audio"); renatofilho@586: gst_pad_link (pad, apad); renatofilho@586: gst_object_unref (apad); renatofilho@586: } else if (strstr (str_caps, "video") != NULL) { renatofilho@586: GstPad *vpad = gst_element_get_pad (priv->vbin, "sink"); renatofilho@586: g_debug ("Linked with Video"); renatofilho@586: gst_pad_link (pad, vpad); renatofilho@586: gst_object_unref (vpad); renatofilho@586: } else { renatofilho@586: g_warning ("invalid caps %s", str_caps); renatofilho@586: } renatofilho@586: renatofilho@586: g_free (str_caps); renatofilho@586: gst_caps_unref (caps); renatofilho@586: g_debug ("OK"); renatofilho@586: } renatofilho@586: renatofilho@586: static void renatofilho@586: _decodebin_unknown_type_cb (GstElement* object, renatofilho@586: GstPad* pad, renatofilho@586: GstCaps* caps, renatofilho@586: gpointer user_data) renatofilho@586: { renatofilho@586: g_warning ("Unknown Type"); renatofilho@586: }