028-86922220

建站动态

根据您的个性需求进行定制 先人一步 抢占小程序红利时代

c实现mp4解封装-创新互联

文章目录

我们提供的服务有:做网站、网站设计、微信公众号开发、网站优化、网站认证、江孜ssl等。为上千余家企事业单位解决了网站和推广的问题。提供周到的售前咨询和贴心的售后服务,是有科学管理、有技术的江孜网站制作公司前序

最近为了更加深入了解音视频demux这块的功能,准备着手写个demuxer,提取视频流。

MP4简介 MP4的定义

MP4是一种常用的视音频流封装格式,按照指定的协议来存放媒体数据;因为mp4是基于苹果QuickTime文件格式,所以与mov有很多相同之处,在苹果开发者平台可以看到详细的有关封装文档(https://developer.apple.com/library/archive/documentation/QuickTime/QTFF/QTFFChap2/qtff2.html#//apple_ref/doc/uid/TP40000939-CH204-25615)

MP4的封装格式Box类型详解 Box格式

在这里插入图片描述

  1. size字段为整个box的大小,包括box header和box body
  2. type为box的类型,通常为四字节的字符串,例如ftyp
  3. 当size == 0时,box的大小为large size
  4. 当box为full box时,存在version和flags字段,具体含义因box不同而不同
  5. 若box没有嵌套其他box,例如ftyp box,则box body部分根据具体规范解析相应字段;若box为container box,则box body部分嵌套其它box,还需一步步解套获取最终的数据
ftyp boxmvhd boxtkhd boxhdlr boxmdat boxstbl box

主要存放了媒体参数(pps、sps、vps等)相关信息和用于解析mdat中视音频数据的关键信息

stsd boxstco boxstsc boxstsz boxstts boxstss boxdemuxer demo的实现(视频数据部分)
  1. 获取sps pps参数

    1. 解析stsd box,其中contain avc1 box和avcC box(此步骤详解见上文)

    2. 解析avcC box可以获取到sps和pps

      以下为ISO/IEC 14496-15中解析avcC的伪代码

    aligned(8) class AVCDecoderConfigurationRecord { unsigned int(8) configurationVersion = 1; 
    	 unsigned int(8) AVCProfileIndication; 
    	 unsigned int(8) profile_compatibility; 
    	 unsigned int(8) AVCLevelIndication; 
    	 bit(6) reserved = ‘111111’b; 
    	 unsigned int(2) lengthSizeMinusOne; 
    	 bit(3) reserved = ‘111’b; 
    	 unsigned int(5) numOfSequenceParameterSets; 
    	 for (i=0; i< numOfSequenceParameterSets; i++) { unsigned int(16) sequenceParameterSetLength ; 
    		 bit(8*sequenceParameterSetLength) sequenceParameterSetNALUnit; 
    	 } 
    	 unsigned int(8) numOfPictureParameterSets; 
    	 for (i=0; i< numOfPictureParameterSets; i++) { unsigned int(16) pictureParameterSetLength; 
    		 bit(8*pictureParameterSetLength) pictureParameterSetNALUnit; 
     }
    
     if( profile_idc == 100 || profile_idc == 110 || 
    	 profile_idc == 122 || profile_idc == 144 ) 
    	 { bit(6) reserved = ‘111111’b; 
    		 unsigned int(2) chroma_format; 
    		 bit(5) reserved = ‘11111’b; 
    		 unsigned int(3) bit_depth_luma_minus8; 
    		 bit(5) reserved = ‘11111’b; 
    		 unsigned int(3) bit_depth_chroma_minus8; 
    		 unsigned int(8) numOfSequenceParameterSetExt; 
    		 for (i=0; i< numOfSequenceParameterSetExt; i++) {	 unsigned int(16) sequenceParameterSetExtLength; 
    			 bit(8*sequenceParameterSetExtLength) sequenceParameterSetExtNALUnit; 
    		 } 
    	 } 
    }
  2. 获取关键帧位置

    解析stss box可以知道哪一个sample中包含关键帧

  3. 获取chunk位置

    解析stco box可以获取到每个chunk在视频文件中的索引

  4. 获取每个chunk中sample个数

    解析stsc box可以获取到每个chunk包含多少个sample

  5. 获取sample大小

    解析stsz box可以获取到每个sample的大小

  6. 获取frame位置(demo视频文件一个sample只包含一个frame,所以sample的位置和大小就是frame的位置和大小)

    1. 根据stsd解析到每个sample中有多少个frame
    2. 然后再根据trunk的位置和sample的大小来定位frame起始地址
    3. mdat中frame的数据格式为: | 4字节数据长度 | frame数据|,所以根据字节长度读取相应个数frame
  7. 获取到一帧数据后

    1. 判断当前frame为I帧,则添加写入(start_code+sps) + (start_code+pps) + (start_code + frame数据)到输出文件
    2. 判断当前frame不为I帧,则写入(start_code + frame数据)到输出文件
  8. 保存成h264文件,可使用ffplay和potplay播放

注意:有些非字串的字段为大端字节序,须要转换

总结:
  1. 解析非字符串的数据时,需要注意大小端的问题
  2. 解析对应的box获取到sps、vps、pps
  3. 解析对应的box拿到视频帧数据
  4. 将视频帧写入本地文件的时候要注意
    1. 视频帧前四个字节为视频帧数据长度
    2. 若为I帧则需要加上sps、vps、pps
    3. 视频帧注意加上start_code
工具介绍
  1. mp4info—可以看到相关box的字节信息,但发现对avcC的解析漏掉了几个字节
    在这里插入图片描述

  2. mp4 exploer—可以更加直观的看到视音频数据信息
    在这里插入图片描述

源码

https://github.com/TaoChou/demuxer-c

参考
  1. https://zhuanlan.zhihu.com/p/333765990
  2. https://developer.apple.com/library/archive/documentation/QuickTime/QTFF/QTFFChap2/qtff2.html#//apple_ref/doc/uid/TP40000939-CH204-25691
  3. ISO/IEC 14496-15

你是否还在寻找稳定的海外服务器提供商?创新互联www.cdcxhl.cn海外机房具备T级流量清洗系统配攻击溯源,准确流量调度确保服务器高可用性,企业级服务器适合批量采购,新人活动首月15元起,快前往官网查看详情吧


本文标题:c实现mp4解封装-创新互联
文章位置:http://www.tsicrk.com/article/didscg.html

其他资讯

让你的专属顾问为你服务

0.9268s