第七季3:分析“将H.264码流打包成MP4格式的文件”的源码

以下内容源于朱有鹏嵌入式课程的学习与整理,如有侵权请告知删除。

前言

“将H.264MP4码流打包成MP4格式文件”的实验,见博文第七季2:MP4v2库的移植与播放实战。

接下来我们将对相关的源码进行分析。建立SI工程,导入sample_mp4_ar0130目录、mpp目录下的ko目录、lib目录、component目录、inlcude目录(该目录包含分析时用到的ortp、mp4等库文件)等文件。

一、Sample的函数调用关系

这里的源码是在第6季的sample_venc.c文件基础上编写的,因此有很多无关的代码没有删去。

修改后的sample_venc.c文件中的main函数的内容如下:

int main(int argc, char *argv[])
{HI_S32 s32Ret;MPP_VERSION_S mppVersion;HI_MPI_SYS_GetVersion(&mppVersion);//获取MPP的版本号printf("MPP Ver  %s\n",mppVersion.aVersion);RtspServer_init();//可以注释掉这个函数,MP4格式打包与这个函数没有关系。s32Ret = SAMPLE_VENC_720P_CLASSIC();//关注这个函数!return HI_FAILURE;if (HI_SUCCESS == s32Ret)printf("program exit normally!\n");elseprintf("program exit abnormally!\n");while(1){usleep(1000);}return s32Ret;
}

其中SAMPLE_VENC_720P_CLASSIC函数流程和第二季的步骤基本相同。不同之处,在于“step6保存码流”这个步骤之前的代码中更改了通道数目;另外更改了“step6保存码流”这个步骤的代码。

修改后的“step6保存码流”这个步骤的函数调用关系如下:

SAMPLE_COMM_VENC_StartGetStream         //位于sample_comm_venc.c文件SAMPLE_COMM_VENC_GetVencStreamProc  //位于sample_comm_venc.c文件//忽略部分调用(和第二季的一样)SAMPLE_COMM_VENC_MP4            //位于sample_comm_venc.c文件

第二季是将编码方式为H.264的码流保存为H264裸流文件,而这里是将编码方式为H.264的码流保存为MP4格式的文件,都是保存为文件,只是格式不一样,因此按道理是在第二季保存文件时(即 step 2.5)多加一个步骤,即上面的 SAMPLE_COMM_VENC_MP4 函数,该函数负责将一帧数据打包成MP4格式。接下来我们重点分析SAMPLE_COMM_VENC_MP4 函数。

三、分析SAMPLE_COMM_VENC_MP4函数

1、函数的整体分析

