I want to play two different local video files at the same time in a single window. The code below without demux and decoder works fine.
static void play_video(){
GMainLoop *loop;
GstElement *pipeline,*videomixer;
GstElement *src,*sink,*filter,*csp,*videobox;
GstElement *src1,*filter1,*csp1,*videobox1;
GstElement *srcb,*filterb,*cspb,*videoboxb;
GstCaps *filtercaps,*filtercaps1,*filtercapsb;
GstPad *pad,*pad1;
const char pattern = "snow";
loop = g_main_loop_new(NULL, FALSE);
pipeline = gst_pipeline_new("my-pipeline");
src = gst_element_factory_make ("videotestsrc","src");
src1 = gst_element_factory_make ("videotestsrc","src1");
g_object_set (G_OBJECT (src), "pattern", 10, NULL);
filter = gst_element_factory_make("capsfilter","filter");
filter1 = gst_element_factory_make("capsfilter","filter1");
csp = gst_element_factory_make("ffmpegcolorspace","csp");
csp1 = gst_element_factory_make("ffmpegcolorspace","csp1");
/**/
videobox=gst_element_factory_make("videobox","videobox");
g_object_set(videobox,"top",0,"bottom",0,"left",0,"right",0,NULL);
videobox1=gst_element_factory_make("videobox","videobox1");
g_object_set(videobox1,"top",-20,"bottom",0,"left",0,"right",0,NULL);
videomixer=gst_element_factory_make("videomixer","videomixer");
/**/
sink = gst_element_factory_make("xvimagesink","sink");
if(sink == NULL)
sink = gst_element_factory_make("ximagesink","sink");
if(sink == NULL)
g_error("'ximagesink' yaratılamadı.");
gst_bin_add_many(GST_BIN(pipeline),src,filter,videobox,videomixer,csp,sink,
src1,filter1,videobox1,csp1,NULL);
gst_element_link_many(src,filter,csp,videobox,videomixer,NULL);
gst_element_link_many(src1,filter1,csp1,videobox1,videomixer,NULL);
/*
videotestsrc pattern="snow" ! video/x-raw-yuv, framerate=1/1, width=350,
height=250 ! \
textoverlay font-desc="Sans 24" text="CAM2" valign=top halign=left
shaded-background=true ! \
videobox border-alpha=0 top=-200 left=-450 ! mix. \
*/
gst_element_link_many(videomixer,sink,NULL);
filtercaps = gst_caps_new_simple ("video/x-raw-rgb",
"width", G_TYPE_INT, 1024,
"height", G_TYPE_INT, 768,
"framerate", GST_TYPE_FRACTION, 25, 1,
"bpp", G_TYPE_INT, 16,
"depth", G_TYPE_INT, 16,
"endianness", G_TYPE_INT, G_BYTE_ORDER,
NULL);
filtercaps1 = gst_caps_new_simple ("video/x-raw-rgb",
"width", G_TYPE_INT, 200,
"height", G_TYPE_INT, 500,
"framerate", GST_TYPE_FRACTION, 25, 1,
"bpp", G_TYPE_INT, 16,
"depth", G_TYPE_INT, 16,
"endianness", G_TYPE_INT, G_BYTE_ORDER,
NULL);
g_object_set (G_OBJECT (filter), "caps", filtercaps, NULL);
gst_caps_unref (filtercaps);
g_object_set (G_OBJECT (filter1), "caps", filtercaps1, NULL);
gst_caps_unref (filtercaps1);
/*pad = gst_element_get_pad (src, "src");
pad1 = gst_element_get_pad (src1, "src1");
//gst_pad_add_buffer_probe (pad, G_CALLBACK (cb_have_data), NULL);
//gst_pad_add_buffer_probe (pad1, G_CALLBACK (cb_have_data), NULL);
//gst_object_unref (pad);
//gst_object_unref (pad1);*/
/* run */
gst_element_set_state (pipeline, GST_STATE_PLAYING);
/* wait until it's up and running or failed */
if (gst_element_get_state (pipeline, NULL, NULL, -1) ==
GST_STATE_CHANGE_FAILURE) {
g_error ("Failed to go into PLAYING state");
}
g_print ("Running ...\n");
g_main_loop_run (loop);
/* exit */
gst_element_set_state (pipeline, GST_STATE_NULL);
gst_object_unref (pipeline);
}
Problem is when I replace the videotestsrc with filesrc it fails and the only error message I get is "Could not lookup object NULL on signal destroy of object window". I'm not an gstreamer expert and my opinion is I am failing at setting demux and decoder.
static void play_video5(){
GMainLoop *loop;
GstElement *pipeline,*videomixer;
GstElement *src,*sink,*filter,*csp,*videobox;
GstElement *src1,*filter1,*csp1,*videobox1;
GstElement *srcb,*filterb,*cspb,*videoboxb;
GstCaps *filtercaps,*filtercaps1,*filtercapsb;
GstPad *pad,*pad1;
GstElement *demux,*decoder;
const char pattern = "snow";
loop = g_main_loop_new(NULL, FALSE);
pipeline = gst_pipeline_new("my-pipeline");
//Source
src = gst_element_factory_make ("videotestsrc","src");
src1 = gst_element_factory_make ("filesrc","src1");
g_object_set (G_OBJECT (src1), "location", "file:///root/yu.mp4", NULL);
//Demux
demux = gst_element_factory_make ("mpegdemux", "demux");
//Decoder
decoder = gst_element_factory_make ("decodebin", "decoder");
// decoder = gst_element_factory_make ("ffdec_mpeg4","mpeg4-decoder");
//Filter
filter = gst_element_factory_make("capsfilter","filter");
filter1 = gst_element_factory_make("capsfilter","filter1");
//Colorspace
csp = gst_element_factory_make("ffmpegcolorspace","csp");
csp1 = gst_element_factory_make("ffmpegcolorspace","csp1");
//Videobox
videobox=gst_element_factory_make("videobox","videobox");
g_object_set(videobox,"top",0,"bottom",0,"left",0,"right",0,NULL);
videobox1=gst_element_factory_make("videobox","videobox1");
g_object_set(videobox1,"top",-20,"bottom",0,"left",0,"right",0,NULL);
//videomixer
videomixer=gst_element_factory_make("videomixer","videomixer");
//Sink
sink = gst_element_factory_make("xvimagesink","sink");
if(sink == NULL)
sink = gst_element_factory_make("ximagesink","sink");
if(sink == NULL)
g_error("'ximagesink' yaratılamadı.");
//Add to Bin
gst_bin_add_many(GST_BIN(pipeline),src,filter,videobox,videomixer,csp,
src1,decoder,filter1,videobox1,csp1,sink,NULL);
//Link Elements
gst_element_link(src,filter);
gst_element_link(filter,csp);
gst_element_link(csp,videobox);
gst_element_link(videobox, videomixer);
gst_element_link(src1,decoder);
gst_element_link(decoder,filter1);
// gst_element_link(decoder,csp1);
gst_element_link(filter1,csp1);
gst_element_link(csp1,videobox1);
gst_element_link(videobox1, videomixer);
gst_element_link(videomixer,sink);
//Cap definition
filtercaps = gst_caps_new_simple ("video/x-raw-rgb",
"width", G_TYPE_INT, 1024,
"height", G_TYPE_INT, 768,
"framerate", GST_TYPE_FRACTION, 25, 1,
"bpp", G_TYPE_INT, 16,
"depth", G_TYPE_INT, 16,
"endianness", G_TYPE_INT, G_BYTE_ORDER,
NULL);
filtercaps1 = gst_caps_new_simple ("video/x-raw-yuv",
"width", G_TYPE_INT, 640,
"height", G_TYPE_INT, 480,
"framerate", GST_TYPE_FRACTION, 25, 1,
/*"bpp", G_TYPE_INT, 16,
"depth", G_TYPE_INT, 16,
"endianness", G_TYPE_INT, G_BYTE_ORDER,*/
NULL);
//Cap to Filter
g_object_set (G_OBJECT (filter), "caps", filtercaps, NU开发者_运维问答LL);
gst_caps_unref (filtercaps);
g_object_set (G_OBJECT (filter1), "caps", filtercaps1, NULL);
gst_caps_unref (filtercaps1);
/* run */
gst_element_set_state (pipeline, GST_STATE_PLAYING);
/* wait until it's up and running or failed */
if (gst_element_get_state (pipeline, NULL, NULL, -1) ==
GST_STATE_CHANGE_FAILURE) {
g_error ("Failed to go into PLAYING state");
}
g_print ("Running ...\n");
g_main_loop_run (loop);
/* exit */
gst_element_set_state (pipeline, GST_STATE_NULL);
gst_object_unref (pipeline);
}
Any ideas or corrections are welcome.
Several issues:
- filesrc does not take uris, but file-paths
- /* wait until it's up and running or failed */ + the code below is not needed, better listen on the bus for the error and warning messages
- "Could not lookup object NULL on signal destroy of object window" has nothing to do with gstreamer
- the whole videobox business is not needed as the pads of videomixer have xpos, ypos and zorder properties
精彩评论