H.264 MP4 文件中的像素格式存储在哪里?
Where is pixel format stored in H.264 MP4 file?
我正在开发一个 transmuxer,它将 H.264/AAC RTMP 流转换为有效的 MP4 文件。我大部分都完成了。我正在解析 AMF 标签,读取 AVCDecoderConfigurationRecord 和 AACSpecificConfig,我正在生成一个有效的 moov 原子,等等。
在我的代码中发现并修复了一些错误后,我得到了一个大部分 有效的 MP4 文件。但是,当我尝试阅读 ffprobe
中的视频时,出现以下错误:
[mov,mp4,m4a,3gp,3g2,mj2 @ 0x7f9fb4000b80] Failed to open codec in avformat_find_stream_info
Last message repeated 1 times
[mov,mp4,m4a,3gp,3g2,mj2 @ 0x7f9fb4000b80] Could not find codec parameters for stream 1 (Video: h264 (avc1 / 0x31637661), none, 640x360): unspecified pixel format
Consider increasing the value for the 'analyzeduration' and 'probesize' options
找不到像素格式。浏览我的 AVCDecoderConfigurationRecord 解析逻辑(用于生成 avcC
原子作为 avc1
原子的一部分),我有以下内容:
// Parsed per: https://github.com/LiminWang/simple-rtmp-server/blob/master/trunk/doc/H.264-AVC-ISO_IEC_14496-15.pdf
var info = parseAVCConfig(packet);
// Fortunately my video sample has one of each of these
// I may need to concatenate multiple in the future
var sps = info.sps[0];
var pps = info.pps[0];
var avcc = box(
types.avcC,
new Uint8Array([
// Version
0x01,
// Profile
info.profile,
// Profile Compat
info.compat,
// Level
info.level,
// LengthSizeMinusOne, hard-coded to 4 bytes (copied HLS.js)
0xfc | 3,
// 3bit reserved (111) + numOfSequenceParameterSets
0xE0 | sps.byteLength
]
.concat(Array.from(sps))
.concat([
// NumOfPictureParametersets
pps.byteLength
])
.concat(Array.from(pps))
)
);
如您所见,avcc
原子包含配置文件、兼容性和级别——但之后我只是直接从 AVCDecoderConfigurationRecord 复制 SPS 和 PPS。我在原子中没有定义像素格式,所以我假设它是 SPS 或 PPS 的一部分。
查看 AVCDecoderConfigurationRecord 的规范,没有什么特别称为 "pixel format",但有一个 "chroma_format"、"bit_depth_luma_minus8" 和 "bit_depth_chroma_minus_8" -- 然而这些仅如果配置文件是 100、110、122 或 244,则存在。我的配置文件是 66(这些字节对我来说不存在)
目前我正在做的这个概念验证只需要支持一个视频,所以最坏的情况我可以将像素格式硬编码为 yuv420
。但我什至不知道将这些信息放在输出 MP4 的什么位置。它会进入 avcC
原子吗?还是 avc1
原子?还是 mvhd
原子?
链接:
- buffer.mp4: 这是我正在创建的文件,它不起作用。
ffprobe
说找不到像素格式。 http://files.stevendesu.com/buffer.mp4
- test.mp4:这是同一视频的一段,由
ffmpeg
转换为MP4,用于比较。 http://files.stevendesu.com/test.mp4
看看 chroma_format_idc
建议。 ITU-T H.264 (04/2017) - 7.3.2.1.1 序列参数集数据句法。 chroma_format_idc
是 SPS 的一部分。
对于 profile_idc
100、110、122、244、44、83、86、118、128、138、139、134 或 135,chroma_format_idc
存储在 SPS 中。否则你假设 1 (= 4:2:0).
7.4.2.1.1 序列参数集数据语义
chroma_format_idc specifies the chroma sampling relative to the luma sampling as specified in clause 6.2. The value of
chroma_format_idc shall be in the range of 0 to 3, inclusive. When chroma_format_idc is not present, it shall be inferred
to be equal to 1 (4:2:0 chroma format).
我正在开发一个 transmuxer,它将 H.264/AAC RTMP 流转换为有效的 MP4 文件。我大部分都完成了。我正在解析 AMF 标签,读取 AVCDecoderConfigurationRecord 和 AACSpecificConfig,我正在生成一个有效的 moov 原子,等等。
在我的代码中发现并修复了一些错误后,我得到了一个大部分 有效的 MP4 文件。但是,当我尝试阅读 ffprobe
中的视频时,出现以下错误:
[mov,mp4,m4a,3gp,3g2,mj2 @ 0x7f9fb4000b80] Failed to open codec in avformat_find_stream_info
Last message repeated 1 times
[mov,mp4,m4a,3gp,3g2,mj2 @ 0x7f9fb4000b80] Could not find codec parameters for stream 1 (Video: h264 (avc1 / 0x31637661), none, 640x360): unspecified pixel format
Consider increasing the value for the 'analyzeduration' and 'probesize' options
找不到像素格式。浏览我的 AVCDecoderConfigurationRecord 解析逻辑(用于生成 avcC
原子作为 avc1
原子的一部分),我有以下内容:
// Parsed per: https://github.com/LiminWang/simple-rtmp-server/blob/master/trunk/doc/H.264-AVC-ISO_IEC_14496-15.pdf
var info = parseAVCConfig(packet);
// Fortunately my video sample has one of each of these
// I may need to concatenate multiple in the future
var sps = info.sps[0];
var pps = info.pps[0];
var avcc = box(
types.avcC,
new Uint8Array([
// Version
0x01,
// Profile
info.profile,
// Profile Compat
info.compat,
// Level
info.level,
// LengthSizeMinusOne, hard-coded to 4 bytes (copied HLS.js)
0xfc | 3,
// 3bit reserved (111) + numOfSequenceParameterSets
0xE0 | sps.byteLength
]
.concat(Array.from(sps))
.concat([
// NumOfPictureParametersets
pps.byteLength
])
.concat(Array.from(pps))
)
);
如您所见,avcc
原子包含配置文件、兼容性和级别——但之后我只是直接从 AVCDecoderConfigurationRecord 复制 SPS 和 PPS。我在原子中没有定义像素格式,所以我假设它是 SPS 或 PPS 的一部分。
查看 AVCDecoderConfigurationRecord 的规范,没有什么特别称为 "pixel format",但有一个 "chroma_format"、"bit_depth_luma_minus8" 和 "bit_depth_chroma_minus_8" -- 然而这些仅如果配置文件是 100、110、122 或 244,则存在。我的配置文件是 66(这些字节对我来说不存在)
目前我正在做的这个概念验证只需要支持一个视频,所以最坏的情况我可以将像素格式硬编码为 yuv420
。但我什至不知道将这些信息放在输出 MP4 的什么位置。它会进入 avcC
原子吗?还是 avc1
原子?还是 mvhd
原子?
链接:
- buffer.mp4: 这是我正在创建的文件,它不起作用。
ffprobe
说找不到像素格式。 http://files.stevendesu.com/buffer.mp4 - test.mp4:这是同一视频的一段,由
ffmpeg
转换为MP4,用于比较。 http://files.stevendesu.com/test.mp4
看看 chroma_format_idc
建议。 ITU-T H.264 (04/2017) - 7.3.2.1.1 序列参数集数据句法。 chroma_format_idc
是 SPS 的一部分。
对于 profile_idc
100、110、122、244、44、83、86、118、128、138、139、134 或 135,chroma_format_idc
存储在 SPS 中。否则你假设 1 (= 4:2:0).
7.4.2.1.1 序列参数集数据语义
chroma_format_idc specifies the chroma sampling relative to the luma sampling as specified in clause 6.2. The value of
chroma_format_idc shall be in the range of 0 to 3, inclusive. When chroma_format_idc is not present, it shall be inferred
to be equal to 1 (4:2:0 chroma format).