summaryrefslogtreecommitdiff
path: root/src/debug/local-play.c
diff options
context:
space:
mode:
authorNirbheek Chauhan <nirbheek@centricular.com>2014-07-09 08:43:04 (GMT)
committerNirbheek Chauhan <nirbheek.chauhan@gmail.com>2014-07-09 08:43:04 (GMT)
commit160c3dbb2ce9172ea8cf3ddb559a4efd9fde1683 (patch)
tree0123dba499f5ada7d82a6ff676732efb7b8a23bd /src/debug/local-play.c
parent8ef516c328ef2cd5b3664be62274a08192608ffb (diff)
downloadsoup-transcoding-proxy-160c3dbb2ce9172ea8cf3ddb559a4efd9fde1683.zip
soup-transcoding-proxy-160c3dbb2ce9172ea8cf3ddb559a4efd9fde1683.tar.gz
Add source files
Diffstat (limited to 'src/debug/local-play.c')
-rw-r--r--src/debug/local-play.c147
1 files changed, 147 insertions, 0 deletions
diff --git a/src/debug/local-play.c b/src/debug/local-play.c
new file mode 100644
index 0000000..497d567
--- /dev/null
+++ b/src/debug/local-play.c
@@ -0,0 +1,147 @@
+/* License: LGPL-2.1
+ * vim: set sts=2 sw=2 et : */
+
+#include "local-play.h"
+
+static void
+pad_has_video_caps (TranscodeServerCtx *ctx,
+ GstPad *decodebin_pad)
+{
+ GstPad *sink_pad;
+ GstElement *bin;
+ GstElement *videoconv, *videoscale, *videosink;
+
+ bin = gst_bin_new (NULL);
+ videoconv = gst_element_factory_make ("videoconvert", "videoconv");
+ videoscale = gst_element_factory_make ("videoscale", "videoscale");
+ videosink = gst_element_factory_make ("autovideosink", "videosink");
+
+ gst_bin_add_many (GST_BIN (bin), videoconv, videoscale, videosink, NULL);
+ gst_element_link_many (videoconv, videoscale, videosink, NULL);
+
+ sink_pad = gst_element_get_static_pad (videoconv, "sink");
+ gst_element_add_pad (bin, gst_ghost_pad_new ("sink", sink_pad));
+ gst_object_unref (sink_pad);
+
+ gst_bin_add (GST_BIN (ctx->pipeline), bin);
+
+ sink_pad = gst_element_get_static_pad (bin, "sink");
+ if (gst_pad_link (decodebin_pad, sink_pad) != GST_PAD_LINK_OK) {
+ g_critical ("ERROR: Unable to link video pads");
+ soup_message_set_status (ctx->msg, SOUP_STATUS_INTERNAL_SERVER_ERROR);
+ goto out;
+ }
+
+ /* Since these elements have been added to the pipeline after the state was
+ * changed from GST_STATE_NULL, they have to be moved to PAUSED manually */
+ gst_element_set_state (bin, GST_STATE_PAUSED);
+out:
+ gst_object_unref (sink_pad);
+ return;
+}
+
+static void
+pad_has_audio_caps (TranscodeServerCtx *ctx,
+ GstPad *decodebin_pad)
+{
+ GstPad *sink_pad;
+ GstElement *bin;
+ GstElement *audioconv, *audioresample, *audiosink;
+
+ bin = gst_bin_new (NULL);
+ audioconv = gst_element_factory_make ("audioconvert", "audioconv");
+ audioresample = gst_element_factory_make ("audioresample", "audioresample");
+ audiosink = gst_element_factory_make ("autoaudiosink", "audiosink");
+
+ gst_bin_add_many (GST_BIN (bin), audioconv, audioresample, audiosink, NULL);
+ gst_element_link_many (audioconv, audioresample, audiosink, NULL);
+
+ sink_pad = gst_element_get_static_pad (audioconv, "sink");
+ gst_element_add_pad (bin, gst_ghost_pad_new ("sink", sink_pad));
+ gst_object_unref (sink_pad);
+
+ gst_bin_add (GST_BIN (ctx->pipeline), bin);
+
+ sink_pad = gst_element_get_static_pad (bin, "sink");
+ if (gst_pad_link (decodebin_pad, sink_pad) != GST_PAD_LINK_OK) {
+ g_critical ("ERROR: Unable to link video pads");
+ soup_message_set_status (ctx->msg, SOUP_STATUS_INTERNAL_SERVER_ERROR);
+ goto out;
+ }
+
+ /* Since these elements have been added to the pipeline after the state was
+ * changed from GST_STATE_NULL, they have to be moved to PAUSED manually */
+ gst_element_set_state (bin, GST_STATE_PAUSED);
+out:
+ gst_object_unref (sink_pad);
+ return;
+}
+
+static gboolean
+structure_printf (GQuark field_id,
+ const GValue *value,
+ gpointer user_data)
+{
+ char *char_value;
+
+ char_value = g_strdup_value_contents (value);
+ g_print ("%s = %s\n", g_quark_to_string (field_id), char_value);
+ g_free (char_value);
+ return TRUE;
+}
+
+static void
+decodebin_pad_added (GstElement *decodebin,
+ GstPad *src_pad,
+ gpointer user_data)
+{
+ GstCaps *pad_caps;
+ GstStructure *structure;
+ TranscodeServerCtx *ctx = user_data;
+
+ if (!gst_pad_has_current_caps (src_pad)) {
+ g_critical ("Decodebin pad doesn't have current caps");
+ soup_message_set_status (ctx->msg, SOUP_STATUS_INTERNAL_SERVER_ERROR);
+ return;
+ }
+
+ pad_caps = gst_pad_get_current_caps (src_pad);
+ structure = gst_caps_get_structure (pad_caps, 0);
+ gst_structure_foreach (structure, structure_printf, NULL);
+
+ if (gst_structure_has_name (structure, "audio/x-raw"))
+ pad_has_audio_caps (ctx, src_pad);
+ else if (gst_structure_has_name (structure, "video/x-raw"))
+ pad_has_video_caps (ctx, src_pad);
+ else
+ g_critical ("Found unsupported caps: %s",
+ gst_structure_get_name (structure));
+
+ gst_caps_unref (pad_caps);
+}
+
+void
+stp_play_from_msg (TranscodeServerCtx *ctx)
+{
+ GstBus *bus;
+ GstElement *src, *decodebin;
+
+ g_debug ("Constructing pipeline\n");
+ src = gst_element_factory_make ("appsrc", "src");
+ g_object_set (src, "is-live", TRUE,
+ "stream-type", 0, NULL);
+ ctx->appsrc = src;
+
+ decodebin = gst_element_factory_make ("decodebin", "decodebin");
+ gst_bin_add_many (GST_BIN (ctx->pipeline), src, decodebin, NULL);
+ gst_element_link (src, decodebin);
+
+ g_signal_connect (decodebin, "pad-added",
+ G_CALLBACK (decodebin_pad_added), ctx);
+
+ bus = gst_pipeline_get_bus (GST_PIPELINE (ctx->pipeline));
+ gst_bus_add_signal_watch (bus);
+ g_signal_connect (bus, "message", G_CALLBACK (stp_on_gst_bus_message), ctx);
+ g_object_unref (bus);
+}
+