playing mp4 files simultaneously
amirulsyahmi
amirulsyahmi at gmail.com
Mon Sep 26 19:08:29 PDT 2011
Hi All
Anybody can help me to compile this code? I try to compile it using the
command that being given but I failed to compile it. I can't find
I/usr/lib/glib-2.0/include. Here is the code.
/* Sample application to run multiple videos. Files to be played are
hardcorded in the code with the variable "FileName". */
/* Application supports mov/mpegts container formats, video codec : mpeg2 or
h264, audio codec: mp3.*/
/* To compile the application do: */
/* gcc -I/usr/include/gstreamer-0.10 -I/usr/include/glib-2.0
-I/usr/lib/glib-2.0/include -I/usr/include/libxml2 -I/usr/lib/liboil-0.3
-I/usr/include -L/usr/lib/gstreamer-0.10 -lglib-2.0 -lgmodule-2.0
-lgstreamer-0.10 -lxml2 -lgobject-2.0 -lgthread-2.0 -lgstbase-0.10 -lX11
-lgstinterfaces-0.10 -lgstvaapi-x11-0.10 -lgstvaapi-0.10 MultiVideo_post.c
-o MultiVideo */
#include <string.h>
#include <gst/gst.h>
#include <unistd.h>
#include <string.h>
#include <ctype.h>
#include <stdlib.h>
#include <pthread.h>
#include <X11/Xlib.h>
#include <X11/Xutil.h>
#include <gst/interfaces/xoverlay.h>
#define VIDEO_ENABLE 1
#define AUDIO_ENABLE 0 /* If the video has audio then enable this */
#define NOOFFILES 4 /* Max No of files to be played simultaneously.
Range is 1-4 */
#define MPEGTS 0 /* To playback mpegts files */
#define MOV 1 /* To playback mov/mp4 files */
/* Right now files are hardcoded for mov filescan
be changed to ts files */
/* Variable Declaration */
/* Display and window declaration*/
Display *dis;
Window win[NOOFFILES];
/* Elements*/
GstElement *pipeline[NOOFFILES];
GstElement *videobin[NOOFFILES] ;
GstElement *audiobin[NOOFFILES] ;
GstElement *src[NOOFFILES] ;
GstElement *decoder[NOOFFILES];
GstElement *sink[NOOFFILES];
GstElement *demux[NOOFFILES];
GstPad *videofilterpad[NOOFFILES];
GstPad *audiofilterpad[NOOFFILES];
GstElement *audpipeline[NOOFFILES];
GstElement *audiodec[NOOFFILES];
GstElement *audiosink[NOOFFILES];
GstElement *videoqueue[NOOFFILES];
GstElement *audioqueue[NOOFFILES];
GstElement *filter[NOOFFILES];
GstBus *bus[NOOFFILES];
GMainLoop *loop[NOOFFILES];
char FileName[NOOFFILES][256] = {"Nature Video Clips (For Review)_1280.mov",
"City Video Clips _1280.mov","City Video Clips _1280.mov","City Video Clips
_1280.mov"};
volatile int EOSFlag = 0;
int cntNoOfFiles = 0;
/*Variables for setting the window location */
int x[NOOFFILES] = {0, 550, 0, 550};
int y[NOOFFILES] = {0, 0, 550 , 550};
int width[NOOFFILES] = {500, 500, 500, 500};
int height[NOOFFILES] = {500, 500, 500, 500};
/* Function definitions*/
/* Api to create window and to give the window ID to vaapi sink*/
static GstBusSyncReply
create_window(GstBus * bus, GstMessage * message, void *data)
{
/*printf("Message src = %s\n", gst_object_get_name(GST_MESSAGE_SRC
(message)));*/
/* ignore anything but 'prepare-xwindow-id' element messages */
if (GST_MESSAGE_TYPE (message) != GST_MESSAGE_ELEMENT)
return GST_BUS_PASS;
if (!gst_structure_has_name (message->structure, "prepare-xwindow-id"))
return GST_BUS_PASS;
static int filenumber = 0;
/* When EOS is received reset the static var */
if(EOSFlag == 1)
{
filenumber = 0;
EOSFlag = 0;
}
/* This is to disable the window manager decorations i.e border, title bar
etc.*/
XSetWindowAttributes stXSWAttr = {0};
int i32XWindowMask = 0;
/* Background color set to black for the display.*/
stXSWAttr.background_pixel = BlackPixel(dis, 0);
/* Set flag to tell Window manager to not intercept commands to this
* window. */
stXSWAttr.override_redirect = True;
/* Set mask. */
i32XWindowMask = CWBackPixel|CWBorderPixel|CWOverrideRedirect;
win[filenumber] = XCreateWindow(dis,
RootWindow(dis,0),
x[filenumber],
y[filenumber],
width[filenumber],
height[filenumber],
0, DefaultDepth(dis,0),
InputOutput,
CopyFromParent,
i32XWindowMask,
&stXSWAttr);
XMapWindow(dis, win[filenumber]);
XFlush (dis);
XSync (dis, False);
/* Tell the sink to render on the X window ID created above */
gst_x_overlay_set_xwindow_id(GST_X_OVERLAY (GST_MESSAGE_SRC (message)),
win[filenumber]);
filenumber++;
gst_message_unref (message);
return GST_BUS_DROP;
}
/* Bus to receive messages like EOS and any error messages */
static gboolean my_bus_callback ( GstBus *bus,
GstMessage *message,
void *data)
{
static int filenumber = 0;
/*printf("Message src = %s\n", gst_object_get_name(GST_MESSAGE_SRC
(message)));*/
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);
g_main_loop_quit (loop[filenumber]);
break;
}/* End of case GST_MESSAGE_ERROR*/
case GST_MESSAGE_EOS:
{
/* end-of-stream received */
printf("Received EOS\n");
/* Stop the gmain loop */
g_main_loop_quit (loop[filenumber]);
/* Destroy the window */
XDestroyWindow(dis, win[filenumber]);
if(filenumber == 0)
EOSFlag = 1;
gst_element_set_state (pipeline[filenumber], GST_STATE_NULL);
gst_element_set_state (pipeline[filenumber], GST_STATE_PLAYING);
g_thread_create ((GThreadFunc)g_main_loop_run, loop[filenumber],
TRUE, NULL);
filenumber++;
/* Reset the static var*/
if(filenumber == NOOFFILES)
filenumber = 0;
break;
}/* End of case GST_MESSAGE_EOS*/
default:
/* unhandled message */
break;
}/* End of switch*/
return TRUE;
}
/* Api to request demuxer pad and to link it the videobin/audiobin*/
static void
cb_newpad (GstElement *demuxbin,
GstPad *pad,
gpointer data)
{
GstCaps *caps;
GstStructure *str;
GstPad *videopad;
GstPad *audiopad;
gchar *tex;
GstElement *trybin = (GstElement *)data;
/* check media type */
caps = gst_pad_get_caps (pad);
str = gst_caps_get_structure (caps, 0);
tex = (gchar*)gst_structure_get_name(str);
if(g_strrstr(tex,"audio"))
{
audiopad = gst_element_get_static_pad(trybin,"sink");
if(GST_PAD_IS_LINKED(audiopad))
{
g_object_unref(audiopad);
}
else
{
gst_pad_link(pad,audiopad);
g_object_unref (audiopad);
}
return;
}
if(g_strrstr(tex,"video"))
{
videopad = gst_element_get_static_pad(trybin,"sink");
if(GST_PAD_IS_LINKED(videopad))
{
g_object_unref(videopad);
}
else
{
gst_pad_link(pad,videopad);
g_object_unref (videopad);
}
return;
}
}
/*Main of the application */
int main (int argc, char *argv[])
{
/* Variable Declaration */
gboolean ret;
GstStateChangeReturn State = GST_STATE_NULL;
/* initialize GStreamer */
gst_init (NULL, NULL);
dis = XOpenDisplay(NULL);
while(cntNoOfFiles < NOOFFILES)
{
printf("\n\n APPLICATION Started -----------------------> \n");
/* Create all elements for the following pipeline */
/* filesrc ! demux d.! queue ! decoder ! sink d.! queue ! audiodec !
audiosink*/
pipeline[cntNoOfFiles] = gst_pipeline_new ("Pipeline to play h264 video
from filesrc.");
if(NULL == pipeline[cntNoOfFiles])
{
printf("ERROR : pipeline could not be created : aborting application
\n");
return -1;
}
/* Create a Gmain LOOP */
loop[cntNoOfFiles] = g_main_loop_new (NULL, FALSE);
/* Create a Bus */
bus[cntNoOfFiles] = gst_pipeline_get_bus (GST_PIPELINE
(pipeline[cntNoOfFiles]));
/* Attach a call-back to the BUS */
gst_bus_add_watch (bus[cntNoOfFiles], my_bus_callback, NULL);
/* Set sync handler to create foriegn X window */
gst_bus_set_sync_handler (bus[cntNoOfFiles], (GstBusSyncHandler)
create_window, NULL);
gst_object_unref (bus[cntNoOfFiles]);
src[cntNoOfFiles] = gst_element_factory_make ("filesrc", "file source");
if(NULL == src[cntNoOfFiles])
{
printf("ERROR : Filesrc could not be created : aborting application
\n");
return -1;
}
#if MPEGTS
demux = gst_element_factory_make ("ffdemux_mpegts", "demux");
#endif
#if MOV
demux[cntNoOfFiles] = gst_element_factory_make
("ffdemux_mov_mp4_m4a_3gp_3g2_mj2", "demux");
#endif
if(NULL == demux[cntNoOfFiles])
{
printf("ERROR : Demuxer could not be created : aborting application
\n");
return -1;
}
decoder[cntNoOfFiles] = gst_element_factory_make ("vaapidecode",
"decoder");
if(NULL == decoder[cntNoOfFiles])
{
printf("ERROR : Decoder could not be created : aborting application
\n");
return -1;
}
sink[cntNoOfFiles] = gst_element_factory_make ("vaapisink", "sink");
if(NULL == sink[cntNoOfFiles])
{
printf("ERROR : Vaapi sink could not be created : aborting application
\n");
return -1;
}
audiodec[cntNoOfFiles] = gst_element_factory_make ("ffdec_mp3",
"audiodec");
if(NULL == audiodec[cntNoOfFiles])
{
printf("ERROR :Audio Decoder could not be created : aborting
application \n");
return -1;
}
audiosink[cntNoOfFiles] = gst_element_factory_make ("alsasink",
"alsasink");
if(NULL == audiosink[cntNoOfFiles])
{
printf("ERROR : Audio sink could not be created : aborting application
\n");
return -1;
}
audioqueue[cntNoOfFiles] = gst_element_factory_make ("queue",
"audioqueue");
if(NULL == audioqueue[cntNoOfFiles])
{
printf("ERROR : Audio Queue could not be created : aborting
application \n");
return -1;
}
videoqueue[cntNoOfFiles] = gst_element_factory_make ("queue",
"videoqueue");
if(NULL == videoqueue[cntNoOfFiles])
{
printf("ERROR : Video Queue could not be created : aborting
application \n");
return -1;
}
g_object_set (G_OBJECT (src[cntNoOfFiles]), "location", (unsigned
char*)FileName[cntNoOfFiles], NULL);
gst_bin_add_many (GST_BIN (pipeline[cntNoOfFiles]), src[cntNoOfFiles],
demux[cntNoOfFiles],NULL);
gst_element_link_many (src[cntNoOfFiles], demux[cntNoOfFiles], NULL);
#if VIDEO_ENABLE
/* create video bin */
videobin[cntNoOfFiles] = gst_bin_new ("videobin");
gst_bin_add_many (GST_BIN (videobin[cntNoOfFiles]),
videoqueue[cntNoOfFiles],
decoder[cntNoOfFiles],
sink[cntNoOfFiles], NULL);
gst_bin_add(GST_BIN(pipeline[cntNoOfFiles]), videobin[cntNoOfFiles]);
videofilterpad[cntNoOfFiles] = gst_element_get_static_pad
(videoqueue[cntNoOfFiles], "sink");
gst_element_add_pad (videobin[cntNoOfFiles], gst_ghost_pad_new ("sink",
videofilterpad[cntNoOfFiles]));
g_signal_connect (demux[cntNoOfFiles], "pad-added", G_CALLBACK
(cb_newpad), videobin[cntNoOfFiles]);
ret = gst_element_link_many (videoqueue[cntNoOfFiles],
decoder[cntNoOfFiles],
sink[cntNoOfFiles], NULL);
if(0 == ret)
{
printf("Failed to link queue decoder and sink.\n");
return -1;
}
gst_object_unref(videofilterpad[cntNoOfFiles]);
#endif
#if AUDIO_ENABLE
/* create audio bin */
audiobin[cntNoOfFiles] = gst_bin_new ("audiobin");
gst_bin_add_many (GST_BIN (audiobin[cntNoOfFiles]),
audioqueue[cntNoOfFiles],audiodec[cntNoOfFiles],audiosink[cntNoOfFiles],
NULL);
gst_bin_add(GST_BIN(pipeline[cntNoOfFiles]), audiobin[cntNoOfFiles]);
audiofilterpad[cntNoOfFiles] = gst_element_get_static_pad
(audioqueue[cntNoOfFiles], "sink");
gst_element_add_pad (audiobin[cntNoOfFiles], gst_ghost_pad_new ("sink",
audiofilterpad[cntNoOfFiles]));
g_signal_connect (demux[cntNoOfFiles], "pad-added", G_CALLBACK
(cb_newpad), audiobin[cntNoOfFiles]);
ret = gst_element_link_many
(audioqueue[cntNoOfFiles],audiodec[cntNoOfFiles], audiosink[cntNoOfFiles],
NULL);
if(0 == ret)
{
printf("Failed to link queue decoder and sink.\n");
return -1;
}
gst_object_unref(audiofilterpad[cntNoOfFiles]);
#endif
/* Change the pipeline state to READY */
State = gst_element_set_state (pipeline[cntNoOfFiles], GST_STATE_READY);
if(GST_STATE_CHANGE_FAILURE == State)
{
printf("State = %d.\n", State);
return 0;
}
/* Change the pipeline state to PLAYING */
printf("\npipeline 1 : PLAYING .................................
\n");
State = gst_element_set_state (pipeline[cntNoOfFiles],
GST_STATE_PLAYING);
if(GST_STATE_CHANGE_FAILURE == State)
{
printf("State = %d.\n", State);
return 0;
}
/*Start the gmain loop by creating a gthread*/
g_thread_create ((GThreadFunc)g_main_loop_run, loop[cntNoOfFiles],
FALSE, NULL);
sleep(1);
cntNoOfFiles++;
}
while(1);
return 0;
}
/* End of application */
--
View this message in context: http://gstreamer-devel.966125.n4.nabble.com/playing-mp4-files-simultaneously-tp3845957p3845957.html
Sent from the GStreamer-devel mailing list archive at Nabble.com.
More information about the gstreamer-devel
mailing list