Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- /*
- * main.c
- *
- * Created on: Feb 20, 2014
- * Author: memphis
- */
- #include <glib.h>
- #include "gst/gst.h"
- #include "X11/Xlib.h"
- static gchar* fileLocation = NULL;
- static gint simultaneousDisplay = 2;
- static gint displayCount = -1;
- static GMutex gMutex;
- typedef struct _DisplayData DisplayData;
- struct _DisplayData {
- GstElement* pipeline;
- GstBus* bus;
- GMainLoop* loop;
- GMainContext* context;
- };
- static void
- demux_pad_added(GstElement* object, GstPad* arg0, gpointer user_data) {
- DisplayData* data = (DisplayData*) user_data;
- GstCaps* caps = gst_pad_query_caps(arg0, NULL);
- GstStructure* struc = gst_caps_get_structure(caps, 0);
- const gchar* name = gst_structure_get_name(struc);
- if (g_str_has_suffix(name, "x-h264")) {
- GstElement* bin = gst_bin_new("decodebin");
- GstElement* h264parse = gst_element_factory_make("h264parse", NULL);
- GstElement* decode = gst_element_factory_make("avdec_h264", NULL);
- GstElement* glColorScale = gst_element_factory_make("glcolorscale", NULL);
- GstElement* capsFilter = gst_element_factory_make("capsfilter", NULL);
- GstElement* videoconvert = gst_element_factory_make("videoconvert", NULL);
- GstElement* displaySink = gst_element_factory_make("xvimagesink", NULL);
- GstCaps* capsFilterProp = gst_caps_from_string("video/x-raw, format=I420, height=500, width=500");
- g_object_set(capsFilter, "caps", capsFilterProp, NULL);
- gst_caps_unref(capsFilterProp);
- g_object_set(displaySink, "sync", FALSE, NULL);
- gst_bin_add_many(GST_BIN(bin), h264parse, decode, glColorScale, capsFilter, videoconvert, displaySink, NULL);
- gst_element_link_many(h264parse, decode, glColorScale, capsFilter, videoconvert, displaySink, NULL);
- //Create the ghost pad
- GstPad* pad = gst_element_get_static_pad (h264parse, "sink");
- gst_element_add_pad (GST_ELEMENT(bin), gst_ghost_pad_new ("sink", pad));
- gst_object_unref (GST_OBJECT (pad));
- //add and sync the decode bin
- gst_bin_add(GST_BIN(data->pipeline), bin);
- GstPad* binSinkPad = gst_element_get_static_pad(bin, "sink");
- gst_pad_link(arg0, binSinkPad);
- gst_object_unref(binSinkPad);
- gst_element_set_state(bin, GST_STATE_PLAYING);
- } else {
- gchar* capsStr = gst_caps_to_string(caps);
- g_message("The following caps isn't supported by this test application : %s", capsStr);
- g_free(capsStr);
- GstElement* fakesink = gst_element_factory_make("fakesink", NULL);
- g_object_set(fakesink, "async", FALSE, "sync", FALSE, NULL);
- gst_bin_add(GST_BIN(data->pipeline), fakesink);
- GstPad* fakesinkPad = gst_element_get_static_pad(fakesink, "sink");
- if (GST_PAD_LINK_FAILED(gst_pad_link(arg0, fakesinkPad)))
- g_warning("Failed to link to the fake sink !!! :S");
- gst_object_unref(fakesinkPad);
- gst_element_set_state(fakesink, GST_STATE_PLAYING);
- }
- gst_caps_unref(caps);
- }
- static void
- display_create_pipeline(DisplayData* data) {
- GstElement* filesrc = gst_element_factory_make("filesrc", NULL);
- GstElement* demux = gst_element_factory_make("matroskademux", NULL);
- g_object_set(filesrc, "location", fileLocation, NULL);
- g_signal_connect(demux, "pad-added", G_CALLBACK(demux_pad_added), data);
- gst_bin_add_many(GST_BIN(data->pipeline), filesrc, demux, NULL);
- gst_element_link(filesrc, demux);
- }
- static gboolean
- display_bus(GstBus* bus, GstMessage* message, gpointer user_data) {
- DisplayData* data = (DisplayData*) user_data;
- switch (GST_MESSAGE_TYPE (message)) {
- case GST_MESSAGE_EOS:
- g_print("Receive EOS on the BUS\n");
- g_main_loop_quit(data->loop);
- return G_SOURCE_REMOVE;
- break;
- default:
- break;
- }
- return G_SOURCE_CONTINUE;
- }
- static void
- display_run() {
- //Create Main object
- DisplayData* data = g_new0(DisplayData, 1);
- data->context = g_main_context_new();
- g_main_context_push_thread_default(data->context);
- data->loop = g_main_loop_new(data->context,FALSE);
- data->pipeline = gst_pipeline_new("display");
- data->bus = gst_element_get_bus (data->pipeline);
- GSource* busSource = gst_bus_create_watch(data->bus);
- g_source_attach(busSource, data->context);
- g_source_set_callback (busSource, (GSourceFunc) display_bus, data, NULL);
- gst_object_unref(data->bus);
- display_create_pipeline(data);
- gst_element_set_state(data->pipeline, GST_STATE_PLAYING);
- g_main_loop_run(data->loop);
- g_main_context_dispatch(data->context);
- gst_element_set_state(data->pipeline, GST_STATE_NULL);
- gst_object_unref(data->pipeline);
- g_source_destroy(busSource);
- g_source_unref(busSource);
- g_main_loop_unref(data->loop);
- g_main_context_pop_thread_default(data->context);
- g_main_context_unref(data->context);
- g_free(data);
- }
- static gpointer
- run_display(gpointer user_data) {
- g_mutex_lock(&gMutex);
- while ((displayCount != 0)) {
- displayCount--;
- g_mutex_unlock(&gMutex);
- display_run();
- g_mutex_lock(&gMutex);
- }
- g_mutex_unlock(&gMutex);
- return NULL;
- }
- static void
- queue_clean(gpointer user_data) {
- GThread* th = (GThread*) user_data;
- g_thread_join(th);
- }
- int main(int argc, char* argv[]) {
- gst_init(NULL, NULL);
- XInitThreads();
- fileLocation = g_strdup("/home/memphis/samples/Monster.mkv");
- GQueue* queue = g_queue_new();
- g_mutex_init(&gMutex);
- gint i=0;
- for (i=0; i< simultaneousDisplay; i++) {
- GThread* thread = g_thread_new("controlTh", run_display, NULL);
- g_queue_push_tail(queue, thread);
- }
- g_queue_free_full(queue, queue_clean);
- gst_deinit();
- g_free(fileLocation);
- g_mutex_clear(&gMutex);
- return 0;
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement