Дублирование рабочего стола: вращение кадров для поддержки портретного режима

Я использую d3d11 (дублирование рабочего стола), чтобы захватывать экраны и отправлять их по сети в Windows 8 и выше. Проблема в том, что кадры переворачиваются / поворачиваются, если монитор установлен в портретном режиме и не может правильно отображаться.

После анализа я узнал, что мне пришлось работать со следующими режимами вращения, но я получил только ограниченные ресурсы, связанные с этим,

typedef enum DXGI_MODE_ROTATION { 
  DXGI_MODE_ROTATION_UNSPECIFIED  = 0,
  DXGI_MODE_ROTATION_IDENTITY     = 1,
  DXGI_MODE_ROTATION_ROTATE90     = 2,
  DXGI_MODE_ROTATION_ROTATE180    = 3,
  DXGI_MODE_ROTATION_ROTATE270    = 4
} DXGI_MODE_ROTATION;

Потратив много времени на просмотр ресурсов, я наткнулся на код в webrtc, который вращает захваченный буфер с помощью libyuv.

Вот код, который я получил от Webrtc для вращения буфера захваченного изображения:

Ссылка: desktop_frame_rotation.cc

void RotateDesktopFrame(const DesktopFrame& source,
                        const DesktopRect& source_rect,
                        const Rotation& rotation,
                        const DesktopVector& target_offset,
                        DesktopFrame* target) {
  RTC_DCHECK(target);
  RTC_DCHECK(DesktopRect::MakeSize(source.size()).ContainsRect(source_rect));
  // The rectangle in |target|.
  const DesktopRect target_rect =
      RotateAndOffsetRect(source_rect, source.size(), rotation, target_offset);
  RTC_DCHECK(DesktopRect::MakeSize(target->size()).ContainsRect(target_rect));

  if (target_rect.is_empty()) {
    return;
  }

  int result = libyuv::ARGBRotate(
       source.GetFrameDataAtPos(source_rect.top_left()), source.stride(),
       target->GetFrameDataAtPos(target_rect.top_left()), target->stride(),
       source_rect.width(), source_rect.height(),
       ToLibyuvRotationMode(rotation));
  RTC_DCHECK_EQ(result, 0);
}

} 

Это нормально, но libYuv не поддерживает GPU, и было бы очень медленно вращать экраны, используя мощность процессора.

Также я получил поток stackru, в котором обсуждается поворот кадров через сам DirectX, но он слишком неполный.

Было бы действительно замечательно, если бы кто-то мог помочь мне с этой проблемой.

1 ответ

Решение

Видеопроцессор Microsoft Media Foundation MFT может помочь с ротацией при выполнении работы на GPU, когда это возможно. УвидетьIMFVideoProcessorControl::SetRotation описание метода конкретно.

Если Media Foundation звучит сложно (что на самом деле так и есть), но вы знакомы с Direct3D 11 в целом, вы можете вместо этого использовать Direct3D 11: либо с помощью ротационного видеопроцессора, либо с помощью рендеринга текстуры с соответственно повернутым четырехугольником.

Другие вопросы по тегам