#include "MP4File.h"
#include <mp4v2/mp4v2.h>
#include <stdio.h>
#define MP4_TRUE 0
#define MP4_FAULE (-1)
void Write_SPS(PT_MP4File ptMP4File)
{
MP4AddH264SequenceParameterSet(ptMP4File->Mp4File, ptMP4File->Mp4Video, ptMP4File->sps, ptMP4File->spsLen);
}
void Write_PPS(PT_MP4File ptMP4File)
{
MP4AddH264PictureParameterSet(ptMP4File->Mp4File, ptMP4File->Mp4Video, ptMP4File->pps, ptMP4File->ppsLen);
}
bool MP4FileOpen(PT_MP4File ptMP4File, char *pMp4FileName)
{
ptMP4File->Mp4File= MP4Create(pMp4FileName, MP4_CREATE_64BIT_DATA);
if (ptMP4File->Mp4File == MP4_INVALID_FILE_HANDLE)
{
printf("open file fialed.\n");
return MP4_FAULE;
}
return MP4_TRUE;
}
bool MP4FileAddVideo(PT_MP4File ptMP4File, unsigned int Fps, unsigned int u32PicWidth,unsigned int u32PicHeight)
{
ptMP4File->Mp4Video = MP4AddH264VideoTrack(ptMP4File->Mp4File, 90000, 90000/Fps, u32PicWidth, u32PicHeight, ptMP4File->sps[1], ptMP4File->sps[2], ptMP4File->sps[3], 3);
if (ptMP4File->Mp4Video == MP4_INVALID_TRACK_ID)
{
printf("add video track failed.\n");
return MP4_FAULE;
}
MP4SetTimeScale(ptMP4File->Mp4File, 90000);
Write_SPS(ptMP4File);
Write_PPS(ptMP4File);
MP4SetVideoProfileLevel(ptMP4File->Mp4File, 0x7F);
return MP4_TRUE;
}
bool MP4FileAddAudio(PT_MP4File ptMP4File)
{
ptMP4File->Mp4Audio = MP4AddAudioTrack(ptMP4File->Mp4File, AUDIO_SAMPLE_RATE_44100, 1024, MP4_MPEG2_AAC_MAIN_AUDIO_TYPE);//MP4_MPEG4_AUDIO_TYPE); //MP4_MPEG2_AAC_LC_AUDIO_TYPE
if(ptMP4File->Mp4Audio == MP4_INVALID_TRACK_ID)
{
MP4Close(ptMP4File->Mp4File, 0);
return MP4_FAULE;
}
MP4SetTrackESConfiguration(ptMP4File->Mp4File, ptMP4File->Mp4Audio, ptMP4File->pConfig, 2);
MP4SetAudioProfileLevel(ptMP4File->Mp4File, 0x0F);
return MP4_TRUE;
}
bool Initialize(PT_MP4File ptMP4File, char *pMp4FileName, unsigned int Fps, unsigned int u32PicWidth,unsigned int u32PicHeight)
{
if(MP4FileOpen(ptMP4File, pMp4FileName))
return MP4_FAULE;
if(MP4FileAddVideo(ptMP4File, Fps, u32PicWidth, u32PicHeight))
return MP4_FAULE;
if(MP4FileAddAudio(ptMP4File))
return MP4_FAULE;
return MP4_TRUE;
}
void WriteVideo(PT_MP4File ptMP4File, VENC_STREAM_S * pstStream)
{
//save mp4
int numPack = 0;
char str_buffer[1000*1024] = "";
unsigned int BufSize = 0;
unsigned int H264Length = 0;
memset(str_buffer, 0, 1000*1024);
for ( numPack = 0; numPack < pstStream->u32PackCount; numPack++)
{
memcpy(&str_buffer[0] + BufSize,pstStream->pstPack[numPack].pu8Addr,
pstStream->pstPack[numPack].u32Len);
if(pstStream->pstPack[numPack].u32Len >= 4)
{
str_buffer[BufSize] = ((pstStream->pstPack[numPack].u32Len - 4) & 0xff000000) >> 24;
str_buffer[BufSize + 1] = ((pstStream->pstPack[numPack].u32Len - 4) & 0x00ff0000) >> 16;
str_buffer[BufSize + 2] = ((pstStream->pstPack[numPack].u32Len - 4) & 0x0000ff00) >> 8;
str_buffer[BufSize + 3] = (pstStream->pstPack[numPack].u32Len - 4) & 0x000000ff;
}
//memcpy(frame_data+pkt.size,stStream.pstPack[numPack].pu8Addr + stStream.pstPack[numPack].u32Offset,pkt.size);
BufSize += pstStream->pstPack[numPack].u32Len;
}
MP4WriteSample(ptMP4File->Mp4File, ptMP4File->Mp4Video, str_buffer, BufSize, MP4_INVALID_DURATION, 0, 1);
}
void WriteAAC(PT_MP4File ptMP4File, unsigned char *pBuffer, unsigned int nLen)
{
MP4WriteSample(ptMP4File->Mp4File, ptMP4File->Mp4Audio, pBuffer, nLen , MP4_INVALID_DURATION, 0, 1);
}
void CloseMP4File(PT_MP4File ptMP4File)
{
MP4Close(ptMP4File->Mp4File, 0);
}
bool Get_SPS_PPS(VENC_STREAM_S * pstStream, PT_MP4File ptMP4File)
{
int numPack = 0;
if(pstStream->u32PackCount == 4)
{
for(numPack = 0; numPack < pstStream->u32PackCount; numPack++)
{
if((pstStream->pstPack[numPack].pu8Addr[0] == 0x00) && (pstStream->pstPack[numPack].pu8Addr[1] == 0x00) && \
(pstStream->pstPack[numPack].pu8Addr[2] == 0x00) && (pstStream->pstPack[numPack].pu8Addr[3] == 0x01))
{
/* sps */
if(pstStream->pstPack[numPack].pu8Addr[4] == 0x67)
{
int spsLen = pstStream->pstPack[numPack].u32Len - 4;
memcpy(ptMP4File->sps, &pstStream->pstPack[numPack].pu8Addr[4], spsLen);
ptMP4File->sps[spsLen] = '\0';
ptMP4File->spsLen= spsLen;
}
/* pps */
if(pstStream->pstPack[numPack].pu8Addr[4] == 0x68)
{
int ppsLen = pstStream->pstPack[numPack].u32Len - 4;
memcpy(ptMP4File->pps, &pstStream->pstPack[numPack].pu8Addr[4], ppsLen);
ptMP4File->pps[ppsLen] = '\0';
ptMP4File->ppsLen= ppsLen;
}
}
}
return MP4_TRUE;
}
return MP4_FAULE;
}