使用mp4v2将H264+AAC合成mp4文件
|
录制程序要添加新功能:录制CMMB电视节目,我们的板卡发送出来的是RTP流(H264视频和AAC音频),录制程序要做的工作是: (1)接收并解析RTP包,分离出H264和AAC数据流; (2)将H264视频和AAC音频以某种格式封装,最后存成文件,供用户查看。 第一步已经有部分代码可供参考,因此很快就完成了。 第二步,我们决定封装成mp4,查找了一些资料后,决定使用开源库mp4v2来合成mp4文件。 技术路线已确定,就开工干活。 (一)mp4格式的基础知识。 关于mp4格式,网上介绍的不少,有以下内容可供参考: (1)两个ISO标准: [ISO/IEC 14496-12]:ISO base media file format --”is a general format forming the basis for a number of other more specific file formats. This format contains the timing, structure, and media information for timed sequences of media data, such as audio-visual presentations ” [ISO/IEC 14496-14]:MP4 file format --”This specification defines MP4 as an instance of the ISO Media File format [ISO/IEC 14496-12 and ISO/IEC 定义了mp4文件格式标准。 (2)http://wenku.baidu.com/view/673482284b73f242336c5f4c.html 是上面两个标准的解释,建议先看这个,了解大概,具体细节再看ISO标准文件。 (二)技术验证。主要就是写验证代码,验证技术可行性。 去官网下载mp4v2源码、编译、安装过程略过不提。所有资料可以在http://code.google.com/p/mp4v2/找到。 先写部分验证代码,很快完成了,但封装出来的文件有问题,无法播放。 合成部分,代码如下:
现象:没有图像,也没有声音,根本无法播放。 于是,艰苦的工作开始了:跟踪查找原因。 (1)使用 vlc播放合成的mp4文件,查看详细输出:
可以看到vlc(实际上是调用libmp4库)解析box都正确的,mdat的大小也是正确的。 (2)既然找到疑点,继续跟踪。 查看vlc的源代码,在文件modules/demux/mp4/libmp4.c中发现:skip信息是由MP4_ReadBoxSkip()函数打印的,而调用的地方在libmp4.c中2641行:
从代码看,vlc调用libmp4解析文件时,主动忽略了mdat,skip,free,wide这四种类型的box。 (3)继续查看modules/demux/mp4/mp4.c中的Open()函数(解析模块的入口函数),可以看到本模块的主要工作是初始化一个demux_sys_t结构体,该结构体定义如下:
似乎只是为了获取mp4的tracks,moov,duration, timescale等基本信息,实际上并不解码数据,因此就不需要关注mdat这个box了。 综上:vlc的输出是正常的,libmp4忽略了mdat这个box也不是造成mp4文件无法播放的原因,只是因为libmp4这个模块并不真正解码数据,所以不需要关注这个box。 (4)继续看vlc的输出: 不管那么多,先看看代码再说。 vlc是以lib的形式使用ffmpeg的,所以我们必须看ffmpeg的代码:
可以看到,正是这里报错的。 (5)在mp4v2的论坛上找到一个帖子,与我的情况非常类似: 内容如下: Jeremy Noring ...so each sample you and to mp4v2 should be prefixed with a size code Ottavio Campana Ottavio Campana 从中得到如下关键信息: 那好说,我将每个sample(也就是NAL)的头四个字节内容改成NAL的长度,且试试看:
测试下来,果然OK了! (6)视频已经解决了,音频还有问题:播放的声音太快。 尝试调整参数: MP4TrackId audio = MP4AddAudioTrack(file, 48000, 1024, MP4_MPEG4_AUDIO_TYPE); 第三个参数sampleDuration,表示每个sample持续多少个duration,网上看到的都是1024。 我尝试了几个不同的值:128,256,512,4096都不行,最后发现设为2048就正常了。 (为什么是2048??????我不清楚,也许是因为我们的音频是双声道?有时间再研究。。。) 正确代码如下:
至此,已经成功的将rtp流合成了mp4文件,证明了技术上是可行的。 关于该demo,可以在这里 http://bbs.rosoo.net/thread-15165-1-1.html 看到。 注意:很多参数都是针对我们的具体应用写死的,仅供参考。 (三)将功能合并到录制程序中。 略。 from:http://www.rosoo.net/a/201305/16631.html
|
使用mp4v2将H264+AAC合成mp4文件的更多相关文章
- 嵌入式 使用mp4v2将H264+AAC合成mp4文件
录制程序要添加新功能:录制CMMB电视节目,我们的板卡发送出来的是RTP流(H264视频和AAC音频),录制程序要做的工作是: (1)接收并解析RTP包,分离出H264和AAC数据流: (2)将H26 ...
- H264视频编码成MP4文件
firehood的专栏 Wince嵌入式开发 目录视图 摘要视图 订阅 赠书 | AI专栏(AI圣经!<深度学习>中文版) 每周荐书:Kotlin.分布式.Keras ...
- 嵌入式 H264—MP4格式及在MP4文件中提取H264的SPS、PPS及码流
一.MP4格式基本概念 MP4格式对应标准MPEG-4标准(ISO/IEC14496) 二.MP4封装格式核心概念 1 MP4封装格式对应标准为 ISO/IEC 14496-12(信息技术 视听对象 ...
- 使用ffmpeg从mp4文件中提取视频流到h264文件中
ffmpeg -i 2018.mp4 -codec copy -bsf: h264_mp4toannexb -f h264 tmp. 注释: -i 2018.mp4: 是输入的MP4文件 -code ...
- (转)MP4文件两种格式AVC1和H264的区别及利用FFMPEG demux为h264码流事项
出自:http://www.mworkbox.com/wp/work/314.html 2013-05-04 MP4的视频H264封装有2种格式:h264和avc1,对于这个细节,很容易被忽略.笔者也 ...
- [转]【流媒體】H264—MP4格式及在MP4文件中提取H264的SPS、PPS及码流
[流媒體]H264—MP4格式及在MP4文件中提取H264的SPS.PPS及码流 SkySeraph Apr 1st 2012 Email:skyseraph00@163.com 一.MP4格式基本 ...
- ffmpeg学习(二) 通过rtsp获取H264裸流并保存到mp4文件
本篇将使用上节http://www.cnblogs.com/wenjingu/p/3977015.html中编译好的库文件通过rtsp获取网络上的h264裸流并保存到mp4文件中. 1.VS2010建 ...
- 多媒体开发之---H264—MP4格式及在MP4文件中提取H264的SPS、PPS及码流
一.MP4格式基本概念 MP4格式对应标准MPEG-4标准(ISO/IEC14496) 二.MP4封装格式核心概念 1 MP4封装格式对应标准为 ISO/IEC 14496-12(信息技术 视听对象 ...
- 嵌入式 hi3518x平台h264+g711a封装mp4代码demo
先看代码吧,有代码有真相,具体代码的demo(下载demo的朋友请勿在网上上传我的demo,谢谢)下载连接为: http://download.csdn.net/detail/skdkjxy/8071 ...
随机推荐
- d3d11 effect state and default value tables
Blend state State Default ValueAlphaToCoverage Enable FALSEIndependentBlend Enable FALSERenderTarget ...
- 关于struts2如何去掉默认的后缀(.action)
struts2是可以配置默认的后缀名的,如http://localhost:8080/test.action,这个是默认的,但是也可以通过配置去修改这个.action为别的. 这里是通过一个常量配置改 ...
- java使用正则表达式——实例
Java代码 import java.util.regex.Matcher; import java.util.regex.Pattern; /** * @author Der * ...
- 为Android Studio 项目手动下载gradle
在http://developer.android.com/samples/index.html上下载的例子,导入Android Studio的时候,第一件事就是下载项目对应版本的gradle.gra ...
- MongoDB安装(Linux)
下载文件 http://downloads.mongodb.org/linux/mongodb-linux-i686-static-2.5.0.tgz 解压: tar -zxvf mongodb-li ...
- JAVA学习路线图---(JAVA1234)
第一阶段-Java基础 这一阶段很重要,关系到你后面阶段的学习,所以务必把这一阶段掌握好: 如果你是0基本,我推荐一本比较好的,适合初学者看的书:明日科技的<Java从入门到精通>,最 ...
- AsyncTask 与 Thread+Handler
AsyncTask是封装好的线程池,比起Thread+Handler的方式,AsyncTask在操作UI线程上更方便,因为onPreExecute().onPostExecute()及更新UI方法on ...
- Netstat 命令
简介 Netstat 命令用于显示各种网络相关信息,如网络连接,路由表,接口状态 (Interface Statistics),masquerade 连接,多播成员 (Multicast Member ...
- DAO设计模式 -- 使用数据库连接类连接MySql数据库并实现添加用户
1. DAO简介 DAO设计模式是属于J2EE数据库层的操作,使用DAO设计模式可以简化大量代码,增强程序的可移植性. 2. DAO各部分详解 DAO设计模式包括5个重要的部分,分别为数据 ...
- 写给系统管理员的25个PHP安全实践
PHP是广泛使用的开源服务端脚本语言.通过HTTP或HTTPS协议,Apache Web服务允许用户访问文件或内容.服务端脚本语言的错误配置会导致各种问题.因此,PHP应该小心使用.以下是为系统管理员 ...