我有一个VideoRenderer类,它继承的图像控制,一类MyVideo网站,其中有一个VideoRenderer实例,并在主窗口一个RenderFrames方法代码隐藏如何在不冻结GUI的情况下不断更新视频帧的内容控件?
我已附加这些类的相关部分,以及作为RenderFrames方法和下面的一些MainWindow代码隐藏构造函数。
VideoRenderer接收外部视频并将视频帧生成为位图对象,存储在“位图”字段中。每完成一次处理后,我将位图的副本存储在“bitmapCopy”字段中。
MyVideo控制何时VideoRenderer实例“sharedVideoRenderer”启动和停止接收和发送帧到MainWindow RenderFrames方法,使用ThreadPool.QueueUserWorkItem传递VideoRenderer实例作为对象参数。
RenderFrames循环,直到MyVideo网站说,停止通过改变它的布尔“是我们渲染”特性,以及它与位图做了转换 - >的BitmapImage - > Image.Source,然后设置VideoContentControl.Content作为图像,使用MainWindow Dispatcher。
一切正常,视频呈现,但GUI控制基本上是冻结的,其他按钮和事情不起作用,因为调度整个操作到MainWindow线程和循环不断正在捆绑线程。
我的问题是:我可以尝试使用其他方法将位图帧从“sharedVideoRenderer”传输到VideoContentControl,并在不冻结GUI的情况下使用新图像继续更新它?
任何帮助,将不胜感激。
相关的代码:
VideoRenderer.cs:
internal void DrawBitmap()
{
lock (bitmapLock)
{
bitmapCopy = (Bitmap)bitmap.Clone();
}
}
MyVideo.cs:
public static void RenderVideoPreview()
{
sharedVideoRenderer.VideoObject = videoPreview;
sharedVideoRenderer.Start();
videoPreviewIsRendering = true;
ThreadPool.QueueUserWorkItem((Application.Current.MainWindow as MainWindow).RenderFrames, sharedVideoRenderer);
}
MainWindow.xaml.cs:
Dispatcher mainWindowDispatcher;
public MainWindow()
{
InitializeComponent();
mainWindowDispatcher = this.Dispatcher;
...
public void RenderFrames(object videoRenderer)
{
while (MyVideo.VideoPreviewIsRendering || MyVideo.LiveSessionParticipantVideoIsRendering)
{
mainWindowDispatcher.Invoke(new Action(() =>
{
try
{
System.Drawing.Bitmap bitmap;
bitmap = (videoRenderer as VideoRenderer).BitmapCopy;
using (MemoryStream memory = new MemoryStream())
{
BitmapImage bitmapImage = new BitmapImage();
ImageSource imageSource;
Image image;
image = new Image();
bitmap.Save(memory, System.Drawing.Imaging.ImageFormat.Bmp);
memory.Position = 0;
bitmapImage.BeginInit();
bitmapImage.StreamSource = memory;
bitmapImage.CacheOption = BitmapCacheOption.OnLoad;
bitmapImage.EndInit();
imageSource = bitmapImage;
image.Source = imageSource;
VideoContentControl.Content = image;
memory.Close();
}
}
catch (Exception)
{
}
}));
}
mainWindowDispatcher.Invoke(new Action(() =>
{
VideoContentControl.ClearValue(ContentProperty);
VideoContentControl.InvalidateVisual();
}));
}
我认为您需要利用GPU来使其可靠工作。 – Kos 2012-07-27 15:33:22