rendered paste body#include <gst/gst.h>
#include <pthread.h>
#include <time.h>
/*
* Global objects are usually a bad thing. For the purpose of this
* example, we will use them, however.
*/
GstElement *pipeline, *source, *bin, *parser, *ff1, *text1, *text2, *text3, *text4, *text5, *ff2, *sink, *mixer, *ff3;
pthread_t thread1, thread2;
typedef struct _TextOverlays TextOverlays;
typedef struct _ImageBinElements ImageBinElements;
struct _TextOverlays{
GstElement* texts[5];
};
struct _ImageBinElements{
GstElement *bin;
GstElement *filesrc;
GstElement *pngdec;
GstElement *videoscale;
GstElement *videobox;
GstElement *alpha;
GstElement *ff1;
GstElement *ff2;
GstElement *ff3;
GstCaps *pngcaps;
GstCaps *scalecaps;
};
static void initImageBin(ImageBinElements *ibe){
ibe->bin = gst_bin_new("image_pipe");
ibe->filesrc = gst_element_factory_make("filesrc","img-src");
ibe->pngdec = gst_element_factory_make("pngdec","img-dec");
ibe->videoscale = gst_element_factory_make("videoscale","img-scale");
ibe->videobox = gst_element_factory_make("videobox","img-box");
ibe->alpha = gst_element_factory_make("alpha","img-alpha");
ibe->ff1 = gst_element_factory_make("ffmpegcolorspace","img-ff1");
ibe->ff2 = gst_element_factory_make("ffmpegcolorspace","img-ff2");
ibe->ff3 = gst_element_factory_make("ffmpegcolorspace","img-ff3");
gst_bin_add_many(GST_BIN(ibe->bin), ibe->filesrc, ibe->pngdec, ibe->ff1, ibe->videoscale, ibe->ff2,
ibe->videobox, ibe->alpha, ibe->ff3, NULL);
ibe->pngcaps = gst_caps_from_string("image/png");
ibe->scalecaps = gst_caps_from_string("video/x-raw-yuv,width=72,height=54");
}
static void linkImageBin(ImageBinElements *ibe){
gst_element_link_many(ibe->pngdec, ibe->ff1, ibe->videoscale, NULL);
gst_element_link_many(ibe->ff2, ibe->videobox, ibe->alpha, ibe->ff3, NULL);
gst_element_link_filtered(ibe->filesrc, ibe->pngdec, ibe->pngcaps);
gst_element_link_filtered(ibe->videoscale, ibe->ff2, ibe->scalecaps);
if(!gst_pad_is_linked(gst_element_get_pad(ibe->filesrc, "src")))
g_print("Error filesrc not linked!\n");
}
TextOverlays *txt;
ImageBinElements *ibm;
static void init_struct1(){
txt = (TextOverlays*) malloc(sizeof(TextOverlays));
txt->texts[0] = text1;
txt->texts[1] = text2;
txt->texts[2] = text3;
txt->texts[3] = text4;
txt->texts[4] = text5;
}
static gboolean
bus_call (GstBus *bus,
GstMessage *msg,
gpointer data)
{
GMainLoop *loop = (GMainLoop *) data;
switch (GST_MESSAGE_TYPE (msg)) {
case GST_MESSAGE_EOS:
g_print ("End-of-stream\n");
g_main_loop_quit (loop);
break;
case GST_MESSAGE_ERROR: {
gchar *debug;
GError *err;
gst_message_parse_error (msg, &err, &debug);
g_free (debug);
g_print ("Error: %s\n", err->message);
g_error_free (err);
g_main_loop_quit (loop);
break;
}
default:
break;
}
return TRUE;
}
static void
new_pad (GstElement *element,
GstPad *pad,
gpointer data)
{
GstPad *sinkpad;
/* We can now link this pad with the audio decoder */
g_print ("Dynamic pad created, linking parser/decoder\n");
sinkpad = gst_element_get_pad (ff1, "sink");
g_print("Linking pads\n");
gst_pad_link (pad, sinkpad);
g_print("Pads were linked\n");
if(!gst_pad_is_linked(pad)){
g_print("ERROR pad was not linked!!!\n");
}else{
g_print("Dynamic pads are linked\n");
}
gst_object_unref (sinkpad);
}
void *change(void* ptr0){
time_t start_time = time(NULL);
time_t now;
char a = 0;
char field [20];
char command [20];
char value [20];
while(TRUE){
sleep(3);
now = time(NULL);
int len = scanf("%s %s %s",&field, &command, &value);
printf("read input: %s\nread command: %s\nread value: %s\n", field, command, value);
int param = 0;
gboolean render = FALSE;
if(strcmp(field, "text1") == 0){
param = 0;
render = TRUE;
}else if(strcmp(field, "text2") == 0){
param = 1;
render = TRUE;
}else if(strcmp(field, "text3") == 0){
param = 2;
render = TRUE;
}else if(strcmp(field, "text4") == 0){
param = 3;
render = TRUE;
}else if(strcmp(field, "text5") == 0){
param = 4;
render = TRUE;
}
if(render){
if(strcmp(command, "text") == 0){
if(strcmp(value, "NULL") == 0)
g_object_set(G_OBJECT((GstElement*)(((TextOverlays*)ptr0)->texts[param])), "text", "", NULL);
else
g_object_set(G_OBJECT((GstElement*)(((TextOverlays*)ptr0)->texts[param])), "text", value, NULL);
}
if(strcmp(command, "hloc") == 0){
if(!strcmp(value, "left")){
g_object_set(G_OBJECT((GstElement*)(((TextOverlays*)ptr0)->texts[param])), "halignment", 0, NULL);
}else if(!strcmp(value, "center")){
g_object_set(G_OBJECT((GstElement*)(((TextOverlays*)ptr0)->texts[param])), "halignment", 1, NULL);
}else if(!strcmp(value, "right")){
g_object_set(G_OBJECT((GstElement*)(((TextOverlays*)ptr0)->texts[param])), "halignment", 2, NULL);
}
}
if(strcmp(command, "vloc") == 0){
if(!strcmp(value, "middle")){
g_object_set(G_OBJECT((GstElement*)(((TextOverlays*)ptr0)->texts[param])), "valignment", 0, NULL);
}else if(!strcmp(value, "bottom")){
g_object_set(G_OBJECT((GstElement*)(((TextOverlays*)ptr0)->texts[param])), "valignment", 1, NULL);
}else if(!strcmp(value, "top")){
g_object_set(G_OBJECT((GstElement*)(((TextOverlays*)ptr0)->texts[param])), "valignment", 2, NULL);
}
}
if(strcmp(command, "dx") == 0){
int val = atoi(value);
g_object_set(G_OBJECT((GstElement*)(((TextOverlays*)ptr0)->texts[param])), "deltax", val, NULL);
}
if(strcmp(command, "dy") == 0){
int val = atoi(value);
g_object_set(G_OBJECT((GstElement*)(((TextOverlays*)ptr0)->texts[param])), "deltay", val, NULL);
}
}
if(strcmp(field, "ready") == 0){
gst_element_set_state(pipeline ,GST_STATE_READY);
}
if(strcmp(field, "play") == 0){
gst_element_set_state(pipeline ,GST_STATE_PLAYING);
}
}
}
void *change2(void* ptr0){
time_t start_time = time(NULL);
time_t now;
double b = 0.9999;
while(TRUE){
sleep(1);
now = time(NULL);
//if(now%3 <=1 ){
printf("New alpha value: %f\n", b);
// gst_element_set_state (bin, GST_STATE_READY);
//g_object_set(G_OBJECT (ptr), "left", b, "top", b, NULL);
g_print("Setting new alpha value\n");
// g_object_set(G_OBJECT (ptr), "alpha", b, "method", 3, NULL);
// gst_element_set_state (bin, GST_STATE_PLAYING);
b=b-0.01;
if(b < 0.5)
b = 0.9999;
if(start_time - now >= 240)
break;
//}
}
}
int
main (int argc,
char *argv[])
{
GMainLoop *loop;
GstBus *bus;
gst_init (&argc, &argv);
loop = g_main_loop_new (NULL, FALSE);
/* create elements */
pipeline = gst_pipeline_new ("video-streamer");
bin = gst_bin_new ("image-loader");
source = gst_element_factory_make ("videotestsrc", "testsrc");
parser = gst_element_factory_make ("decodebin", "decoder");
ff1 = gst_element_factory_make ("ffmpegcolorspace", "ff1");
text1 = gst_element_factory_make ("textoverlay", "text1");
text2 = gst_element_factory_make ("textoverlay", "text2");
text3 = gst_element_factory_make ("textoverlay", "text3");
text4 = gst_element_factory_make ("textoverlay", "text4");
text5 = gst_element_factory_make ("textoverlay", "text5");
ff2 = gst_element_factory_make ("ffmpegcolorspace", "ff2");
mixer = gst_element_factory_make("videomixer","mixer");
ff3 = gst_element_factory_make("ffmpegcolorspace","ff6");
sink = gst_element_factory_make("autovideosink","autovsink");
ibm = (ImageBinElements*) malloc(sizeof(ImageBinElements));
initImageBin(ibm);
GstCaps *pngcaps = gst_caps_from_string("image/png");
GstCaps *filter = gst_caps_from_string("video/x-raw-yuv,width=72,height=54");
if (!pipeline || !source || !parser || !ff1 || !text1 || !text2 || !text3 || !text4 || !text5 || !ff2 || !sink || !mixer || !ff3 || !ibm || !ibm->bin || !ibm->filesrc || !ibm->pngdec || !ibm->ff1 || !ibm->videoscale || !ibm->ff2 || !ibm->videobox || !ibm->alpha || !ibm->ff3) {
g_print ("One element could not be created\n");
return -1;
}
/* set filename property on the file source. Also add a message
* handler. */
g_object_set (G_OBJECT (text1), "text", "bla1", NULL);
g_object_set (G_OBJECT (text1), "halignment", 0, NULL);
g_object_set (G_OBJECT (text1), "valignment", 2, NULL);
g_object_set (G_OBJECT (text2), "text", "bla2", NULL);
g_object_set (G_OBJECT (text2), "halignment", 1, NULL);
g_object_set (G_OBJECT (text2), "valignment", 2, NULL);
g_object_set (G_OBJECT (ibm->filesrc), "location" ,"./NetBSD1.png", NULL);
g_object_set (G_OBJECT (ibm->videobox), "left", -60, "top", -60, "border-alpha", 0.0, "alpha", 1.0, NULL);
g_object_set (G_OBJECT (ibm->alpha), "alpha", 0.9999, NULL);
g_object_set (G_OBJECT (mixer), "background", 2, NULL);
bus = gst_pipeline_get_bus (GST_PIPELINE (pipeline));
gst_bus_add_watch (bus, bus_call, loop);
gst_object_unref (bus);
/* put all elements in a bin */
// gst_bin_add_many (GST_BIN (bin),
//filesrc, pngdec, ff3, scale, ff4, box, alpha, ff7, NULL);
gst_bin_add_many (GST_BIN (pipeline),
source, parser, ff1, text1, text2, text3, text4, text5, ff2, sink, mixer, ff3, ibm->bin, NULL);
/* link together - note that we cannot link the parser and
* decoder yet, becuse the parser uses dynamic pads. For that,
* we set a pad-added signal handler. */
gst_element_link (source, parser);
gst_element_link_many (ff1, text1, text2, text3, text4, text5, ff2, NULL);
gst_element_link_many (mixer, ff3, sink, NULL);
linkImageBin(ibm);
GstPad *imagesrcpad = gst_element_get_pad(ibm->ff3,"src");
GstPad *livesrcpad = gst_element_get_pad(ff2,"src");
GstPad *livesinkpad = gst_element_get_request_pad(mixer, "sink_2");
GstPad *imagesinkpad = gst_element_get_request_pad(mixer, "sink_1");
GstPadLinkReturn a = 0;
a = gst_pad_link(imagesrcpad, imagesinkpad);
g_print("Image link returned: %d\n", a);
a = gst_pad_link(livesrcpad, livesinkpad);
g_print("Live link returned: %d\n", a);
g_signal_connect (parser, "pad-added", G_CALLBACK (new_pad), NULL);
/* Now set to playing and iterate. */
g_print ("Running\n");
init_struct1();
pthread_create(&thread1, NULL, change, txt);
//pthread_create(&thread2, NULL, change2, alpha);
g_print ("Setting to PLAYING\n");
gst_element_set_state (pipeline, GST_STATE_PLAYING);
printf("Looping from now\n");
g_main_loop_run (loop);
/* clean up nicely */
g_print ("Returned, stopping playback\n");
gst_element_set_state (pipeline, GST_STATE_NULL);
g_print ("Deleting pipeline\n");
gst_object_unref (GST_OBJECT (pipeline));
return 0;
}