开发者

How to get a series of images from the ui thread into the draw thread in Silverlight 5 using XNA

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

            }开发者_如何学Go);
        }

        Draw(frames);

        e.InvalidateSurface();
    }


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.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