我正在使用 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 获得的用于旋转捕获的图像缓冲区的代码:
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 能力旋转屏幕会很慢。
我也得到了一个stackoverflow线程,讨论了通过directX本身的帧旋转,但这太不完整了。
如果有人可以帮助我解决这个问题,那将是非常可观的。