0

D3DImage コントロールを介して DirectX 11 および WPF の SharpDx を介して BGRA32 ピクセル形式にデコードされる IP カメラから H264 ビデオ フレームをレンダリングしています。

多くの調査とさまざまなサンプルと例の調査の後、最終的にDirectX 11 で H264 フレームをレンダリングすることができました。

私の現在のセットアップには、以下のように頂点シェーダーとピクセル シェーダーをセットアップすることが含まれます。

var device = this.Device;
var context = device.ImmediateContext;

// Compile Vertex and Pixel shaders
vertexShaderByteCode = ShaderBytecode.CompileFromFile("TriangleShader.fx", "VSMain", "vs_5_0", ShaderFlags.Debug, EffectFlags.None);
vertexShader = new VertexShader(device, vertexShaderByteCode);
pixelShaderByteCode = ShaderBytecode.CompileFromFile("TriangleShader.fx", "PSMain", "ps_5_0", ShaderFlags.Debug, EffectFlags.None);
pixelShader = new PixelShader(device, pixelShaderByteCode);

// Layout from VertexShader input signature
// An input layout is the layout of the data containing the location and properties of a vertex. It would be a format of data that you can modify and set according
layout = new InputLayout(device, ShaderSignature.GetInputSignature(vertexShaderByteCode), new[] {
          new InputElement("SV_Position", 0, Format.R32G32B32A32_Float, 0, 0),
          new InputElement("COLOR", 0, Format.R32G32_Float, 16, 0),
          new InputElement("TEXCOORD", 0, Format.R32G32_Float, 32, 0),
        });

// Write vertex data to a datastream
var stream = new DataStream(Utilities.SizeOf<Vertex>() * 6, true, true);

int iWidth = (int)this.ActualWidth;
int iHeight = (int)this.ActualHeight;

float top = iWidth / 2;
float bottom = iHeight / 2;

stream.WriteRange(new[]
                             {
   new Vertex(
               new Vector4(-top, bottom, 0.5f, 0.0f), // position top-center
               new Color4(0.0f, 0.0f, 0.0f, 0.0f), // color top-center (r,g,b,alpha)
               new Vector2(0f,0f)),
    new Vertex(
               new Vector4(top, bottom, 0.5f, 0.0f), // position top-right
               new Color4(0.0f, 0.0f, 0.0f, 0.0f), // color top-right (r,g,b,alpha)
               new Vector2(iWidth,iHeight)),
    new Vertex(
               new Vector4(-top, -bottom, 0.5f, 0.0f), // position bottom-left
               new Color4(0.0f, 0.0f, 0.0f, 0.0f), // color bottom-left (r,g,b,alpha)
               new Vector2(iWidth,iHeight)),
    new Vertex( 
                new Vector4(-top, -bottom, 0.5f, 0.0f), // position bottom-right
                new Color4(0.0f, 0.0f, 0.0f, 0.0f), // color bottom-left (r,g,b,alpha)
                new Vector2(iWidth,0f)),
        new Vertex(
                new Vector4(top, -bottom, 0.5f, 0.0f), // position bottom-right
                new Color4(0.0f, 0.0f, 0.0f, 0.0f), // color bottom-right (r,g,b,alpha)
                new Vector2(iWidth,iHeight)),
        new Vertex(
                new Vector4(top, bottom, 0.5f, 0.0f), // position top-right
                new Color4(0.0f, 0.0f, 0.0f, 0.0f), // color top-right (r,g,b,alpha)
                new Vector2(0f, iHeight)),
        });

        stream.Position = 0;

        // Instantiate Vertex buiffer from vertex data
        // 
        vertices = new SharpDX.Direct3D11.Buffer(device, stream, new BufferDescription()
        {
            BindFlags = BindFlags.VertexBuffer,
            CpuAccessFlags = CpuAccessFlags.None,
            OptionFlags = ResourceOptionFlags.None,
            SizeInBytes = Utilities.SizeOf<Vertex>() * 6,
            Usage = ResourceUsage.Default,
            StructureByteStride = 0
        });
        stream.Dispose();

        // Prepare All the stages
        context.InputAssembler.InputLayout = (layout);
        context.InputAssembler.PrimitiveTopology = (PrimitiveTopology.TriangleStrip);
        context.InputAssembler.SetVertexBuffers(0, new VertexBufferBinding(vertices, Utilities.SizeOf<Vertex>(), 0));
        context.VertexShader.Set(vertexShader);
        context.PixelShader.Set(pixelShader);
        context.OutputMerger.SetTargets(m_RenderTargetView);

