在Silverlight中,我正在尝试在一系列3d四边形上获得网络摄像头(实时)流的帧纹理。我在摄像头控制器类的摄像头控制器类中使用VideoSink。然后,我在DrawingSurface中绘制四边形。但我一直在CrossAppDomainMarshaledException中运行。作为解决方案,我尝试使用Dispatcher.BeginInvoke,但有时BeginInvoke中的代码似乎会跳过或跳出线程。如何处理这样的事情呢?
//Video sink capture
// Is called every time the webcam provides a complete frame (Push)
protected override void OnSample(long sampleTime, long frameDuration, byte[] sampleData)
{
System.Windows.Deployment.Current.Dispatcher.BeginInvoke(() =>
{
WriteableBitmap bmp = new WriteableBitmap(vidFormat.PixelWidth, vidFormat.PixelHeight);
RaiseFrameCapture(new FrameCapturedEventArgs { Frame = bmp.FromByteArray(sampleData) });
});
}
//Capture from sink into WebCamController
void sink_FrameCaptured(object sender, FrameCapturedEventArgs e)
{
//List<WriteableBitmap>
_WebCamSource.AddImage(e.Frame.Clone());
}
//XNA draw event handler
private void DrawingSurface_Draw(object sender, DrawEventArgs e)
{
List<WriteableBitmap> frames = new List<WriteableBitmap>();
if (webCamSource.Frames.Count > 0)
{
Deployment.Current.Dispatcher.BeginInvoke(() =>
{
frames = new List<WriteableBitmap>(webCamSource.Frames.ToArray());
});
}
Draw(frames);
e.InvalidateSurface();
}发布于 2011-10-24 04:32:06
即使你解决了你的问题,我也可以提供一些见解。XNA与经典的Silverlight呈现有很大的不同。
在经典的Silverlight渲染管道中,您以声明方式构建可视化树,并将您的更改推送到它。渲染循环已经看不见了,你很少需要去弄乱它。
因此,您希望尽快将更改推送到可视化树。如果您在UI线程(正在运行的线程)之外的其他线程中更新可视化树,则更新可能会在呈现期间发生,这将是灾难性的。因此,UI线程公开一个可通过Dispatcher.BeginInvoke使用的消息泵,以确保线程安全。
有了XNA,你就没有这些了.因为您实现了自己的渲染管道,并对其进行了完全控制。
每次处理webcame帧时,在您的网络摄像头控制器中设置它(使用锁)。在每个XNA帧中,如果摄像头控制器接收到新帧,则获取摄像头帧(使用锁)并更新XNA纹理(不要为每个帧创建新纹理,这效率不高)。然后,使用此纹理渲染您的3D对象。
https://stackoverflow.com/questions/7700804
复制相似问题