PMP格式详解

PMP格式详解:著名的jonny设计了PMP格式,让大家可以使用小P来欣赏到高质量的影音; 
但随着版本的推进,出现了PMP1.0, PMP2.0, PMP-AVC, 这些名词和概念可能让大家感到很困惑,现在,我根据我的研究和理解来给大家解释一下这些名词的意思。

【PMP格式】 
PMP是jonny设计的视频音频封装格式,如同AVI一样,只是一种封装的容器格式 
PMP格式现在只有两个版本,一个是1.0, 一个是2.0

PMP1.0是一个比较简陋的版本,只支持封装MP4V流(xvid, divx)和MP3流(而且要求是CBR的,采样率为44100), 
从文件头开始,顺序结构如下:

4字节:一定是"pmpm",pmp的标志; 
4字节:版本号,为0,表示版本是1.0 
4字节:视频帧总数 
4字节:视频宽度 
4字节:视频高度 
4字节:视频scale 
4字节:视频rate , 注意:视频的帧率fps = rate/scale 
4字节:最大视频帧的大小 
视频帧总数×4个字节:每帧视频的索引,每个索引4个字节,最低一个bit位表示是否关键帧,其余的31位bit表示帧的大小 
视频数据:字节数,由上面的索引计算可以得出; 
4个字节:音频帧的数据大小(由于采用的是cbr模式,所有的音频帧数据大小一样,但关键帧的大小比普通帧大小多一个字节) 
4个字节:音频帧的总数 
音频帧总数×1个字节:每帧音频的索引,每个索引1个字节,关键帧为1,普通帧为0,注意:每帧的实际大小=音频帧的数据大小+索引值; 
音频数据:字节数,由上面的索引计算得出;

从上面的分析来看,PMP1.0格式有很大的不足,没有视频和音频的标志位,也就是说,固定死了视频和音频的编码格式,无法封装各式的流, 
同时,由于视频和音频数据是非交错存储,播放程序在回放的时候,文件指针在来回地移动,读视频帧的时候移到前面,读音频帧又移到后面;

PMP2.0开始,jonny估计意识到1.0的不足,重新设计了文件的格式结构,我个人认为这个改变很不错: 
从文件头开始,顺序结构如下:

4字节:一定是"pmpm",pmp的标志; 
4字节:版本号,为1,表示版本是2.0 
4字节:视频格式标志,这是一个改进,为支持封装各种视频流提供保证,0表示MP4V流(xvid, divx),1表示AVC流(PMP-AVC其实就是PMP2.0格式,只不过封装了AVC流) 
4字节:视频帧总数 
4字节:视频宽度 
4字节:视频高度 
4字节:视频scale 
4字节:视频rate , 注意:视频的帧率fps = rate/scale 
4字节:音频格式标志,同样为了以后支持封装各种音频提供保证,现在只支持mp3流,该值为0; 
4字节:包含的音频流数量,为支持多音轨封装提供了保证,如果一个pmp中封装了两条音轨,该值就为2 
4字节:每帧视频附带的音频帧的最大数,由于PMP2.0采用了视频音频交错存储的方式,一帧视频和相应的几帧音频放在一起,这是一个最大值; 
4字节:音频scale,默认为1152 
4字节:音频rate,默认为44100 
4字节:音频是否立体声,0表示单声,1表示立体声; 
视频帧总数×4个字节:每帧视频的索引,每个索引4个字节,最低一个bit位表示是否关键帧,其余的31位bit表示帧的大小(注意,这里的帧大小和1.0格式的帧大小不一样,看下面的解释) 
视频音频混和数据:这里,jonny做了一个比较有意思的设计,把1个视频帧和其相应的音频帧混合起来,当做一个数据帧;那究竟怎么个混合法呢,我们分析一下: 
首先计算每个视频帧的时间戳和每个音频帧的时间戳,videotime = videonum / videofps , audiotime = audionum / audiofps (videonum和audionum都从0开始) 
那么第一个视频帧的时间戳就是0/videofps =0,而第二个视频帧的时间戳就是1/videofps ,然后,把第一个视频帧和所有时间戳小于1/videofps的音频帧接在一起,成了一个数据帧,如此类推下去; 
然后在每个数据帧的前面再加上n个字节, n=1+4+4+4+4×每音轨被混合的帧数×音轨数, 
其中这n个字节的意义如下: 
1字节:本数据帧中,每音轨被混合的帧数; 
4字节:被混合的第一个音频帧和视频帧之间的时间差; 
4字节:被混合的最后一个音频帧和视频帧之间的时间差; 
4字节:视频帧的大小; 
4×每音轨被混合的帧数×音轨数:每个被混合的音频帧的大小

【PMP的播放】 
从上面的分析,我们知道,PMP有两种格式(1.0,2.0),又由于2.0格式中封装的流不一样,出现了所谓pmp2.0和pmp-avc的不同; 
所有,我们需要不同的播放器(pmp-mod1, pmp-mod2, pmp-avc)来播放这些文件;

由于pmp1.0和pmp2.0格式文件的差异太大,在小p上如果要实现同时支持这两种的话,代码编写会比较复杂,效率可能也会因此降低 
同时由于pmp1.0格式的不足,我建议大家放弃pmp1.0格式,原有的pmp1.0格式的片子可以通过remux转成2.0格式; 
至于pmp-mp4v和pmp-avc文件,我个人认为,他们是可以放在一个程序中支持的,因为他们的封装是一样的,只是里面的流不一样而已; 
只需要通过对不同解码器的解码即可。

【后话】 
写这篇东西的目的就是希望能让大家了解到pmp的各种格式的区别. 
我希望自己有时间和能力来给大家做一个pmp-mod,支持pmp2.0(包括pmp-mp4v,pmp-avc),但实际上,我现在的工作比较繁忙,没有太多精力来编写这个。 
所以,写这个的另一个目的是分享我的研究,希望能有技术高手能通过这篇东西,写出一个新的pmp-mod,支持pmp2.0格式的播放(包括pmp-mp4v和pmp-avc)。

(0)

相关推荐

  • PMP格式详解

    PMP格式详解:著名的jonny设计了PMP格式,让大家可以使用小P来欣赏到高质量的影音:  但随着版本的推进,出现了PMP1.0, PMP2.0, PMP-AVC, 这些名词和概念可能让大家感到很困惑,现在,我根据我的研究和理解来给大家解释一下这些名词的意思. [PMP格式]  PMP是jonny设计的视频音频封装格式,如同AVI一样,只是一种封装的容器格式  PMP格式现在只有两个版本,一个是1.0, 一个是2.0 PMP1.0是一个比较简陋的版本,只支持封装MP4V流(xvid, divx

  • PHP书写格式详解(必看)

    从一个例子开始. 启动编辑器,创建一个php文件并键入如下代码: <?php echo "你好!"; ?> 将该文件命名为 test.php 并存储于 E:html 目录下. 在浏览器地址栏里访问该 php 文件:http://127.0.0.1/test.php,输出结果如下: 你好!在该例子中,我们以 echo 指令输出一个字符串"你好!". 从这个例子可以看出: •PHP 文件或 PHP 代码段以"<?php"开头,以&q

  • Python用sndhdr模块识别音频格式详解

    本文主要介绍了Python编程中,用sndhdr模块识别音频格式的相关内容,具体如下. sndhdr模块 功能描述:sndhdr模块提供检测音频类型的接口. 唯一一个API sndhdr模块提供了sndhdr.what(filename)和sndhdr.whathdr(filename)两个函数.但实际上它们的功能是一样的.(不知道多写一个的意义何在,what函数在内部调用了whathdr函数并把数据完完整整地返回) 在之前的版本,whathdr函数返回元组类型的数据,在Python3.5版本之

  • 基于nginx access日志格式详解

    nginx的nginx.cnf中,使用log_format字段可以指定日志的格式文件. log.fromat: log_format access ' [$time_local] | $host | $remote_addr | $request | $request_time | $body_bytes_sent | $status |' '| $upstream_addr | $upstream_response_time | $upstream_status |' ' "$http_ref

  • 基于form-data请求格式详解

    最近一直都比较忙,坚持月月更新博客的计划不得中止了,今天抽出点时间来说说最近项目中遇到的一个问题,有关request post请求格式中的multipart/form-data格式. 引言 最近在参与一个项目过程中遇到一个问题,相信大部分人都遇到过: 在后端与前端约定好application/json格式传递数据时,因为后台是go强类型语言,在定义api接口时,某些字段要求是整型类型,但是对于前端来说输入框或者从url中的search取到的参数都是字符串,不得不进行前端类型转换. 咋一看,对于接

  • Python实现批量将MP3音频转为WAV格式详解

    目录 前言 环境依赖 代码 验证一下 前言 本文提供批量将MP3格式的音频转为wav格式的工具代码,一如既往的实用主义. 环境依赖 ffmpeg环境安装,可以参考:windows ffmpeg安装部署 ffmpy安装: pip install ffmpy -i https://pypi.douban.com/simple 代码 不废话,上代码. #!/user/bin/env python # coding=utf-8 """ @project : batch-pro @au

  • json文件书写格式详解

    目录  JSON是什么 为什么有这个技术 JSON 如何使用 - 数据格式 - 注意事项 - JS 内置两个Json方法 实例:  JSON是什么 JSON ( JavaScript Object Notation) ,是一种数据交互格式. 为什么有这个技术 Json之前,大家都用 XML 传递数据.XML 是一种纯文本格式,所以适合在网络上交换数据,但是 XML 格式比较复杂,终于道格拉斯·克罗克福特(Douglas Crockford)发明了JSON 这种超轻量级的数据交换格式. JSON

  • rollup输出的6种格式详解

    目录 学习本文 为什么要学这个? DEMO与示例构建 一.IIFE 自执行函数 1.1 打包结果分析 1.2 如何运行 1.3 优缺点 二.CommonJS 2.1 分析打包结果 2.2 如何运行 2.3 优缺点 三.AMD 和 requirejs ! 3.1 打包结果分析 3.2 如何运行 3.3 优缺点 四.UMD 伟大的整合 4.1 打包分析 4.2 如何运行? 4.3 优缺点 五.SystemJs 六.ESM 6.1 打包分析 6.2 如何运行 总结:分别适合在什么场景使用? 学习本文

  • flask路由分模块管理及自定义restful响应格式详解

    目录 一.flask路由分模块管理 1.1.使用蓝图 1.2.使用flask_restful 二.自定义flask_restful响应格式 一.flask路由分模块管理 1.1.使用蓝图 在flask中可以使用蓝图Blueprint来进行创建路由进行分模块. 具体操作,我们可以在项目根目录下创建一个controller文件夹来存储分模块的路由. 在controller文件夹里创建product_controller.py,在里面如下写法引入蓝图,并且注册蓝图: from flask import

  • Linux shell命令帮助格式详解

    前言 linux shell命令通常可以通过-h或--help来打印帮助说明,或者通过man命令来查看帮助,有时候我们也会给自己的程序写简单的帮助说明,其实帮助说明格式是有规律可循的 帮助示例 下面是git reset命令的帮助说明,通过man git-reset可以查看 git reset [-q] [<tree-ish>] [--] <paths>... git reset (--patch | -p) [<tree-ish>] [--] [<paths>

随机推荐