媒体基础:ReadSample - 访问冲突异常
Media Foundation: ReadSample - Access Violation Exception
上下文: 我正在查看向下采样,然后向上采样视频文件的效果。我正在使用 Media Foundation .NET 在 C# 中公开 MF。程序当前经历以下过程:
- 拍摄高分辨率视频并读取每一帧(SourceReader 和 ReadSample)
- 使用在字节级别操作的自定义代码向下采样
- 将下采样数据写入一个新的、分辨率较低的视频文件(使用 SinkWriter)
- 针对 Media Foundation 支持的一系列分辨率重复此操作
- 向下读取采样视频并向上读取下一个更高分辨率的样本,再次使用处理每个字节的自定义代码
- 将新数据写入更高分辨率的文件(再次使用 SinkWriter)
我使用的分辨率是:
- 2560,1440
- 2346,1320
- 2134,1200
- 1920,1080
- 1706,960
- 1494,840
- 1280,720
- 1068,600
- 854,480
- 640,360
- 428,240
- 214,120
当前情况: 这几乎 完美。我 运行 通过下采样过程并有 11 个下采样视频文件(上面列表中每个分辨率各一个),加上原始 1440p 视频。然后我阅读了这 11 个视频中的每一个和样本。它适用于其中的 10 个。
问题: 当我尝试将 (1280,720) 视频采样到 (1494,840) 时,我得到:
System.AccessViolationException: 'Attempted to read or write protected memory. This is often an indication that other memory is corrupt.'
...当我尝试阅读第一帧时。我不知道为什么。 SourceReader 配置良好(至少没有错误 returns)。我做了 Marshal.Copy 之类的事情,将采样的帧数据放入托管内存 space,我最初认为这是问题所在。不过,代码并没有走那么远——只是在我尝试读取第一帧样本时出现错误。 ReadSample 在 Try...Catch 块中,但异常仍未处理,因此没有返回其他错误信息。
我不想开始粘贴无用的代码,所以请让我知道有什么用,我会添加到问题中。大部分代码取自 SourceReader 和 SinkWriter 的 MS 教程。同样值得记住的是,这在大多数情况下都有效,因此代码不是 'broken'。
我试过在 Release 和 Debug、x86 和 x64 中编译。还尝试在 Visual Studio 选项中抑制 JIT 优化。
对接下来要看的地方有什么想法吗?
原来这是 Media Foundation .NET 接口的问题,而不是底层 MF 框架的问题。我用 C++ 构建了一个小型测试程序,它实现了代码的关键部分并且运行良好。
不确定为什么 Media Foundation .NET 会导致问题,但解决方案只是设置属性:
MF_SOURCE_READER_ENABLE_ADVANCED_VIDEO_PROCESSING
而不是
MF_SOURCE_READER_ENABLE_VIDEO_PROCESSING
启用高级处理后,它会正常运行。
上下文: 我正在查看向下采样,然后向上采样视频文件的效果。我正在使用 Media Foundation .NET 在 C# 中公开 MF。程序当前经历以下过程:
- 拍摄高分辨率视频并读取每一帧(SourceReader 和 ReadSample)
- 使用在字节级别操作的自定义代码向下采样
- 将下采样数据写入一个新的、分辨率较低的视频文件(使用 SinkWriter)
- 针对 Media Foundation 支持的一系列分辨率重复此操作
- 向下读取采样视频并向上读取下一个更高分辨率的样本,再次使用处理每个字节的自定义代码
- 将新数据写入更高分辨率的文件(再次使用 SinkWriter)
我使用的分辨率是:
- 2560,1440
- 2346,1320
- 2134,1200
- 1920,1080
- 1706,960
- 1494,840
- 1280,720
- 1068,600
- 854,480
- 640,360
- 428,240
- 214,120
当前情况: 这几乎 完美。我 运行 通过下采样过程并有 11 个下采样视频文件(上面列表中每个分辨率各一个),加上原始 1440p 视频。然后我阅读了这 11 个视频中的每一个和样本。它适用于其中的 10 个。
问题: 当我尝试将 (1280,720) 视频采样到 (1494,840) 时,我得到:
System.AccessViolationException: 'Attempted to read or write protected memory. This is often an indication that other memory is corrupt.'
...当我尝试阅读第一帧时。我不知道为什么。 SourceReader 配置良好(至少没有错误 returns)。我做了 Marshal.Copy 之类的事情,将采样的帧数据放入托管内存 space,我最初认为这是问题所在。不过,代码并没有走那么远——只是在我尝试读取第一帧样本时出现错误。 ReadSample 在 Try...Catch 块中,但异常仍未处理,因此没有返回其他错误信息。
我不想开始粘贴无用的代码,所以请让我知道有什么用,我会添加到问题中。大部分代码取自 SourceReader 和 SinkWriter 的 MS 教程。同样值得记住的是,这在大多数情况下都有效,因此代码不是 'broken'。
我试过在 Release 和 Debug、x86 和 x64 中编译。还尝试在 Visual Studio 选项中抑制 JIT 优化。
对接下来要看的地方有什么想法吗?
原来这是 Media Foundation .NET 接口的问题,而不是底层 MF 框架的问题。我用 C++ 构建了一个小型测试程序,它实现了代码的关键部分并且运行良好。
不确定为什么 Media Foundation .NET 会导致问题,但解决方案只是设置属性: MF_SOURCE_READER_ENABLE_ADVANCED_VIDEO_PROCESSING 而不是 MF_SOURCE_READER_ENABLE_VIDEO_PROCESSING
启用高级处理后,它会正常运行。