Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- /*
- * main.c
- *
- * Created on: Jan 22, 2014
- * Author: memphis
- */
- #include "glib.h"
- #include "gst/gst.h"
- #include <gst/app/gstappsink.h>
- #define USE_VIDEO_SINK
- #define VIDEO_FILE_PATH "/home/memphis/test.mkv"
- typedef struct _CustomData CustomData;
- struct _CustomData {
- GMainLoop* loop;
- GstBus* bus;
- GstElement* pipeline;
- GstElement* filesrc;
- GstElement* filedemux;
- GstElement* h264parse;
- GstElement* h264dec;
- GstElement* videoconvert;
- GstElement* enc;
- GstElement* sink;
- gint64 targetPTSTimecode;
- gint64 frame_duration;
- gint64 lastSeek;
- };
- static gint buffer_count = 0;
- void print_segment(GstSegment* segment) {
- g_print("Segment : Base : %"G_GUINT64_FORMAT" \n", segment->base);
- g_print(" Offset : %"G_GUINT64_FORMAT" \n", segment->offset);
- g_print(" Start : %"G_GUINT64_FORMAT" \n", segment->start);
- g_print(" Stop : %"G_GUINT64_FORMAT" \n", segment->stop);
- g_print(" Time : %"G_GUINT64_FORMAT" \n", segment->time);
- g_print(" Position: %"G_GUINT64_FORMAT" \n", segment->position);
- g_print(" Duration: %"G_GUINT64_FORMAT" \n", segment->duration);
- }
- GstPadProbeReturn
- demux_src_probe(GstPad * pad, GstPadProbeInfo * info, gpointer user_data) {
- if (GST_PAD_PROBE_INFO_TYPE(info) & GST_PAD_PROBE_TYPE_EVENT_BOTH) {
- if ((GST_EVENT_TYPE (GST_PAD_PROBE_INFO_DATA (info)) == GST_EVENT_EOS)) {
- g_print("Receive EOS on the probe. Dropping...\n");
- return GST_PAD_PROBE_DROP;
- }
- // if ((GST_EVENT_TYPE (GST_PAD_PROBE_INFO_DATA (info)) == GST_EVENT_SEGMENT)) {
- // //g_print("########## REceive segment \n");
- // CustomData* data = (CustomData*) user_data;
- // gint64 duration = 0;
- // gst_element_query_duration(data->filedemux, GST_FORMAT_TIME, &duration);
- // g_print("Duration : %"G_GINT64_FORMAT"\n", duration);
- // data->targetPTSTimecode = duration;
- // }
- } else if (GST_PAD_PROBE_INFO_TYPE(info) & GST_PAD_PROBE_TYPE_BUFFER) {
- CustomData* data = (CustomData*) user_data;
- g_print("DemuxSrcPad Buffer");
- GstBuffer* buffer = GST_PAD_PROBE_INFO_BUFFER (info);
- if (GST_BUFFER_FLAG_IS_SET(buffer, GST_BUFFER_FLAG_LIVE)) g_print(" LIVE");
- if (GST_BUFFER_FLAG_IS_SET(buffer, GST_BUFFER_FLAG_DECODE_ONLY)) g_print(" GST_BUFFER_FLAG_DECODE_ONLY");
- if (GST_BUFFER_FLAG_IS_SET(buffer, GST_BUFFER_FLAG_DISCONT)) g_print(" GST_BUFFER_FLAG_DISCONT");
- if (GST_BUFFER_FLAG_IS_SET(buffer, GST_BUFFER_FLAG_RESYNC)) g_print(" GST_BUFFER_FLAG_RESYNC");
- if (GST_BUFFER_FLAG_IS_SET(buffer, GST_BUFFER_FLAG_CORRUPTED)) g_print(" GST_BUFFER_FLAG_CORRUPTED");
- if (GST_BUFFER_FLAG_IS_SET(buffer, GST_BUFFER_FLAG_MARKER)) g_print(" GST_BUFFER_FLAG_MARKER");
- if (GST_BUFFER_FLAG_IS_SET(buffer, GST_BUFFER_FLAG_HEADER)) g_print(" GST_BUFFER_FLAG_HEADER");
- if (GST_BUFFER_FLAG_IS_SET(buffer, GST_BUFFER_FLAG_GAP)) g_print(" GST_BUFFER_FLAG_GAP");
- if (GST_BUFFER_FLAG_IS_SET(buffer, GST_BUFFER_FLAG_DROPPABLE)) g_print(" GST_BUFFER_FLAG_DROPPABLE");
- if (GST_BUFFER_FLAG_IS_SET(buffer, GST_BUFFER_FLAG_DELTA_UNIT)) g_print(" GST_BUFFER_FLAG_DELTA_UNIT");
- gint64 pts = GST_BUFFER_PTS(buffer);
- g_print(" PTS : %"G_GINT64_FORMAT" Target : %"G_GINT64_FORMAT" \n", pts, data->lastSeek);
- }
- return GST_PAD_PROBE_PASS;
- }
- GstPadProbeReturn
- sink_src_probe(GstPad * pad, GstPadProbeInfo * info, gpointer user_data) {
- if (GST_PAD_PROBE_INFO_TYPE(info) & GST_PAD_PROBE_TYPE_EVENT_BOTH) {
- if ((GST_EVENT_TYPE (GST_PAD_PROBE_INFO_DATA (info)) == GST_EVENT_EOS)) {
- g_print("Receive EOS on the probe. Dropping...\n");
- return GST_PAD_PROBE_DROP;
- }
- if ((GST_EVENT_TYPE (GST_PAD_PROBE_INFO_DATA (info)) == GST_EVENT_SEGMENT)) {
- g_print("########## Receive segment \n");
- GstSegment* segment;
- gst_event_parse_segment(GST_EVENT(info->data), &segment);
- print_segment(segment);
- }
- } else if (GST_PAD_PROBE_INFO_TYPE(info) & GST_PAD_PROBE_TYPE_BUFFER) {
- CustomData* data = (CustomData*) user_data;
- g_print("DecodeSrcPad : Buffer %d", buffer_count);
- GstBuffer* buffer = GST_PAD_PROBE_INFO_BUFFER (info);
- if (GST_BUFFER_FLAG_IS_SET(buffer, GST_BUFFER_FLAG_LIVE)) g_print(" LIVE");
- if (GST_BUFFER_FLAG_IS_SET(buffer, GST_BUFFER_FLAG_DECODE_ONLY)) g_print(" GST_BUFFER_FLAG_DECODE_ONLY");
- if (GST_BUFFER_FLAG_IS_SET(buffer, GST_BUFFER_FLAG_DISCONT)) g_print(" GST_BUFFER_FLAG_DISCONT");
- if (GST_BUFFER_FLAG_IS_SET(buffer, GST_BUFFER_FLAG_RESYNC)) g_print(" GST_BUFFER_FLAG_RESYNC");
- if (GST_BUFFER_FLAG_IS_SET(buffer, GST_BUFFER_FLAG_CORRUPTED)) g_print(" GST_BUFFER_FLAG_CORRUPTED");
- if (GST_BUFFER_FLAG_IS_SET(buffer, GST_BUFFER_FLAG_MARKER)) g_print(" GST_BUFFER_FLAG_MARKER");
- if (GST_BUFFER_FLAG_IS_SET(buffer, GST_BUFFER_FLAG_HEADER)) g_print(" GST_BUFFER_FLAG_HEADER");
- if (GST_BUFFER_FLAG_IS_SET(buffer, GST_BUFFER_FLAG_GAP)) g_print(" GST_BUFFER_FLAG_GAP");
- if (GST_BUFFER_FLAG_IS_SET(buffer, GST_BUFFER_FLAG_DROPPABLE)) g_print(" GST_BUFFER_FLAG_DROPPABLE");
- if (GST_BUFFER_FLAG_IS_SET(buffer, GST_BUFFER_FLAG_DELTA_UNIT)) g_print(" GST_BUFFER_FLAG_DELTA_UNIT");
- g_print(" Duration %"G_GINT64_FORMAT,GST_BUFFER_DURATION(buffer));
- gint64 pts = GST_BUFFER_PTS(buffer);
- data->frame_duration = GST_BUFFER_DURATION(buffer);
- g_print(" PTS : %"G_GINT64_FORMAT" Target : %"G_GINT64_FORMAT" \n", pts, data->lastSeek);
- }
- return GST_PAD_PROBE_PASS;
- }
- void demux_pad_added (GstElement* object, GstPad* arg0, gpointer user_data) {
- CustomData *data = (CustomData*)user_data;
- GstPad* h264parseSinkPad = gst_element_get_static_pad(data->h264parse, "sink");
- if (gst_pad_can_link(arg0, h264parseSinkPad)) {
- gst_pad_link(arg0, h264parseSinkPad);
- 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);
- } else {
- //TODO : Add fakesink
- }
- gst_object_unref(h264parseSinkPad);
- }
- static gboolean goto_first(gpointer user_data);
- static gboolean goto_end(gpointer user_data) {
- g_print("Go to end\n");
- CustomData* data = (CustomData*) user_data;
- data->lastSeek = 99967000000;
- gst_element_seek_simple(data->sink,GST_FORMAT_TIME, GST_SEEK_FLAG_FLUSH, data->lastSeek);
- //g_timeout_add_seconds(5, goto_first,data);
- return FALSE;
- }
- static gboolean goto_middle(gpointer user_data) {
- g_print("Go to midle\n");
- CustomData* data = (CustomData*) user_data;
- data->lastSeek = data->targetPTSTimecode / 2;
- gst_element_seek_simple(data->pipeline,GST_FORMAT_TIME, GST_SEEK_FLAG_FLUSH, data->targetPTSTimecode / 2);
- g_timeout_add_seconds(5, goto_end,data);
- return FALSE;
- }
- static gboolean goto_first(gpointer user_data) {
- g_print("Go to first\n");
- CustomData* data = (CustomData*) user_data;
- data->lastSeek = 0;
- gst_element_seek_simple(data->pipeline,GST_FORMAT_TIME, GST_SEEK_FLAG_FLUSH, data->lastSeek);
- g_timeout_add_seconds(5, goto_middle,data);
- return FALSE;
- }
- static gboolean my_bus_callback (GstBus *bus, GstMessage *message, gpointer data)
- {
- CustomData* source = (CustomData*)data;
- switch (GST_MESSAGE_TYPE (message)) {
- case GST_MESSAGE_ERROR: {
- GError *err;
- gchar *debug;
- gst_message_parse_error (message, &err, &debug);
- g_print ("Error: %s\n", err->message);
- g_error_free (err);
- g_free (debug);
- GST_DEBUG_BIN_TO_DOT_FILE(GST_BIN(source->pipeline), GST_DEBUG_GRAPH_SHOW_ALL,"test-snapshot-mkv-on-error");
- g_main_loop_quit (source->loop);
- break;
- }
- case GST_MESSAGE_EOS:
- /* end-of-stream */
- g_print("Receive EOS on the bus\n");
- g_main_loop_quit (source->loop);
- break;
- case GST_MESSAGE_SEGMENT_DONE:
- g_print("Receive segment done\n");
- break;
- case GST_MESSAGE_ASYNC_DONE:
- g_print("Receive async done\n");
- gint64 duration;
- if (gst_element_query_duration(source->pipeline, GST_FORMAT_TIME, &duration)) {
- source->targetPTSTimecode = duration;
- g_print("Duration : %"G_GINT64_FORMAT" \n", duration);
- } else {
- g_print("Failed to query the duration\n");
- }
- break;
- case GST_MESSAGE_DURATION_CHANGED:
- g_print("Receive duration change\n");
- gint64 durationChange;
- if (gst_element_query_duration(source->pipeline, GST_FORMAT_TIME, &durationChange)) {
- //source->targetPTSTimecode = duration;
- g_print("Duration : %"G_GINT64_FORMAT" \n", durationChange);
- } else {
- g_print("Failed to query the duration\n");
- }
- break;
- default:
- //g_print("%d\n",GST_MESSAGE_TYPE (message));
- /* unhandled message */
- break;
- }
- return TRUE;
- }
- void new_preroll(GstElement* object, gpointer user_data) {
- g_print("########## New preroll\n");
- GstSample* sample = gst_app_sink_pull_preroll(GST_APP_SINK(object));
- if (sample != NULL) {
- g_print("Sample not NULL.\n");
- GstBuffer *buffer = gst_sample_get_buffer(sample);
- if (buffer) {
- g_print("Buffer not NULL !!! \n");
- }
- }
- }
- void eos(GstElement* object, gpointer user_data) {
- g_print("########## EOS\n");
- }
- int main(int argc, char* argv[]) {
- gst_init(NULL, NULL);
- CustomData* data = g_new0(CustomData, 1);
- //Initialisation
- data->lastSeek= 0;
- data->frame_duration = 0;
- data->pipeline = gst_pipeline_new("snapshot");
- data->filesrc = gst_element_factory_make("filesrc", NULL);
- data->filedemux = gst_element_factory_make("matroskademux", NULL);
- data->h264parse = gst_element_factory_make("h264parse", NULL);
- data->h264dec = gst_element_factory_make("avdec_h264", NULL);
- data->videoconvert = gst_element_factory_make("videoconvert", NULL);
- #ifdef USE_VIDEO_SINK
- data->enc = gst_element_factory_make("identity", NULL);
- data->sink = gst_element_factory_make("xvimagesink", NULL);
- g_object_set(data->sink, "sync", FALSE, "async", TRUE, "qos", FALSE, NULL);
- #else
- data->enc = gst_element_factory_make("pngenc", NULL);
- data->sink = gst_element_factory_make("appsink", NULL);
- g_object_set(data->sink, "sync", FALSE, "async", FALSE, "emit-signals", TRUE,NULL);
- g_object_set(data->enc, "snapshot", FALSE, NULL);
- g_signal_connect(data->sink, "new-preroll", G_CALLBACK(new_preroll),data);
- g_signal_connect(data->sink, "eos", G_CALLBACK(eos),data);
- #endif
- //Set initial pipeline settings
- g_signal_connect(data->filedemux, "pad-added", G_CALLBACK(demux_pad_added),data);
- g_object_set(data->filesrc, "location",VIDEO_FILE_PATH , NULL);
- gst_bin_add_many(GST_BIN(data->pipeline), data->filesrc, data->filedemux, data->h264parse, data->h264dec, data->videoconvert, data->enc, data->sink, NULL);
- gst_element_link(data->filesrc, data->filedemux);
- gst_element_link_many(data->h264parse, data->h264dec, data->videoconvert, data->enc, data->sink, NULL);
- GstPad* sinPad = gst_element_get_static_pad(data->h264dec, "src");
- 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);
- gst_object_unref(sinPad);
- data->bus = gst_element_get_bus (data->pipeline);
- gst_bus_add_watch (data->bus, my_bus_callback, data);
- gst_element_set_state(data->pipeline, GST_STATE_PAUSED);
- data->loop = g_main_loop_new(NULL,FALSE);
- g_timeout_add_seconds(5, goto_end,data);
- g_main_loop_run(data->loop);
- g_print("Loop exited\n");
- g_free(data);
- return 0;
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement