[gst-devel] play audio and video simultaneously

alavariega alavariega at dextratech.com
Wed Apr 22 22:37:01 CEST 2009


Hi everybody!

Actually im writing an gstreamer application to playback video and audio
simultaneously in gstreamer0.10  but i have some problems to gain my goal,
the on_decpad_added function is not executed, do you have any ideas what
could be the problem:

#include

static gboolean bus_call (GstBus     *bus,  GstMessage *msg,   gpointer   
data);
static void on_pad_added (GstElement *element, GstPad *pad);
static void on_decpad_added(GstElement *element, GstPad *pad );

GstElement *pipeline, *src, *demux, *decoderv,*sinkv,*decodera, *convert,
*resample, *sinka;
GstElement *queueA,* *queueV;

int main(int argc, char *argv[])
  {
   GstStateChangeReturn ret;
   GMainLoop *loop;
   GstBus *bus;
   /*initialization*/
   gst_init(&argc,&argv);
   loop = g_main_loop_new(NULL, FALSE);
   
   if(argc != 2)
     {
     g_print("Usage: %s ", argv[0]);
     return -1;
     }

    pipeline = gst_pipeline_new("VIDEO PLAYER");
    bus = gst_pipeline_get_bus(GST_PIPELINE(pipeline));
    gst_bus_add_watch(bus, bus_call, loop);

    src = gst_element_factory_make("filesrc", "filesource");
    demux = gst_element_factory_make("dvddemux", "mpg-demux");
   
    /*Gstreamer video elements*/
    decoderv = gst_element_factory_make("mpeg2dec", "mpeg-decoder");
    sinkv = gst_element_factory_make("xvimagesink", "video-out");
    if(!decoderv || !sinkv)
     {
      g_print("\nthe video could not playback\n");
      return -1;
     }

   /*Gstreamer audio elements*/

   decodera = gst_element_factory_make("mad", "decoder-audio");
   convert = gst_element_factory_make("audioconvert", "a-convert");
   resample = gst_element_factory_make("audioresample", "a-resample");
   sinka = gst_element_factory_make("osssink", "play audio");
   if(!decodera || !convert || !resample || !sinka)
     {
      g_print("\nthe audio could not playback\n");
      return -1;
     }
   
   queueA = gst_element_factory_make("queue", "queue-audio");
   queueV = gst_element_factory_make("queue", "queue-video");

   g_object_set (G_OBJECT (src), "location", argv[1], NULL);
   gst_bin_add_many(GST_BIN(pipeline), src, demux, decoderv,
queueV,sinkv,decodera, queueA,convert, resample, sinka, NULL);
  
   gst_element_link (src, demux);
   gst_element_link (queueV, sinkv);
   gst_element_link (queueA, convert);
   gst_element_link (convert, resample);
   gst_element_link (resample, sinka);

   g_signal_connect (demux, "pad-added",G_CALLBACK (on_pad_added), NULL);
   g_signal_connect (decodera,
"pad-added",G_CALLBACK(on_decpad_added),decodera);
   //g_signal_connect (decoderv,
"pad-added",G_CALLBACK(on_decpad_added),decoderv);
  
 /* run */
   ret = gst_element_set_state (pipeline, GST_STATE_PLAYING);
  
   if (ret == GST_STATE_CHANGE_FAILURE) 
    {
     GstMessage *msg;

     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;
       g_print("\nDISPLAY ERROR:\n");
       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;

  }


static gboolean bus_call (GstBus     *bus,  GstMessage *msg,   gpointer   
data)
{
  GMainLoop *loop = 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 details: %s\n", debug);
        g_free (debug);
      }

      g_main_loop_quit (loop);
      break;
    }
    default:
      break;
  }

  return TRUE;
}


static void on_decpad_added(GstElement *element, GstPad *pad )
{
    g_debug ("Signal: decoder pad-added");
    GstCaps *caps;
    GstStructure *str;
    GstPad *targetsink;
    caps = gst_pad_get_caps (pad);
    g_assert (caps != NULL);
    str = gst_caps_get_structure (caps, 0);
    g_assert (str != NULL);

	g_debug ("Linking decoder to QUEUE pad ");
	// Link it actually
        element = (element == decodera ? queueA : queueV);
	targetsink = gst_element_get_pad ( element, "sink");
	g_assert (targetsink != NULL);
	gst_pad_link (pad, targetsink);        
        if (gst_pad_is_linked(pad))
            g_print("The decoder pad src was linked\n");
        else
           g_print("The stream:%s pad src was
linked\n",gst_pad_get_name(pad));
	gst_object_unref (targetsink);
        gst_caps_unref (caps);
}

static void on_pad_added (GstElement *element, GstPad *pad)
{
        g_debug ("Signal: pad-added");
        GstCaps *caps;
        GstStructure *str;

        caps = gst_pad_get_caps (pad);
        g_assert (caps != NULL);
        str = gst_caps_get_structure (caps, 0);
        g_assert (str != NULL);

        const gchar *c = gst_structure_get_name(str);
        g_print("on_pad_added: %s\n",c);
        if (g_strrstr (c, "video") || g_strrstr (c, "image")) {
                g_debug ("Linking video pad to dec_vd");
                // Link it actually
                GstPad *targetsink = gst_element_get_pad (decoderv, "sink");              
                g_assert (targetsink != NULL);
                g_print("\nVIDEO--pad source: %s\n", gst_pad_get_name(pad));
                g_print("\nVIDEO--pad sink: %s\n",
gst_pad_get_name(targetsink));
                gst_pad_link (pad, targetsink);
                if (gst_pad_is_linked(pad))
                  g_print("The video pad src was linked\n");
                gst_object_unref (targetsink);
        }

        if (g_strrstr (c, "audio")) {
                g_debug ("Linking audio pad to dec_ad");
                // Link it actually
                GstPad *targetsink = gst_element_get_pad (decodera, "sink");
                g_assert (targetsink != NULL);
                g_print("\nAUDIO--pad source: %s\n", gst_pad_get_name(pad));
                g_print("\nAUDIO--pad sink: %s\n",
gst_pad_get_name(targetsink));
                gst_pad_link (pad, targetsink);
                if (gst_pad_is_linked(pad))
                  g_print("The audio pad src was linked\n");
                gst_object_unref (targetsink);
        }

        gst_caps_unref (caps);
}

When i execute the application, this is the results:


** (testvideop:6122): DEBUG: Signal: pad-added
on_pad_added: audio/mpeg
** (testvideop:6122): DEBUG: Linking audio pad to dec_ad

AUDIO--pad source: audio_00

AUDIO--pad sink: sink
The audio pad src was linked
** (testvideop:6122): DEBUG: Signal: pad-added
on_pad_added: video/mpeg
** (testvideop:6122): DEBUG: Linking video pad to dec_vd

VIDEO--pad source: video_00

VIDEO--pad sink: sink
The video pad src was linked
Error: Internal data flow error.
Debug details: gstbasesrc.c(2193): gst_base_src_loop (): /VIDEO
PLAYER/filesource:
streaming task paused, reason not-linked (-1)


thanks in advance for your help,

Alberto
-- 
View this message in context: http://www.nabble.com/play-audio-and-video-simultaneously-tp23175849p23175849.html
Sent from the GStreamer-devel mailing list archive at Nabble.com.
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.freedesktop.org/archives/gstreamer-devel/attachments/20090422/51366fb0/attachment.htm>


More information about the gstreamer-devel mailing list