HI_S32 SAMPLE_COMM_VENC_MP4(VENC_STREAM_S *stStream)
{static int nRecordFlag = 0x00;static int recording = 0x1;static int spsflag = 0;static int ppsflag = 0;static MP4TrackId video = 0;static MP4FileHandle hMP4File = NULL;static char recordfish = 0x1;int j = 0;int len = 0;char *pData = NULL;char isSyncSample = 0;if(recordfish == 0x00){return 0;}if(hMP4File == NULL){hMP4File = MP4CreateEx("/usr/mmc/test.mp4",0, 1, 1, 0, 0, 0, 0);//文件存储路径if (hMP4File == MP4_INVALID_FILE_HANDLE)	{printf("open file fialed.\n");return -1;}MP4SetTimeScale(hMP4File, 90000);}if(recording && stStream->u32Seq > 30){	//丢弃前30帧,也可以不丢弃if(stStream->u32PackCount >= 3){	//从I帧开始编码,保证文件开始就能播放nRecordFlag = 1;}if(nRecordFlag){for(j = 0;j < stStream->u32PackCount;j++){len 	= stStream->pstPack[j].u32Len - stStream->pstPack[j].u32Offset;pData	= (stStream->pstPack[j].pu8Addr + stStream->pstPack[j].u32Offset);						if(stStream->pstPack[j].DataType.enH264EType == H264E_NALU_SPS){if(spsflag == 0x00){spsflag = 0x1;//写spsprintf("Write sps =================\n");	video = MP4AddH264VideoTrack(hMP4File, 90000, 90000 / 30, 1280, 720,pData[4+1], //sps[1] AVCProfileIndicationpData[4+2], //sps[2] profile_compatpData[4+3], //sps[3] AVCLevelIndication3); // 4 bytes length before each NAL unitMP4SetVideoProfileLevel(hMP4File, 0x7F);MP4AddH264SequenceParameterSet(hMP4File, video, pData+4, len-4);										}continue;}if(stStream->pstPack[j].DataType.enH264EType == H264E_NALU_PPS){if(ppsflag == 0x00){ppsflag = 0x1;//写pps									printf("Write pps -------------------\n");										MP4AddH264PictureParameterSet(hMP4File, video, pData+4, len-4);}continue;}isSyncSample = (stStream->pstPack[j].DataType.enH264EType == H264E_NALU_ISLICE)	?  (1) : (0);pData[0] = (len - 4) >> 24;pData[1] = (len - 4) >> 16;pData[2] = (len - 4) >> 8;pData[3] = len - 4; 							printf("Write date type = %d  isSyncSample = %d\n",stStream->pstPack[j].DataType.enH264EType,isSyncSample);								MP4WriteSample(hMP4File, video, pData, len , MP4_INVALID_DURATION, 0, isSyncSample);}					}}if((recording && stStream->u32Seq > 900)){//控制文件时长。900帧/30帧每秒=30秒recording = 0x00;printf("Close mp4 file\n");						MP4Close(hMP4File, 0);hMP4File = NULL;video = 0;recordfish = 0x00;}}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/460903.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

什么代码才是线程安全的

转自&#xff1a;http://www.cnblogs.com/lidabo/archive/2013/04/10/3011518.html 对于多线程编程&#xff0c;很多人概念不清&#xff0c;写代码的时候要么是处处加锁&#xff0c;影响性能不说&#xff0c;还容易莫名其妙的死锁&#xff0c;还有人对多线程敬而远之。所以学习…

百度富文本编辑器的应用技巧---在一个页面中使用多个样式不同功能不同的编辑器...

//1.2.4以后可以使用一下代码实例化编辑器 //UE.getEditor(myEditor)在官方的说明文档上看到这个注释&#xff0c;不是很明白&#xff0c;而且需要在一个页面中使用多次样式功能不同的ueditor&#xff0c;经过多次测试&#xff0c;终于成功自定义功能。代码如下<form><…

计算机基础知识复习题,计算机基础知识理论复习题及答案.doc

《计算机基础知识理论复习题及答案.doc》由会员分享&#xff0c;提供在线免费全文阅读可下载&#xff0c;此文档格式为doc&#xff0c;更多相关《计算机基础知识理论复习题及答案.doc》文档请在天天文库搜索。1、&#xfeff;基础知识复习题及答案一、 选择题1. 第三代计算机所…

RAM、ROM和FLASH三大类常见存储器简介

以下内容源于网络资源的学习与整理&#xff0c;如有侵权请告知删除。 参考博客&#xff1a; Flash、RAM、ROM的区别_天籁东东的博客-CSDN博客_flash和rom的区别 RAM、ROM和FLASH三大类常见存储器简介 - 存储技术 - 电子发烧友网 RAM、NANDFlash、NORFlash的区别详解 - 百度…

SHELL中的IF判断 ​

SHELL中的IF判断shell中if做比较比较两个字符串是否相等的办法是&#xff1a;if [ "$test"x "test"x ]; then这里的关键有几点&#xff1a;1 使用单个等号2 注意到等号两边各有一个空格&#xff1a;这是unix shell的要求3 注意到"$test"x最后的…

wangeditor html编辑,Vue整合wangEditor富文本编辑器

最近在做项目时&#xff0c;客户有个发布新闻动态的功能&#xff0c;具体页面内容让客户自己编写&#xff0c;所以要选择富文本编辑器&#xff0c;这样用户体验好一点。网上有很多的富文本编辑器&#xff0c; 因为项目的功能并不是很复杂&#xff0c;所以选择了wangEditor&…

SqlSever分页查询,仅扫描一次表

数据库的分页查询一般由两个查询组成&#xff1a; select count(*) from Goods 和 select * from (select row_number() over(order by goodsId) as rowid, *from Goods ) as a where rowid > pageSize * (pageIndex - 1) 1 and rowid < pageSize * pageIndex 第一个查询…

嵌入式基础认识2:shell脚本的一些简单语法规则

一、关于shell的一些认识 1、shell语言&#xff0c;是一类编程语言。常用shell语言有sh、bash、csh、ksh、perl、python等。linux下最常用的脚本就是bash。 2、shell脚本&#xff0c;即把在命令行中输入的命令写成程序。这样可以避免反复地在命令行下手工输入命令的繁琐工作。…

DreamWeaver连接Tomcat用以编辑和测试JSP

2019独角兽企业重金招聘Python工程师标准>>> 3 、打开软件之后&#xff0c;大家选择【站点】中的【新建站点】 。 4 、填写要填的内容。 站点名称&#xff1a;可以随便起&#xff0c;只是用来区分站点用的。因为&#xff0c;可以建立多个站点。 本地根文件夹&…

2013多校第三场

hdu 4629 题意&#xff1a;给你n个三角形&#xff0c;问覆盖1~n次的面积各是多少&#xff0c;n < 50; 分析&#xff1a;取出所有端点和交点的x坐标&#xff0c;排序&#xff0c;然后对于每一段xi~xi1的范围的线段都是不相交的&#xff0c;所以组成的 面积要么是三角形&#…

TSS 任务状态段

TSS(任务状态段)1 什么是TSS TSS 全称task state segment&#xff0c;是指在操作系统进程管理的过程中&#xff0c;任务&#xff08;进程&#xff09;切换时的任务现场信息。 2 TSS工作细节 TSS在任务切换过程中起着重要作用&#xff0c;通过它实现任务的挂起和恢复。所谓…

Linux下C语言程序的内存布局

以下内容源于C语言中文网的内容学习与整理。如有侵权&#xff0c;请告知删除。 一、C语言内存布局 C程序所占用的内存&#xff0c;可以划分为以下几个部分。 1、栈区&#xff08;stack&#xff09;。由编译器自动分配释放&#xff0c;存放函数的参数值&#xff0c;局部变量的值…

HTML/CSS/Javascript代码在线压缩、格式化(美化)工具

CSS 格式化ProCSSor - http://procssor.com/CSS 压缩CSS Compressor - http://www.cssdrive.com/index.php/main/csscompressorHTML 格式化Tabifier - http://tools.arantius.com/tabifierHTML 压缩Compress HTML - http://www.textfixer.com/html/compress-html-compression.p…

【运动快乐】享受赤脚慢跑 收获健康快乐

享受赤脚慢跑 收获健康快乐——写给想锻炼的您当您看到赤脚客时&#xff0c;您或许忍不住会问&#xff1a;为什么要赤脚跑呢&#xff1f;不怕扎破脚&#xff1f;跑起来不会硌疼么&#xff1f;赤脚踩在看起来扎脚硌脚的路面上&#xff0c;因为怕疼&#xff0c;我们的脚落地会轻而…

微型计算机频繁死机的原因,电脑经常死机是什么原因|电脑经常死机的解决方法...

‍‍电脑出现死机是很常见的一种故障&#xff0c;造成的原因也有很多种。而最近有些用户的电脑经常死机&#xff0c;开机几分钟就死机&#xff0c;有时还会出现蓝屏&#xff0c;这到底是怎么回事呢&#xff1f;电脑经常死机是什么原因呢&#xff1f;下面小编结合自己的实际情况…

Linux系统命令行的符号含义

内容整理于网络&#xff0c;如有侵权&#xff0c;请告知删除。 1、常见符号含义 . 代表当前目录 .. 代表上一层目录&#xff0c;当前目录的父目录 - 代表前一个目录&#xff0c;我刚才从哪个目录cd过来 ~ 代表当前用户的宿主目录 / 代表根目录 $ 普通用户的命令行提示符…

ExtJs 分组表格控件----监听

ExtJs 分组表格控件----监听2013年8月1日10:59如图&#xff0c;点击expand可以展开所有的分组&#xff0c;collapse可以合并所有的列&#xff0c;toggle和toggleone展开合并一个分组Ext.get(expand).on(click, function() { grid.getView().expandAllGroups(); });…

PKI系统深入介绍

公钥基础设施&#xff08;Public Key Infrastructure&#xff0c;简称PKI&#xff09;是眼下网络安全建设的基础与核心&#xff0c;是电子商务安全实施的基本保障&#xff0c;因此&#xff0c;对PKI技术的研究和开发成为眼下信息安全领域的热点。本文对PKI技术进行了全面的分析…

html 禁止缩放 ios10,完美解决ios10及以上Safari无法禁止缩放的问题

完美解决 ios10 及以上 Safari 无法禁止缩放的问题转载自掘金-互联网学徒移动端web缩放有两种&#xff1a;双击缩放双指手势缩放在 iOS 10之前&#xff0c;iOS 和 Android 都可以通过一行 meta 标签来禁止页面缩放&#xff1a;但 iOS 10开始&#xff0c;meta 设置在 Safari 内无…

SCRT软件的使用教程

以下内容源于网络资源的学习与整理&#xff0c;如有侵权请告知删除。 SCRT软件下载&#xff1a;提取码1234 快速链接的步骤与设置 先选择“快速链接”&#xff1b; 然后协议选serial&#xff0c;端口在设备管理器中查看&#xff08;我的是com3&#xff09;&#xff0c;波特率…