Skip to content

Instantly share code, notes, and snippets.

@mohan43u
Last active August 29, 2015 14:05
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save mohan43u/214fd99d0a2596e03b9e to your computer and use it in GitHub Desktop.
Save mohan43u/214fd99d0a2596e03b9e to your computer and use it in GitHub Desktop.
#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