diff options
Diffstat (limited to 'src/debug')
-rw-r--r-- | src/debug/local-play.c | 147 | ||||
-rw-r--r-- | src/debug/local-play.h | 11 |
2 files changed, 158 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); +} + diff --git a/src/debug/local-play.h b/src/debug/local-play.h new file mode 100644 index 0000000..a56a572 --- /dev/null +++ b/src/debug/local-play.h @@ -0,0 +1,11 @@ +/* License: LGPL-2.1 + * vim: set sts=2 sw=2 et : */ + +#ifndef _SST_LOCAL_PLAY +#define _SST_LOCAL_PLAY + +#include "../lib.h" + +void stp_play_from_msg (TranscodeServerCtx *ctx); + +#endif /* _SST_LOCAL_PLAY */ |