Mp4

mp4v2を使用してH.264をmp4にパッケージ化する最も簡単な例



Simplest Example Using Mp4v2 Package H



hmp264を使用してh.264をmp4にパッケージ化する最も簡単な例


いくつかの重要なAPI

  • MP4Create

    /* * Function: Create an mp4 file * Parameters: fileName - mp4 filename * Parameters: flags - set properties (MP4_CREATE_64BIT_DATA, MP4_CREATE_64BIT_TIME) * Return value: handle of mp4 file */ MP4FileHandle MP4Create( const char* fileName, uint32_t flags DEFAULT(0) )
  • MP4Close



    /* * Function: Close mp4 file, this function must be called after writing mp4 file, otherwise mp4 file will be damaged * Parameters: handle of hFile - mp4 file */ void MP4Close( MP4FileHandle hFile, uint32_t flags DEFAULT(0) )
  • MP4AddH264VideoTrack

    /* * Function: Add track, which is equivalent to adding one stream * Parameters: handle of hFile - mp4 file * Parameters: width - video width * Parameters: height - video height * Parameters: AVCProfileIndication - sps[1] * Parameters: profile_compat - sps[2] * Parameters: AVCLevelIndication - sps[3] * Parameters: sampleLenFieldSizeMinusOne - set to 3 * Return value: add track id */ MP4TrackId MP4AddH264VideoTrack( MP4FileHandle hFile, uint32_t timeScale, MP4Duration sampleDuration, uint16_t width, uint16_t height, uint8_t AVCProfileIndication, uint8_t profile_compat, uint8_t AVCLevelIndication, uint8_t sampleLenFieldSizeMinusOne )
  • MP4AddH264SequenceParameterSet



    /* * Function: Add sps to mp4 file * Parameters: handle of hFile - mp4 file * Parameters: pSequence - a pointer to sps * Parameters: length of sequenceLen - sps */ MP4V2_EXPORT void MP4AddH264SequenceParameterSet( MP4FileHandle hFile, MP4TrackId trackId, const uint8_t* pSequence, uint16_t sequenceLen )
  • MP4AddH264PictureParameterSet

    /* * Function: Add sps to mp4 file * Parameters: handle of hFile - mp4 file * Parameters: pPict - a pointer to pps * Parameters: pictLen - length of pps */ void MP4AddH264PictureParameterSet( MP4FileHandle hFile, MP4TrackId trackId, const uint8_t* pPict, uint16_t pictLen )
  • MP4WriteSample

    /* * Function: Write to nalu * Parameters: handle of hFile - mp4 file * Note: The first four bytes indicate the length of the nalu */ bool MP4WriteSample( MP4FileHandle hFile, MP4TrackId trackId, const uint8_t* pBytes, uint32_t numBytes, MP4Duration duration DEFAULT(MP4_INVALID_DURATION), MP4Duration renderingOffset DEFAULT(0), bool isSyncSample DEFAULT(true) )v

包装プロセス

sps pps 他の種類のナルMP4Create MP4AddH264VideoTrack MP4AddH264SequenceParameterSet MP4AddH264PictureParameterSet MP4WriteSample

ソースコード

#include #include #include #include int getNalu(FILE *pFile, unsigned char *pNalu) { unsigned char c int pos = 0 int len if(!pFile) return -1 if((len = fread(pNalu, 1, 4, pFile)) <= 0) return -1 if(pNalu[0] != 0 || pNalu[1] != 0 || pNalu[2] != 0 || pNalu[3] != 1) return -1 pos = 4 while(1) { if(feof(pFile)) break pNalu[pos] = fgetc(pFile) if(pNalu[pos-3] == 0 && pNalu[pos-2] == 0 && pNalu[pos-1] == 0 && pNalu[pos] == 1) { fseek(pFile, -4, SEEK_CUR) pos -= 4 break } pos++ } len = pos+1 return len } int packet2Mp4(const char *inputFile, const char *outputFiles) { FILE *pIn = NULL unsigned char *pBuf = malloc(1024*1024) unsigned char *pNalu = NULL unsigned char naluType int len int num = 0 MP4FileHandle pHandle = NULL MP4TrackId videoId int width = 640 int height = 480 int frameRate = 15 int timeScale = 90000 int addStream = 1 pIn = fopen(inputFile, 'rb') if(!pIn) return -1 pHandle = MP4Create(outputFiles, 0) if(pHandle == MP4_INVALID_FILE_HANDLE) { printf('ERROR:Create mp4 handle fialed. ') return -1 } MP4SetTimeScale(pHandle, timeScale) while(1) { len = getNalu(pIn, pBuf) if (len <= 0) break if (pBuf[0] != 0 || pBuf[1] != 0 || pBuf[2] != 0 || pBuf[3] != 1) continue len -= 4 pNalu = pBuf+4 naluType = pNalu[0]&0x1F switch (naluType) { case 0x07: // SPS printf('------------------------------------ ') printf('sps(%d) ', len) if (addStream) { videoId = MP4AddH264VideoTrack (pHandle, timeScale, // How many timescales in a second timeScale/frameRate, // How many timescales per frame width, // width height, // height pNalu[1], // sps[1] AVCProfileIndication pNalu[2], // sps[2] profile_compat pNalu[3], // sps[3] AVCLevelIndication 3) // 4 bytes length before each NAL unit if (videoId == MP4_INVALID_TRACK_ID) { printf('Error:Can't add track. ') return -1 } MP4SetVideoProfileLevel(pHandle, 0x7F) addStream = 0 } MP4AddH264SequenceParameterSet(pHandle, videoId, pNalu, len) break case 0x08: // PPS printf('pps(%d) ', len) MP4AddH264PictureParameterSet(pHandle, videoId, pNalu, len) break default: printf('slice(%d) ', len) pBuf[0] = (len>>24)&0xFF pBuf[1] = (len>>16)&0xFF pBuf[2] = (len>>8)&0xFF pBuf[3] = (len>>0)&0xFF MP4WriteSample(pHandle, videoId, pBuf, len+4, MP4_INVALID_DURATION, 0, 1) break } } free(pBuf) fclose(pIn) MP4Close(pHandle, 0) return 0 } int main(int argc, char *argv[]) { if (packet2Mp4('test.h264', 'test.mp4')) { printf('Error:Packet to Mp4 fail. ') return -1 } return 0 }