Last active
August 29, 2015 14:05
-
-
Save mohan43u/214fd99d0a2596e03b9e to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <stdio.h> | |
#include <stdlib.h> | |
#include <glib-unix.h> | |
#include <gst/gst.h> | |
typedef struct { | |
GstElement *audioin; | |
GstElement *audiodecode; | |
GstElement *audiobin; | |
GstElement *audiosource; | |
GstElement *audiocomp; | |
GstElement *audioout; | |
GstElement *videoin; | |
GstElement *videodecode; | |
GstElement *videobin; | |
GstElement *videosource; | |
GstElement *videocomp; | |
GstElement *videoout; | |
} TestGnonlinElements; | |
typedef struct { | |
TestGnonlinElements *elements; | |
GstElement *pipeline; | |
GMainLoop *mainloop; | |
GstBus *msgbus; | |
} TestGnonlin; | |
void testgnonlin_audiodecode_pad_added_cb(GstElement *element, GstPad *pad, gpointer data) { | |
TestGnonlin *this = (TestGnonlin *) data; | |
if(gst_caps_is_always_compatible(gst_pad_query_caps(pad, NULL), | |
gst_pad_query_caps(gst_element_get_static_pad(this->elements->audioout, | |
"sink"), | |
NULL))) { | |
GstPad *gpad = gst_ghost_pad_new(NULL, pad); | |
gst_pad_set_active(gpad, TRUE); | |
gst_element_add_pad(this->elements->audiobin, gpad); | |
} | |
} | |
void testgnonlin_videodecode_pad_added_cb(GstElement *element, GstPad *pad, gpointer data) { | |
TestGnonlin *this = (TestGnonlin *) data; | |
if(gst_caps_is_always_compatible(gst_pad_query_caps(pad, NULL), | |
gst_pad_query_caps(gst_element_get_static_pad(this->elements->videoout, | |
"sink"), | |
NULL))) { | |
GstPad *gpad = gst_ghost_pad_new(NULL, pad); | |
gst_pad_set_active(gpad, TRUE); | |
gst_element_add_pad(this->elements->videobin, gpad); | |
} | |
} | |
void testgnonlin_audiocomp_no_more_pads_cb(GstElement *element, gpointer data) { | |
TestGnonlin *this = (TestGnonlin *) data; | |
if(!gst_element_link(this->elements->audiocomp, this->elements->audioout)) { | |
g_printerr("audiocomp->audioout not linked\n"); | |
} | |
} | |
void testgnonlin_videocomp_no_more_pads_cb(GstElement *element, gpointer data) { | |
TestGnonlin *this = (TestGnonlin *) data; | |
if(!gst_element_link(this->elements->videocomp, this->elements->videoout)) { | |
g_printerr("videocomp->videoout not linked\n"); | |
} | |
} | |
void testgnonlin_elements_init(TestGnonlin *this, char *longvideo, char *start, char *inpoint, char *duration) { | |
gboolean ret = TRUE; | |
this->elements = g_new(TestGnonlinElements, 1); | |
this->elements->audioin = gst_element_factory_make("filesrc", NULL); | |
this->elements->audiodecode = gst_element_factory_make("decodebin", NULL); | |
this->elements->audiobin = gst_bin_new("audiobin0"); | |
this->elements->audiosource = gst_element_factory_make("gnlsource", NULL); | |
this->elements->audiocomp = gst_element_factory_make("gnlcomposition", NULL); | |
this->elements->audioout = gst_element_factory_make("autoaudiosink", NULL); | |
this->elements->videoin = gst_element_factory_make("filesrc", NULL); | |
this->elements->videodecode = gst_element_factory_make("decodebin", NULL); | |
this->elements->videobin = gst_bin_new("videobin0"); | |
this->elements->videosource = gst_element_factory_make("gnlsource", NULL); | |
this->elements->videocomp = gst_element_factory_make("gnlcomposition", NULL); | |
this->elements->videoout = gst_element_factory_make("autovideosink", NULL); | |
gst_bin_add_many(GST_BIN(this->pipeline), | |
this->elements->audiocomp, | |
this->elements->audioout, | |
this->elements->videocomp, | |
this->elements->videoout, | |
NULL); | |
gst_bin_add_many(GST_BIN(this->elements->audiocomp), | |
this->elements->audiosource, | |
NULL); | |
gst_bin_add_many(GST_BIN(this->elements->audiosource), | |
this->elements->audiobin, | |
NULL); | |
gst_bin_add_many(GST_BIN(this->elements->audiobin), | |
this->elements->audioin, | |
this->elements->audiodecode, | |
NULL); | |
gst_bin_add_many(GST_BIN(this->elements->videocomp), | |
this->elements->videosource, | |
NULL); | |
gst_bin_add_many(GST_BIN(this->elements->videosource), | |
this->elements->videobin, | |
NULL); | |
gst_bin_add_many(GST_BIN(this->elements->videobin), | |
this->elements->videoin, | |
this->elements->videodecode, | |
NULL); | |
gst_element_link(this->elements->audioin, this->elements->audiodecode); | |
gst_element_link(this->elements->videoin, this->elements->videodecode); | |
g_signal_connect(this->elements->audiodecode, | |
"pad-added", | |
G_CALLBACK(testgnonlin_audiodecode_pad_added_cb), | |
this); | |
g_signal_connect(this->elements->videodecode, | |
"pad-added", | |
G_CALLBACK(testgnonlin_videodecode_pad_added_cb), | |
this); | |
g_signal_connect(this->elements->audiocomp, | |
"no-more-pads", | |
G_CALLBACK(testgnonlin_audiocomp_no_more_pads_cb), | |
this); | |
g_signal_connect(this->elements->videocomp, | |
"no-more-pads", | |
G_CALLBACK(testgnonlin_videocomp_no_more_pads_cb), | |
this); | |
g_object_set(this->elements->audioin, "location", longvideo, NULL); | |
g_object_set(this->elements->audiosource, "start", (glong) (g_strtod(start, NULL) * GST_SECOND), NULL); | |
g_object_set(this->elements->audiosource, "inpoint", (glong) (g_strtod(inpoint, NULL) * GST_SECOND), NULL); | |
g_object_set(this->elements->audiosource, "duration", (glong) (g_strtod(duration, NULL) * GST_SECOND), NULL); | |
g_signal_emit_by_name(this->elements->audiocomp, "commit", TRUE, &ret); | |
g_object_set(this->elements->videoin, "location", longvideo, NULL); | |
g_object_set(this->elements->videosource, "start", (glong) (g_strtod(start, NULL) * GST_SECOND), NULL); | |
g_object_set(this->elements->videosource, "inpoint", (glong) (g_strtod(inpoint, NULL) * GST_SECOND), NULL); | |
g_object_set(this->elements->videosource, "duration", (glong) (g_strtod(duration, NULL) * GST_SECOND), NULL); | |
g_signal_emit_by_name(this->elements->videocomp, "commit", TRUE, &ret); | |
} | |
void testgnonlin_stop(TestGnonlin *this) { | |
gst_element_set_state(this->pipeline, GST_STATE_NULL); | |
g_main_loop_quit(this->mainloop); | |
} | |
gboolean testgnonlin_msgbus_cb(GstBus *bus, GstMessage *message, gpointer *data) { | |
TestGnonlin *this = (TestGnonlin *) data; | |
switch(GST_MESSAGE_TYPE(message)) { | |
case(GST_MESSAGE_EOS): testgnonlin_stop(this); | |
break; | |
case(GST_MESSAGE_STATE_CHANGED): { | |
GstState old; | |
GstState new; | |
gst_message_parse_state_changed(message, &old, &new, NULL); | |
g_printerr("%d: state changed from %s to %s on %s\n", | |
GST_MESSAGE_SEQNUM(message), | |
gst_element_state_get_name(old), | |
gst_element_state_get_name(new), | |
GST_MESSAGE_SRC_NAME(message)); | |
} | |
break; | |
default: g_printerr("%d: received %s from %s..\n", | |
GST_MESSAGE_SEQNUM(message), | |
GST_MESSAGE_TYPE_NAME(message), | |
GST_MESSAGE_SRC_NAME(message)); | |
} | |
return TRUE; | |
} | |
void testgnonlin_init(TestGnonlin *this, char *longvideo, char *start, char *inpoint, char *duration) { | |
if(! gst_is_initialized()) gst_init(NULL, NULL); | |
this->mainloop = g_main_loop_new(NULL, FALSE); | |
this->pipeline = gst_pipeline_new("pipeline0"); | |
testgnonlin_elements_init(this, longvideo, start, inpoint, duration); | |
this->msgbus = gst_element_get_bus(GST_ELEMENT(this->pipeline)); | |
gst_bus_add_watch_full(this->msgbus, | |
G_PRIORITY_DEFAULT, | |
(GstBusFunc) testgnonlin_msgbus_cb, | |
this, | |
NULL); | |
} | |
void testgnonlin_run(TestGnonlin *this) { | |
gst_element_set_state(this->pipeline, GST_STATE_PLAYING); | |
g_main_loop_run(this->mainloop); | |
} | |
int main(int argc, char *argv[]) { | |
if(argc < 5) { | |
g_printerr("[usage] %s longvideo start inpoint duration\n", argv[0]); | |
exit(EXIT_FAILURE); | |
} | |
TestGnonlin testgnonlin; | |
testgnonlin_init(&testgnonlin, argv[1], argv[2], argv[3], argv[4]); | |
testgnonlin_run(&testgnonlin); | |
return 0; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment