博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
01.mp4v2应用—mp4转h264
阅读量:7185 次
发布时间:2019-06-29

本文共 3401 字,大约阅读时间需要 11 分钟。

1.h264文件基本功能

NAL 头 0x00 0x00 0x00 0x01 

sps :nal+0x67开头 
pps :nal+0x68开头

I帧 0x65 开头 

......

2.mp4v2提取264文件的代码

#include 
#include
#include
#include
#include
#include
#include
#include
unsigned char sps[64],pps[64];int spslen = 0,ppslen = 0;int get264stream(MP4FileHandle oMp4File,int VTrackId,int totalFrame){ if(!oMp4File) return -1; char NAL[5] = { 0x00,0x00,0x00,0x01}; unsigned char *pData = NULL; unsigned int nSize = 0; MP4Timestamp pStartTime; MP4Duration pDuration; MP4Duration pRenderingOffset; bool pIsSyncSample = 0; int nReadIndex = 0; FILE *pFile = NULL; pFile = fopen("out.h264","wb"); while(nReadIndex < totalFrame) { nReadIndex ++; //printf("nReadIndex:%d\n",nReadIndex); MP4ReadSample(oMp4File,VTrackId,nReadIndex,&pData,&nSize,&pStartTime,&pDuration,&pRenderingOffset,&pIsSyncSample); //IDR֡ 帧,写入sps pps先 if(pIsSyncSample) { fwrite(NAL,4,1,pFile); fwrite(sps,spslen,1,pFile); fwrite(NAL,4,1,pFile); fwrite(pps,ppslen,1,pFile); } //264frame if(pData && nSize > 4) { //标准的264帧,前面几个字节就是frame的长度. //需要替换为标准的264 nal 头. pData[0] = 0x00; pData[1] = 0x00; pData[2] = 0x00; pData[3] = 0x01; fwrite(pData,nSize,1,pFile); } //如果传入MP4ReadSample的视频pData是null // 它内部就会new 一个内存 //如果传入的是已知的内存区域, //则需要保证空间bigger then max frames size. free(pData); pData = NULL; } fflush(pFile); fclose(pFile); return 0;}int openmp4file(char *sMp4file){ MP4FileHandle oMp4File; int i; //unsigned int oStreamDuration; unsigned int oFrameCount; oMp4File = MP4Read(sMp4file); int videoindex = -1,audioindex = -1; uint32_t numSamples; //uint32_t timescale; //uint64_t duration; if (!oMp4File) { printf("Read error....%s\r\n",sMp4file); return -1; } MP4TrackId trackId = MP4_INVALID_TRACK_ID; uint32_t numTracks = MP4GetNumberOfTracks(oMp4File,NULL,0); printf("numTracks:%d\n",numTracks); for (i = 0; i < numTracks; i++) { trackId = MP4FindTrackId(oMp4File, i,NULL,0); const char* trackType = MP4GetTrackType(oMp4File, trackId); if (MP4_IS_VIDEO_TRACK_TYPE(trackType)) { //printf("[%s %d] trackId:%d\r\n",__FUNCTION__,__LINE__,trackId); videoindex= trackId; //duration = MP4GetTrackDuration(oMp4File, trackId ); numSamples = MP4GetTrackNumberOfSamples(oMp4File, trackId); //timescale = MP4GetTrackTimeScale(oMp4File, trackId); //oStreamDuration = duration/(timescale/1000); oFrameCount = numSamples; // read sps/pps uint8_t **seqheader; uint8_t **pictheader; uint32_t *pictheadersize; uint32_t *seqheadersize; uint32_t ix; MP4GetTrackH264SeqPictHeaders(oMp4File, trackId, &seqheader, &seqheadersize, &pictheader, &pictheadersize); for (ix = 0; seqheadersize[ix] != 0; ix++) { memcpy(sps, seqheader[ix], seqheadersize[ix]); spslen = seqheadersize[ix]; free(seqheader[ix]); } free(seqheader); free(seqheadersize); for (ix = 0; pictheadersize[ix] != 0; ix++) { memcpy(pps, pictheader[ix], pictheadersize[ix]); ppslen = pictheadersize[ix]; free(pictheader[ix]); }          free(pictheader); free(pictheadersize); }131 else if (MP4_IS_AUDIO_TRACK_TYPE(trackType)) { audioindex = trackId; printf("audioindex:%d\n",audioindex); } } //解析完了mp4,主要是为了获取sps pps 还有video的trackID if(videoindex >= 0) get264stream(oMp4File,videoindex,oFrameCount); //需要mp4close 否则在嵌入式设备打开mp4上多了会内存泄露挂掉. MP4Close(oMp4File,0); return 0;}int main(void){ openmp4file("test.mp4"); return 0;}

 

转载于:https://www.cnblogs.com/Lwd-linux/p/7390951.html

你可能感兴趣的文章
编译时
查看>>
Android中实现两次点击返回键退出本程序
查看>>
git 教程1
查看>>
django(一)
查看>>
架构探险笔记9-框架优化之参数优化
查看>>
循环链表(隔M杀1)
查看>>
【转】C语言中access函数
查看>>
Journal List
查看>>
JavaScript-构造函数模式
查看>>
浅试 Webview 一app 加载 H5小游戏
查看>>
谈谈OpenNI 2初体验
查看>>
stars
查看>>
Boosting决策树:GBDT
查看>>
投影矩阵
查看>>
微软职位内部推荐-Senior Software Engineer II-Search
查看>>
如何使用JCONSOLE 监控eclipse的tomcat
查看>>
SpringBoot+Maven多模块项目(创建、依赖、打包可执行jar包部署测试)完整流程
查看>>
Caused by: java.sql.SQLException: Field 'id' doesn't have a default value
查看>>
gitHub上如何设置或者取消电子邮箱提醒
查看>>
VC++2005快速构建安全的应用程序
查看>>