Gstreamer and vdpau

arnaud tonda arnaud.tonda at gmail.com
Thu Jun 30 03:28:48 PDT 2011


Hi everybody,

i have started the development of a multimedia player based on gstreamer
pipelines and i encounter some problems.

i work on a debian platform using Nvidia drivers, and so vdpau.

after reading the documentations on the gstreamer mechanisms and the
different example codes, i have started to make pipelines using gst-launch,
and then i have written some C source code.

i don't know if it's the better way, but i use the playbin2 element, with
setting video-sink property to a "vdpau sink" pipeline.

in commandLine, i use this :

gst-launch-0.10 -v -m playbin2 uri=file:///Movies/test.mkv
video-sink="vdpauvideopostprocess ! vdpausink" audio-sink="alsasink"

this works fine, except that i can't set the Rank of the vdpau decoder, and
so it hangs...

i tried to make the same in C source code, and the results are not
convincing... a piece of my code is below :

/*************************************************************************************************************************/
int main (int argc, char *argv[])
{
/***************************/
/*Variables Declaration*/
/***************************/

//GStreamer main event loop
GMainLoop *loop;

//elementary elements
GstElement *playbin;
        GstElement *videoOutputBin;

//VideoSink elements for VDPau;
GstElement *vdpauSink;
GstElement *vdpauVideoPostProcess;

//AudioSink elements for Alsa;
GstElement *alsaSink;

//Gstreamer bus to communicate with elements
GstBus *bus;

        //pad for videoOutputBin
GstPad *vdpauBinPad;

/********************/
/*Real code start*/
/********************/
//Gstreamer initialisation
gst_init(&argc, &argv);
loop = g_main_loop_new(NULL, FALSE);

//Sanity check on parameters
if(argc != 2)
{
    g_printerr ("Usage: %s <Multimedia filename>\n", argv[0]);
    return -1;
}
 //elements initialisation
 videoOutputBin         = gst_bin_new("vdpau-output-chain");
playbin         = gst_element_factory_make("playbin2","play-bin");
vdpauSink                 =
gst_element_factory_make("vdpausink","vdpau-sink");
vdpauVideoPostProcess =
gst_element_factory_make("vdpauvideopostprocess","post-process");
alsaSink                   =
gst_element_factory_make("alsasink","alsa-sink");

//Sanity check on elements validity
if(!playbin || !vdpauSink || !alsaSink || !audioConverter
||!vdpauVideoPostProcess || !videoOutputBin)
{
g_printerr("Some gstreamer elements could'nt itialized exit\n");
return -1;
}

//set up the pipeline
//1 - We set the URI input filename to the fileSource element
g_object_set(G_OBJECT(playbin),"uri",argv[1],NULL);
 //2 - We add a message Handler
bus = gst_pipeline_get_bus (GST_PIPELINE(playbin));
gst_bus_add_watch(bus, bus_callback, loop);
gst_object_unref(bus);


//3 - define specific rank for VDpau decoders
GstElementFactory *vdpauh264dec = gst_element_factory_find("vdpauh264dec");
gst_plugin_feature_set_rank (GST_PLUGIN_FEATURE(vdpauh264dec),
GST_RANK_PRIMARY+2);
GstElementFactory *vdpaumpeg4dec =
gst_element_factory_find("vdpaumpeg4dec");
gst_plugin_feature_set_rank (GST_PLUGIN_FEATURE(vdpaumpeg4dec),
GST_RANK_PRIMARY+2);
GstElementFactory *vdpaumpegdec = gst_element_factory_find("vdpaumpegdec");
gst_plugin_feature_set_rank (GST_PLUGIN_FEATURE(vdpaumpegdec),
GST_RANK_PRIMARY+2);

        //4 - create the videoOutputBin
g_signal_connect (G_OBJECT(videoOutputBin), "pad-added", G_CALLBACK
(on_pad_added), NULL);
g_signal_connect (G_OBJECT(videoOutputBin), "pad-removed", G_CALLBACK
(on_pad_removed), NULL);

gst_bin_add_many(GST_BIN(videoOutputBin),vdpauVideoPostProcess,vdpauSink,
NULL);

gst_element_link(vdpauVideoPostProcess,vdpauSink);


vdpauBinPad =
gst_ghost_pad_new("sink",gst_element_get_static_pad(vdpauVideoPostProcess,"sink"));

if(!vdpauBinPad)
        {
g_printerr("vdpauBinPad is null\n");
                exit -1;
}
        else
{
g_print("vpaudBinPad Exist\n");
gst_element_add_pad(videoOutputBin,vdpauBinPad);
}

//4 - set playbin properties
g_object_set(G_OBJECT(playbin),"video-sink",videoOutputBin,"audio-sink",alsaSink,NULL);


/* Set the pipeline to "playing" state*/
g_print ("Now playing: %s\n", argv[1]);
gst_element_set_state (playbin, GST_STATE_PLAYING);

/* Iterate */
g_print ("Running...\n");
g_timeout_add (200, (GSourceFunc) cb_print_position, playbin);
g_main_loop_run (loop);


/* Out of the main loop, clean up nicely */
g_print ("Returned, stopping playback\n");
gst_element_set_state (playbin, GST_STATE_NULL);

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


return 0;
}
/*************************************************************************************************************************/

As you can see, i have made a GstBin to encapsulate the post process
element, and the vdpauSink, and created a ghost pad to
vdpauvideopostprocess.

but i don't know if it is the right way to do this, because on certain
streams, video is displayed, but in other cases, gstreamer pipeline hang...
and when it hangs, in the gstreamer debug traces, i have a lot of warnings,
and some errors like this :

0:00:04.675157784   669  0x8783ff0 ERROR                h264dpb
h264/gsth264dpb.c:145:gst_h264_dpb_add:<GstH264DPB at 0x8659ea8> Couldn't make
room in DPB
0:00:04.696232757   669  0x8783ff0 WARN           basetransform
gstbasetransform.c:1065:gst_base_transform_acceptcaps_default:<passthrough-identity>
transform could not transform video/x-vdpau-video, chroma-type=(int)0,
width=(int)1920, height=(int)1080, framerate=(fraction)1710843747/71356439,
pixel-aspect-ratio=(fraction)1/1, interlaced=(boolean)false in anything we
support
0:00:04.729182133   669  0x8783ff0 WARN           basetransform
gstbasetransform.c:1065:gst_base_transform_acceptcaps_default:<passthrough-identity>
transform could not transform video/x-vdpau-video, chroma-type=(int)0,
width=(int)1920, height=(int)1080, framerate=(fraction)1710843747/71356439,
pixel-aspect-ratio=(fraction)1/1, interlaced=(boolean)false in anything we
support
0:00:04.729352573   669  0x8783ff0 ERROR                h264dpb
h264/gsth264dpb.c:145:gst_h264_dpb_add:<GstH264DPB at 0x8659ea8> Couldn't make
room in DPB
0:00:04.749110902   669  0x8783ff0 WARN           basetransform
gstbasetransform.c:1065:gst_base_transform_acceptcaps_default:<passthrough-identity>
transform could not transform video/x-vdpau-video, chroma-type=(int)0,
width=(int)1920, height=(int)1080, framerate=(fraction)1710843747/71356439,
pixel-aspect-ratio=(fraction)1/1, interlaced=(boolean)false in anything we
support

As it works in commandLine, i think i have made some errors, but i don't see
them right now.

if necessary i can take you some more informations.

Best regards

-- 
Arnaud Tonda
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.freedesktop.org/archives/gstreamer-devel/attachments/20110630/4614342a/attachment-0001.htm>


More information about the gstreamer-devel mailing list