pcm+H264封装MP4代码

昵称:海鱼           日期:20141110日—20141117

1.本周已完成任务:对添加osd代码进行了解

2.本周未完成任务:改善添加的osd代码

3.下周计划:改善osd代码

4.关键技术点说明:

因为osd代码没有完成,所以就把前面的代码拿出来了


为了音视频同步,我在裸音频流中每写320个字节,加入了8字节的时间戳,每个I,p帧H264的视频流中加了时间戳。

程序读出各时间戳比较,因为是随便写的DEMO,前提是视频全程都有,音频从一段时间后开始,所以我只是将视频的第一个时间戳拿出来,作为起始时间,然后音频的第一个时间戳大于它就写入空数据,直到小于它时再开始写入音频。

前面一个微博写的G711A+H264封装成MP4的有个严重的bug,因为写入音视频是一起的,哪个读完数据就停止,然而写音频和视频的时间不同。比如我录制的pcm音频2048个字节大概播放0.128秒,H264视频每个I,P帧是40ms,这样会导致音频插入了20s而视频就只插入了7s左右,导致播放中视频就卡住了,音频还在播。

所以这次改成了先把视频全部写进MP4文件后再写音频,靠起始时间戳和每次写入加上对应的时间来计算当前时间,这样可以将音视频更好的加入,也能保持音视频同步。

#include <fcntl.h>
#include <stdio.h>
#include <ctype.h>  
#include <errno.h>
#include <stdlib.h>
#include <string.h>
#include <limits.h>  
#include <unistd.h>
#include <signal.h>
#include <dirent.h>
#include <pthread.h>

#include <asm/types.h>
#include <arpa/inet.h>

#include <sys/vfs.h>
#include <sys/time.h>
#include <sys/wait.h>
#include <sys/stat.h> 
#include <sys/ioctl.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <sys/utsname.h> 

#include <netdb.h>  
#include <net/if.h>
#include <netinet/in.h>
#include <net/route.h>
#include <net/if_arp.h>

#include <linux/fs.h>
#include <linux/sockios.h>   
#include <linux/netlink.h>
#include <linux/rtnetlink.h>

#include <netinet/in.h>
#include <netinet/ip.h>   
#include <netinet/ether.h>
#include <netinet/ip_icmp.h>  

#include "faac.h"
#include "mp4v2.h"  


#define  JOSEPH_G711A_LOCATION  "../av_file/test1.pcm"
#define  JOSEPH_H264_LOCALTION "../av_file/test1.h264"
#define  JOSEPH_MP4_FILE   "test.mp4"

#define  MP4_DETAILS_ALL	 0xFFFFFFFF
#define  NALU_SPS  0
#define  NALU_PPS  1
#define  NALU_I    2
#define  NALU_P    3
#define  NALU_SET  4

typedef unsigned int  uint32_t;
typedef unsigned char   uint8_t;

typedef struct Joseph_Acc_Config
{
	FILE* fpIn;                    //打开的音频文件
	faacEncHandle hEncoder;        //音频文件描述符
	unsigned long nSampleRate;     //音频采样数
	unsigned int nChannels;  	      //音频声道数
	unsigned int nPCMBitSize;        //音频采样精度
	unsigned long nInputSamples;      //每次调用编码时所应接收的原始数据长度
	unsigned long nMaxOutputBytes;    //每次调用编码时生成的AAC数据的最大长度
	unsigned char* pbPCMBuffer;       //pcm数据
	unsigned char* pbAACBuffer;       //aac数据
	unsigned long long int timestamp;
	unsigned long long int mtimestamp;
}JOSEPH_ACC_CONFIG;

typedef struct Joseph_Mp4_Config
{
	FILE* fpInVideo;               //打开的视频文件
	MP4FileHandle hFile;          //mp4文件描述符
	MP4TrackId video;              //视频轨道标志符
	MP4TrackId audio;              //音频轨道标志符
	int m_vFrameDur;               //帧间隔时间
	unsigned int timeScale;        //视频每秒的ticks数,如90000
	unsigned int fps;              //视频帧率
	unsigned short width;          //视频宽
	unsigned short height;         //视频高
	unsigned long long int timestamp;
	unsigned long long int mtimestamp;
}JOSEPH_MP4_CONFIG;
int joseph_get_h264_frame(JOSEPH_MP4_CONFIG* joseph_mp4_config)
{		
	joseph_mp4_config->fpInVideo = fopen(JOSEPH_H264_LOCALTION, "rb");
	return 0;
}

/***********************************************************mp4 encode***********************************************/
JOSEPH_MP4_CONFIG* InitMp4Encoder(JOSEPH_ACC_CONFIG* joseph_aac_config)
{
	JOSEPH_MP
  • 3
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值