1

最初にビデオをXNAゲームエンジンにマージし、拡張現実コンテンツを追加してから、レンダリングされたコンテンツを別のユーザーにストリーミングするアプリケーションを作成しようとしています。これらはすべて、リアルタイムまたはほぼリアルタイムで発生する必要があります。基本的に、システムは次のようになります。

ビデオ->XNA(ゲーム)->(???)->エクスプレッションエンジン->ライブストリーム->ネットワーク->クライアント

これを行うためのクリーンでエレガントな方法は、XNAのレンダリングされた出力をLiveDeviceSourceとして扱い、それをExpressionEngineストリームジョブに直接フィードすることです。カスタムLiveDeviceSourceまたはこれに類似したものを作成することは可能ですか?基本的に、レンダリングされたXNAバッファーをエンコーダーに直接プッシュできる式エンジンのカスタムソースを作成する方法を誰かが知っていますか?バッファをファイルにダンプし、式エンジンにそれをエンコードさせるのはかなり簡単ですが、ディスクへの書き込みには時間がかかるため、ディスクへの書き込みには待ち時間がかかりすぎるのではないかと心配しています。

別の、迅速で汚いハックは、Expression Engineに出力ウィンドウのスクリーンキャプチャを実行させてから、それをストリーミングさせることです。Expression Engineでスクリーンショットをキャプチャすることはできますが、ライブでストリーミングすることはできません。誰かが両方を同時に行う方法を提案できますか?

私はまだExpressionEngineSDKに精通しているため、この質問が十分に形成されていないことを事前に謝罪します。参考までに、私はXNA 4、MS Expression Engine 4、およびVisual Studio 2010を使用しています。私たちの目標は、最終的にこのテクノロジをGoblinXNAの次のリリースと統合することです。

また、XNAから直接ライブビデオをストリーミングする他の方法についての提案も受け付けています。私たちはExpressionEngineと結婚していません。これは、これまでに出会った中で最高のストリーミングソリューションのようです(ffmpegで問題が発生しています)。

4

1 に答える 1

0

AVStream miindriver を実装して、ライブ ソースとして認識されるドライバーを作成してパイプラインを完成させる必要があります (詳細については、 http://msdn.microsoft.com/en-us/library/ff554228(v=VS . 85).aspx ) 別の解決策は、DirectShowFilter または MFT フィルターを使用して記述することですが、この部門ではあまり役に立ちません。

エクスプレッション エンコーダー sdk を使用しましたが、まだ質問されていることに対する解決策は見つかりませんでした。ただし、イメージ データを Expression Encoder に転送するのは非常に簡単です。1 つの方法は、レンダー ターゲットからバイトを取得し、任意の方法でそれらを式エンコーダーに転送し (WCF がこれに適しています)、ストリーミングに使用するビットマップにデータを再構築することです。

Texture2D (したがって RenderTarget2D) からバイト データを取得し、それらから Bitmap オブジェクトを構築するためのソースを配置しました。

    public static Bitmap ToBitmap(this Microsoft.Xna.Framework.Graphics.Texture2D rd, int Width, int Height)
    {
        var Bmp = new Bitmap(Width, Height, System.Drawing.Imaging.PixelFormat.Format32bppArgb);

        byte[] data = ToBytes(rd);

        var bmpData = Bmp.LockBits(new Rectangle(0, 0, rd.Width, rd.Height), System.Drawing.Imaging.ImageLockMode.WriteOnly, System.Drawing.Imaging.PixelFormat.Format32bppArgb);

        System.Runtime.InteropServices.Marshal.Copy(data, 0, bmpData.Scan0, data.Length);

        Bmp.UnlockBits(bmpData);

        return Bmp;
    }

    public static byte[] ToBytes(this Microsoft.Xna.Framework.Graphics.Texture2D rd, byte[] data = null)
    {
        if (data == null || data.Length != 4 * rd.Height * rd.Width)
            data = new byte[4 * rd.Height * rd.Width];

        rd.GetData<byte>(data);

        SwapBytes(data);

        return data;
    }

    private static void SwapBytes(byte[] data)
    {
        System.Threading.Tasks.ParallelOptions po = new System.Threading.Tasks.ParallelOptions();
        po.MaxDegreeOfParallelism = -1;

        System.Threading.Tasks.Parallel.For(0, data.Length / 4, po, t =>
        {
            int bi = t * 4;
            byte temp = data[bi];
            data[bi] = data[bi + 2];
            data[bi + 2] = temp;
        });
    }

    public static void FromBytes(this Texture2D texture, byte[] bytes)
    {
        SwapBytes(bytes);

        texture.SetData<byte>(bytes);
    }

お役に立てば幸いです。

于 2011-06-15T16:54:03.857 に答える