【发布时间】:2012-07-27 13:34:31
【问题描述】:
我有一个 VideoRenderer 类,它继承了一个 Image 控件,一个 MyVideo 类,它有一个 VideoRenderer 实例,以及 MainWindow 代码隐藏中的一个 RenderFrames 方法
我在下面附上了这些类的相关部分,以及 RenderFrames 方法和一些 MainWindow 代码隐藏构造函数。
VideoRenderer 接收外部视频并将视频帧生成为位图对象,存储在“位图”字段中。在每个完成的过程之后,我将位图的副本存储在“bitmapCopy”字段中。
MyVideo 控制 VideoRenderer 实例“sharedVideoRenderer”何时开始和停止接收和发送帧到 MainWindow RenderFrames 方法,使用 ThreadPool.QueueUserWorkItem 将 VideoRenderer 实例作为对象参数传递。
RenderFrames 循环直到 MyVideo 说通过更改它的任一布尔“我们正在渲染”属性来停止,它从 Bitmap -> BitmapImage -> Image.Source 进行转换,然后将 VideoContentControl.Content 设置为图像,使用MainWindow 调度程序。
一切正常,视频渲染,但 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 来确保这项工作可靠。
标签: c# wpf xaml user-interface contentcontrol