Advertisement
Guest User

Untitled

a guest
Jan 24th, 2014
83
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 9.29 KB | None | 0 0
  1. /*
  2. * main.c
  3. *
  4. * Created on: Jan 22, 2014
  5. * Author: memphis
  6. */
  7.  
  8. #include "glib.h"
  9. #include "gst/gst.h"
  10. #include <gst/app/gstappsink.h>
  11.  
  12. #define USE_VIDEO_SINK
  13.  
  14. typedef struct _CustomData CustomData;
  15. struct _CustomData {
  16. GMainLoop* loop;
  17. GstBus* bus;
  18. GstElement* pipeline;
  19. GstElement* filesrc;
  20. GstElement* filedemux;
  21. GstElement* h264parse;
  22. GstElement* h264dec;
  23. GstElement* videoconvert;
  24. GstElement* enc;
  25. GstElement* sink;
  26.  
  27. gint64 targetPTSTimecode;
  28. gint64 lastSeek;
  29. };
  30.  
  31. static gint buffer_count = 0;
  32.  
  33. GstPadProbeReturn
  34. demux_src_probe(GstPad * pad, GstPadProbeInfo * info, gpointer user_data) {
  35. if (GST_PAD_PROBE_INFO_TYPE(info) & GST_PAD_PROBE_TYPE_EVENT_BOTH) {
  36. if ((GST_EVENT_TYPE (GST_PAD_PROBE_INFO_DATA (info)) == GST_EVENT_EOS)) {
  37. g_print("Receive EOS on the probe\n");
  38. return GST_PAD_PROBE_DROP;
  39. }
  40.  
  41. // if ((GST_EVENT_TYPE (GST_PAD_PROBE_INFO_DATA (info)) == GST_EVENT_SEGMENT)) {
  42. // //g_print("########## REceive segment \n");
  43. // CustomData* data = (CustomData*) user_data;
  44. // gint64 duration = 0;
  45. // gst_element_query_duration(data->filedemux, GST_FORMAT_TIME, &duration);
  46. // g_print("Duration : %"G_GINT64_FORMAT"\n", duration);
  47. // data->targetPTSTimecode = duration;
  48. // }
  49. } else if (GST_PAD_PROBE_INFO_TYPE(info) & GST_PAD_PROBE_TYPE_BUFFER) {
  50. CustomData* data = (CustomData*) user_data;
  51. g_print("Buffer %d ", buffer_count);
  52. GstBuffer* buffer = GST_PAD_PROBE_INFO_BUFFER (info);
  53. if (GST_BUFFER_FLAG_IS_SET(buffer, GST_BUFFER_FLAG_LIVE)) g_print(" LIVE");
  54. if (GST_BUFFER_FLAG_IS_SET(buffer, GST_BUFFER_FLAG_DECODE_ONLY)) g_print(" GST_BUFFER_FLAG_DECODE_ONLY");
  55. if (GST_BUFFER_FLAG_IS_SET(buffer, GST_BUFFER_FLAG_DISCONT)) g_print(" GST_BUFFER_FLAG_DISCONT");
  56. if (GST_BUFFER_FLAG_IS_SET(buffer, GST_BUFFER_FLAG_RESYNC)) g_print(" GST_BUFFER_FLAG_RESYNC");
  57. if (GST_BUFFER_FLAG_IS_SET(buffer, GST_BUFFER_FLAG_CORRUPTED)) g_print(" GST_BUFFER_FLAG_CORRUPTED");
  58. if (GST_BUFFER_FLAG_IS_SET(buffer, GST_BUFFER_FLAG_MARKER)) g_print(" GST_BUFFER_FLAG_MARKER");
  59. if (GST_BUFFER_FLAG_IS_SET(buffer, GST_BUFFER_FLAG_HEADER)) g_print(" GST_BUFFER_FLAG_HEADER");
  60. if (GST_BUFFER_FLAG_IS_SET(buffer, GST_BUFFER_FLAG_GAP)) g_print(" GST_BUFFER_FLAG_GAP");
  61. if (GST_BUFFER_FLAG_IS_SET(buffer, GST_BUFFER_FLAG_DROPPABLE)) g_print(" GST_BUFFER_FLAG_DROPPABLE");
  62. if (GST_BUFFER_FLAG_IS_SET(buffer, GST_BUFFER_FLAG_DELTA_UNIT)) g_print(" GST_BUFFER_FLAG_DELTA_UNIT");
  63.  
  64. g_print(" Duration %"G_GINT64_FORMAT"\n",GST_BUFFER_DURATION(buffer));
  65. gint64 pts = GST_BUFFER_PTS(buffer);
  66. g_print("PTS : %"G_GINT64_FORMAT" Target : %"G_GINT64_FORMAT" \n", pts, data->lastSeek);
  67. return GST_PAD_PROBE_PASS;
  68. }
  69.  
  70. return GST_PAD_PROBE_PASS;
  71. }
  72.  
  73. void demux_pad_added (GstElement* object, GstPad* arg0, gpointer user_data) {
  74. CustomData *data = (CustomData*)user_data;
  75.  
  76. GstPad* h264parseSinkPad = gst_element_get_static_pad(data->h264parse, "sink");
  77. if (gst_pad_can_link(arg0, h264parseSinkPad)) {
  78. gst_pad_link(arg0, h264parseSinkPad);
  79. gst_pad_add_probe (arg0, GST_PAD_PROBE_TYPE_DATA_BOTH | GST_PAD_PROBE_TYPE_EVENT_BOTH | GST_PAD_PROBE_TYPE_BLOCKING, demux_src_probe, data, NULL);
  80. } else {
  81. //TODO : Add fakesink
  82. }
  83. gst_object_unref(h264parseSinkPad);
  84. }
  85.  
  86. static gboolean goto_first(gpointer user_data);
  87. static gboolean goto_end(gpointer user_data) {
  88. g_print("Go to end\n");
  89. CustomData* data = (CustomData*) user_data;
  90. data->lastSeek = data->targetPTSTimecode;
  91. gst_element_seek(data->pipeline,1.0,GST_FORMAT_TIME, GST_SEEK_FLAG_FLUSH | GST_SEEK_FLAG_SNAP_BEFORE , GST_SEEK_TYPE_END, data->targetPTSTimecode, GST_SEEK_TYPE_NONE, 0);
  92.  
  93. // GstEvent* event = gst_event_new_step(GST_FORMAT_TIME, data->targetPTSTimecode / 2, 1.0, TRUE, FALSE);
  94. // gst_element_send_event(data->sink, event);
  95. //gst_query_unref(query);
  96.  
  97. g_timeout_add_seconds(5, goto_first,data);
  98. return FALSE;
  99. }
  100.  
  101. static gboolean goto_middle(gpointer user_data) {
  102. g_print("Go to midle\n");
  103. CustomData* data = (CustomData*) user_data;
  104. data->lastSeek = data->targetPTSTimecode / 2;
  105. gst_element_seek_simple(data->pipeline,GST_FORMAT_TIME, GST_SEEK_FLAG_FLUSH, data->targetPTSTimecode / 2);
  106. g_timeout_add_seconds(5, goto_end,data);
  107. return FALSE;
  108.  
  109. }
  110.  
  111. static gboolean goto_first(gpointer user_data) {
  112. g_print("Go to first\n");
  113. CustomData* data = (CustomData*) user_data;
  114. data->lastSeek = data->targetPTSTimecode / 4;
  115. gst_element_seek_simple(data->pipeline,GST_FORMAT_TIME, GST_SEEK_FLAG_FLUSH, 0);
  116. g_timeout_add_seconds(5, goto_middle,data);
  117. return FALSE;
  118. }
  119.  
  120. static gboolean my_bus_callback (GstBus *bus, GstMessage *message, gpointer data)
  121. {
  122. CustomData* source = (CustomData*)data;
  123. switch (GST_MESSAGE_TYPE (message)) {
  124. case GST_MESSAGE_ERROR: {
  125. GError *err;
  126. gchar *debug;
  127.  
  128. gst_message_parse_error (message, &err, &debug);
  129. g_print ("Error: %s\n", err->message);
  130. g_error_free (err);
  131. g_free (debug);
  132.  
  133. GST_DEBUG_BIN_TO_DOT_FILE(GST_BIN(source->pipeline), GST_DEBUG_GRAPH_SHOW_ALL,"test");
  134.  
  135. g_main_loop_quit (source->loop);
  136. break;
  137. }
  138. case GST_MESSAGE_INFO:
  139. g_print("Receive info");
  140. break;
  141. case GST_MESSAGE_EOS:
  142. /* end-of-stream */
  143. g_print("Receive EOS on the bus\n");
  144. g_main_loop_quit (source->loop);
  145. break;
  146. case GST_MESSAGE_SEGMENT_DONE:
  147. g_print("Receive segment done\n");
  148. //g_main_loop_quit(source->loop);
  149. break;
  150. case GST_MESSAGE_STATE_CHANGED:
  151. if (message->src == source->pipeline) {
  152. g_print("Receive state changed\n");
  153. GstState old_state, new_state, pending;
  154. gst_message_parse_state_changed(message, &old_state,&new_state, &pending);
  155. if (new_state == GST_STATE_PAUSED) {
  156. g_print("Arrive in paused \n");
  157.  
  158. GstQuery* segmentQuery = gst_query_new_segment(GST_FORMAT_TIME);
  159. gst_element_query(source->pipeline, segmentQuery);
  160. gdouble rate = 0.0;
  161. GstFormat format;
  162. gint64 startvalue, stop_value;
  163. gst_query_parse_segment(segmentQuery, &rate, &format, &startvalue, &stop_value);
  164. g_print("Query : Rate %f Format : %s Start : %"G_GINT64_FORMAT" Stop %"G_GINT64_FORMAT" \n", rate, format == GST_FORMAT_TIME ? "TIME" : "Other", startvalue, stop_value);
  165. gst_query_unref(segmentQuery);
  166. }
  167. }
  168. break;
  169. case GST_MESSAGE_ASYNC_DONE:
  170. g_print("Receive async done\n");
  171. gint64 duration;
  172. if (gst_element_query_duration(source->pipeline, GST_FORMAT_TIME, &duration)) {
  173. source->targetPTSTimecode = duration;
  174. g_print("Duration ASYNC : %"G_GINT64_FORMAT" \n", duration);
  175. }
  176.  
  177. break;
  178. case GST_MESSAGE_DURATION_CHANGED:
  179. g_print("Receive duration change\n");
  180.  
  181. break;
  182. default:
  183. //g_print("%d\n",GST_MESSAGE_TYPE (message));
  184. /* unhandled message */
  185. break;
  186. }
  187.  
  188. return TRUE;
  189. }
  190.  
  191. void new_sample(GstElement* object, gpointer user_data) {
  192. g_print("########## New sample\n");
  193. }
  194.  
  195. void new_preroll(GstElement* object, gpointer user_data) {
  196. g_print("########## New preroll\n");
  197. GstSample* sample = gst_app_sink_pull_preroll(GST_APP_SINK(object));
  198. if (sample != NULL) {
  199. g_print("Sample not NULL.\n");
  200. GstBuffer *buffer = gst_sample_get_buffer(sample);
  201. if (buffer) {
  202. g_print("Buffer not NULL !!! \n");
  203. }
  204. }
  205. }
  206.  
  207. void eos(GstElement* object, gpointer user_data) {
  208. g_print("########## EOS\n");
  209. }
  210.  
  211. int main(int argc, char* argv[]) {
  212. gst_init(NULL, NULL);
  213.  
  214. CustomData* data = g_new0(CustomData, 1);
  215. //Initialisation
  216. data->lastSeek= 0;
  217.  
  218. data->pipeline = gst_pipeline_new("snapshot");
  219. data->filesrc = gst_element_factory_make("filesrc", NULL);
  220. data->filedemux = gst_element_factory_make("matroskademux", NULL);
  221. data->h264parse = gst_element_factory_make("h264parse", NULL);
  222. data->h264dec = gst_element_factory_make("avdec_h264", NULL);
  223. data->videoconvert = gst_element_factory_make("videoconvert", NULL);
  224.  
  225. #ifdef USE_VIDEO_SINK
  226. data->enc = gst_element_factory_make("identity", NULL);
  227. data->sink = gst_element_factory_make("xvimagesink", NULL);
  228. g_object_set(data->sink, "sync", FALSE, "async", TRUE, NULL);
  229. #else
  230. data->enc = gst_element_factory_make("pngenc", NULL);
  231. data->sink = gst_element_factory_make("appsink", NULL);
  232. g_object_set(data->sink, "sync", FALSE, "async", FALSE, "emit-signals", TRUE,NULL);
  233. g_object_set(data->enc, "snapshot", FALSE, NULL);
  234. g_signal_connect(data->sink, "new-sample", G_CALLBACK(new_sample),data);
  235. g_signal_connect(data->sink, "new-preroll", G_CALLBACK(new_preroll),data);
  236. g_signal_connect(data->sink, "eos", G_CALLBACK(eos),data);
  237. #endif
  238. //Set initial pipeline settings
  239. g_signal_connect(data->filedemux, "pad-added", G_CALLBACK(demux_pad_added),data);
  240. g_object_set(data->filesrc, "location", "/home/memphis/samples/Monster.mkv", NULL);
  241.  
  242. gst_bin_add_many(GST_BIN(data->pipeline), data->filesrc, data->filedemux, data->h264parse, data->h264dec, data->videoconvert, data->enc, data->sink, NULL);
  243. gst_element_link(data->filesrc, data->filedemux);
  244. gst_element_link_many(data->h264parse, data->h264dec, data->videoconvert, data->enc, data->sink, NULL);
  245.  
  246.  
  247.  
  248. data->bus = gst_element_get_bus (data->pipeline);
  249. gst_bus_add_watch (data->bus, my_bus_callback, data);
  250. gst_element_set_state(data->pipeline, GST_STATE_PAUSED);
  251. data->loop = g_main_loop_new(NULL,FALSE);
  252. g_timeout_add_seconds(5, goto_middle,data);
  253. g_main_loop_run(data->loop);
  254. g_print("Loop exited\n");
  255.  
  256. g_free(data);
  257.  
  258. return 0;
  259. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement