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 &lt;gst/gst.h&gt;
#include <unistd.h>
#include <string.h>
#include <ctype.h>
#include <stdlib.h>
#include <pthread.h>
#include &lt;X11/Xlib.h&gt;
#include &lt;X11/Xutil.h&gt;
#include &lt;gst/interfaces/xoverlay.h&gt;


#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