简体   繁体   English

解码由 ffmpeg 从 mp4 文件转储的单个 (H264) 数据包

[英]Decode a single (H264) packet dumped by ffmpeg from a mp4 file

I used ffmpeg to dump a packet representing a single frame from an h264 video inside a mp4我使用 ffmpeg 从 mp4 中的 h264 视频转储表示单个帧的数据包

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

The data inside frame.bin seems to be fine and seems to be composed of exactly the same bytes as the first chunk/packet (I'm not sure what is the correct term) from the mdat atom. frame.bin的数据似乎很好,并且似乎由与mdat原子中的第一个块/数据包(我不确定正确的术语是什么)完全相同的字节组成。

Now I want to decode that frame.现在我想解码那个帧。 Since I know the codec that was used to create that packet (h264), I thought I could simply prepare a codec context, load all that data into a packet and the use traditional avcodec_send_packet(codecContext, packet) followed by avcodec_receive_frame() combo.由于我知道用于创建该数据包 (h264) 的编解码器,我想我可以简单地准备一个编解码器上下文,将所有数据加载到一个数据包中,然后使用传统的avcodec_send_packet(codecContext, packet)avcodec_receive_frame()组合。

Unfortunately the call to avcodec_send_packet fails and I receive the following error不幸的是,对avcodec_send_packet的调用失败,我收到以下错误

(-1094995529) Invalid data found when processing input

Since the first 4 bytes of the packet data is the size of the packet itself, I tried skipping those bytes before passing the buffer to the packet, but that also failed.由于数据包数据的前 4 个字节是数据包本身的大小,我尝试在将缓冲区传递给数据包之前跳过这些字节,但也失败了。

Am I skipping some step or doing something wrong?我是跳过了某个步骤还是做错了什么? Is what I am trying to do even possible?我正在尝试做的甚至可能吗? (please say yes :) (请说是:)

ITU-T Rec. ITU-T 建议书H.264 & Annex B H.264 & 附件 B

Recommendation H.264 is a video codec standard defined by the International Telecommunication Union, T elecommunications Standardization Sector (ITU- T ).建议H.264是国际电信联盟,T elecommunications标准化部门(ITU-T)定义的视频编解码标准。 It is available free of charge and can be downloaded from their website .它是免费提供的可以从他们的网站上下载

The standard defines a bytestream format, whose lowest level of abstraction is the NALU (Network Layer Abstraction Unit).该标准定义了一种字节流格式,其最低抽象级别是 NALU(网络层抽象单元)。

32 types of NALUs can exist, although about 11 are reserved or unused.可以存在 32 种类型的 NALU,尽管大约有 11 种是保留或未使用的。 Some carry video slice data, some don't.有些携带视频切片数据,有些不携带。 Two NALU types will be important later in this discussion: SPS (Sequence Parameter Set) and PPS (Picture Parameter Set).两种 NALU 类型将在本讨论的后面很重要:SPS(序列参数集)和 PPS(图片参数集)。 Both are required to decode a video slice, and provide important information about the stream, such as its size and interpretation of the raw data.两者都需要解码视频切片,并提供有关流的重要信息,例如其大小和原始数据的解释。

H.264 leaves undefined how these NALUs are transported and framed. H.264 未定义这些 NALU 如何传输和构建。 However, it does describe one possible scheme, in the Standard's own Annex B. This scheme, for want of a better name, is generally referred to as Annex B .但是,它在标准自己的附录 B 中确实描述了一种可能的方案。由于需要更好的名称,该方案通常称为附录 B。

The scheme consists in prefixing the NALUs with an easy-to-synchronize-to start code that cannot occur within a NALU: A 3- or 4-byte pattern 00 00 01 or 00 00 00 01 .该方案包括在 NALU 前面加上一个易于同步的起始代码,该代码不能出现在 NALU 中:3 或 4 字节模式00 00 0100 00 00 01 The rest of the NALU then follows.其余的 NALU 紧随其后。 This scheme is popular in hardware and/or streaming situations because it allows acquiring bit-lock and byte-alignment easily, sends the SPS/PPS “in-band” periodically and thus allows one to tune into the stream at a random point to begin decoding, and has the interesting property that between NALUs one can validly send an arbitrary number of 0 bits or bytes.这种方案在硬件和/或流媒体情况下很流行,因为它允许轻松获取位锁定和字节对齐,定期“带内”发送 SPS/PPS,从而允许在随机点开始调谐到流中解码,并具有有趣的特性,即在 NALU 之间可以有效地发送任意数量的 0 位或字节。

ISO/IEC 14496 MPEG-4 & AVCC ISO/IEC 14496 MPEG-4 & AVCC

MPEG-4 is a family in multiple “parts” of standards for Audio-Video coding and storage made by a joint group of the International Standards Organization (ISO) and International Electrotechnical Commission (IEC) called the Moving Pictures Expert Group (MPEG). MPEG-4 是由国际标准组织 (ISO) 和国际电工委员会 (IEC) 的一个联合小组制定的音频-视频编码和存储标准的多个“部分”系列,称为运动图像专家组 (MPEG)。 A few parts only of the MPEG-4 family are relevant:只有 MPEG-4 系列的几个部分是相关的:

  • MPEG-4 Part 10 / Advanced Video Coding (AVC), technically identical to ITU-T H.264. MPEG-4 Part 10 / 高级视频编码 (AVC),技术上与 ITU-T H.264 相同。 Free of charge .免费
  • MPEG-4 Part 12, ISO Base Media File Format (BMFF), defines a generic binary container file format that can be specialized. MPEG-4 第 12 部分,ISO 基本媒体文件格式 (BMFF),定义了可以专门化的通用二进制容器文件格式。 Free of charge .免费
  • MPEG-4 Part 14 (MP4), which specializes Part 12 for video in general and defines the .mp4 file extension and format. MPEG-4 Part 14 (MP4),专门针对一般视频的第 12 部分,并定义了.mp4文件扩展名和格式。 This part is very expensive ( 88 Swiss francs ) and not available to the public.这部分非常昂贵( 88 瑞士法郎)并且不向公众开放。
  • MPEG-4 Part 15, which defines how NALU-structured video data such as Part 10/H.264 video is stored in the Part 12 ISO BMFF. MPEG-4 Part 15,它定义了 NALU 结构的视频数据(如 Part 10/H.264 视频)如何存储在 Part 12 ISO BMFF 中。 This part is extremely expensive ( 198 Swiss francs ), and not available to the public, but it, Part 14, 12 and 10 are the basis of the commonly-used .mp4 container with H.264-coded video.这部分非常昂贵( 198 瑞士法郎),并且不向公众开放,但它,第 14、12 和 10 部分是常用的带有 H.264 编码视频的.mp4容器的基础。

AVCC AVCC

Unfortunately, Part 15 is also the part that defines a new scheme for framing of NALUs.不幸的是,第 15 部分也是定义 NALU 框架的新方案的部分。 This scheme proposes to extract all SPS/PPS NALUs into an “out-of-band” structure called AVCC , and also strips and replaces the start code prefixes in front of NALUs by an (almost-always) 4-byte number representing the size, in bytes, of the following NALU.该方案提出将所有 SPS/PPS NALU 提取到一个称为AVCC 的“带外”结构中,并且还将 NALU 前面的起始代码前缀剥离并替换为一个(几乎总是)表示大小的 4 字节数字,以字节为单位,以下 NALU。

This scheme is popular for fast- and random-seeking through video data, and by gathering all video decoder configuration data (SPS/PPS) in one standardized place, one can configure the video decoder once at the beginning and thereafter not worry about unexpected surprises like a dynamic change in the size of the video frame (which Annex B allows).该方案流行于快速随机搜索视频数据,通过将所有视频解码器配置数据(SPS/PPS)收集在一个标准化的地方,一开始就可以配置视频解码器,然后不用担心意外的惊喜就像视频帧大小的动态变化(附件 B 允许)。

Fortunately, hints about AVCC's structure exist online, as does code to translate between AVCC and Annex B.幸运的是,网上有关于 AVCC 结构的提示,在 AVCC 和 Annex B 之间转换的代码也是如此。

Your needs您的需求

You seem to need AVCC -> Annex B conversion.您似乎需要 AVCC -> Annex B 转换。 This can be done with FFmpeg's bitstream filter, h264_mp4toannexb :这可以通过 FFmpeg 的比特流过滤器h264_mp4toannexb来完成:

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 AVI,MP4和“原始” h264流中的h264。 不同格式的NAL单元(或ffmpeg错误) - h264 inside AVI, MP4 and “Raw” h264 streams. Different format of NAL units (or ffmpeg bug) 如何使用 libAV 库 (ffmpeg) 将 H264 编码数据放入类似 .mp4 的容器中? - How to put H264 encoded data, inside a container like .mp4 using libAV libraries (ffmpeg)? 如何将MP4(h264 / aac)文件转换为HDS的F4F片段(Adobe) - How to convert MP4 (h264/aac) file to F4F fragments for HDS (Adobe) FFmpeg H264解析 - FFmpeg H264 parsing 使用C / C ++中的ffmpeg库从CCTV(HW)编码器将H.264多路复用到MP4,如何获取AVCodecContext :: extradata - H.264 muxing to MP4 from CCTV (HW) encoder using ffmpeg library in C / C++, how to fetch AVCodecContext::extradata 使用FFmpeg h264解码器与android - Using FFmpeg h264 decoder with android Linux Mint LMDE ffmpeg h264 - Linux Mint LMDE ffmpeg h264 使用ffmpeg进行H264解码 - H264 decoding using ffmpeg 如何使用ffmpeg API将h.264的原始PCM混合到MP4? - How to mux raw PCM with h.264 to MP4 with ffmpeg API? libavcodec:如何使用可控制的帧速率和比特率(通过C代码)使用h264编解码器,mp4容器进行编码 - libavcodec : how to encode with h264 codec ,with mp4 container using controllable frame rate and bitrate(through c code)
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM