Advertisement
Guest User

Untitled

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