0

我使用 intel qsv 解码视频,并使用 dxva2 进行渲染。代码是intel的owt原生windows sdk:

void WebrtcVideoRendererD3D9Impl::OnFrame(
    const webrtc::VideoFrame& video_frame) {
  // Do we need to Lock the renderframe call? since we have the device lock here
  // it seems no neccessary.
  if (video_frame.video_frame_buffer()->type() ==
      webrtc::VideoFrameBuffer::Type::kNative) {  // We're handling DXVA buffer
    NativeD3DSurfaceHandle* nativeHandle =
        reinterpret_cast<NativeD3DSurfaceHandle*>(
            reinterpret_cast<owt::base::NativeHandleBuffer*>(video_frame.video_frame_buffer().get())->native_handle());

    IDirect3DDeviceManager9* dev_manager = nativeHandle->dev_manager_;
    if(dev_manager == nullptr){
        RTC_LOG(LS_ERROR) << "dev_manager is nullptr";
        return;
    }
    IDirect3DSurface9* surface = nativeHandle->surface_;

    IDirect3DDevice9* pDevice;
    HANDLE hDevice = 0;
    HRESULT hr = dev_manager->OpenDeviceHandle(&hDevice);
    if (FAILED(hr)) {
      RTC_LOG(LS_ERROR) << "Failed to open the d3d device handle";
      return;
    }

    // Our renderer does not need to lock the device.
    hr = dev_manager->LockDevice(hDevice, &pDevice, FALSE);
    if (FAILED(hr)) {
      RTC_LOG(LS_ERROR) << "Failed to lock device";
      dev_manager->CloseDeviceHandle(hDevice);
      return;
    }    
    
    CComPtr<IDirect3DSurface9> back_buffer;
    hr = pDevice->GetBackBuffer(0, 0, D3DBACKBUFFER_TYPE_MONO, &back_buffer);
    if (FAILED(hr)) {
      RTC_LOG(LS_ERROR) << "Failed to get back buffer";
      return;
    }

    D3DSURFACE_DESC desc;
    back_buffer->GetDesc(&desc);
    RTC_LOG(LS_ERROR) << "111111111111 desc width is "<<desc.Width<<",height is "<<desc.Height;
    if (surface != nullptr) {
      hr = pDevice->StretchRect(surface, nullptr, back_buffer, nullptr,
                                D3DTEXF_NONE);
      if (FAILED(hr)) {
        RTC_LOG(LS_ERROR) << "Failed to stretch the rectangle";
        return;
      }
    }

    hr = pDevice->Present(nullptr, nullptr, wnd_, nullptr);

    if (hr == D3DERR_DEVICELOST) {
      RTC_LOG(LS_WARNING) << "Device lost for present.";
    }
    dev_manager->UnlockDevice(hDevice, FALSE);
    dev_manager->CloseDeviceHandle(hDevice);

    // Done with the native handle.
    delete nativeHandle;
    nativeHandle = nullptr;
  } 

在视频图像的大小改变时,结果渲染的图像是不正确的,例如渲染窗口是1920*1080,但是只有左上角,大约1/4的窗口被填充了图像。我猜 StretchRect 没有做任何事情,即使它返回正常。

4

0 回答 0