新しいフレームを受け取るたびに、次のようにリソースをマッピングして RenderTexture を更新します。

device.ImmediateContext.ClearRenderTargetView(this.m_RenderTargetView, Color4.Black);

        Texture2DDescription colordesc = new Texture2DDescription
        {
            BindFlags = BindFlags.ShaderResource,
            Format = m_PixelFormat,
            Width = iWidth,
            Height = iHeight,
            MipLevels = 1,
            SampleDescription = new SampleDescription(1, 0),
            Usage = ResourceUsage.Dynamic,
            OptionFlags = ResourceOptionFlags.None,
            CpuAccessFlags = CpuAccessFlags.Write,
            ArraySize = 1
        };

        Texture2D newFrameTexture = new Texture2D(this.Device, colordesc);

        DataStream dtStream = null;
        DataBox dBox = Device.ImmediateContext.MapSubresource(newFrameTexture, 0, MapMode.WriteDiscard, 0, out dtStream);
        if (dtStream != null)
        {
            int iRowPitch = dBox.RowPitch;

            for (int iHeightIndex = 0; iHeightIndex < iHeight; iHeightIndex++)
            {
                //Copy the image bytes to Texture
                // we write row strides multiplies by bytes per pixel
                // as our case is bgra32 which is 4 bytes 
                dtStream.Position = iHeightIndex * iRowPitch;
                Marshal.Copy(decodedData, iHeightIndex * iWidth * 4, new IntPtr(dtStream.DataPointer.ToInt64() + iHeightIndex * iRowPitch), iWidth * 4);
            }
        }

        Device.ImmediateContext.UnmapSubresource(newFrameTexture, 0);

        Texture2D srcTexture = m_RenderTargetView.ResourceAs<Texture2D>();
        Device.ImmediateContext.CopySubresourceRegion(newFrameTexture, 0, null, this.RenderTarget, 0);

        Device.ImmediateContext.Draw(6, 0);
        Device.ImmediateContext.Flush();
        this.D3DSurface.InvalidateD3DImage();

        Disposer.SafeDispose(ref newFrameTexture);

私の効果/HLSL ファイル:

Texture2D ShaderTexture : register(t0);
SamplerState Sampler : register(s0);

cbuffer PerObject: register(b0)
{
    float4x4 WorldViewProj;
};
struct VertexShaderInput
{
    float4 Position : SV_Position;
    float4 Color : COLOR;
    float2 TextureUV : TEXCOORD0;
};
struct VertexShaderOutput
{
    float4 Position : SV_Position;
    float4 Color : COLOR;
    float2 TextureUV : TEXCOORD0;
};

VertexShaderOutput VSMain(VertexShaderInput input)
{
    VertexShaderOutput output = (VertexShaderOutput)0;

output.Position = mul(input.Position, WorldViewProj);
output.Color = mul(input.Color, WorldViewProj);
output.TextureUV = input.TextureUV;

return output;
}

float4 PSMain(VertexShaderOutput input) : SV_Target
{
    return ShaderTexture.Sample(Sampler, input.TextureUV).rgb;
}

画像は正しくレンダリングされますが、親色の背景色が黒以外の場合、不透明に見えます。

今、テクスチャを透明にレンダリングしているここで何が起こっているのか正確に理解できないようです。

以下に示すように、親グリッド コントロールの背景がコアラの写真の場合も、レンダリングを試みました。 ここに画像の説明を入力

この問題で何か助けていただければ幸いです。

4

0 に答える 0