SHARE
TWEET

Untitled

a guest Jan 27th, 2014 117 Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  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. #define VIDEO_FILE_PATH "/home/memphis/test.mkv"
  14.  
  15. typedef struct _CustomData CustomData;
  16. struct _CustomData {
  17.         GMainLoop* loop;
  18.         GstBus* bus;
  19.         GstElement* pipeline;
  20.         GstElement* filesrc;
  21.         GstElement* filedemux;
  22.         GstElement* h264parse;
  23.         GstElement* h264dec;
  24.         GstElement* videoconvert;
  25.         GstElement* enc;
  26.         GstElement* sink;
  27.  
  28.         gint64 targetPTSTimecode;
  29.         gint64 frame_duration;
  30.         gint64 lastSeek;
  31. };
  32.  
  33. static gint buffer_count = 0;
  34.  
  35. void print_segment(GstSegment* segment) {
  36.         g_print("Segment : Base    : %"G_GUINT64_FORMAT" \n", segment->base);
  37.         g_print("          Offset  : %"G_GUINT64_FORMAT" \n", segment->offset);
  38.         g_print("          Start   : %"G_GUINT64_FORMAT" \n", segment->start);
  39.         g_print("          Stop    : %"G_GUINT64_FORMAT" \n", segment->stop);
  40.         g_print("          Time    : %"G_GUINT64_FORMAT" \n", segment->time);
  41.         g_print("          Position: %"G_GUINT64_FORMAT" \n", segment->position);
  42.         g_print("          Duration: %"G_GUINT64_FORMAT" \n", segment->duration);
  43.  
  44. }
  45.  
  46. GstPadProbeReturn
  47. demux_src_probe(GstPad * pad, GstPadProbeInfo * info, gpointer user_data) {
  48.         if (GST_PAD_PROBE_INFO_TYPE(info) & GST_PAD_PROBE_TYPE_EVENT_BOTH) {
  49.                 if ((GST_EVENT_TYPE (GST_PAD_PROBE_INFO_DATA (info)) == GST_EVENT_EOS)) {
  50.                         g_print("Receive EOS on the probe. Dropping...\n");
  51.                         return GST_PAD_PROBE_DROP;
  52.                 }
  53.  
  54. //              if ((GST_EVENT_TYPE (GST_PAD_PROBE_INFO_DATA (info)) == GST_EVENT_SEGMENT)) {
  55. //                      //g_print("########## REceive segment \n");
  56. //                      CustomData* data = (CustomData*) user_data;
  57. //                      gint64 duration = 0;
  58. //                      gst_element_query_duration(data->filedemux, GST_FORMAT_TIME, &duration);
  59. //                      g_print("Duration : %"G_GINT64_FORMAT"\n", duration);
  60. //                      data->targetPTSTimecode = duration;
  61. //              }
  62.         } else if (GST_PAD_PROBE_INFO_TYPE(info) & GST_PAD_PROBE_TYPE_BUFFER) {
  63.                 CustomData* data = (CustomData*) user_data;
  64.                 g_print("DemuxSrcPad Buffer");
  65.                 GstBuffer* buffer = GST_PAD_PROBE_INFO_BUFFER (info);
  66.                 if (GST_BUFFER_FLAG_IS_SET(buffer, GST_BUFFER_FLAG_LIVE)) g_print(" LIVE");
  67.                 if (GST_BUFFER_FLAG_IS_SET(buffer, GST_BUFFER_FLAG_DECODE_ONLY)) g_print(" GST_BUFFER_FLAG_DECODE_ONLY");
  68.                 if (GST_BUFFER_FLAG_IS_SET(buffer, GST_BUFFER_FLAG_DISCONT)) g_print(" GST_BUFFER_FLAG_DISCONT");
  69.                 if (GST_BUFFER_FLAG_IS_SET(buffer, GST_BUFFER_FLAG_RESYNC)) g_print(" GST_BUFFER_FLAG_RESYNC");
  70.                 if (GST_BUFFER_FLAG_IS_SET(buffer, GST_BUFFER_FLAG_CORRUPTED)) g_print(" GST_BUFFER_FLAG_CORRUPTED");
  71.                 if (GST_BUFFER_FLAG_IS_SET(buffer, GST_BUFFER_FLAG_MARKER)) g_print(" GST_BUFFER_FLAG_MARKER");
  72.                 if (GST_BUFFER_FLAG_IS_SET(buffer, GST_BUFFER_FLAG_HEADER)) g_print(" GST_BUFFER_FLAG_HEADER");
  73.                 if (GST_BUFFER_FLAG_IS_SET(buffer, GST_BUFFER_FLAG_GAP)) g_print(" GST_BUFFER_FLAG_GAP");
  74.                 if (GST_BUFFER_FLAG_IS_SET(buffer, GST_BUFFER_FLAG_DROPPABLE)) g_print(" GST_BUFFER_FLAG_DROPPABLE");
  75.                 if (GST_BUFFER_FLAG_IS_SET(buffer, GST_BUFFER_FLAG_DELTA_UNIT)) g_print(" GST_BUFFER_FLAG_DELTA_UNIT");
  76.  
  77.                 gint64 pts = GST_BUFFER_PTS(buffer);
  78.                 g_print(" PTS : %"G_GINT64_FORMAT" Target : %"G_GINT64_FORMAT" \n", pts, data->lastSeek);
  79.         }
  80.  
  81.         return GST_PAD_PROBE_PASS;
  82. }
  83.  
  84. GstPadProbeReturn
  85. sink_src_probe(GstPad * pad, GstPadProbeInfo * info, gpointer user_data) {
  86.         if (GST_PAD_PROBE_INFO_TYPE(info) & GST_PAD_PROBE_TYPE_EVENT_BOTH) {
  87.                 if ((GST_EVENT_TYPE (GST_PAD_PROBE_INFO_DATA (info)) == GST_EVENT_EOS)) {
  88.                         g_print("Receive EOS on the probe. Dropping...\n");
  89.                         return GST_PAD_PROBE_DROP;
  90.                 }
  91.  
  92.                 if ((GST_EVENT_TYPE (GST_PAD_PROBE_INFO_DATA (info)) == GST_EVENT_SEGMENT)) {
  93.                         g_print("########## Receive segment \n");
  94.                         GstSegment* segment;
  95.                         gst_event_parse_segment(GST_EVENT(info->data), &segment);
  96.                         print_segment(segment);
  97.                 }
  98.         } else if (GST_PAD_PROBE_INFO_TYPE(info) & GST_PAD_PROBE_TYPE_BUFFER) {
  99.                 CustomData* data = (CustomData*) user_data;
  100.                 g_print("DecodeSrcPad : Buffer %d", buffer_count);
  101.                 GstBuffer* buffer = GST_PAD_PROBE_INFO_BUFFER (info);
  102.                 if (GST_BUFFER_FLAG_IS_SET(buffer, GST_BUFFER_FLAG_LIVE)) g_print(" LIVE");
  103.                 if (GST_BUFFER_FLAG_IS_SET(buffer, GST_BUFFER_FLAG_DECODE_ONLY)) g_print(" GST_BUFFER_FLAG_DECODE_ONLY");
  104.                 if (GST_BUFFER_FLAG_IS_SET(buffer, GST_BUFFER_FLAG_DISCONT)) g_print(" GST_BUFFER_FLAG_DISCONT");
  105.                 if (GST_BUFFER_FLAG_IS_SET(buffer, GST_BUFFER_FLAG_RESYNC)) g_print(" GST_BUFFER_FLAG_RESYNC");
  106.                 if (GST_BUFFER_FLAG_IS_SET(buffer, GST_BUFFER_FLAG_CORRUPTED)) g_print(" GST_BUFFER_FLAG_CORRUPTED");
  107.                 if (GST_BUFFER_FLAG_IS_SET(buffer, GST_BUFFER_FLAG_MARKER)) g_print(" GST_BUFFER_FLAG_MARKER");
  108.                 if (GST_BUFFER_FLAG_IS_SET(buffer, GST_BUFFER_FLAG_HEADER)) g_print(" GST_BUFFER_FLAG_HEADER");
  109.                 if (GST_BUFFER_FLAG_IS_SET(buffer, GST_BUFFER_FLAG_GAP)) g_print(" GST_BUFFER_FLAG_GAP");
  110.                 if (GST_BUFFER_FLAG_IS_SET(buffer, GST_BUFFER_FLAG_DROPPABLE)) g_print(" GST_BUFFER_FLAG_DROPPABLE");
  111.                 if (GST_BUFFER_FLAG_IS_SET(buffer, GST_BUFFER_FLAG_DELTA_UNIT)) g_print(" GST_BUFFER_FLAG_DELTA_UNIT");
  112.  
  113.                 g_print(" Duration %"G_GINT64_FORMAT,GST_BUFFER_DURATION(buffer));
  114.                 gint64 pts = GST_BUFFER_PTS(buffer);
  115.                 data->frame_duration = GST_BUFFER_DURATION(buffer);
  116.                 g_print(" PTS : %"G_GINT64_FORMAT" Target : %"G_GINT64_FORMAT" \n", pts, data->lastSeek);
  117.         }
  118.  
  119.         return GST_PAD_PROBE_PASS;
  120. }
  121.  
  122. void demux_pad_added (GstElement* object, GstPad* arg0, gpointer user_data) {
  123.         CustomData *data = (CustomData*)user_data;
  124.  
  125.         GstPad* h264parseSinkPad = gst_element_get_static_pad(data->h264parse, "sink");
  126.         if (gst_pad_can_link(arg0, h264parseSinkPad)) {
  127.                 gst_pad_link(arg0, h264parseSinkPad);
  128.                 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);
  129.         } else {
  130.                 //TODO : Add fakesink
  131.         }
  132.         gst_object_unref(h264parseSinkPad);
  133. }
  134.  
  135. static gboolean goto_first(gpointer user_data);
  136. static gboolean goto_end(gpointer user_data) {
  137.         g_print("Go to end\n");
  138.         CustomData* data = (CustomData*) user_data;
  139.         data->lastSeek = 99967000000;
  140.         gst_element_seek_simple(data->sink,GST_FORMAT_TIME, GST_SEEK_FLAG_FLUSH, data->lastSeek);
  141.  
  142.         //g_timeout_add_seconds(5, goto_first,data);
  143.         return FALSE;
  144. }
  145.  
  146. static gboolean goto_middle(gpointer user_data) {
  147.         g_print("Go to midle\n");
  148.         CustomData* data = (CustomData*) user_data;
  149.         data->lastSeek = data->targetPTSTimecode / 2;
  150.         gst_element_seek_simple(data->pipeline,GST_FORMAT_TIME, GST_SEEK_FLAG_FLUSH, data->targetPTSTimecode / 2);
  151.         g_timeout_add_seconds(5, goto_end,data);
  152.         return FALSE;
  153.  
  154. }
  155.  
  156. static gboolean goto_first(gpointer user_data) {
  157.         g_print("Go to first\n");
  158.         CustomData* data = (CustomData*) user_data;
  159.         data->lastSeek = 0;
  160.         gst_element_seek_simple(data->pipeline,GST_FORMAT_TIME, GST_SEEK_FLAG_FLUSH, data->lastSeek);
  161.         g_timeout_add_seconds(5, goto_middle,data);
  162.         return FALSE;
  163. }
  164.  
  165. static gboolean my_bus_callback (GstBus     *bus,        GstMessage *message,    gpointer    data)
  166. {
  167.         CustomData* source = (CustomData*)data;
  168.           switch (GST_MESSAGE_TYPE (message)) {
  169.                 case GST_MESSAGE_ERROR: {
  170.                   GError *err;
  171.                   gchar *debug;
  172.                   gst_message_parse_error (message, &err, &debug);
  173.                   g_print ("Error: %s\n", err->message);
  174.                   g_error_free (err);
  175.                   g_free (debug);
  176.  
  177.                   GST_DEBUG_BIN_TO_DOT_FILE(GST_BIN(source->pipeline), GST_DEBUG_GRAPH_SHOW_ALL,"test-snapshot-mkv-on-error");
  178.  
  179.                   g_main_loop_quit (source->loop);
  180.                   break;
  181.                 }
  182.                 case GST_MESSAGE_EOS:
  183.                   /* end-of-stream */
  184.                   g_print("Receive EOS on the bus\n");
  185.                   g_main_loop_quit (source->loop);
  186.                   break;
  187.                 case GST_MESSAGE_SEGMENT_DONE:
  188.                         g_print("Receive segment done\n");
  189.                         break;
  190.                 case GST_MESSAGE_ASYNC_DONE:
  191.                         g_print("Receive async done\n");
  192.                         gint64 duration;
  193.                         if (gst_element_query_duration(source->pipeline, GST_FORMAT_TIME, &duration)) {
  194.                                 source->targetPTSTimecode = duration;
  195.                                 g_print("Duration : %"G_GINT64_FORMAT" \n", duration);
  196.                         } else {
  197.                                 g_print("Failed to query the duration\n");
  198.                         }
  199.                         break;
  200.                 case GST_MESSAGE_DURATION_CHANGED:
  201.                         g_print("Receive duration change\n");
  202.                         gint64 durationChange;
  203.                         if (gst_element_query_duration(source->pipeline, GST_FORMAT_TIME, &durationChange)) {
  204.                                 //source->targetPTSTimecode = duration;
  205.                                 g_print("Duration : %"G_GINT64_FORMAT" \n", durationChange);
  206.                         } else {
  207.                                 g_print("Failed to query the duration\n");
  208.                         }
  209.                         break;
  210.                 default:
  211.                         //g_print("%d\n",GST_MESSAGE_TYPE (message));
  212.                   /* unhandled message */
  213.                   break;
  214.           }
  215.  
  216.           return TRUE;
  217. }
  218.  
  219. void new_preroll(GstElement* object, gpointer user_data) {
  220.         g_print("########## New preroll\n");
  221.         GstSample* sample = gst_app_sink_pull_preroll(GST_APP_SINK(object));
  222.         if (sample != NULL) {
  223.                 g_print("Sample not NULL.\n");
  224.                 GstBuffer *buffer = gst_sample_get_buffer(sample);
  225.                 if (buffer) {
  226.                         g_print("Buffer not NULL !!! \n");
  227.                 }
  228.         }
  229. }
  230.  
  231. void eos(GstElement* object, gpointer user_data) {
  232.         g_print("########## EOS\n");
  233. }
  234.  
  235. int main(int argc, char* argv[]) {
  236.         gst_init(NULL, NULL);
  237.  
  238.         CustomData* data = g_new0(CustomData, 1);
  239.         //Initialisation
  240.         data->lastSeek= 0;
  241.         data->frame_duration = 0;
  242.  
  243.         data->pipeline = gst_pipeline_new("snapshot");
  244.         data->filesrc = gst_element_factory_make("filesrc", NULL);
  245.         data->filedemux = gst_element_factory_make("matroskademux", NULL);
  246.         data->h264parse = gst_element_factory_make("h264parse", NULL);
  247.         data->h264dec = gst_element_factory_make("avdec_h264", NULL);
  248.         data->videoconvert = gst_element_factory_make("videoconvert", NULL);
  249.  
  250. #ifdef USE_VIDEO_SINK
  251.         data->enc = gst_element_factory_make("identity", NULL);
  252.         data->sink = gst_element_factory_make("xvimagesink", NULL);
  253.         g_object_set(data->sink, "sync", FALSE, "async", TRUE, "qos", FALSE, NULL);
  254. #else
  255.         data->enc = gst_element_factory_make("pngenc", NULL);
  256.         data->sink = gst_element_factory_make("appsink", NULL);
  257.         g_object_set(data->sink, "sync", FALSE, "async", FALSE, "emit-signals", TRUE,NULL);
  258.         g_object_set(data->enc, "snapshot", FALSE, NULL);
  259.         g_signal_connect(data->sink, "new-preroll", G_CALLBACK(new_preroll),data);
  260.         g_signal_connect(data->sink, "eos", G_CALLBACK(eos),data);
  261. #endif
  262.         //Set initial pipeline settings
  263.         g_signal_connect(data->filedemux, "pad-added", G_CALLBACK(demux_pad_added),data);
  264.         g_object_set(data->filesrc, "location",VIDEO_FILE_PATH , NULL);
  265.  
  266.         gst_bin_add_many(GST_BIN(data->pipeline), data->filesrc, data->filedemux, data->h264parse, data->h264dec, data->videoconvert, data->enc, data->sink, NULL);
  267.         gst_element_link(data->filesrc, data->filedemux);
  268.         gst_element_link_many(data->h264parse, data->h264dec, data->videoconvert, data->enc, data->sink, NULL);
  269.  
  270.         GstPad* sinPad = gst_element_get_static_pad(data->h264dec, "src");
  271.         gst_pad_add_probe (sinPad, GST_PAD_PROBE_TYPE_DATA_BOTH | GST_PAD_PROBE_TYPE_EVENT_BOTH | GST_PAD_PROBE_TYPE_BLOCKING, sink_src_probe, data, NULL);
  272.         gst_object_unref(sinPad);
  273.  
  274.  
  275.         data->bus = gst_element_get_bus (data->pipeline);
  276.         gst_bus_add_watch (data->bus, my_bus_callback, data);
  277.         gst_element_set_state(data->pipeline, GST_STATE_PAUSED);
  278.         data->loop = g_main_loop_new(NULL,FALSE);
  279.         g_timeout_add_seconds(5, goto_end,data);
  280.         g_main_loop_run(data->loop);
  281.         g_print("Loop exited\n");
  282.  
  283.         g_free(data);
  284.  
  285.         return 0;
  286. }
RAW Paste Data
We use cookies for various purposes including analytics. By continuing to use Pastebin, you agree to our use of cookies as described in the Cookies Policy. OK, I Understand
Not a member of Pastebin yet?
Sign Up, it unlocks many cool features!
 
Top