我将从我想象如何使用我想创建的代码开始。它不必完全像这样,但它是我在标题中所说的“简洁”的一个很好的例子。就我而言,它是将类型映射到相关枚举值。
struct bar : foo<bar, foo_type::bar> { /* ... */ };
// \_/ \___________/
// ^ Type ^ Value
Run Code Online (Sandbox Code Playgroud)
理想情况下,这应该做的是自动注册foo一个类型的第一个模板参数和第二个值之间的双向映射,只需使用继承语法和正确的模板参数,以便我稍后可以执行下面示例中的操作.
foo_type value = to_value<bar>; // Should be foo_type::bar
using type = to_type<foo_type::bar>; // Should be bar
Run Code Online (Sandbox Code Playgroud)
我知道我可以为每个类型值对手动编写两个模板特化来做到这一点,但我想知道它是否会比不使用宏更乏味。
我已经尝试过的是......
struct foo_base
{
template<typename T>
struct to_value
{};
template<foo_type E>
struct to_type
{};
};
template<typename T, foo_type E>
struct foo : public foo_base
{
template<>
struct to_value<T>
{
static constexpr auto value = E; …Run Code Online (Sandbox Code Playgroud) 我正在使用Media Foundation的Source Reader编写硬件加速的h264解码器,但遇到了问题.我按照本教程使用Windows SDK Media Foundation示例支持自己.
当硬件加速关闭时,我的应用似乎工作正常,但它不提供我需要的性能.当我通过传递一个用来创建阅读器IMFDXGIDeviceManager来加速加速时IMFAttributes,事情就变得复杂了.
如果我创建ID3D11Device使用D3D_DRIVER_TYPE_NULL驱动程序,应用程序工作正常,帧处理速度比在软件模式下更快,但从CPU和GPU使用情况来看,它仍然在CPU上进行大部分处理.
另一方面,当我创建ID3D11Device使用D3D_DRIVER_TYPE_HARDWARE驱动程序并运行应用程序时,可能会发生以下四种情况之一.
在IMFMediaBuffer::Lock函数返回0x887a0005 之前,我只得到一个不可预测的帧数(通常为1-3),这被描述为"GPU设备实例已被暂停.GetDeviceRemovedReason用于确定适当的操作".当我打电话时ID3D11Device::GetDeviceRemovedReason,我得到0x887a0020,这被描述为"驱动程序遇到问题,并被置于设备移除状态",这没有我希望的那样有用.
应用程序在外部dll中随时崩溃IMFMediaBuffer::Lock.似乎dll取决于所使用的GPU.对于Intel集成GPU,它是igd10iumd32.dll,对于Nvidia移动GPU,它是mfplat.dll.此特定崩溃的消息如下:"在decoder_ tester.exe中0x53C6DB8C(mfplat.dll)抛出异常:0xC0000005:访问冲突读取位置0x00000024".执行之间的地址不同,有时涉及阅读,有时甚至是写作.
图形驱动程序停止响应,系统暂停一小段时间,然后应用程序崩溃,如第2点或完成第1点.
该应用程序工作正常,并通过硬件加速处理所有帧.
大部分时间是1或2,很少3或4.
以下是我的机器上不同模式下处理时不受限制的CPU/GPU使用情况(英特尔酷睿i5-6500与HD Graphics 530,Windows 10 Pro).
我在三台机器上测试了应用程序.他们都拥有英特尔集成GPU(HD 4400,HD 4600,HD 530).其中一个还有可切换的Nvidia专用GPU(GF 840M).它在所有这些方面完全相同,唯一的区别是当使用Nvidia的GPU时它会在不同的dll中崩溃.
我以前没有使用COM或DirectX的经验,但所有这些都是不一致和不可预测的,所以它看起来像是一个内存损坏我.不过,我不知道我在哪里弄错了.你能帮我找一下我做错的事吗?
我能想出的最小代码示例如下.我正在使用Visual Studio Professional 2015将其编译为C++项目.我准备了定义以启用硬件加速并选择硬件驱动程序.评论它们以改变行为.此外,代码期望此视频文件存在于项目目录中.
#include <iostream>
#include <string>
#include <atlbase.h>
#include <d3d11.h>
#include <mfapi.h>
#include <mfidl.h>
#include <mfreadwrite.h>
#include <windows.h> …Run Code Online (Sandbox Code Playgroud) 考虑以下代码。
#include <array>
#include <span>
std::array<int, 2> Foo()
{
return {1, 2};
}
int main()
{
std::array a = {3, 4};
std::span s1 = a;
// std::span s2 = Foo(); // Nope
// std::span s3 = std::move(a); // Nope
// std::span s4 = std::array<int, 2>{5, 6}; // Nope
// MSVC 19.29: 'initializing': cannot convert from 'std::array<int,2>' to 'std::span<int,18446744073709551615>'
// GCC 12.0.0: conversion from 'std::array<int, 2>' to non-scalar type 'std::span<int, 18446744073709551615>' requested
// clang 13.0.0: actually compiles!
}
Run Code Online (Sandbox Code Playgroud)
似乎只有在 clang 上它是右值时 …