我可以从命令行运行一个非常简单的启动管道,因此:
gst-launch-1.0 videotestsrc ! ximagesink
并且,从 开始gst-inspect-1.0,ximagesink似乎支持该GstVideoOverlay界面,以便我可以将其绑定到特定的 Gtk 小部件。
但是,当尝试从我碰巧在网上发现的一些代码中执行此操作时,似乎管道不被视为垃圾箱(因此,没有为其提供小部件 ID)。
执行此操作的代码如下,首先创建管道并将其设置为捕获总线消息:
Gst.Element playbin = Gst.Parse.Launch("videotestsrc ! ximagesink");
Gst.Bus bus = playbin.Bus;
bus.AddSignalWatch();
bus.Message += MsgCallback;
然后实际处理总线消息:
private void MsgCallback(object o, MessageArgs args) {
// Only care about window ID binding requests.
Gst.Message msg = args.Message;
if (! Gst.Video.Global.IsVideoOverlayPrepareWindowHandleMessage(msg))
return;
// Get source of message.
Gst.Element src = msg.Src as Gst.Element;
if (src == null)
return;
// Find element supporting interface and notify it to bind.
Gst.Element ov = null;
if (src is Gst.Bin) {
ov = ((Gst.Bin) src).GetByInterface(VideoOverlayAdapter.GType);
VideoOverlayAdapter ad = new VideoOverlayAdapter(ov.Handle);
ad.WindowHandle = windowXId;
}
}
现在,由于某种原因,src is Gst.Bin是错误的,这意味着windowXId(我之前设置的小部件 ID)永远不会与 GStreamer 通信。
但是,如果我提供playbin管道(playbin uri=XYZZY videosink='videoconvert ! videoflip method=none ! videoconvert ! autovideosink'如果您有兴趣),它可以正常工作。
据我从文档中可以看出Gst.Parse.Launch(),它应该给我一个管道,它是一个 bin 的特例,按照这里(在修复了残暴的语法之后):
NULL成功或失败时返回一个新元素。如果管道描述指定了多个顶级元素,则将所有元素放入 aGstPipeline中,然后返回。
我很确定,videotestsrc并且ximagesink是两个独立的顶级元素,但是,当我添加以下代码时,在检查之后src是null:
Console.WriteLine("is bin " + (src is Gst.Bin));
Console.WriteLine("is element " + (src is Gst.Element));
Console.WriteLine("is pipeline " + (src is Gst.Pipeline));
Console.WriteLine(type is " + src.GetType());
我懂了:
is bin False
is element True
is pipeline False
type is Gst.Element
对于有问题的videotestsrc管道,以下是好的管道playbin:
is bin True
is element True
is pipeline False
type is Gst.Bin
因此,尽管文档说明了什么,但一切都指向给出元素而不是垃圾箱的问题。
我在这里想念什么?会导致不同行为的两条管道之间有什么区别?