如何使用 XNA 将一系列图像从 ui 线程获取到 Silverlight 5 中的绘制线程

发布于 2024-12-09 00:43:55 字数 1486 浏览 1 评论 0原文

在 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();
    }

in Silverlight I'm trying to get the frames of a webcam (live) stream textured on a series of 3d quads. I use a VideoSink in a webcam controller class in a webcam controller class. Then i draw the quads in the DrawingSurface. But I keep running in CrossAppDomainMarshaledException. As a solution I try to use the Dispatcher.BeginInvoke but sometimes the code in the BeginInvoke seems to jump over or out of the thread. How does one approach things like this?

    //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();
    }

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

桜花祭 2024-12-16 00:43:55

即使您解决了问题,我也许可以提供一些见解。 XNA 与经典的 Silverlight 渲染有很大不同。

在经典的 Silverlight 渲染管道中,您以声明方式构建可视化树,并将更改推送到它。渲染循环在看不见的地方运行,您很少需要打扰它。

因此,您希望尽快将更改推送到可视化树。如果您在 UI 线程(正在运行的线程)之外的其他线程中更新可视化树,则更新可能会在渲染期间发生,这将是灾难性的。因此,UI 线程公开了一个消息泵,可通过 Dispatcher.BeginInvoke 使用,以确保线程安全。

使用 XNA,您就没有这些...因为您实现了自己的渲染管道,并且可以完全控制它。

每次处理网络摄像头帧时,将其设置在网络摄像头控制器中(使用锁)。在每个 XNA 帧中,如果网络摄像头控制器收到新帧,则获取网络摄像头帧(使用锁)并更新 XNA 纹理(不要为每个帧创建新纹理,这样效率不高)。然后,使用该纹理渲染 3D 对象。

Even if you solved your issue, I can maybe provide some insight. XNA is quite different from classical Silverlight rendering.

In the classical Silverlight rendering pipeline, you declaratively build the visual tree, and push your changes to it. The rendering loop is running out of sight, and you rarely have to mess with it.

Therefore, you want to push your changes to the visual tree as soon as possible. If you update the visual tree in an other thread than the UI thread (the one running), the update could happen during rendering, which would be catastrophic. Therefore the UI thread exposes a message pump, useable through Dispatcher.BeginInvoke, to ensure thread safety.

With XNA, you don't have any of this... Because you implement your own rendering pipeline, and have full control on it.

Each time you process a webcame frame, set it in an your webcam controller (using a lock). In each XNA frame, if the webcam controller received a new frame, get the webcam frame (using the lock) and update a XNA texture (don't create a new texture for each frame, it's NOT efficient). Then, render your 3D object using this texture.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文