[gst-devel] Newbie help. Cannot output audio/video simultaneously (with DirectFB)

danielkun at iremo.com danielkun at iremo.com
Tue Feb 26 11:10:30 CET 2008


Hello,
	
I'm new to Gstreamer and new to this mail subscription but I'm hoping
someone will try to help me ;)

I trying to playback MPEG files using DirectFB. The code below does the
job but it won't let me output
video and audio at the same time. It's either audio only or video only. 

What have I not understood completely?

I put the src and the demuxer in the pipeline and made 2 bins for
audio/video and added ghost pads.
This seems to work well but not simultaneously.

I would appreciate any help.

Thanks,

Daniel



#include <string.h>
#include <directfb.h>
#include <gst/gst.h>

static IDirectFB *dfb = NULL;
static IDirectFBSurface *primary = NULL;
static GMainLoop *loop;

GstElement *pipeline, *bin_audio, *bin_video, *source, *parser,
*decoder_audio, *decoder_video,
										*convert_audio, *convert_video, *sink_audio, *sink_video;

GstPad *pad_video, *pad_audio;

#define DFBCHECK(x...)                                         \
  {                                                            \
    DFBResult err = x;                                         \
                                                               \
    if (err != DFB_OK)                                         \
      {                                                        \
        fprintf( stderr, "%s <%d>:\n\t", __FILE__, __LINE__ ); \
        DirectFBErrorFatal( #x, err );                         \
      }                                                        \
  }

static gboolean
get_me_out (gpointer data)
{
  g_main_loop_quit (loop);
  return FALSE;
}


static void
new_pad (GstElement *element,
		 GstPad     *pad,	//src
	 	 gpointer    data)
{

  gchar *name;
  name = gst_pad_get_name (pad);
  
  if ( NULL != strstr(name, "video"))
  {
  	GstPad *sinkpad;	//sink
  	g_print ("Dynamic pad created, linking parser/decoder '%s'\n", name);
  	sinkpad = gst_element_get_pad (bin_video, "sink");
  	gst_pad_link (pad, sinkpad);
  	gst_object_unref (sinkpad);
  }

  if ( NULL != strstr(name, "audio"))
  {
  	GstPad *sinkpad;	//sink
  	g_print ("Dynamic pad created, linking parser/decoder '%s'\n", name);
	sinkpad = gst_element_get_pad (bin_audio, "sink");
  	gst_pad_link (pad, sinkpad);
  	gst_object_unref (sinkpad);
  }

}

int 
main (int argc, char *argv[])
{
  DFBSurfaceDescription dsc;
  GstBus *bus;


  /* Init both GStreamer and DirectFB */
  DFBCHECK (DirectFBInit (&argc, &argv));
  gst_init (&argc, &argv);

  loop = g_main_loop_new (NULL, FALSE);

  /* Creates DirectFB main context and set it to fullscreen layout */
  DFBCHECK (DirectFBCreate (&dfb));
  DFBCHECK (dfb->SetCooperativeLevel (dfb, DFSCL_FULLSCREEN));

  /* We want a double buffered primary surface */
  dsc.flags = DSDESC_CAPS;
  dsc.caps = DSCAPS_PRIMARY | DSCAPS_FLIPPING;

  DFBCHECK (dfb->CreateSurface (dfb, &dsc, &primary));


  // create elements
  pipeline = gst_pipeline_new (NULL);
  bin_audio = gst_bin_new (NULL);
  bin_video = gst_bin_new (NULL);

  source = gst_element_factory_make ("filesrc", NULL);	// videotestsrc

  parser = gst_element_factory_make ("mpegdemux", NULL);	// dvddemux,
mpegparse, mpegvideoparse

  decoder_audio = gst_element_factory_make ("mad", NULL);
  decoder_video = gst_element_factory_make ("mpeg2dec", NULL);

  convert_audio = gst_element_factory_make ("audioconvert", NULL);
  convert_video = gst_element_factory_make("ffmpegcolorspace", NULL);

  sink_audio = gst_element_factory_make ("alsasink", NULL);
  sink_video = gst_element_factory_make ("dfbvideosink", NULL);


  // That's the interesting part, giving the primary surface to
dfbvideosink
  g_object_set (sink_video, "surface", primary, NULL);

  // set filename property on the file source
  g_object_set (G_OBJECT (source), "location", argv[1], NULL);

  // add source and parser
  gst_bin_add_many (GST_BIN (pipeline), source, parser, NULL);

  // put all elements in a bin
  gst_bin_add_many (GST_BIN (bin_video), decoder_video, convert_video,
sink_video, NULL);
  gst_bin_add_many (GST_BIN (bin_audio), decoder_audio, convert_audio,
sink_audio, NULL);


  // add ghostpad to audio
  pad_audio = gst_element_get_pad (decoder_audio, "sink");
  gst_element_add_pad (bin_audio, gst_ghost_pad_new ("sink",
pad_audio));
  gst_object_unref (GST_OBJECT (pad_audio));

  // add ghostpad to video
  pad_video = gst_element_get_pad (decoder_video, "sink");
  gst_element_add_pad (bin_video, gst_ghost_pad_new ("sink",
pad_video));
  gst_object_unref (GST_OBJECT (pad_video));


  // add bins to pipeline
  gst_bin_add_many (GST_BIN (pipeline), bin_video, bin_audio, NULL);

  // link together - note that we cannot link the parser and decoder yet
  gst_element_link (source, parser);
  gst_element_link_many (decoder_video, convert_video, sink_video,
NULL);
  gst_element_link_many (decoder_audio, convert_audio, sink_audio,
NULL);

  g_signal_connect (parser, "pad-added", G_CALLBACK (new_pad), NULL);


  // Now set to playing and iterate.
  g_print ("Setting to PLAYING\n");
  gst_element_set_state (pipeline, GST_STATE_PLAYING);

  g_print ("Running\n");

  // Get us out after xx seconds
  g_timeout_add (5000, get_me_out, NULL);
  g_main_loop_run (loop);


  // Release elements and stop playback
  gst_element_set_state (pipeline, GST_STATE_NULL);


  // Free the main loop
  g_main_loop_unref (loop);

  // clean up nicely
  g_print ("Returned, stopping playback\n");
  gst_element_set_state (pipeline, GST_STATE_NULL);

  g_print ("Deleting pipeline\n");
  gst_object_unref (GST_OBJECT (pipeline));

  /* Release DirectFB context and surface */
  primary->Release (primary);
  dfb->Release (dfb);

  return 0;
}






More information about the gstreamer-devel mailing list