将 Playbin 状态设置为 NULL 或 READY 后 GStreamer XOverlay 丢失
我正在使用 OSSBuild 和 gstreamersharp 开发 C# WPF 应用程序。我使用 XOverlayAdapter 在我拥有 Windows 句柄的托管 WindowsForms 控件上显示视频。除了我将 playbin2 状态设置为 NULL 或 READY 时的情况外,一切都运行良好。这正是我正在做的事情(我删除了元素是否已正确创建的所有检查):
创建一个 playbin
Gst.BasePlugins.PlayBin2 playBin = new Gst.BasePlugins.PlayBin2(); playBin.PlayFlags &= ~((Gst.BasePlugins.PlayBin2.PlayFlagsType)(1 << 2)); playBin.Bus.AddSignalWatch(); playBin.Bus.EnableSyncMessageEmission(); playBin.Bus.Message += new Gst.MessageHandler(OnPlayBinMessage);
创建一个视频接收器
Gst.Video.VideoSink videoSink = Gst.ElementFactory.Make("dshowvideosink") as Gst.Video.VideoSink; videoSink["力纵横比"] = true;
将视频接收器与 WindowsForms 控件(屏幕)关联,以在 WPF 窗口的矩形区域中显示视频。
Gst.Interfaces.XOverlayAdapter overrideAdapter = 新的 Gst.Interfaces.XOverlayAdapter(videoSink.Handle); overlayAdapter.XwindowId = (ulong)screen.Handle;
将视频接收器附加到播放箱
playBin.VideoSink = videoSink;
将 playbin 的 URI 设置为我的硬盘驱动器上的某个视频文件
playBin.SetState(Gst.State.Ready); playBin.Uri = @"file:///" + fileName.Replace('\\', '/'); playBin.SetState(Gst.State.Paused);
现在我可以通过更改 playbin 的状态来播放和暂停视频
playBin.SetState(Gst.State.Playing); playBin.SetState(Gst.State.Paused);
到目前为止一切顺利,我可以播放、暂停、搜索窗口中矩形区域中显示的视频。当我尝试播放另一个视频文件时,问题开始出现。根据网上找到的所有手册,我应该在更改 URI 之前将管道状态设置为 NULL 或 READY:
打开另一个视频文件
playBin.SetState(Gst.State.Ready); playBin.Uri = @"file:///" + newFileName.Replace('\\', '/'); playBin.SetState(Gst.State.Playing);
不幸的是,这会导致我的窗口中的矩形区域变黑并由 GStreamer 创建一个单独的窗口。它与更改 URI 无关,它将 playbin 状态设置为 NULL 或 READY,从而断开视频输出与叠加层的连接。我做错了什么?
I'm developing a C# WPF application using OSSBuild and gstreamersharp. I'm using XOverlayAdapter to display video on a hosted WindowsForms control to which I have a Windows handle. Everything is working nicely except the situation when I set the playbin2 state to NULL or READY. This is exactly what I'm doing (I stripped out all checks if the elements have been created correctly):
Create a playbin
Gst.BasePlugins.PlayBin2 playBin = new Gst.BasePlugins.PlayBin2(); playBin.PlayFlags &= ~((Gst.BasePlugins.PlayBin2.PlayFlagsType)(1 << 2)); playBin.Bus.AddSignalWatch(); playBin.Bus.EnableSyncMessageEmission(); playBin.Bus.Message += new Gst.MessageHandler(OnPlayBinMessage);
Create a videosink
Gst.Video.VideoSink videoSink = Gst.ElementFactory.Make("dshowvideosink") as Gst.Video.VideoSink; videoSink["force-aspect-ratio"] = true;
Associate the videosink with a WindowsForms control (screen) to display the video in a rectangular area in my WPF window.
Gst.Interfaces.XOverlayAdapter overlayAdapter = new Gst.Interfaces.XOverlayAdapter(videoSink.Handle); overlayAdapter.XwindowId = (ulong)screen.Handle;
Attach the videosink to the playbin
playBin.VideoSink = videoSink;
Set playbin's URI to some video file on my hard drive
playBin.SetState(Gst.State.Ready); playBin.Uri = @"file:///" + fileName.Replace('\\', '/'); playBin.SetState(Gst.State.Paused);
Now I can play and pause the video by changing the state of the playbin
playBin.SetState(Gst.State.Playing); playBin.SetState(Gst.State.Paused);
So far so good, everything is working smoothly, I can play, pause, seek the video displayed in a rectangular area in my window. The problems start when I try to play another video file. According to all manuals found on the net, I should set the pipeline state to NULL or READY before changing the URI:
Open another video file
playBin.SetState(Gst.State.Ready); playBin.Uri = @"file:///" + newFileName.Replace('\\', '/'); playBin.SetState(Gst.State.Playing);
Unfortunately this causes the rectangular area in my window to become black and a separate window created by GStreamer. It has nothing to do with changing the URI, it is setting the playbin state to NULL or READY which disconnects the video output from the overlay. What am I doing wrong?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
解决方案是防止视频接收器改变其状态。
感谢 gstreamer-devel 邮件列表中的 Stefan Sauer。
The solution is to prevent the videosink from changing its state.
Credit to Stefan Sauer from the gstreamer-devel mailing list.