2

Windows 8以降のオペレーティングシステムで、d3d11(デスクトップ複製)を使用して画面をキャプチャし、ネットワーク経由で送信しています。問題は、モニターが縦向きモードに設定されていて適切にレンダリングできない場合、フレームが反転/回転することです。

分析した結果、次の回転モードを処理する必要があることがわかりましたが、これに関連するリソースは限られていました。

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;

リソースを調べるのに多くの時間を費やした後、libyuv を使用してキャプチャされたバッファをローテーションする webrtc のコードに出くわしました。

キャプチャした画像バッファを回転させるために 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 をサポートしていないため、CPU パワーを使用して画面を回転させると非常に遅くなります。

また、directX自体を介したフレームの回転について議論するstackoverflowスレッドを取得しましたが、それは不完全すぎます。

誰かがこの問題で私を助けてくれれば、本当にありがたいです。

4

1 に答える 1