NVIDIA NVENC媒体基金会编码的 h.264 帧未使用 VideoToolbox 正确解码

问题描述

在 iPad Pro OS v14.3 上尝试解码帧时,我遇到了与 here 所述相同的问题(我也在使用 Olivia Stork's example):

25% 的图片数据被正确解码,图片的其余部分只是绿色。

在 iPad Pro OS v14.3 上解码后的图像看起来像 this(图像被转换并保存在解码器回调中,如 here 所述,所以这不仅仅是一个显示问题)。>

原始图像看起来像 this

图像在 Windows10 上使用 NVIDIA NVENC(媒体基金会)编码。

如链接中所述,我在帧图片数据中搜索了额外的 4 字节 NALU 起始代码,但对于 SPS、PPS 和 IDR 图片数据,只有三个预期的代码。

我有另一个在 Windows10 上运行的 Media Foundation 解码器应用程序,它可以正确解码来自完全相同来源的帧。

我已经挣扎了好几天才找到问题的原因......有人有什么想法吗?

提前致谢。罗布

- 编辑 2021-01-11

我发现在 NALU 类型 5 的 IDR 图片数据块中实际上还有三个额外的 3 字节起始代码 (0x000001)。

我尝试将这些起始代码替换为以下数据块的长度(大端),如 here 所述,但结果相同。

我还尝试添加仿真预防字节 (0x000001 => 0x000301),如here 所述,但这也没有任何区别。

也许我被误导了,这些起始代码与问题无关..至少它们不仅仅是随机图像数据,因为它们总是出现在图片数据块中的相同位置(索引)。目前我的想法不多了..有什么提示吗?

- 编辑 2021-01-14

我想出了更多的事情:

出于完全缺乏想法,我复制了块开头最后一个起始代码之后的图片数据(紧跟在 4 字节 NALU 起始代码之后)。 我原以为——如果这真的可行的话——会在解码图像的顶部看到原始图像的最后四分之一,但令我惊讶的是,解码图像看起来像 this

我对第二个和第三个起始码之后的图片数据进行了同样的尝试,解码后的图像看起来像thisthis: 图像数据被正确解码,甚至在正确的位置(与 original image 相比)。

即使我去掉所有的 3 字节起始码,复制 4 字节起始码后连接的图片数据,结果还是一样,只解码了 25% 的图像。所以额外的 3 字节起始码显然不是问题。某处必须有一些设置告诉解码器只解码图像的 25%。我会提示 CMVideoFormatDescription,但据我所知,它看起来还不错。

我也想知道解码器如何知道在哪里显示不同的图片数据块。要么在图片数据的某处定义了一个偏移量,要么编码器以某种方式添加了每个像素的 xy 位置..

解决方法

我找到了问题的原因:IDE图片数据块中的3-Byte起始码必须用4-Byte起始码代替。

因此首先将所有 3 字节起始代码替换为 4 字节起始代码。 然后将 4 字节起始代码替换为以下数据块的长度(大端)。切片应该这样排列(如 'Blackie' 提到的 here):

[4byte slice1 大小][slice1 数据][4byte slice2 大小][slice2 数据]...[4byte slice4 大小][slice4 数据]

记住不要在切片大小中包含起始代码长度。

更改后,我的框架完全显示了。

顺便说一句: 在每个NALU的头部数据(参数'first_mb_in_slice')中指定了在何处显示不同图片数据块的信息。

有一个很好的c#示例here如何提取NALU头数据。你几乎可以 1:1 复制它。

相关问答

错误1:Request method ‘DELETE‘ not supported 错误还原:...
错误1:启动docker镜像时报错:Error response from daemon:...
错误1:private field ‘xxx‘ is never assigned 按Alt...
报错如下,通过源不能下载,最后警告pip需升级版本 Requirem...