【问题标题】:Render h264 video frames in directx 11在directx 11中渲染h264视频帧
【发布时间】:2015-10-15 22:23:58
【问题描述】:

我是DirectX 的新手。我正在尝试编写一个自定义 IP 摄像机视频播放器,为此我使用 DirectX11 以 Wpf Gui 作为我的前端来渲染解码图像。

我是一个 c# 开发人员,并且使用过托管的 directx,它不再由 microsoft 更新,因此移至 wpf 和 directx11。

我的应用程序的所有部分直到帧的渲染都工作正常。

我已经设法创建了一个将在 Wpf 应用程序中使用的 D3DImage 源,成功创建了我的视口和我的设备,包括我的共享资源,因为 D3DImage 仅适用于 Directx9。我使用SharpDX 作为DirectX API 的包装器。

现在我的问题是我似乎无法找到一种方法来从解码的图像字节创建纹理/更新纹理,或者为了从接收到的字节渲染解码的图像,这样做的正确方法是什么。

这方面的任何帮助都会很棒,或者如果有人可以指导我如何处理这个问题的正确方向?

谢谢。

【问题讨论】:

    标签: c# wpf video-streaming directx directx-11


    【解决方案1】:

    经过近 2 周的搜索并试图找到我所说的问题的解决方案,我终于找到了如下。

    但是,这确实显示了图像,但并不像预期的那样,但我相信这对我来说是一个开始,因为下面的代码回答了我最初提出的问题。

    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
                dtStream.Position = iHeightIndex * iRowPitch;
                 Marshal.Copy(decodedData, iHeightIndex * iWidth * 4, new IntPtr(dtStream.DataPointer.ToInt64() + iHeightIndex * iRowPitch), iWidth * 4);
            }
        }
    
        Device.ImmediateContext.UnmapSubresource(newFrameTexture, 0);
    
    
        Device.ImmediateContext.CopySubresourceRegion(newFrameTexture, 0, null, this.RenderTarget, 0);
        var shaderRescVw = new ShaderResourceView(this.Device, this.RenderTarget);
    
        Device.ImmediateContext.PixelShader.SetShaderResource(0, shaderRescVw);
    
        Device.ImmediateContext.Draw(6, 0);
        Device.ImmediateContext.Flush();
        this.D3DSurface.InvalidateD3DImage();
    
        Disposer.SafeDispose(ref newFrameTexture);
    

    使用上面的代码,我现在可以使用我收到的新图像数据填充纹理,但图像没有以正确的颜色/像素渲染,如下图红色框中所示。

    渲染图像的屏幕截图:

    图像字节通过解码器以 BGRA32 像素格式接收。 任何解决此问题的建议都会非常有帮助。

    【讨论】:

    • 我也终于修复了图像问题。首先,原始纹理没有使用正确的尺寸进行初始化。其次,为了正确渲染图像,我必须确保考虑到每个像素的字节数。因为我的像素格式是 bgra32,这意味着每个像素 4 个字节。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-09-08
    • 1970-01-01
    • 2018-03-18
    • 2019-04-16
    • 2020-11-20
    • 1970-01-01
    相关资源
    最近更新 更多