Crash for multiple videos using gstreamer-vaapi

classic Classic list List threaded Threaded
1 message Options
Reply | Threaded
Open this post in threaded view
|

Crash for multiple videos using gstreamer-vaapi

jyotsanasingh
Hi,

I am trying to play multiple videos [mov/mp4/mpeg-ts container, H.264/MPEG2
Video Codec] using a sample gstreamer application, [This application runs as
a single process spawning multiple threads] simultaneously using
GStreamer-vaapi and libVA-1.0.7.
The driver used for hardware acceleration of video is "i965".
Following is the result of "vainfo":
------------------------------------------------------------------
libva: libva version 0.31.1
libva: va_getDriverName() returns 0
libva: Trying to open /opt/X11R7/lib/dri/i965_drv_video.so
libva: va_openDriver() returns 0
vainfo: VA API version: 0.31
vainfo: Driver version: i965 Driver 0.1
vainfo: Supported profile and entrypoints
      VAProfileMPEG2Simple            : VAEntrypointVLD
      VAProfileMPEG2Main              : VAEntrypointVLD
      VAProfileH264Baseline           : VAEntrypointVLD
      VAProfileH264Main               : VAEntrypointVLD
      VAProfileH264High               : VAEntrypointVLD
      VAProfileVC1Simple              : VAEntrypointVLD
      VAProfileVC1Main                : VAEntrypointVLD
      VAProfileVC1Advanced            : VAEntrypointVLD
------------------------------------------------------------------

In the sample application I am creating multiple windows using
"XCreateWindow" and passing the generated window ID to vaapisink.
There following is the problem that I am facing:

The application crashes randomly:
None of the gstreamer calls return a failure and the state is getting
changed to play successfully. Tried the application with different container
formats.
Also from the command line using "gst-launch" I am able to playback multiple
videos simultaneously. [Here one difference compared to the sample
application is, these are running as separate processes]

Following is the backtrace of the gdb :
------------------------------------------------------------------
0xb7fe856c in do_bo_emit_reloc () from /opt/X11R7//lib/libdrm_intel.so.1
#1  0xb7fe882a in drm_intel_gem_bo_emit_reloc () from
/opt/X11R7//lib/libdrm_intel.so.1
#2  0xb7fe36da in drm_intel_bo_emit_reloc () from
/opt/X11R7//lib/libdrm_intel.so.1
#3  0xb130fe3b in intel_batchbuffer_emit_reloc_helper (ctx=,
batch=0xaf2beb30, bo=0x0, read_domains=16, write_domains=0, delta=0) at
intel_batchbuffer.c:198
#4  0xb1317a19 in gen6_emit_wm_state (ctx=0xaf2bc178, kernel=) at
i965_render.c:1808
#5  gen6_render_emit_states (ctx=0xaf2bc178, kernel=) at i965_render.c:1894
#6  0xb1318f85 in gen6_render_put_surface (ctx=0xaf2bc178, surface=67108868,
srcx=0, srcy=0, srcw=1280, srch=720, destx=0, desty=0, destw=940, desth=528,
flag=0) at i965_render.c:1921
#7  intel_render_put_surface (ctx=0xaf2bc178, surface=67108868, srcx=0,
srcy=0, srcw=1280, srch=720, destx=0, desty=0, destw=940, desth=528, flag=0)
at i965_render.c:2020
#8  0xb131b082 in i965_PutSurface (ctx=0xaf2bc178, surface=67108868,
draw=0x3e00007, srcx=0, srcy=0, srcw=1280, srch=720, destx=0, desty=0,
destw=940, desth=528, cliprects=0x0, number_cliprects=0, flags=0) at
i965_drv_video.c:1772
#9  0xb4902796 in vaPutSurface (dpy=0xaf2bc008, surface=67108868,
draw=65011719, srcx=0, srcy=0, srcw=1280, srch=720, destx=0, desty=0,
destw=940, desth=528, cliprects=0x0, number_cliprects=0, flags=0) at
va_x11.c:288
#10 0xb490ad15 in gst_vaapi_window_x11_render (window=0xb0cc05f8,
surface=0xa95bcc70, src_rect=0xa94fe988, dst_rect=0xaf246598, flags=3) at
gstvaapiwindow_x11.c:424
#11 0xac25a820 in gst_vaapi_window_put_surface (window=0xb0cc05f8,
surface=0xa95bcc70, src_rect=0xa94fe988, dst_rect=0xaf246598, flags=3) at
gstvaapiwindow.c:506
#12 0xb492f2f4 in gst_vaapisink_show_frame_x11 (base_sink=0xaf2463d8,
buffer=0xb65dd6a8) at gstvaapisink.c:680
#13 gst_vaapisink_show_frame (base_sink=0xaf2463d8, buffer=0xb65dd6a8) at
gstvaapisink.c:714
#14 0x4d782435 in gst_base_sink_render_object (basesink=0xaf2463d8,
pad=0xaf2ae998, is_list=0, obj=0xb65dd6a8) at gstbasesink.c:2833
#15 0x4d783eb7 in gst_base_sink_queue_object_unlocked (basesink=0xaf2463d8,
pad=0xaf2ae998, is_list=0, obj=0xb65dd6a8, prerollable=1) at
gstbasesink.c:3111
#16 0x4d78a599 in gst_base_sink_chain_unlocked (basesink=0xaf2463d8,
pad=0xaf2ae998, is_list=0, obj=0xb65dd6a8) at gstbasesink.c:3485
#17 0x4d78aa99 in gst_base_sink_chain_main (basesink=, pad=0xaf2ae998,
is_list=0, obj=0xb65dd6a8) at gstbasesink.c:3523
#18 0x4cad55cd in gst_pad_chain_data_unchecked (pad=0xaf2ae998, is_buffer=1,
data=0xb65dd6a8) at gstpad.c:4190
#19 0x4cad5fe7 in gst_pad_push_data (pad=0xace0c580, is_buffer=1,
data=0xb65dd6a8) at gstpad.c:4419
#20 0xb493427a in gst_vaapidecode_step (pad=0xaf20a268, buf=0xa8313770) at
gstvaapidecode.c:162
#21 gst_vaapidecode_chain (pad=0xaf20a268, buf=0xa8313770) at
gstvaapidecode.c:536
#22 0x4cad55cd in gst_pad_chain_data_unchecked (pad=0xaf20a268, is_buffer=1,
data=0xa8313770) at gstpad.c:4190
#23 0x4cad5fe7 in gst_pad_push_data (pad=0xaf2ae8d0, is_buffer=1,
data=0xa8313770) at gstpad.c:4419
#24 0xb662ada6 in gst_queue_push_one (pad=0xaf2ae8d0) at gstqueue.c:1144
#25 gst_queue_loop (pad=0xaf2ae8d0) at gstqueue.c:1260
#26 0x4cb040f1 in gst_task_func (task=0xaf21f5a8) at gsttask.c:271
#27 0x4cb05727 in default_func (tdata=0xaf201a40, pool=0xb6509408) at
gsttaskpool.c:70
#28 0x4b9e4214 in ?? () from /lib/libglib-2.0.so.0
#29 0x4b9e2210 in ?? () from /lib/libglib-2.0.so.0
#30 0x4b91b919 in start_thread () from /lib/libpthread.so.0
#31 0x4b85de5e in clone () from /lib/libc.so.6
------------------------------------------------------------------

I am using the following packages as mentioned on Intel Linux graphics site
"http://intellinuxgraphics.org/2010Q4.html".

Apart from this I have installed the following gstreamer packages:
gstreamer-0.10.31
gst-plugins-base-0.10.29
gst-plugins-good-0.10.22
gst-plugins-bad-0.10.19
gst-plugins-ugly-0.10.15
gst-ffmpeg-0.10.10
gstreamer-vaapi-latest(downloaded from
http://www.splitted-desktop.com/~gbeauchesne/gstreamer-vaapi/).

For reference attaching the sample application(MultiVideos.c).

I am not sure if it is application problem or plugin or driver limitation or
X? As the same application runs with "ximagesink" and software decoder like
ffmpeg.
What could be the problem?

PS:
OS : Fedora Core 13
Kernel : 2.6.37
Platform: Intel i5, Sandy Bridge

Regards,
Jyotsana.



/* 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 not supported in this application.*/

/* 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 */
/**************************************************************************************************************************************************/

/*------------------------------ System Includes -----------------------------*/
#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>


/*------------------------------ Macros -----------------------------*/
#define MAX_VIDEOS     4   /* Maximum number of videos that can be played.*/
#define NOOFWINDOWS    4   /* Max No of windows that can be created 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 */

#define ENABLE_DBGPRINT 0  /* Macro to enable printf*/
/* Macro for printf */
#if (1 == ENABLE_DBGPRINT)
#define PRINT(fmt, args...) \
        printf("\n DEBUG : TEST => %s : %s:\n " fmt "\n", __FILE__, __FUNCTION__ , ## args);
#else
#define PRINT(fmt, args...)
#endif/*!< #if(1 == ENABLE_DBGPRINT) */



/*------------------------------ Global variables -----------------------------*/
/*Instance of the displayplay connection*/
Display *display;

/*Files to be played*/
char FileName[MAX_VIDEOS][256] = {"City Video Clips _1280.mov",
                                  "City Video Clips _1280.mov",
                                  "City Video Clips _1280.mov",
                                  "City Video Clips _1280.mov"};

/*Variables for setting the window location, width and height */
int x[MAX_VIDEOS] = {0, 550, 0, 550};
int y[MAX_VIDEOS] = {0, 0, 550 , 550};
int width[MAX_VIDEOS] = {500, 500, 500, 500};
int height[MAX_VIDEOS] = {500, 500, 500, 500};

/*------------------------------ Structure Declaration -----------------------------*/
/*Holds general info like window ID, width , height etc.*/
typedef struct _tag_APP_GENERALINFO_ST
{
    Window win;
    int x;
    int y;
    int width;
    int height;
    char currentfilename[256];
}APP_GENERALINFO_ST;

/* Stores information specific to gstreamer */
typedef struct _tag_APP_GSTINFO_ST
{
    GstElement *pipeline;
    GstElement *filesrc;
    GstElement *demux;
    GstElement *videodecoder;
    GstElement *videobin;
    GstElement *videosink;
    GstPad *videofilterpad;
    GstElement *videoqueue;
    GstBus *bus;    
    GMainLoop *loop;
}APP_GSTINFO_ST;

/*Stores all the infomation required by the application*/
typedef struct _tag_APP_INFO_ST
{
    APP_GSTINFO_ST stAppGstInfo;
    APP_GENERALINFO_ST stAppGeneralInfo;
}APP_INFO_ST;

/*------------------------------ Function Definitions------------------------*/
/******************************************************************************
* Function               :   InitializeAppInfostruct
* Description            :   Api to initialize APP_INFO_ST structure.
*                            This will also set the width, height, filename etc.
* *****************************************************************************/
void InitializeAppInfostruct(APP_INFO_ST *pstAppInfo, int cntNoofWindows)
{
  memset(pstAppInfo, 0, sizeof(APP_INFO_ST));  

  pstAppInfo->stAppGeneralInfo.x = x[cntNoofWindows];
  pstAppInfo->stAppGeneralInfo.y = y[cntNoofWindows];
  pstAppInfo->stAppGeneralInfo.width = width[cntNoofWindows];
  pstAppInfo->stAppGeneralInfo.height = height[cntNoofWindows];
  strcpy(pstAppInfo->stAppGeneralInfo.currentfilename,
           FileName[cntNoofWindows]);

  return;
}

/******************************************************************************
* Function               :   CreateApp_Window
* Description            :   Api to create window and to give the window ID
*                            to vaapi sink.
*                            Window ID to be created by the application only
*                            when 'prepare-xwindow-id' message comes.
******************************************************************************/
static GstBusSyncReply
CreateApp_Window(GstBus * bus, GstMessage * message, void *pvAppGeneralInfo)
{
  APP_GENERALINFO_ST *pstAppGeneralInfo = pvAppGeneralInfo;

  PRINT("Message src = %s\n", gst_object_get_name(GST_MESSAGE_SRC (message)));
  /* Ignore all other messages except '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;

  /* This is to displayable the window manager decorations i.e border, title bar etc.*/
  XSetWindowAttributes stXSWAttr = {0};
  int i32XWindowMask = 0;

  /* Background color set to black for the displayplay.*/
  stXSWAttr.background_pixel = BlackPixel(display, 0);

  /* Set flag to tell Window manager to not intercept commands to this
   * window. */
  stXSWAttr.override_redirect = True;

  /* Set mask. */
  i32XWindowMask = CWBackPixel|CWBorderPixel|CWOverrideRedirect;

  /* Create X window */
  pstAppGeneralInfo->win = XCreateWindow(display,
                                         RootWindow(display,0),
                                         pstAppGeneralInfo->x,
                                         pstAppGeneralInfo->y,
                                         pstAppGeneralInfo->width,
                                         pstAppGeneralInfo->height,
                                         0,
                                         DefaultDepth(display,0),
                                         InputOutput,
                                         CopyFromParent,
                                         i32XWindowMask,
                                         &stXSWAttr);
   
  /*Map the contents of the window to displayplay */
  XMapWindow(display, pstAppGeneralInfo->win);

  XFlush (display);
  XSync (display, 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)),
                              pstAppGeneralInfo->win);

  gst_message_unref (message);

  return GST_BUS_DROP;
}

/******************************************************************************
* Function               :   bus_callback
* Description            :   Callback api for bus to receives messages
*                            like EOS, error etc.
******************************************************************************/
static gboolean bus_callback (GstBus     *bus,
                              GstMessage *message,
                              void    *pvAppInfo)
{
  APP_INFO_ST *pstAppInfo = pvAppInfo;

  PRINT("Message src = %s", 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 (pstAppInfo->stAppGstInfo.loop);
      break;
    }/* End of case GST_MESSAGE_ERROR*/
       
    case GST_MESSAGE_EOS:
    {
      /* end-of-stream received */
      PRINT("Received EOS");

      /* Stop the gmain loop */
      g_main_loop_quit (pstAppInfo->stAppGstInfo.loop);
           
      /* Destroy the window */
      XDestroyWindow(display, pstAppInfo->stAppGeneralInfo.win);

      /* Set the pipeline to NULL state */      
      gst_element_set_state (pstAppInfo->stAppGstInfo.pipeline,
                                   GST_STATE_NULL);

      /* Set the pipeline to PLAYING state */      
      gst_element_set_state (pstAppInfo->stAppGstInfo.pipeline,
                                   GST_STATE_PLAYING);

      /* Create gthread again and run gmain loop */      
      g_thread_create ((GThreadFunc)g_main_loop_run,
                             pstAppInfo->stAppGstInfo.loop,  
                             TRUE,
                             NULL);

      break;
    }/* End of case GST_MESSAGE_EOS*/

    default:
    break;

  }/* End of switch*/

  return TRUE;
}

/******************************************************************************
* Function               :   cb_newpad
* Description            :   Linking the demuxer pad to video bin pad.
******************************************************************************/
static void
cb_newpad (GstElement *demuxbin,
       GstPad     *pad,
       gpointer    data)
{
  GstCaps *caps;
  GstStructure *str;
  GstPad *videopad;
  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"))
  {
     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;
  }
}

