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
- 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 lastSeek;
- };
- static gint buffer_count = 0;
- 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\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("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"\n",GST_BUFFER_DURATION(buffer));
- 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;
- }
- 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 = data->targetPTSTimecode;
- 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);
- // GstEvent* event = gst_event_new_step(GST_FORMAT_TIME, data->targetPTSTimecode / 2, 1.0, TRUE, FALSE);
- // gst_element_send_event(data->sink, event);
- //gst_query_unref(query);
- 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 = data->targetPTSTimecode / 4;
- gst_element_seek_simple(data->pipeline,GST_FORMAT_TIME, GST_SEEK_FLAG_FLUSH, 0);
- 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");
- g_main_loop_quit (source->loop);
- break;
- }
- case GST_MESSAGE_INFO:
- g_print("Receive info");
- 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");
- //g_main_loop_quit(source->loop);
- break;
- case GST_MESSAGE_STATE_CHANGED:
- if (message->src == source->pipeline) {
- g_print("Receive state changed\n");
- GstState old_state, new_state, pending;
- gst_message_parse_state_changed(message, &old_state,&new_state, &pending);
- if (new_state == GST_STATE_PAUSED) {
- g_print("Arrive in paused \n");
- GstQuery* segmentQuery = gst_query_new_segment(GST_FORMAT_TIME);
- gst_element_query(source->pipeline, segmentQuery);
- gdouble rate = 0.0;
- GstFormat format;
- gint64 startvalue, stop_value;
- gst_query_parse_segment(segmentQuery, &rate, &format, &startvalue, &stop_value);
- 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);
- gst_query_unref(segmentQuery);
- }
- }
- 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 ASYNC : %"G_GINT64_FORMAT" \n", duration);
- }
- break;
- case GST_MESSAGE_DURATION_CHANGED:
- g_print("Receive duration change\n");
- break;
- default:
- //g_print("%d\n",GST_MESSAGE_TYPE (message));
- /* unhandled message */
- break;
- }
- return TRUE;
- }
- void new_sample(GstElement* object, gpointer user_data) {
- g_print("########## New sample\n");
- }
- 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->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, 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-sample", G_CALLBACK(new_sample),data);
- 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", "/home/memphis/samples/Monster.mkv", 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);
- 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_middle,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