我使用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获得的用于旋转捕获的图像缓冲区的代码:
参考资料: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电源旋转屏幕的速度会很慢。
此外,我还得到了一个stackoverflow线程,它讨论了通过directX本身进行帧旋转的问题,但这太不完整了。
如果有人能帮我解决这个问题,那就太好了。
发布于 2018-03-25 23:23:28
可以在任何可能的情况下在GPU上进行轮转。具体参见IMFVideoProcessorControl::SetRotation方法描述。
如果Media听起来很复杂(确实如此),但是您熟悉Direct3D 11,那么您可以使用Direct3D 11 :要么使用旋转视频处理器,要么用分别旋转的四角体呈现纹理。
https://stackoverflow.com/questions/49259762
复制相似问题