Advertisement
Guest User

Untitled

a guest
Feb 20th, 2014
87
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 5.29 KB | None | 0 0
  1. /*
  2. * main.c
  3. *
  4. * Created on: Feb 20, 2014
  5. * Author: memphis
  6. */
  7. #include <glib.h>
  8. #include "gst/gst.h"
  9. #include "X11/Xlib.h"
  10.  
  11.  
  12. static gchar* fileLocation = NULL;
  13. static gint simultaneousDisplay = 4;
  14. static gint displayCount = -1;
  15. static GMutex gMutex;
  16.  
  17. typedef struct _DisplayData DisplayData;
  18. struct _DisplayData {
  19. GstElement* pipeline;
  20. GstBus* bus;
  21. GMainLoop* loop;
  22. GMainContext* context;
  23. };
  24.  
  25. static void
  26. demux_pad_added(GstElement* object, GstPad* arg0, gpointer user_data) {
  27. DisplayData* data = (DisplayData*) user_data;
  28.  
  29. GstCaps* caps = gst_pad_query_caps(arg0, NULL);
  30. GstStructure* struc = gst_caps_get_structure(caps, 0);
  31. const gchar* name = gst_structure_get_name(struc);
  32. if (g_str_has_suffix(name, "x-h264")) {
  33. GstElement* bin = gst_bin_new("decodebin");
  34. GstElement* h264parse = gst_element_factory_make("h264parse", NULL);
  35. GstElement* decode = gst_element_factory_make("vaapidecode", NULL);
  36. GstElement* glColorScale = gst_element_factory_make("glcolorscale", NULL);
  37. GstElement* capsFilter = gst_element_factory_make("capsfilter", NULL);
  38. GstElement* displaySink = gst_element_factory_make("xvimagesink", NULL);
  39.  
  40. GstCaps* capsFilterProp = gst_caps_from_string("video/x-raw, height=500, width=500");
  41. g_object_set(capsFilter, "caps", capsFilterProp, NULL);
  42. gst_caps_unref(capsFilterProp);
  43.  
  44. gst_bin_add_many(GST_BIN(bin), h264parse, decode, glColorScale, capsFilter, displaySink, NULL);
  45. gst_element_link_many(h264parse, decode, glColorScale, capsFilter, displaySink, NULL);
  46. //Create the ghost pad
  47. GstPad* pad = gst_element_get_static_pad (h264parse, "sink");
  48. gst_element_add_pad (GST_ELEMENT(bin), gst_ghost_pad_new ("sink", pad));
  49. gst_object_unref (GST_OBJECT (pad));
  50.  
  51. //add and sync the decode bin
  52. gst_bin_add(GST_BIN(data->pipeline), bin);
  53. GstPad* binSinkPad = gst_element_get_static_pad(bin, "sink");
  54. gst_pad_link(arg0, binSinkPad);
  55. gst_object_unref(binSinkPad);
  56. gst_element_set_state(bin, GST_STATE_PLAYING);
  57.  
  58.  
  59. } else {
  60. gchar* capsStr = gst_caps_to_string(caps);
  61. g_message("The following caps isn't supported by this test application : %s", capsStr);
  62. g_free(capsStr);
  63.  
  64. GstElement* fakesink = gst_element_factory_make("fakesink", NULL);
  65. g_object_set(fakesink, "async", FALSE, "sync", FALSE, NULL);
  66. gst_bin_add(GST_BIN(data->pipeline), fakesink);
  67.  
  68. GstPad* fakesinkPad = gst_element_get_static_pad(fakesink, "sink");
  69. if (GST_PAD_LINK_FAILED(gst_pad_link(arg0, fakesinkPad)))
  70. g_warning("Failed to link to the fake sink !!! :S");
  71. gst_object_unref(fakesinkPad);
  72.  
  73. gst_element_set_state(fakesink, GST_STATE_PLAYING);
  74. }
  75. gst_caps_unref(caps);
  76. }
  77.  
  78. static void
  79. display_create_pipeline(DisplayData* data) {
  80.  
  81. GstElement* filesrc = gst_element_factory_make("filesrc", NULL);
  82. GstElement* demux = gst_element_factory_make("matroskademux", NULL);
  83.  
  84. g_object_set(filesrc, "location", fileLocation, NULL);
  85. g_signal_connect(demux, "pad-added", G_CALLBACK(demux_pad_added), data);
  86. gst_bin_add_many(GST_BIN(data->pipeline), filesrc, demux, NULL);
  87. gst_element_link(filesrc, demux);
  88. }
  89.  
  90. static gboolean
  91. display_bus(GstBus* bus, GstMessage* message, gpointer user_data) {
  92. DisplayData* data = (DisplayData*) user_data;
  93.  
  94. switch (GST_MESSAGE_TYPE (message)) {
  95. case GST_MESSAGE_EOS:
  96. g_print("Receive EOS on the BUS\n");
  97. g_main_loop_quit(data->loop);
  98. return G_SOURCE_REMOVE;
  99. break;
  100. default:
  101. break;
  102. }
  103.  
  104. return G_SOURCE_CONTINUE;
  105. }
  106.  
  107. static void
  108. display_run() {
  109. DisplayData* data = g_new0(DisplayData, 1);
  110. //Create Main object
  111. data->context = g_main_context_new();
  112. g_main_context_push_thread_default(data->context);
  113. data->loop = g_main_loop_new(data->context,FALSE);
  114. data->pipeline = gst_pipeline_new("display");
  115. data->bus = gst_element_get_bus (data->pipeline);
  116. GSource* busSource = gst_bus_create_watch(data->bus);
  117. g_source_attach(busSource, data->context);
  118. g_source_set_callback (busSource, (GSourceFunc) display_bus, data, NULL);
  119. gst_object_unref(data->bus);
  120.  
  121. display_create_pipeline(data);
  122.  
  123. gst_element_set_state(data->pipeline, GST_STATE_PLAYING);
  124. g_main_loop_run(data->loop);
  125. g_main_context_dispatch(data->context);
  126. gst_element_set_state(data->pipeline, GST_STATE_NULL);
  127. gst_object_unref(data->pipeline);
  128.  
  129. g_main_loop_unref(data->loop);
  130. g_main_context_pop_thread_default(data->context);
  131. g_main_context_unref(data->context);
  132.  
  133. g_source_destroy(busSource);
  134. g_source_unref(busSource);
  135.  
  136. g_free(data);
  137. }
  138.  
  139. static gpointer
  140. run_display(gpointer user_data) {
  141.  
  142. g_mutex_lock(&gMutex);
  143. while ((displayCount != 0)) {
  144. displayCount--;
  145. g_mutex_unlock(&gMutex);
  146. display_run();
  147. g_mutex_lock(&gMutex);
  148. }
  149. g_mutex_unlock(&gMutex);
  150.  
  151. return NULL;
  152. }
  153.  
  154. static void
  155. queue_clean(gpointer user_data) {
  156. GThread* th = (GThread*) user_data;
  157. g_thread_join(th);
  158. }
  159.  
  160. int main(int argc, char* argv[]) {
  161. gst_init(NULL, NULL);
  162.  
  163. XInitThreads();
  164.  
  165. fileLocation = g_strdup("/home/memphis/samples/Monster.mkv");
  166. GQueue* queue = g_queue_new();
  167. g_mutex_init(&gMutex);
  168.  
  169. gint i=0;
  170. for (i=0; i< simultaneousDisplay; i++) {
  171. GThread* thread = g_thread_new("controlTh", run_display, NULL);
  172. g_queue_push_tail(queue, thread);
  173. }
  174.  
  175. g_queue_free_full(queue, queue_clean);
  176.  
  177.  
  178. gst_deinit();
  179. g_free(fileLocation);
  180. g_mutex_clear(&gMutex);
  181.  
  182. return 0;
  183. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement