[gst-devel] Why auido and video can not play at the same time?

gtxia xia_guangtai at visualon.com
Wed May 23 07:09:08 CEST 2007


Hello all.

I developed a application to play avi (video is xvid and audio is
mp3)file. Use the define to only play video or audio or all. When play
only video or audio, this application is OK. But when I want to use it
to play all. It seems deadlock. I don't know how to solve this problem.
Thanks for any help.

The application codes:




#include <gst/gst.h>

#define ONLY_VIDEO

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 = NULL;
       GError *err = NULL;
       gst_message_parse_error (msg, &err, &debug);
       g_print ("Error: %s\n", err->message);
       g_error_free (err);
       if (debug) {
         g_print ("Debug deails: %s\n", debug);
         g_free (debug);
       }
       g_main_loop_quit (loop);
       break;
     }
     default:
       break;
  }
  return TRUE;
}

struct Elem_Info
{
	GstElement* pVideoDec;
	GstElement* pAudioDec;
};


static void new_pad(GstElement* element, GstPad *pad, gpointer data)
{
	GstPad* sinkPad;
	GstCaps* caps;
	GstStructure* str;
	const gchar* pName;
	Elem_Info* pInfo = (Elem_Info*)(data);
	g_print("Dynamic pad created, linking parser/decoder\n");

	
	// only link when pad belong to video
	caps = gst_pad_get_caps(pad);
	str = gst_caps_get_structure(caps, 0);
	pName = gst_structure_get_name (str);
	if (pInfo->pVideoDec && g_strrstr (pName, "video"))
	{
		sinkPad = gst_element_get_pad(pInfo->pVideoDec, "sink");
		gst_pad_link(pad, sinkPad);
		gst_object_unref(sinkPad);
		
	}
	else if(pInfo->pAudioDec && g_strrstr(pName, "audio"))
	{
		sinkPad = gst_element_get_pad(pInfo->pAudioDec, "sink");
		gst_pad_link(pad, sinkPad);
		gst_object_unref(sinkPad);
		
	}

}


gint main (gint    argc,  gchar *argv[])
{
  GstStateChangeReturn ret;
  GstElement *pipeline,  *filesrc, *decoder, *sink;
  GstElement* demux, *video_decoder, *color_convert, *video_sink;
  GstElement *convert1, *convert2, *resample;
  GMainLoop *loop;
  GstBus *bus;
  /* initialization */
  gst_init (&argc, &argv);
  loop = g_main_loop_new (NULL, FALSE);
  if (argc != 2) {
	 g_print("Usage: %s < mpeg4 filename>\n", argv[0]);
     return 01;
  }
  /* create elements */
  pipeline = gst_pipeline_new ("my_pipeline");
  /* watch for messages on the pipeline’s bus (note that this will only
    * work like this when a GLib main loop is running) */
  bus = gst_pipeline_get_bus (GST_PIPELINE (pipeline));
  gst_bus_add_watch (bus, bus_call, loop);
  gst_object_unref (bus);

  filesrc   = gst_element_factory_make ("filesrc", "my_filesource");

  demux= gst_element_factory_make("avidemux", "my_avidemux");
  video_decoder = gst_element_factory_make("xviddec", "my_xviddec");
  
  

  color_convert = gst_element_factory_make("ffmpegcolorspace",
"my_color_convert");

  decoder = gst_element_factory_make("mad", "my_mp3_decoder");
	
  sink = gst_element_factory_make ("alsasink", "audiosink");

  video_sink = gst_element_factory_make("ximagesink", "my_video_sink");
  if (!video_sink || !video_decoder)
  {
	  g_print ("Decoder or output could not be found - check your install
\n");
	  return -1;
  }
  else if (!demux || !color_convert )
  {
	  g_print ("Could not create audioconvert or audioresample element, "
            "check your installation\n");
	  return -1;
  }	

  g_object_set (G_OBJECT (filesrc), "location", argv[1], NULL);


  Elem_Info info;
#if defined(ONLY_VIDEO)
  gst_bin_add_many (GST_BIN (pipeline), filesrc, demux,
video_decoder,color_convert, video_sink, NULL);
  gst_element_link(filesrc, demux);
  gst_element_link_many(video_decoder, color_convert, video_sink, NULL);
  
  info.pVideoDec = video_decoder;
  info.pAudioDec = NULL;
#elif defined (ONLY_AUDIO)
  gst_bin_add_many (GST_BIN (pipeline), filesrc, demux, decoder, sink,
NULL);
  gst_element_link(filesrc, demux);
  gst_element_link_many(decoder, sink, NULL);

  info.pVideoDec = NULL;
  info.pAudioDec = decoder;
#else
  gst_bin_add_many (GST_BIN (pipeline), filesrc, demux,
video_decoder,color_convert, video_sink, decoder, sink, NULL);
  gst_element_link(filesrc, demux);
  gst_element_link_many(video_decoder, color_convert, video_sink, NULL);
  gst_element_link_many(decoder, sink, NULL);
  
  info.pVideoDec = video_decoder;
  info.pAudioDec = decoder;
#endif
  g_signal_connect(demux, "pad-added", G_CALLBACK(new_pad), &info);
	


ret = gst_element_set_state (pipeline, GST_STATE_PLAYING);

GstMessage* msg;

if (ret == GST_STATE_CHANGE_FAILURE) {
    g_print ("Failed to start up pipeline!\n");
    /* check if there is an error message with details on the bus */
    msg = gst_bus_poll (bus, GST_MESSAGE_ERROR, 0);
    if (msg) {
      GError *err = NULL;
      gst_message_parse_error (msg, &err, NULL);
      g_print ("ERROR: %s\n", err->message);
      g_error_free (err);
      gst_message_unref (msg);
    }
    return -1;
  }
  g_main_loop_run (loop);
  /* clean up */
  gst_element_set_state (pipeline, GST_STATE_NULL);
  gst_object_unref (pipeline);
  return 0;
}







More information about the gstreamer-devel mailing list