Advertisement
Guest User

Untitled

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