如何将接收到的 Argb32VideoFrame(或 I420AVideoFrame)从 Webrtc 更改为 Texture2D?

How to change received Argb32VideoFrame(or I420AVideoFrame) from Webrtc to Texture2D?

我在 webrtc 测试中有一个问题。 (客户对客户) 从Direct3D获取的截屏帧是通过webrtc方式传输的

(Sender)
_screenShareSource = ExternalVideoTrackSource.CreateFromArgb32Callback(FrameCallback);

var videoTrackConfig = new LocalVideoTrackInitConfig { trackName = "screen_track" };            
_localVideoTrack = LocalVideoTrack.CreateFromSource(_screenShareSource, videoTrackConfig);

_videoTransceiver = _peerConnection.AddTransceiver(MediaKind.Video);
_videoTransceiver.LocalVideoTrack = _localVideoTrack;
_videoTransceiver.DesiredDirection = Transceiver.Direction.SendReceive;


(Receiver)
_peerConnection.VideoTrackAdded += (RemoteVideoTrack track) =>
{
    _remoteVideoTrack = track;
    **_remoteVideoTrack.Argb32VideoFrameReady += _remoteVideoTrack_Argb32VideoFrameReady;
    // or _remoteVideoTrack.I420AVideoFrameReady += _remoteVideoTrack_I420AVideoFrameReady;**
};

接收帧成功

private void _remoteVideoTrack_Argb32VideoFrameReady(Argb32VideoFrame frame)
{    
    if (frame.width != lastWidthSize ||
        frame.height != lastHeigthSize)
    {
        //newSize = true;
        lastWidthSize = frame.width;
        lastHeigthSize = frame.height;
        swapChain.ResizeBuffers(
            2,
            (int)lastWidthSize,
            (int)lastHeigthSize,
            SharpDX.DXGI.Format.B8G8R8A8_UNorm,
            SharpDX.DXGI.SwapChainFlags.None);
    }

    using (var backBuffer = swapChain.GetBackBuffer<SharpDX.Direct3D11.Texture2D>(0))
        using (var bitmap = Direct3D11Helper.CreateSharpDXTexture2D(UpdateImage(frame)))
    {
        d3dDevice.ImmediateContext.CopyResource(bitmap, backBuffer);
    }
    swapChain.Present(0, SharpDX.DXGI.PresentFlags.None);
}

所以,我想用Direct3D把它显示在屏幕上,但我不知道怎么做。

如何将Argb32VideoFrame(或I420AVideoFrame)改为Texture2D?

或者...有没有办法在当前环境下在屏幕上显示Argb32VideoFrame(或者I420AVideoFrame)?

这是将位图更改为 Texture2D 的方法之一。

    public SharpDX.Direct3D11.Texture2D CreateTexture2DFromBitmap(Argb32VideoFrame frame)
    {
        var width = (int)frame.width;
        var height = (int)frame.height;
        var stride = (int)frame.stride;

        SharpDX.Direct3D11.Texture2DDescription desc = new SharpDX.Direct3D11.Texture2DDescription
        {
            Width = width,
            Height = height,
            ArraySize = 1,
            BindFlags = SharpDX.Direct3D11.BindFlags.ShaderResource,
            Usage = SharpDX.Direct3D11.ResourceUsage.Default,
            CpuAccessFlags = SharpDX.Direct3D11.CpuAccessFlags.None,
            Format = SharpDX.DXGI.Format.B8G8R8A8_UNorm,
            MipLevels = 1,
            OptionFlags = SharpDX.Direct3D11.ResourceOptionFlags.None,
            SampleDescription = new SharpDX.DXGI.SampleDescription { Count = 1, Quality = 0 }
        };

        using (Bitmap bitmap = new Bitmap(width, height, stride, PixelFormat.Format32bppPArgb, frame.data))
        {
            BitmapData bmData = bitmap.LockBits(new System.Drawing.Rectangle(0, 0, bitmap.Width, bitmap.Height), System.Drawing.Imaging.ImageLockMode.ReadWrite, bitmap.PixelFormat);
            SharpDX.DataBox data = new SharpDX.DataBox(bmData.Scan0, bmData.Stride, 0);
            SharpDX.DataRectangle rect = new SharpDX.DataRectangle(data.DataPointer, data.RowPitch);
            SharpDX.Direct3D11.Texture2D _texture = new SharpDX.Direct3D11.Texture2D(d3dDevice, desc, new[] { rect });
            bitmap.UnlockBits(bmData);
            return _texture;
        }
    }