1.
交叉编译
../configure --prefix=/work/MP4V2_arm --host=arm-hisiv300-linux --disable-debug --disable-shared CC=arm-hisiv300-linux-gcc CXX=arm-hisiv300-linux-g++
make
make install
/* 音频封装注意事项: */
一定要设置音频解码参数:
方法:
1.
可以通过faac获得解码参数:
2.
分析源码自己填充解码参数
int GetSRIndex(unsigned int sampleRate)
{
if (92017 <= sampleRate) return 0;
if (75132 <= sampleRate) return 1;
if (55426 <= sampleRate) return 2;
if (46009 <= sampleRate) return 3;
if (37566 <= sampleRate) return 4;
if (27713 <= sampleRate) return 5;
if (23004 <= sampleRate) return 6;
if (18783 <= sampleRate) return 7;
if (13856 <= sampleRate) return 8;
if (11502 <= sampleRate) return 9;
if (9391 <= sampleRate) return 10;
return 11;
}//--------->通过此函数查看自己的编码率:------我的事44100 (Sample Rate Index)所以是 4
#define MAIN 1
#define LOW 2
#define SSR 3
#define LTP 4 ------->AAC Object Type
char pConfig[] = {0x12, 0x8}设置规则:
前五 bit为 AAC object types LOW 2
接着4 bit为 码率index 44100 4
接着4 bit为 channels 个数 1
应打印出的正确2进制形式为 00010 | 0100 | 0001 | 000
2 8 1
------>pConfig[] = {0x12, 0x8};
2.
封装MP4:
/* 1. 头文件 */
#include
/* 2. 定义MP4文件相关文件句柄 */
MP4FileHandle Mp4File;
MP4TrackId Mp4Video;
MP4TrackId Mp4Audio;
char pConfig[] = {0x12, 0x8};
/* 3. 定义视频数据相关的初始sps和pps,后期会修改为接受视频流的sps和pps */
unsigned char sps[30] = {0x67, 0x42, 0x00, 0x32, 0x95 ,0xa8, 0x09, 0xd0, 0x27, 0xf9, 0x26, 0xe0,0x20,0x20,0x20,0x40}; //根据视频流而定
unsigned char pps[30] = {0x67, 0xCE, 0x3c, 0x80};
/* 4. 打开MP4的视频文件 */
Mp4File = MP4Create(stream_filename, MP4_CREATE_64BIT_DATA);
if (Mp4File == MP4_INVALID_FILE_HANDLE)
{
printf("open file fialed.\n");
return NULL;
}
MP4SetTimeScale(Mp4File, 90000);
/* 5. 添加视频数据到MP4文件中 */
Mp4Video = MP4AddH264VideoTrack(Mp4File, 90000, FPS, Width, u32PicHeight, sps[1], sps[2], sps[3], 3);
if (Mp4Video == MP4_INVALID_TRACK_ID)
{
printf("add video track failed.\n");
return NULL;
}
/* 6. 添加sps pps */
MP4AddH264SequenceParameterSet(Mp4File, Mp4Video, sps, 17);
MP4AddH264PictureParameterSet(Mp4File, Mp4Video, pps, 4);
MP4SetVideoProfileLevel(Mp4File, 0x7F);
/* 获取sps和pps */
if((stStream.pstPack[numPack].pu8Addr[0] == 0x00) && (stStream.pstPack[numPack].pu8Addr[1] == 0x00) && \
(stStream.pstPack[numPack].pu8Addr[2] == 0x00) && (stStream.pstPack[numPack].pu8Addr[3] == 0x01))
{
/* sps */
if(stStream.pstPack[numPack].pu8Addr[4] == 0x67)
{
int spsLen = stStream.pstPack[numPack].u32Len - 4;
memcpy(sps, &stStream.pstPack[numPack].pu8Addr[4], spsLen);
sps[spsLen] = '\0';
MP4AddH264SequenceParameterSet(Mp4File, Mp4Video, sps, spsLen);
}
/* pps */
if(stStream.pstPack[numPack].pu8Addr[4] == 0x68)
{
int ppsLen = stStream.pstPack[numPack].u32Len - 4;
memcpy(pps, &stStream.pstPack[numPack].pu8Addr[4], ppsLen);
pps[ppsLen] = '\0';
MP4AddH264PictureParameterSet(Mp4File, Mp4Video, pps, ppsLen);
}
}
/* 添加音频数据设置 */
Mp4Audio = MP4AddAudioTrack(Mp4File, 1600, MP4_INVALID_DURATION, MP4_MPEG4_AUDIO_TYPE); //MP4_MPEG2_AAC_LC_AUDIO_TYPE
if(Mp4Audio == MP4_INVALID_TRACK_ID)
{
MP4Close(Mp4File, 0);
return NULL;
}
MP4SetAudioProfileLevel(Mp4File, 0x0F);
MP4SetTrackESConfiguration(Mp4File, Mp4Audio, &pConfig, 2);
/* 向MP4文件中添加视频数据 */
while(1)
{
for ( numPack = 0; numPack < stStream.u32PackCount; numPack++)
{
memcpy(&str_buffer[0] + BufSize,stStream.pstPack[numPack].pu8Addr,
stStream.pstPack[numPack].u32Len);
if(stStream.pstPack[numPack].u32Len >= 4)
{
str_buffer[BufSize] = ((stStream.pstPack[numPack].u32Len - 4) & 0xff000000) >> 24;
str_buffer[BufSize + 1] = ((stStream.pstPack[numPack].u32Len - 4) & 0x00ff0000) >> 16;
str_buffer[BufSize + 2] = ((stStream.pstPack[numPack].u32Len - 4) & 0x0000ff00) >> 8;
str_buffer[BufSize + 3] = (stStream.pstPack[numPack].u32Len - 4) & 0x000000ff;
}
//memcpy(frame_data+pkt.size,stStream.pstPack[numPack].pu8Addr + stStream.pstPack[numPack].u32Offset,pkt.size);
BufSize += stStream.pstPack[numPack].u32Len;
}
MP4WriteSample(Mp4File, Mp4Video, str_buffer, BufSize, MP4_INVALID_DURATION, 0, 1);
}