【问题标题】:Decode a single (H264) packet dumped by ffmpeg from a mp4 file解码 ffmpeg 从 mp4 文件转储的单个 (H264) 数据包
【发布时间】:2019-08-25 14:48:13
【问题描述】:

我使用 ffmpeg 从 mp4 中的 h264 视频中转储代表单个帧的数据包

ffmpeg -i video.mp4 -c copy -vframes 1 -map 0:v:0 -f data frame.bin

frame.bin 中的数据似乎很好,并且似乎由与来自mdat 原子的第一个块/数据包(我不确定正确的术语是什么)完全相同的字节组成。

现在我想解码那个帧。由于我知道用于创建该数据包的编解码器 (h264),我想我可以简单地准备一个编解码器上下文,将所有数据加载到一个数据包中,然后使用传统的 avcodec_send_packet(codecContext, packet)avcodec_receive_frame() 组合。

不幸的是,对avcodec_send_packetfails 的调用,我收到以下错误

(-1094995529) Invalid data found when processing input

由于数据包数据的前 4 个字节是数据包本身的大小,因此我尝试在将缓冲区传递给数据包之前跳过这些字节,但这也失败了。

我是跳过了某个步骤还是做错了什么?我想要做的甚至可能吗? (请说是 :)

【问题讨论】:

  • 你必须阅读“AVCC”与“附件 B”。
  • 你的意思是告诉 ffmpeg 读回它从原始文件中提取的同一个数据包是行不通的?
  • 按照您的建议,我找到了stackoverflow.com/a/24890903/1593842,这似乎是一个非常好的解释,还告诉我 ffmpeg 给我的数据在 AVCC 上,但没有“标题”或“额外数据”或“序列阅读器”。所以我假设,没有它,ffmpeg 不知道如何解释数据流。我接近了吗?
  • 它们是 H.264 NALUs 最常见的两种构图方式,AVCC 也将 SPS/PPS NALUs 置于“out-of-line”,在 FFmpeg 中这称为“extradata”。你大体上是正确的。
  • 愿意将此作为答案发布以便我接受吗?你几乎给了我所有需要的信息。

标签: c ffmpeg h.264 libavcodec


【解决方案1】:

ITU-T 建议书。 H.264 和附件 B

推荐 H.264 是由国际电信联盟T电信标准化部门 (ITU-T) 定义的视频编解码器标准。 免费can be downloaded from their website

标准定义了一种字节流格式,其最低抽象层是NALU(网络层抽象单元)。

可以存在 32 种类型的 NALU,但大约有 11 种被保留或未使用。有些携带视频切片数据,有些则不携带。 两种 NALU 类型将在本次讨论的后面很重要:SPS(序列参数集)和 PPS(图片参数集)。两者都需要解码视频片段,并提供有关流的重要信息,例如其大小和原始数据的解释。

H.264 未定义这些 NALU 是如何传输和成帧的。但是,它确实在标准自己的附录 B 中描述了一种可能的方案。由于没有更好的名称,该方案通常称为 附录 B

该方案包括在 NALU 前加上一个不能在 NALU 中出现的易于同步的起始代码:3 或 4 字节模式 00 00 0100 00 00 01。然后是 NALU 的其余部分。这种方案在硬件和/或流媒体情况下很流行,因为它允许轻松获取位锁定和字节对齐,定期发送 SPS/PPS“带内”,因此允许在随机点调谐到流开始解码,并且具有有趣的特性,即在 NALU 之间可以有效地发送任意数量的 0 位或字节。

ISO/IEC 14496 MPEG-4 和 AVCC

MPEG-4 是由国际标准组织 (ISO) 和国际电工委员会 (IEC) 组成的名为“运动图像专家组”的联合小组制定的音频-视频编码和存储标准的多个“部分”系列 ( MPEG)。只有 MPEG-4 系列的几个部分是相关的:

  • MPEG-4 第 10 部分/高级视频编码 (AVC),技术上与 ITU-T H.264 相同。 免费
  • MPEG-4 第 12 部分,ISO 基本媒体文件格式 (BMFF),定义了一种可以专门化的通用二进制容器文件格式。 免费
  • MPEG-4 Part 14 (MP4),它专门针对视频的第 12 部分,并定义了 .mp4 文件扩展名和格式。这部分非常非常昂贵(88 瑞士法郎)并且不向公众提供。
  • MPEG-4 Part 15,它定义了 NALU 结构化视频数据(例如 Part 10/H.264 视频)如何存储在 Part 12 ISO BMFF 中。这部分极其昂贵(198瑞士法郎),并且不向公众提供,但它,第14、12和10部分是常用@的基础987654326@ 包含 H.264 编码视频的容器。

AVCC

不幸的是,第 15 部分也是定义 NALU 框架的新方案的部分。该方案提出将所有 SPS/PPS NALU 提取到称为 AVCC 的“带外”结构中,并且还剥离和替换 NALU 前面的起始代码前缀(几乎总是) 4 字节数字,表示以下 NALU 的大小,以字节为单位。

此方案适用于通过视频数据进行快速和随机搜索,通过将所有视频解码器配置数据 (SPS/PPS) 收集到一个标准化位置,可以在开始时配置视频解码器一次,之后无需担心关于意外的惊喜,例如视频帧大小的动态变化(附件 B 允许)。

幸运的是,关于 AVCC 结构的提示在线存在,在 AVCC 和附件 B 之间转换的代码也是如此。

您的需求

你好像需要AVCC -> Annex B转换。这可以通过 FFmpeg 的比特流过滤器来完成,h264_mp4toannexb:

ffmpeg -i INPUT.mp4 -codec copy -bsf:v h264_mp4toannexb OUTPUT.ts

【讨论】:

  • 谢谢。在我谷歌搜索期间,我意识到了那个 ffmpeg 过滤器。虽然那个过滤器不是我需要的(我实际上正在使用一个丢失 moov 原子的截断 mp4),但你基本上教会了我,当 SPS/PPS数据存储在其他地方(即AVCC) 我将不得不找出一种方法来生成它并将其传递给编解码器。我使用的代码过去一直有效,但这只是因为我很幸运,并且向它提供了一个流,其中配置数据正好位于视频数据 NALU 之前(即,附件 B)。跨度>
猜你喜欢
  • 1970-01-01
  • 2012-03-07
  • 2011-11-24
  • 1970-01-01
  • 2016-06-16
  • 1970-01-01
  • 2013-01-10
  • 2012-07-05
  • 2019-12-15
相关资源
最近更新 更多