H.264 编码的视频能同时被 mov 和 mp4 进行封装?

2021-09-13 11:45:14 +08:00
 xlsepiphone

我在上一个帖子『Golang 的 http.DetectContentType 有更好的替代实现吗?』求问了 Golang 下面对于不同文件头识别的开源库,有 V 友回复了filetype这个库,但是我最后使用了mimetype这个库的解决方案。

mimetype能够正确把视频的 mimetype 识别成 video/mp4,但是filetype这个库却识别出来的是 video/quicktime 。

然后我在上面的帖子也 append 了一下让我困惑的问题,就是我接着用 ffprobe 查看视频的编码信息,输出的是 H.264 ,封装格式如下:

format_name=mov,mp4,m4a,3gp,3g2,mj2
format_long_name=QuickTime / MOV

最后我用 Mac 的 Finder 查看,显示的又是 MPEG-4 影片,完全糊涂了,这意味着这个视频是先用用 mov 封装,再用 mp4 进行封装的吗?

本人对视频编解码相关知识的了解非常基础,基本处于懵懵懂懂的状态,Google 了好久都没有找到对于 format_name 这个字段的多个值的具体解释。

求 V 友解惑。

3840 次点击
所在节点    程序员
26 条回复
lostvincent
2021-09-13 17:28:39 +08:00
@mikewang 多谢指正,quicktime 这部分不是了解太多,对表达失误带来的误解,表示抱歉
关于 ISO/IEC 14496-12 是因为我手边之前研究的是这份,也只看过这份,所以想了下,没删掉-12

@xlsepiphone 你要了解的话,看下 mp4 的 ftyp 这个东西就够了
litesoar
2021-09-13 17:48:36 +08:00
应该可以吧。

h.264 是视频编码格式
mp4 和 mov 是视频封装格式,都能采用 h264 编码。
xylophone21
2021-09-13 18:20:57 +08:00
score 越大,可能性越高

```c
static int mov_probe(const AVProbeData *p)
{
int64_t offset;
uint32_t tag;
int score = 0;
int moov_offset = -1;

/* check file header */
offset = 0;
for (;;) {
int64_t size;
int minsize = 8;
/* ignore invalid offset */
if ((offset + 8ULL) > (unsigned int)p->buf_size)
break;
size = AV_RB32(p->buf + offset);
if (size == 1 && offset + 16 <= (unsigned int)p->buf_size) {
size = AV_RB64(p->buf+offset + 8);
minsize = 16;
} else if (size == 0) {
size = p->buf_size - offset;
}
if (size < minsize) {
offset += 4;
continue;
}
tag = AV_RL32(p->buf + offset + 4);
switch(tag) {
/* check for obvious tags */
case MKTAG('m','o','o','v'):
moov_offset = offset + 4;
case MKTAG('m','d','a','t'):
case MKTAG('p','n','o','t'): /* detect movs with preview pics like ew.mov and april.mov */
case MKTAG('u','d','t','a'): /* Packet Video PVAuthor adds this and a lot of more junk */
case MKTAG('f','t','y','p'):
if (tag == MKTAG('f','t','y','p') &&
( AV_RL32(p->buf + offset + 8) == MKTAG('j','p','2',' ')
|| AV_RL32(p->buf + offset + 8) == MKTAG('j','p','x',' ')
)) {
score = FFMAX(score, 5);
} else {
score = AVPROBE_SCORE_MAX;
}
break;
/* those are more common words, so rate then a bit less */
case MKTAG('e','d','i','w'): /* xdcam files have reverted first tags */
case MKTAG('w','i','d','e'):
case MKTAG('f','r','e','e'):
case MKTAG('j','u','n','k'):
case MKTAG('p','i','c','t'):
score = FFMAX(score, AVPROBE_SCORE_MAX - 5);
break;
case MKTAG(0x82,0x82,0x7f,0x7d):
case MKTAG('s','k','i','p'):
case MKTAG('u','u','i','d'):
case MKTAG('p','r','f','l'):
/* if we only find those cause probedata is too small at least rate them */
score = FFMAX(score, AVPROBE_SCORE_EXTENSION);
break;
}
if (size > INT64_MAX - offset)
break;
offset += size;
}
if (score > AVPROBE_SCORE_MAX - 50 && moov_offset != -1) {
/* moov atom in the header - we should make sure that this is not a
* MOV-packed MPEG-PS */
offset = moov_offset;

while (offset < (p->buf_size - 16)) { /* Sufficient space */
/* We found an actual hdlr atom */
if (AV_RL32(p->buf + offset ) == MKTAG('h','d','l','r') &&
AV_RL32(p->buf + offset + 8) == MKTAG('m','h','l','r') &&
AV_RL32(p->buf + offset + 12) == MKTAG('M','P','E','G')) {
av_log(NULL, AV_LOG_WARNING, "Found media data tag MPEG indicating this is a MOV-packed MPEG-PS.\n");
/* We found a media handler reference atom describing an
* MPEG-PS-in-MOV, return a
* low score to force expanding the probe window until
* mpegps_probe finds what it needs */
return 5;
} else {
/* Keep looking */
offset += 2;
}
}
}

return score;
}
```
msg7086
2021-09-13 18:50:06 +08:00
Mp4 isom mov 本来就是一家人。
顺便提一个有趣的小知识,avi 和 wav 也是一家人,都是基于 riff 。
视频音频方面的水本来就很深,一大堆公司在搞,各种组织在定自己的标准,然后各种标准又在借鉴别的标准。
然后甚至有时候还会出现软件输出的文件不那么标准的情况,然后软件也要一步步迭代完善。
很多格式还在不停发展变化,比如说 opus 或 flac in MP4 还没完全搞明白,各家软件还没支持,标准也还在草案阶段一点点推进,等哪天定稿了再逐步给各大工具平台推,再一点点开始普及,等等。
本来已经成熟的格式也在不停变化,比如前段时间 NHK 搞了 24 声道的 AAC,一直无人支持,后来有一天我去问了,然后给了个音轨样本以后他们才一点点开始实现功能。
这方面的浑水要趟的话得要有一些心理准备的。
thunderw
2021-09-14 08:58:58 +08:00
https://blog.csdn.net/pirateleo/article/details/7583321
这里面说的好像比较清楚。可以指定一种主格式,另外声明还兼容哪些格式。
所以你这个具体的文件就是 isom 兼容 moov 。约等于既是 mp4 又是 mov 。
参阅: http://www.ftyps.com
tsanie
2021-09-14 10:30:01 +08:00
@thunderw 那倒不是,他这个文件第一个 atom 是 0x14 个字节,major_brand 是 isom,compatible_brands 只有 4 字节也是 isom,moov 是另一个 atom,里面存视频时长之类的信息的。

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/801517

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX