Hi everybody,<div><br></div><div>i have started the development of a multimedia player based on gstreamer pipelines and i encounter some problems.</div><div><br></div><div>i work on a debian platform using Nvidia drivers, and so vdpau.</div>
<div><br></div><div>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.</div><div><br>
</div><div>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.</div><div><br></div><div>in commandLine, i use this :</div><div>
<br></div><div>gst-launch-0.10 -v -m playbin2 uri=file:///Movies/test.mkv video-sink="vdpauvideopostprocess ! vdpausink" audio-sink="alsasink"</div><div><br></div><div>this works fine, except that i can't set the Rank of the vdpau decoder, and so it hangs...</div>
<div><br></div><div>i tried to make the same in C source code, and the results are not convincing... a piece of my code is below :</div><div><br></div><div>/*************************************************************************************************************************/</div>
<div><div>int main (int argc, char *argv[])</div><div>{</div><div>/***************************/</div><div>/*Variables Declaration*/</div><div>/***************************/</div><div><br></div><div><span class="Apple-tab-span" style="white-space:pre">        </span>//GStreamer main event loop</div>
<div><span class="Apple-tab-span" style="white-space:pre">        </span>GMainLoop *loop;</div><div><br></div><div><span class="Apple-tab-span" style="white-space:pre">        </span>//elementary elements</div><div><span class="Apple-tab-span" style="white-space:pre">        </span>GstElement *playbin;</div>
<div> GstElement *videoOutputBin;</div><div><br></div><div><span class="Apple-tab-span" style="white-space:pre">        </span>//VideoSink elements for VDPau;</div><div><span class="Apple-tab-span" style="white-space:pre">        </span>GstElement *vdpauSink;</div>
<div><span class="Apple-tab-span" style="white-space:pre">        </span>GstElement *vdpauVideoPostProcess;</div><div><span class="Apple-tab-span" style="white-space:pre"><br></span></div><div><span class="Apple-tab-span" style="white-space:pre">        </span>//AudioSink elements for Alsa;</div>
<div><span class="Apple-tab-span" style="white-space:pre">        </span>GstElement *alsaSink;</div><div><br></div><div><span class="Apple-tab-span" style="white-space:pre">        </span>//Gstreamer bus to communicate with elements</div>
<div><span class="Apple-tab-span" style="white-space:pre">        </span>GstBus *bus;</div><div><br></div><div> //pad for videoOutputBin</div><div><span class="Apple-tab-span" style="white-space:pre">        </span>GstPad *vdpauBinPad;</div>
<div><br></div><div>/********************/</div><div>/*Real code start*/</div><div>/********************/</div><div><span class="Apple-tab-span" style="white-space:pre">        </span>//Gstreamer initialisation</div><div><span class="Apple-tab-span" style="white-space:pre">        </span>gst_init(&argc, &argv);</div>
<div><span class="Apple-tab-span" style="white-space:pre">        </span>loop = g_main_loop_new(NULL, FALSE);</div><div><br></div><div><span class="Apple-tab-span" style="white-space:pre">        </span>//Sanity check on parameters</div>
<div><span class="Apple-tab-span" style="white-space:pre">        </span>if(argc != 2)</div><div><span class="Apple-tab-span" style="white-space:pre">        </span>{</div><div><span class="Apple-tab-span" style="white-space:pre">        </span> g_printerr ("Usage: %s <Multimedia filename>\n", argv[0]);</div>
<div><span class="Apple-tab-span" style="white-space:pre">        </span> return -1;</div><div><span class="Apple-tab-span" style="white-space:pre">        </span>}</div><div><span class="Apple-tab-span" style="white-space:pre">        </span></div>
<div><span class="Apple-tab-span" style="white-space:pre">        </span>//elements initialisation</div><div><span class="Apple-tab-span" style="white-space:pre">        </span></div><div><span class="Apple-tab-span" style="white-space:pre">        </span>videoOutputBin<span class="Apple-tab-span" style="white-space:pre">                </span> = gst_bin_new("vdpau-output-chain");</div>
<div><span class="Apple-tab-span" style="white-space:pre">        </span>playbin<span class="Apple-tab-span" style="white-space:pre">                        </span> = gst_element_factory_make("playbin2","play-bin");</div><div>
<span class="Apple-tab-span" style="white-space:pre">        </span>vdpauSink<span class="Apple-tab-span" style="white-space:pre">                </span> = gst_element_factory_make("vdpausink","vdpau-sink");</div>
<div><span class="Apple-tab-span" style="white-space:pre">        </span>vdpauVideoPostProcess<span class="Apple-tab-span" style="white-space:pre">        </span>= gst_element_factory_make("vdpauvideopostprocess","post-process");</div>
<div><span class="Apple-tab-span" style="white-space:pre">        </span>alsaSink<span class="Apple-tab-span" style="white-space:pre">        </span> <span class="Apple-tab-span" style="white-space:pre">        </span> = gst_element_factory_make("alsasink","alsa-sink");</div>
<div><br></div><div><span class="Apple-tab-span" style="white-space:pre">        </span>//Sanity check on elements validity</div><div><span class="Apple-tab-span" style="white-space:pre">        </span>if(!playbin || !vdpauSink || !alsaSink || !audioConverter ||!vdpauVideoPostProcess || !videoOutputBin)</div>
<div><span class="Apple-tab-span" style="white-space:pre">        </span>{</div><div><span class="Apple-tab-span" style="white-space:pre">                </span>g_printerr("Some gstreamer elements could'nt itialized exit\n");</div>
<div><span class="Apple-tab-span" style="white-space:pre">                </span>return -1;</div><div><span class="Apple-tab-span" style="white-space:pre">        </span>}</div><div><br></div><div><span class="Apple-tab-span" style="white-space:pre">        </span>//set up the pipeline</div>
<div><span class="Apple-tab-span" style="white-space:pre">        </span>//1 - We set the URI input filename to the fileSource element</div><div><span class="Apple-tab-span" style="white-space:pre">        </span>g_object_set(G_OBJECT(playbin),"uri",argv[1],NULL);</div>
<div><span class="Apple-tab-span" style="white-space:pre">        </span></div><div><span class="Apple-tab-span" style="white-space:pre">        </span>//2 - We add a message Handler</div><div><span class="Apple-tab-span" style="white-space:pre">        </span>bus<span class="Apple-tab-span" style="white-space:pre">        </span>= gst_pipeline_get_bus (GST_PIPELINE(playbin));</div>
<div><span class="Apple-tab-span" style="white-space:pre">        </span>gst_bus_add_watch(bus, bus_callback, loop);</div><div><span class="Apple-tab-span" style="white-space:pre">        </span>gst_object_unref(bus);</div><div><br></div>
<div><br></div><div><span class="Apple-tab-span" style="white-space:pre">        </span>//3 - define specific rank for VDpau decoders</div><div><span class="Apple-tab-span" style="white-space:pre">        </span>GstElementFactory *vdpauh264dec = gst_element_factory_find("vdpauh264dec");</div>
<div><span class="Apple-tab-span" style="white-space:pre">        </span>gst_plugin_feature_set_rank (GST_PLUGIN_FEATURE(vdpauh264dec), GST_RANK_PRIMARY+2);</div><div><span class="Apple-tab-span" style="white-space:pre">        </span>GstElementFactory *vdpaumpeg4dec = gst_element_factory_find("vdpaumpeg4dec");</div>
<div><span class="Apple-tab-span" style="white-space:pre">        </span>gst_plugin_feature_set_rank (GST_PLUGIN_FEATURE(vdpaumpeg4dec), GST_RANK_PRIMARY+2);</div><div><span class="Apple-tab-span" style="white-space:pre">        </span>GstElementFactory *vdpaumpegdec = gst_element_factory_find("vdpaumpegdec");</div>
<div><span class="Apple-tab-span" style="white-space:pre">        </span>gst_plugin_feature_set_rank (GST_PLUGIN_FEATURE(vdpaumpegdec), GST_RANK_PRIMARY+2);</div><div><br></div><div> //4 - create the videoOutputBin</div><div>
<span class="Apple-tab-span" style="white-space:pre">        </span>g_signal_connect (G_OBJECT(videoOutputBin), "pad-added", G_CALLBACK (on_pad_added), NULL);</div><div><span class="Apple-tab-span" style="white-space:pre">        </span>g_signal_connect (G_OBJECT(videoOutputBin), "pad-removed", G_CALLBACK (on_pad_removed), NULL);</div>
<div><br></div><div><span class="Apple-tab-span" style="white-space:pre">        </span>gst_bin_add_many(GST_BIN(videoOutputBin),vdpauVideoPostProcess,vdpauSink, NULL);</div><div><br></div><div><span class="Apple-tab-span" style="white-space:pre">        </span>gst_element_link(vdpauVideoPostProcess,vdpauSink);</div>
<div><br></div><div><br></div><div><span class="Apple-tab-span" style="white-space:pre">        </span>vdpauBinPad = gst_ghost_pad_new("sink",gst_element_get_static_pad(vdpauVideoPostProcess,"sink"));</div><div>
<br></div><div><span class="Apple-tab-span" style="white-space:pre">        </span>if(!vdpauBinPad)</div><div> {</div><div><span class="Apple-tab-span" style="white-space:pre">                </span>g_printerr("vdpauBinPad is null\n");</div>
<div> exit -1;</div><div><span class="Apple-tab-span" style="white-space:pre">        </span>}</div><div><span class="Apple-tab-span" style="white-space:pre"></span> else</div><div><span class="Apple-tab-span" style="white-space:pre">        </span>{</div>
<div><span class="Apple-tab-span" style="white-space:pre">                </span>g_print("vpaudBinPad Exist\n");</div><div><span class="Apple-tab-span" style="white-space:pre">                </span>gst_element_add_pad(videoOutputBin,vdpauBinPad);</div>
<div><span class="Apple-tab-span" style="white-space:pre">        </span>}</div><div><br></div><div><span class="Apple-tab-span" style="white-space:pre">        </span>//4 - set playbin properties</div><div><span class="Apple-tab-span" style="white-space:pre">        </span>g_object_set(G_OBJECT(playbin),"video-sink",videoOutputBin,"audio-sink",alsaSink,NULL);</div>
<div><br></div><div><br></div><div><span class="Apple-tab-span" style="white-space:pre">        </span>/* Set the pipeline to "playing" state*/</div><div><span class="Apple-tab-span" style="white-space:pre">        </span>g_print ("Now playing: %s\n", argv[1]);</div>
<div><span class="Apple-tab-span" style="white-space:pre">        </span>gst_element_set_state (playbin, GST_STATE_PLAYING);</div><div><br></div><div><span class="Apple-tab-span" style="white-space:pre">        </span>/* Iterate */</div>
<div><span class="Apple-tab-span" style="white-space:pre">        </span>g_print ("Running...\n");</div><div><span class="Apple-tab-span" style="white-space:pre">        </span>g_timeout_add (200, (GSourceFunc) cb_print_position, playbin);</div>
<div><span class="Apple-tab-span" style="white-space:pre">        </span>g_main_loop_run (loop);</div><div><br></div><div><br></div><div><span class="Apple-tab-span" style="white-space:pre">        </span>/* Out of the main loop, clean up nicely */</div>
<div><span class="Apple-tab-span" style="white-space:pre">        </span>g_print ("Returned, stopping playback\n");</div><div><span class="Apple-tab-span" style="white-space:pre">        </span>gst_element_set_state (playbin, GST_STATE_NULL);</div>
<div><br></div><div><span class="Apple-tab-span" style="white-space:pre">        </span>g_print ("Deleting pipeline\n");</div><div><span class="Apple-tab-span" style="white-space:pre">        </span>gst_object_unref (GST_OBJECT (playbin));</div>
<div><br></div><div><br></div><div><span class="Apple-tab-span" style="white-space:pre">        </span>return 0;</div><div>}</div></div><div><meta http-equiv="content-type" content="text/html; charset=utf-8"><div>/*************************************************************************************************************************/</div>
<div></div></div><div><br></div><div>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.</div><div><br></div><div>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 :</div>
<div><br></div><div><div>0:00:04.675157784 669 0x8783ff0 ERROR h264dpb h264/gsth264dpb.c:145:gst_h264_dpb_add:<GstH264DPB@0x8659ea8> Couldn't make room in DPB</div><div>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</div>
<div>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</div>
<div>0:00:04.729352573 669 0x8783ff0 ERROR h264dpb h264/gsth264dpb.c:145:gst_h264_dpb_add:<GstH264DPB@0x8659ea8> Couldn't make room in DPB</div><div>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</div>
</div><div><br></div><div>As it works in commandLine, i think i have made some errors, but i don't see them right now.</div><div><br></div><div>if necessary i can take you some more informations.</div><div><br></div><div>
Best regards</div><div><br></div><div>-- </div><div>Arnaud Tonda<br><br>
</div>