/******************************************************************************
* Function               :   main
* Description            :   main of the application.
* ******************************************************************************/
int main (int argc, char *argv[])
{
  /* Variable Declaration */
  gboolean ret = 0;
  GstStateChangeReturn State = GST_STATE_NULL;    
  int cntNoOfWindows = 0;
  APP_INFO_ST stAppInfo[NOOFWINDOWS];

  /* initialize GStreamer */
  gst_init (NULL, NULL);

  display = XOpenDisplay(NULL);

  while(cntNoOfWindows < NOOFWINDOWS)
  {      
    PRINT("APPLICATION Started -----------------------");
   
    /* Initialize AppInfo struct */
    InitializeAppInfostruct(&stAppInfo[cntNoOfWindows], cntNoOfWindows);

    /* Create all elements for the following pipeline */
    /* filesrc ! demux ! queue ! decoder ! sink*/

    stAppInfo[cntNoOfWindows].stAppGstInfo.pipeline =
    gst_pipeline_new ("Pipeline to play video using vaapi");
    if(NULL == stAppInfo[cntNoOfWindows].stAppGstInfo.pipeline)
    {
      PRINT("ERROR : pipeline could not be created : aborting application");
      return -1;
    }
   
    /* Create a Gmain LOOP */
    stAppInfo[cntNoOfWindows].stAppGstInfo.loop = g_main_loop_new (NULL, FALSE);

    /* Create a Bus */
    stAppInfo[cntNoOfWindows].stAppGstInfo.bus =
    gst_pipeline_get_bus (GST_PIPELINE (stAppInfo[cntNoOfWindows].\
                          stAppGstInfo.pipeline));

    /* Attach a call-back to the BUS */
    gst_bus_add_watch (stAppInfo[cntNoOfWindows].stAppGstInfo.bus,
                       bus_callback,
                       &stAppInfo[cntNoOfWindows]);

    /* Set sync handler to create foriegn X window */
    gst_bus_set_sync_handler (stAppInfo[cntNoOfWindows].\
                              stAppGstInfo.bus,
                             (GstBusSyncHandler) CreateApp_Window,
                              &(stAppInfo[cntNoOfWindows].stAppGeneralInfo));

    gst_object_unref (stAppInfo[cntNoOfWindows].stAppGstInfo.bus);    

    stAppInfo[cntNoOfWindows].stAppGstInfo.filesrc =
    gst_element_factory_make ("filesrc", "file source");
    if(NULL == stAppInfo[cntNoOfWindows].stAppGstInfo.filesrc)
    {
      PRINT("ERROR : Filesrc could not be created : aborting application");
      return -1;
    }

#if MPEGTS
    demux = gst_element_factory_make ("ffdemux_mpegts", "demux");
#endif
#if MOV
    stAppInfo[cntNoOfWindows].stAppGstInfo.demux =
    gst_element_factory_make ("ffdemux_mov_mp4_m4a_3gp_3g2_mj2", "demux");
#endif
    if(NULL == stAppInfo[cntNoOfWindows].stAppGstInfo.demux)
    {
      PRINT("ERROR : Demuxer could not be created : aborting application");
      return -1;
    }

    stAppInfo[cntNoOfWindows].stAppGstInfo.videodecoder =
    gst_element_factory_make ("vaapidecode", "decoder");
    if(NULL == stAppInfo[cntNoOfWindows].stAppGstInfo.videodecoder)
    {
      PRINT("ERROR : Vaapi Decoder could not be created : aborting application");
      return -1;
    }

    stAppInfo[cntNoOfWindows].stAppGstInfo.videosink =
    gst_element_factory_make ("vaapisink", "sink");
    if(NULL == stAppInfo[cntNoOfWindows].stAppGstInfo.videosink)
    {
      PRINT("ERROR : Vaapi sink could not be created : aborting application");
      return -1;
    }    

    stAppInfo[cntNoOfWindows].stAppGstInfo.videoqueue =
    gst_element_factory_make ("queue", "videoqueue");
    if(NULL == stAppInfo[cntNoOfWindows].stAppGstInfo.videoqueue)
    {
      PRINT("ERROR : Video Queue could not be created : aborting application");
      return -1;
    }

    g_object_set (G_OBJECT (stAppInfo[cntNoOfWindows].stAppGstInfo.filesrc),
                  "location",
                  (unsigned char*)stAppInfo[cntNoOfWindows].stAppGeneralInfo.\
                  currentfilename,
                  NULL);

    gst_bin_add_many (GST_BIN (stAppInfo[cntNoOfWindows].stAppGstInfo.pipeline),
                      stAppInfo[cntNoOfWindows].stAppGstInfo.filesrc,
                      stAppInfo[cntNoOfWindows].stAppGstInfo.demux,NULL);

    gst_element_link_many (stAppInfo[cntNoOfWindows].stAppGstInfo.filesrc,
                           stAppInfo[cntNoOfWindows].stAppGstInfo.demux,
                           NULL);

    /* create video bin */
    stAppInfo[cntNoOfWindows].stAppGstInfo.videobin = gst_bin_new ("videobin");

    gst_bin_add_many (GST_BIN (stAppInfo[cntNoOfWindows].stAppGstInfo.videobin),
                      stAppInfo[cntNoOfWindows].stAppGstInfo.videoqueue,
                      stAppInfo[cntNoOfWindows].stAppGstInfo.videodecoder,
                      stAppInfo[cntNoOfWindows].stAppGstInfo.videosink, NULL);

    gst_bin_add(GST_BIN(stAppInfo[cntNoOfWindows].stAppGstInfo.pipeline),
                        stAppInfo[cntNoOfWindows].stAppGstInfo.videobin);

    stAppInfo[cntNoOfWindows].stAppGstInfo.videofilterpad =
    gst_element_get_static_pad (stAppInfo[cntNoOfWindows].stAppGstInfo.videoqueue,
                                "sink");

    gst_element_add_pad (stAppInfo[cntNoOfWindows].stAppGstInfo.videobin,
    gst_ghost_pad_new ("sink",
                       stAppInfo[cntNoOfWindows].stAppGstInfo.videofilterpad));

    g_signal_connect (stAppInfo[cntNoOfWindows].stAppGstInfo.demux,
                      "pad-added",
                      G_CALLBACK (cb_newpad),
                      stAppInfo[cntNoOfWindows].stAppGstInfo.videobin);

    ret = gst_element_link_many (stAppInfo[cntNoOfWindows].stAppGstInfo.videoqueue,
                                 stAppInfo[cntNoOfWindows].stAppGstInfo.videodecoder,
                                 stAppInfo[cntNoOfWindows].stAppGstInfo.videosink,
                                 NULL);

    if(0 == ret)
    {
      PRINT("Failed to link queue, decoder and sink");
      return -1;
    }

    gst_object_unref(stAppInfo[cntNoOfWindows].stAppGstInfo.videofilterpad);

    /* Change the pipeline state to READY */
    State =
    gst_element_set_state (stAppInfo[cntNoOfWindows].stAppGstInfo.pipeline,
                           GST_STATE_READY);
    if(GST_STATE_CHANGE_FAILURE == State)
    {
      PRINT("State = %d", State);
      return 0;
    }
   
    /* Change the pipeline state to PLAYING */
    State =
    gst_element_set_state (stAppInfo[cntNoOfWindows].stAppGstInfo.pipeline,
                           GST_STATE_PLAYING);
    if(GST_STATE_CHANGE_FAILURE == State)
    {
      PRINT("State = %d", State);
      return 0;
    }
   
    /*Start the gmain loop by creating a gthread*/
    g_thread_create ((GThreadFunc)g_main_loop_run,
                     stAppInfo[cntNoOfWindows].stAppGstInfo.loop,  
                     FALSE,
                     NULL);          
    sleep(1);  
   
    cntNoOfWindows++;
  }
     
  while(1);

  return 0;

}

/* End of application */


_______________________________________________
gstreamer-devel mailing list
[hidden email]
http://lists.freedesktop.org/mailman/listinfo/gstreamer-devel