Mp4v2封装H264+AAC为MP4

http://blog.csdn.net/u011298831/article/details/52119948


本文介绍Mp4v2的使用,成功将H264 ES文件和AAC文件封装成MP4文件


1. Mp4V2使用VS2013编译

studio9.0\下打开方案

一般情况,编译会出现错误

原因是缺少几个关键文件:vstudio9.0\libmp4v2\Version.rc

Libplatform\platform_win32_impl.h  Libplatform\platform_win32.cpp

点击下载缺失文件(http://download.csdn.NET/download/u011298831/9594523):点击打开链接

下载文件放入响应位置即可成功编译,生成bin\目录下的相关文件


2. 新建项目Mux

这里给出一个MP4Encoder的封装类

[cpp]  view plain  copy
  1. /******************************************************************** 
  2. filename:   MP4Encoder.h 
  3. created:    2016-08-06 
  4. author:     Donyj 
  5. purpose:    MP4编码器,基于开源库mp4v2实现(https://code.google.com/p/mp4v2/)。 
  6. *********************************************************************/  
  7. #pragma once  
  8. #include "mp4v2\mp4v2.h"  
  9.   
  10. // NALU单元  
  11. typedef struct _MP4ENC_NaluUnit  
  12. {  
  13.     int type;  
  14.     int size;  
  15.     unsigned char *data;  
  16. }MP4ENC_NaluUnit;  
  17.   
  18. typedef struct _MP4ENC_Metadata  
  19. {  
  20.     // video, must be h264 type  
  21.     unsigned int    nSpsLen;  
  22.     unsigned char   Sps[1024];  
  23.     unsigned int    nPpsLen;  
  24.     unsigned char   Pps[1024];  
  25.   
  26. } MP4ENC_Metadata, *LPMP4ENC_Metadata;  
  27.   
  28. class MP4Encoder  
  29. {  
  30. public:  
  31.     MP4Encoder(void);  
  32.     ~MP4Encoder(void);  
  33. public:  
  34.     // open or creat a mp4 file.  
  35.     bool MP4FileOpen(const char *fileName, int width, int height, int timeScale = 90000, int frameRate = 25);  
  36.     // wirte 264 metadata in mp4 file.  
  37.     bool Write264Metadata(MP4FileHandle hMp4File, LPMP4ENC_Metadata lpMetadata);  
  38.     // wirte 264 data, data can contain  multiple frame.  
  39.     int WriteH264Data(MP4FileHandle hMp4File, const unsigned char* pData, int size);  
  40.     // close mp4 file.  
  41.     void MP4FileClose();  
  42.     // convert H264 file OR aac file to mp4 file.  
  43.     bool MP4FileWrite(int(*read_h264)(unsigned char *buf, int buf_size), int(*read_aac)(unsigned char *buf, int buf_size));  
  44.       
  45.     // Prase H264 metamata from H264 data frame  
  46.     static bool PraseMetadata(const unsigned char* pData, int size, MP4ENC_Metadata &metadata);  
  47. private:  
  48.     // read one nalu from H264 data buffer  
  49.     static int ReadOneNaluFromBuf(const unsigned char *buffer, unsigned int nBufferSize, unsigned int offSet, MP4ENC_NaluUnit &nalu);  
  50. private:  
  51.     int m_nWidth;  
  52.     int m_nHeight;  
  53.     double m_nFrameRate;  
  54.     int m_nTimeScale;  
  55.     MP4FileHandle m_hMp4File;  
  56.     MP4TrackId m_videoId;  
  57.     MP4TrackId m_audioId;  
  58. };  

本例存在使用默认已知参数的情况,读者可根据自己的情况修改参数,或者实时从数据中解析出来进行设置;一下是完整cpp文件:

[cpp]  view plain  copy
  1. /******************************************************************** 
  2. filename:   MP4Encoder.h 
  3. created:    2016-08-06 
  4. author:     Donyj 
  5. purpose:    MP4编码器,基于开源库mp4v2实现(https://code.google.com/p/mp4v2/)。 
  6. *********************************************************************/  
  7. #include "MP4Encoder.h"  
  8. //#include "sps_decode.h"  
  9. #include <string.h>  
  10. #include "sps_pps_parser.h"  
  11. #include <stdio.h>  
  12. #include <Windows.h>  
  13.   
  14. static double audio_tick_gap = (1024000.0) / (48000.0);  
  15. static double video_tick_gap = (1000.0 + 1.0) / 30.0;  
  16. static int sps_wt = 0; //确保sps已经 MP4AddH264SequenceParameterSet  
  17. static int pps_wt = 0; //确保pps已经 MP4AddH264PictureParameterSet  
  18.   
  19. #define BUFFER_SIZE     (1024*1024)  
  20. #define FRAME_FRATE     (30)  
  21. #define TIME_SCALE      (90000)  
  22.   
  23.   
  24.   
  25. MP4Encoder::MP4Encoder(void) :  
  26. m_videoId(NULL),  
  27. m_nWidth(0),  
  28. m_nHeight(0),  
  29. m_nTimeScale(TIME_SCALE),  
  30. m_nFrameRate(FRAME_FRATE)  
  31. {  
  32.     m_hMp4File = NULL;  
  33.     m_audioId = NULL;  
  34. }  
  35.   
  36. MP4Encoder::~MP4Encoder(void)  
  37. {  
  38.     if (m_hMp4File != NULL)  
  39.     {  
  40.         MP4Close(m_hMp4File);  
  41.         m_hMp4File = NULL;  
  42.     }  
  43. }  
  44.   
  45. bool MP4Encoder::MP4FileOpen(const char *pFileName, int width, int height, int timeScale/* = 90000*/int frameRate/* = 25*/)  
  46. {  
  47.     if (pFileName == NULL)  
  48.     {  
  49.         return false;  
  50.     }  
  51.     // create mp4 file  
  52.     m_hMp4File = MP4Create(pFileName);  
  53.     if (m_hMp4File == MP4_INVALID_FILE_HANDLE)  
  54.     {  
  55.         printf("ERROR:Open file fialed.\n");  
  56.         return false;  
  57.     }  
  58.     m_nWidth = width;  
  59.     m_nHeight = height;  
  60.     m_nTimeScale = TIME_SCALE;  
  61.     m_nFrameRate = FRAME_FRATE;  
  62.     MP4SetTimeScale(m_hMp4File, m_nTimeScale);  
  63.   
  64.     return true;  
  65. }  
  66.   
  67. bool MP4Encoder::Write264Metadata(MP4FileHandle hMp4File, LPMP4ENC_Metadata lpMetadata)  
  68. {  
  69.     m_videoId = MP4AddH264VideoTrack  
  70.         (hMp4File,  
  71.         m_nTimeScale,  
  72.         m_nTimeScale / m_nFrameRate,  
  73.         m_nWidth, // width  
  74.         m_nHeight,// height  
  75.         lpMetadata->Sps[1], // sps[1] AVCProfileIndication  
  76.         lpMetadata->Sps[2], // sps[2] profile_compat  
  77.         lpMetadata->Sps[3], // sps[3] AVCLevelIndication  
  78.         3);           // 4 bytes length before each NAL unit  
  79.   
  80.     if (m_videoId == MP4_INVALID_TRACK_ID)  
  81.     {  
  82.         printf("add video track failed.\n");  
  83.         return false;  
  84.     }  
  85.     MP4SetVideoProfileLevel(hMp4File, 0x03); //  Simple Profile @ Level 3  
  86.   
  87.     // write sps  
  88.     MP4AddH264SequenceParameterSet(hMp4File, m_videoId, lpMetadata->Sps, lpMetadata->nSpsLen);  
  89.   
  90.     // write pps  
  91.     MP4AddH264PictureParameterSet(hMp4File, m_videoId, lpMetadata->Pps, lpMetadata->nPpsLen);  
  92.   
  93.     return true;  
  94. }  
  95.   
  96. int MP4Encoder::WriteH264Data(MP4FileHandle hMp4File, const unsigned char* pData, int size)  
  97. {  
  98.     if (hMp4File == NULL)  
  99.     {  
  100.         return -1;  
  101.     }  
  102.     if (pData == NULL)  
  103.     {  
  104.         return -1;  
  105.     }  
  106.     MP4ENC_NaluUnit nalu;  
  107.     int pos = 0, len = 0;  
  108.     int wt_frame = 0;  //测试 - 单帧单Nalu发送  
  109.   
  110.     while (len = ReadOneNaluFromBuf(pData, size, pos, nalu))  
  111.     {  
  112.         if (nalu.type == 0x07 && sps_wt == 0) // sps  
  113.         {  
  114.             //从sps pps中获取信息  
  115.             float fps = 0.0;  
  116.             //int ret = h264_decode_sps(nalu.data, nalu.size, &m_nWidth, &m_nHeight, &fps);  
  117.             get_bit_context buffer;  
  118.             memset(&buffer, 0, sizeof(get_bit_context));  
  119.             SPS _sps;  
  120.             buffer.buf = nalu.data + 1;  
  121.             buffer.buf_size = nalu.size - 1;  
  122.             int ret = h264dec_seq_parameter_set(&buffer, &_sps);  
  123.             m_nWidth = h264_get_width(&_sps);  
  124.             m_nHeight = h264_get_height(&_sps);  
  125.             ret = h264_get_framerate(&fps, &_sps);  
  126.             if (ret == 0)  
  127.             {  
  128.                 m_nFrameRate = (double)fps;  
  129.             }  
  130.   
  131.             video_tick_gap = (1000.0 + 1.0) / m_nFrameRate;  
  132.             // 添加h264 track      
  133.             m_videoId = MP4AddH264VideoTrack  
  134.                 (hMp4File,  
  135.                 m_nTimeScale,  
  136.                 (double)m_nTimeScale / m_nFrameRate,  
  137.                 m_nWidth,     // width  
  138.                 m_nHeight,    // height  
  139.                 nalu.data[1], // sps[1] AVCProfileIndication  
  140.                 nalu.data[2], // sps[2] profile_compat  
  141.                 nalu.data[3], // sps[3] AVCLevelIndication  
  142.                 3);           // 4 bytes length before each NAL unit  
  143.             if (m_videoId == MP4_INVALID_TRACK_ID)  
  144.             {  
  145.                 printf("add video track failed.\n");  
  146.                 return 0;  
  147.             }  
  148.             MP4SetVideoProfileLevel(hMp4File, 1); //  Simple Profile @ Level 3  
  149.   
  150.             MP4AddH264SequenceParameterSet(hMp4File, m_videoId, nalu.data, nalu.size);  
  151.             sps_wt = 1;  
  152.         }  
  153.         else if (nalu.type == 0x08 && pps_wt == 0) // pps  
  154.         {  
  155.             MP4AddH264PictureParameterSet(hMp4File, m_videoId, nalu.data, nalu.size);  
  156.             pps_wt = 1;  
  157.         }  
  158.         else if (nalu.type == 0x01 || nalu.type == 0x05)  
  159.         {  
  160.             int datalen = nalu.size + 4;  
  161.             unsigned char *data = new unsigned char[datalen];  
  162.             // MP4 Nalu前四个字节表示Nalu长度  
  163.             data[0] = nalu.size >> 24;  
  164.             data[1] = nalu.size >> 16;  
  165.             data[2] = nalu.size >> 8;  
  166.             data[3] = nalu.size & 0xff;  
  167.             memcpy(data + 4, nalu.data, nalu.size);  
  168.   
  169.             bool syn = 0;  
  170.             if (nalu.type == 0x05)  
  171.             {  
  172.                 syn = 1;  
  173.             }  
  174.               
  175.             //if (!MP4WriteSample(hMp4File, m_videoId, data, datalen, MP4_INVALID_DURATION, 0, syn))  
  176.             if (!MP4WriteSample(hMp4File, m_videoId, data, datalen, 90000 / 30, 0, syn))  
  177.             {  
  178.                 return 0;  
  179.             }  
  180.             delete[] data;  
  181.             wt_frame++;  
  182.         }  
  183.   
  184.         pos += len;  
  185.         if (wt_frame > 0)  
  186.         {  
  187.             break;  
  188.         }  
  189.     }  
  190.     return pos;  
  191. }  
  192.   
  193. int MP4Encoder::ReadOneNaluFromBuf(const unsigned char *buffer, unsigned int nBufferSize, unsigned int offSet, MP4ENC_NaluUnit &nalu)  
  194. {  
  195.     int i = offSet;  
  196.     while (i<nBufferSize)  
  197.     {  
  198.         if (buffer[i++] == 0x00 &&  
  199.             buffer[i++] == 0x00 &&  
  200.             buffer[i++] == 0x00 &&  
  201.             buffer[i++] == 0x01  
  202.             )  
  203.         {  
  204.             int pos = i;  
  205.             while (pos<nBufferSize)  
  206.             {  
  207.                 if (buffer[pos++] == 0x00 &&  
  208.                     buffer[pos++] == 0x00 &&  
  209.                     buffer[pos++] == 0x00 &&  
  210.                     buffer[pos++] == 0x01  
  211.                     )  
  212.                 {  
  213.                     break;  
  214.                 }  
  215.             }  
  216.             if (pos == nBufferSize)  
  217.             {  
  218.                 nalu.size = pos - i;  
  219.             }  
  220.             else  
  221.             {  
  222.                 nalu.size = (pos - 4) - i;  
  223.             }  
  224.   
  225.             nalu.type = buffer[i] & 0x1f;  
  226.             nalu.data = (unsigned char*)&buffer[i];  
  227.             return (nalu.size + i - offSet);  
  228.         }  
  229.     }  
  230.     return 0;  
  231. }  
  232.   
  233. void MP4Encoder::MP4FileClose()  
  234. {  
  235.     if (m_hMp4File)  
  236.     {  
  237.         MP4Close(m_hMp4File);  
  238.         m_hMp4File = NULL;  
  239.     }  
  240. }  
  241.   
  242.   
  243. bool MP4Encoder::MP4FileWrite(int(*read_h264)(unsigned char *buf, int buf_size), int(*read_aac)(unsigned char *buf, int buf_size))  
  244. {  
  245.     //添加aac音频 -- default init, you can get config information by parsering aac data if you want  
  246.     m_audioId = MP4AddAudioTrack(m_hMp4File, 48000, 1024, MP4_MPEG4_AUDIO_TYPE); //1024??? 这里不明白为什么用1024 希望有大神解释下  
  247.     if (m_audioId == MP4_INVALID_TRACK_ID)  
  248.     {  
  249.         printf("add audio track failed.\n");  
  250.         return false;  
  251.     }  
  252.     MP4SetAudioProfileLevel(m_hMp4File, 0x2);  
  253.     uint8_t buf3[2] = { 0x11, 0x88 }; //important! AAC config infomation;  读者应该根据使用的AAC数据分析出此数据,  
  254.     MP4SetTrackESConfiguration(m_hMp4File, m_audioId, buf3, 2);  
  255.     //--------------------------------------------------------------------  
  256.   
  257.     unsigned char *buffer = new unsigned char[BUFFER_SIZE];  
  258.     unsigned char audioBuf[1024];  
  259.     int pos = 0;  
  260.     int readlen = 0;  
  261.     int writelen = 0;  
  262.   
  263.     //--------------------------------------------------------------------  
  264.     uint32_t audio_tick_now, video_tick_now, last_update;  
  265.     unsigned int tick = 0;  
  266.     unsigned int audio_tick = 0;  
  267.     unsigned int video_tick = 0;  
  268.   
  269.     uint32_t tick_exp_new = 0;  
  270.     uint32_t tick_exp = 0;  
  271.     //--------------------------------------------------------------------  
  272.   
  273.     audio_tick_now = video_tick_now = GetTickCount();  
  274.   
  275.     /* 
  276.         尝试时间音视频间隔内去取得视频或者音频数据进行Write 
  277.     */  
  278.     while (1)  
  279.     {  
  280.         last_update = GetTickCount();  
  281.   
  282.         //时间溢出情况处理  
  283.         if (read_h264 != NULL)  
  284.         {  
  285.             if (last_update - video_tick_now > video_tick_gap - tick_exp)  
  286.             {  
  287.                 printf("now:%lld last_update:%lld video_tick:%d tick_exp:%d\n", video_tick_now, last_update, video_tick, tick_exp);  
  288.                 video_tick += video_tick_gap;  
  289.                 ///  
  290.                 //-- 这里针对单帧单Nalu的情况处理, 若有差异,请读者自行修改  
  291.                 readlen = read_h264(buffer + pos, BUFFER_SIZE - pos);  
  292.                 if (readlen <= 0 && pos == 0)  
  293.                 {  
  294.                     break;  
  295.                 }  
  296.                 readlen += pos;  
  297.   
  298.                 //查找开始位 -- 确保存在Nalu起始位  
  299.                 writelen = 0;  
  300.                 for (int i = readlen; i >= 4; i--)  
  301.                 {  
  302.                     if (buffer[i - 1] == 0x01 &&  
  303.                         buffer[i - 2] == 0x00 &&  
  304.                         buffer[i - 3] == 0x00 &&  
  305.                         buffer[i - 4] == 0x00  
  306.                         )  
  307.                     {  
  308.                         writelen = i - 4; //???  
  309.                         break;  
  310.                     }  
  311.                 }  
  312.   
  313.                 //单个NALU  
  314.                 writelen = WriteH264Data(m_hMp4File, buffer, writelen);  
  315.                 if (writelen <= 0)  
  316.                 {  
  317.                     break;  
  318.                 }  
  319.   
  320.                 //剩余数据  
  321.                 memcpy(buffer, buffer + writelen, readlen - writelen);  
  322.                 pos = readlen - writelen;  
  323.                 if (pos == 0)  
  324.                 {  
  325.                     break;  
  326.                 }  
  327.                 ///  
  328.                 video_tick_now = GetTickCount();  
  329.             }  
  330.         }  
  331.           
  332.         if (read_aac != NULL)  
  333.         {  
  334.             if (last_update - audio_tick_now > audio_tick_gap - tick_exp)  
  335.             {  
  336.                 printf("now:%lld last_update:%lld audio_tick:%d tick_exp:%d\n", audio_tick_now, last_update, audio_tick, tick_exp);  
  337.                 audio_tick += audio_tick_gap;  
  338.                 /  
  339.                 int audio_len = read_aac(audioBuf, 1024); //get aac header if you want , so that you can get aac config info  
  340.                 if (audio_len <= 0)  
  341.                 {  
  342.                     break;  
  343.                 }  
  344.   
  345.                 MP4WriteSample(m_hMp4File, m_audioId, audioBuf, audio_len, MP4_INVALID_DURATION, 0, 1);  
  346.                 /  
  347.                 audio_tick_now = GetTickCount();  
  348.             }  
  349.         }  
  350.   
  351.         tick_exp_new = GetTickCount();  
  352.         tick_exp = tick_exp_new - last_update;  
  353.   
  354.         //sleep  
  355.     }  
  356. }  
  357.   
  358. bool MP4Encoder::PraseMetadata(const unsigned char* pData, int size, MP4ENC_Metadata &metadata)  
  359. {  
  360.     if (pData == NULL || size<4)  
  361.     {  
  362.         return false;  
  363.     }  
  364.     MP4ENC_NaluUnit nalu;  
  365.     int pos = 0;  
  366.     bool bRet1 = false, bRet2 = false;  
  367.     while (int len = ReadOneNaluFromBuf(pData, size, pos, nalu))  
  368.     {  
  369.         if (nalu.type == 0x07)  
  370.         {  
  371.             memcpy(metadata.Sps, nalu.data, nalu.size);  
  372.             metadata.nSpsLen = nalu.size;  
  373.             bRet1 = true;  
  374.         }  
  375.         else if ((nalu.type == 0x08))  
  376.         {  
  377.             memcpy(metadata.Pps, nalu.data, nalu.size);  
  378.             metadata.nPpsLen = nalu.size;  
  379.             bRet2 = true;  
  380.         }  
  381.         pos += len;  
  382.     }  
  383.     if (bRet1 && bRet2)  
  384.     {  
  385.         return true;  
  386.     }  
  387.     return false;  
  388. }  

为了获取H264视频的帧率和分辨率,这里给出SPS解析的源码( 存在部分H264 ES文件无framerate 描述是,采用默认帧率进行处理

[cpp]  view plain  copy
  1. /******************************************************************** 
  2. filename:   sps_pps_parser.h 
  3. created:    2016-08-06 
  4. author:     Donyj 
  5. *********************************************************************/  
  6. #ifndef _sps_pps_H_  
  7. #define _sps_pps_H_  
  8.   
  9. //#include <stdint.h>  
  10.   
  11. #if defined (__cplusplus)  
  12. extern "C" {  
  13. #endif  
  14.     /*** 
  15.     * Sequence parameter set 
  16.     * 可参考H264标准第7节和附录D E 
  17.     */  
  18. #define Extended_SAR 255  
  19.     typedef struct vui_parameters{  
  20.         int aspect_ratio_info_present_flag; //0 u(1)   
  21.         int aspect_ratio_idc;               //0 u(8)   
  22.         int sar_width;                      //0 u(16)   
  23.         int sar_height;                     //0 u(16)   
  24.         int overscan_info_present_flag;     //0 u(1)   
  25.         int overscan_appropriate_flag;      //0 u(1)   
  26.         int video_signal_type_present_flag; //0 u(1)   
  27.         int video_format;                   //0 u(3)   
  28.         int video_full_range_flag;          //0 u(1)   
  29.         int colour_description_present_flag; //0 u(1)   
  30.         int colour_primaries;                //0 u(8)   
  31.         int transfer_characteristics;        //0 u(8)   
  32.         int matrix_coefficients;             //0 u(8)   
  33.         int chroma_loc_info_present_flag;     //0 u(1)   
  34.         int chroma_sample_loc_type_top_field;  //0 ue(v)   
  35.         int chroma_sample_loc_type_bottom_field; //0 ue(v)   
  36.         int timing_info_present_flag;          //0 u(1)   
  37.         uint32_t num_units_in_tick;           //0 u(32)   
  38.         uint32_t time_scale;                 //0 u(32)   
  39.         int fixed_frame_rate_flag;           //0 u(1)   
  40.         int nal_hrd_parameters_present_flag; //0 u(1)  
  41.         int cpb_cnt_minus1;                 //0 ue(v)  
  42.         int bit_rate_scale;                 //0 u(4)  
  43.         int cpb_size_scale;                 //0 u(4)  
  44.         int bit_rate_value_minus1[16];      //0 ue(v)  
  45.         int cpb_size_value_minus1[16];      //0 ue(v)  
  46.         int cbr_flag[16];                   //0 u(1)  
  47.         int initial_cpb_removal_delay_length_minus1; //0 u(5)  
  48.         int cpb_removal_delay_length_minus1;         //0 u(5)  
  49.         int dpb_output_delay_length_minus1;         //0 u(5)  
  50.         int time_offset_length;                      //0 u(5)  
  51.         int vcl_hrd_parameters_present_flag;         //0 u(1)  
  52.         int low_delay_hrd_flag;                      //0 u(1)  
  53.         int pic_struct_present_flag;                 //0 u(1)  
  54.         int bitstream_restriction_flag;              //0 u(1)  
  55.         int motion_vectors_over_pic_boundaries_flag;  //0 ue(v)  
  56.         int max_bytes_per_pic_denom;                  //0 ue(v)  
  57.         int max_bits_per_mb_denom;                    //0 ue(v)  
  58.         int log2_max_mv_length_horizontal;            //0 ue(v)  
  59.         int log2_max_mv_length_vertical;              //0 ue(v)  
  60.         int num_reorder_frames;                       //0 ue(v)  
  61.         int max_dec_frame_buffering;                  //0 ue(v)  
  62.     }vui_parameters_t;  
  63.   
  64.     typedef struct SPS  
  65.     {  
  66.         int profile_idc;  
  67.         int constraint_set0_flag;  
  68.         int constraint_set1_flag;  
  69.         int constraint_set2_flag;  
  70.         int constraint_set3_flag;  
  71.         int reserved_zero_4bits;  
  72.         int level_idc;  
  73.         int seq_parameter_set_id;                       //ue(v)  
  74.         int chroma_format_idc;                          //ue(v)  
  75.         int separate_colour_plane_flag;                 //u(1)  
  76.         int bit_depth_luma_minus8;                      //0 ue(v)   
  77.         int bit_depth_chroma_minus8;                    //0 ue(v)   
  78.         int qpprime_y_zero_transform_bypass_flag;       //0 u(1)   
  79.         int seq_scaling_matrix_present_flag;            //0 u(1)  
  80.         int seq_scaling_list_present_flag[12];  
  81.         int UseDefaultScalingMatrix4x4Flag[6];  
  82.         int UseDefaultScalingMatrix8x8Flag[6];  
  83.         int ScalingList4x4[6][16];  
  84.         int ScalingList8x8[6][64];  
  85.         int log2_max_frame_num_minus4;                  //0 ue(v)  
  86.         int pic_order_cnt_type;                     //0 ue(v)  
  87.         int log2_max_pic_order_cnt_lsb_minus4;              //  
  88.         int delta_pic_order_always_zero_flag;           //u(1)  
  89.         int offset_for_non_ref_pic;                     //se(v)  
  90.         int offset_for_top_to_bottom_field;            //se(v)  
  91.         int num_ref_frames_in_pic_order_cnt_cycle;    //ue(v)     
  92.         int offset_for_ref_frame_array[16];           //se(v)  
  93.         int num_ref_frames;                           //ue(v)  
  94.         int gaps_in_frame_num_value_allowed_flag;    //u(1)  
  95.         int pic_width_in_mbs_minus1;                //ue(v)  
  96.         int pic_height_in_map_units_minus1;         //u(1)  
  97.         int frame_mbs_only_flag;                    //0 u(1)   
  98.         int mb_adaptive_frame_field_flag;           //0 u(1)   
  99.         int direct_8x8_inference_flag;              //0 u(1)   
  100.         int frame_cropping_flag;                    //u(1)  
  101.         int frame_crop_left_offset;                //ue(v)  
  102.         int frame_crop_right_offset;                //ue(v)  
  103.         int frame_crop_top_offset;                  //ue(v)  
  104.         int frame_crop_bottom_offset;               //ue(v)  
  105.         int vui_parameters_present_flag;            //u(1)  
  106.         vui_parameters_t vui_parameters;  
  107.     }SPS;  
  108.   
  109.     /*** 
  110.     * Picture parameter set 
  111.     */  
  112.     typedef struct PPS  
  113.     {  
  114.         int pic_parameter_set_id;  
  115.         int seq_parameter_set_id;  
  116.         int entropy_coding_mode_flag;  
  117.         int pic_order_present_flag;  
  118.         int num_slice_groups_minus1;  
  119.         int slice_group_map_type;  
  120.         int run_length_minus1[32];  
  121.         int top_left[32];  
  122.         int bottom_right[32];  
  123.         int slice_group_change_direction_flag;  
  124.         int slice_group_change_rate_minus1;  
  125.         int pic_size_in_map_units_minus1;  
  126.         int slice_group_id[32];  
  127.         int num_ref_idx_10_active_minus1;  
  128.         int num_ref_idx_11_active_minus1;  
  129.         int weighted_pred_flag;  
  130.         int weighted_bipred_idc;  
  131.         int pic_init_qp_minus26;  
  132.         int pic_init_qs_minus26;  
  133.         int chroma_qp_index_offset;  
  134.         int deblocking_filter_control_present_flag;  
  135.         int constrained_intra_pred_flag;  
  136.         int redundant_pic_cnt_present_flag;  
  137.         int transform_8x8_mode_flag;  
  138.         int pic_scaling_matrix_present_flag;  
  139.         int pic_scaling_list_present_flag[32];  
  140.         int second_chroma_qp_index_offset;  
  141.         int UseDefaultScalingMatrix4x4Flag[6];  
  142.         int UseDefaultScalingMatrix8x8Flag[6];  
  143.         int ScalingList4x4[6][16];  
  144.         int ScalingList8x8[2][64];  
  145.     }PPS;  
  146.   
  147.     typedef struct get_bit_context  
  148.     {  
  149.         uint8_t     *buf;         /*指向SPS start*/  
  150.         int             buf_size;     /*SPS 长度*/  
  151.         int             bit_pos;      /*bit已读取位置*/  
  152.         int             total_bit;    /*bit总长度*/  
  153.         int             cur_bit_pos;  /*当前读取位置*/  
  154.     }get_bit_context;  
  155.   
  156.     int h264dec_seq_parameter_set(void *buf, SPS *sps_ptr);  
  157.     int h264dec_picture_parameter_set(void *buf, PPS *pps_ptr);  
  158.   
  159.     int h264_get_width(SPS *sps_ptr);  
  160.   
  161.     int h264_get_height(SPS *sps_ptr);  
  162.   
  163.     int h264_get_format(SPS *sps_ptr);  
  164.   
  165.     int h264_get_framerate(float *framerate, SPS *sps_ptr);  
  166.   
  167.   
  168.     typedef struct _sequence_header_  
  169.     {  
  170.         unsigned int sequence_header_code; // 0x000001b3  
  171.   
  172.         unsigned int frame_rate_code : 4;  
  173.         unsigned int aspect_ratio_information : 4;  
  174.         unsigned int vertical_size_value : 12;  
  175.         unsigned int horizontal_size_value : 12;  
  176.   
  177.         unsigned int marker_bit : 2;  
  178.         unsigned int bit_rate_value : 30;  
  179.   
  180.     }sequence_header;  
  181.   
  182.     // sequence extension  
  183.     typedef struct _sequence_extension_  
  184.     {  
  185.         unsigned int sequence_header_code; // 0x000001b5  
  186.   
  187.         unsigned int marker_bit : 1;  
  188.         unsigned int bit_rate_extension : 12;  
  189.         unsigned int vertical_size_extension : 2;  
  190.         unsigned int horizontal_size_extension : 2;  
  191.         unsigned int chroma_format : 2;  
  192.         unsigned int progressive_sequence : 1;  
  193.         unsigned int profile_and_level_indication : 8;  
  194.         unsigned int extension_start_code : 4;  
  195.     }sequence_extension;  
  196.   
  197.   
  198.     void memcpy_sps_data(uint8_t *dst, uint8_t *src, int len);  
  199.   
  200.   
  201. #if defined (__cplusplus)  
  202. }  
  203. #endif  
  204.   
  205. #endif  
[cpp]  view plain  copy
  1. /******************************************************************** 
  2. filename:   sps_pps_parser.c 
  3. created:    2016-08-06 
  4. author:     Donyj 
  5. *********************************************************************/  
  6. #include <stdio.h>  
  7. #include <stdlib.h>  
  8. #include <string.h>  
  9. #include <stdint.h> /* for uint32_t, etc */  
  10. #include "sps_pps_parser.h"  
  11. #ifdef __cplusplus   
  12. extern "C" {  
  13. #endif   
  14.     /* report level */  
  15. #define RPT_ERR         (1) // error, system error  
  16. #define RPT_WRN     (2) // warning, maybe wrong, maybe OK  
  17. #define RPT_INF         (4) // important information  
  18. #define RPT_DBG         (8) // debug information  
  19.   
  20. static int rpt_lvl = RPT_ERR; /* report level: ERR, WRN, INF, DBG */  
  21.   
  22. /* report micro */  
  23. #define RPT(lvl, ...) \  
  24. do {\  
  25. if (lvl & rpt_lvl) {\  
  26.         switch (lvl) {\  
  27.         case RPT_ERR: \  
  28.         fprintf(stderr, "\"%s\" line %d [err]: ", __FILE__, __LINE__); \  
  29.         break; \  
  30.         case RPT_WRN: \  
  31.         fprintf(stderr, "\"%s\" line %d [wrn]: ", __FILE__, __LINE__); \  
  32.         break; \  
  33.         case RPT_INF: \  
  34.         fprintf(stderr, "\"%s\" line %d [inf]: ", __FILE__, __LINE__); \  
  35.         break; \  
  36.         case RPT_DBG: \  
  37.         fprintf(stderr, "\"%s\" line %d [dbg]: ", __FILE__, __LINE__); \  
  38.         break; \  
  39.         default: \  
  40.         fprintf(stderr, "\"%s\" line %d [???]: ", __FILE__, __LINE__); \  
  41.         break; \  
  42.     } \  
  43.     fprintf(stderr, __VA_ARGS__); \  
  44.     fprintf(stderr, "\n"); \  
  45. } \  
  46. while (0)  
  47.   
  48. #define SPS_PPS_DEBUG  
  49. #undef  SPS_PPS_DEBUG  
  50.   
  51. #define MAX_LEN 32  
  52.   
  53. /** 
  54. *  @brief Function get_1bit()   读1个bit 
  55. *  @param[in]     h     get_bit_context structrue 
  56. *  @retval        0: success, -1 : failure 
  57. *  @pre 
  58. *  @post 
  59. */  
  60. static int get_1bit(void *h)  
  61. {  
  62.     get_bit_context *ptr = (get_bit_context *)h;  
  63.     int ret = 0;  
  64.     uint8_t *cur_char = NULL;  
  65.     uint8_t shift;  
  66.   
  67.     if (NULL == ptr)  
  68.     {  
  69.         RPT(RPT_ERR, "NULL pointer");  
  70.         ret = -1;  
  71.         goto exit;  
  72.     }  
  73.   
  74.     cur_char = ptr->buf + (ptr->bit_pos >> 3);  
  75.     shift = 7 - (ptr->cur_bit_pos);  
  76.     ptr->bit_pos++;  
  77.     ptr->cur_bit_pos = ptr->bit_pos & 0x7;  
  78.     ret = ((*cur_char) >> shift) & 0x01;  
  79.   
  80. exit:  
  81.     return ret;  
  82. }  
  83.   
  84. /** 
  85. *  @brief Function get_bits()  读n个bits,n不能超过32 
  86. *  @param[in]     h     get_bit_context structrue 
  87. *  @param[in]     n     how many bits you want? 
  88. *  @retval        0: success, -1 : failure 
  89. *  @pre 
  90. *  @post 
  91. */  
  92. static int get_bits(void *h, int n)  
  93. {  
  94.     get_bit_context *ptr = (get_bit_context *)h;  
  95.     uint8_t temp[5] = { 0 };  
  96.     uint8_t *cur_char = NULL;  
  97.     uint8_t nbyte;  
  98.     uint8_t shift;  
  99.     uint32_t result;  
  100.     uint64_t ret = 0;  
  101.   
  102.     if (NULL == ptr)  
  103.     {  
  104.         RPT(RPT_ERR, "NULL pointer");  
  105.         ret = -1;  
  106.         goto exit;  
  107.     }  
  108.   
  109.     if (n > MAX_LEN)  
  110.     {  
  111.         n = MAX_LEN;  
  112.     }  
  113.     if ((ptr->bit_pos + n) > ptr->total_bit)  
  114.     {  
  115.         n = ptr->total_bit - ptr->bit_pos;  
  116.     }  
  117.   
  118.     cur_char = ptr->buf + (ptr->bit_pos >> 3);  
  119.     nbyte = (ptr->cur_bit_pos + n + 7) >> 3;  
  120.     shift = (8 - (ptr->cur_bit_pos + n)) & 0x07;  
  121.   
  122.     if (n == MAX_LEN)  
  123.     {  
  124.         RPT(RPT_DBG, "12(ptr->bit_pos(:%d) + n(:%d)) > ptr->total_bit(:%d)!!! ", \  
  125.             ptr->bit_pos, n, ptr->total_bit);  
  126.         RPT(RPT_DBG, "0x%x 0x%x 0x%x 0x%x", (*cur_char), *(cur_char + 1), *(cur_char + 2), *(cur_char + 3));  
  127.     }  
  128.   
  129.     memcpy(&temp[5 - nbyte], cur_char, nbyte);  
  130.     ret = (uint32_t)temp[0] << 24;  
  131.     ret = ret << 8;  
  132.     ret = ((uint32_t)temp[1] << 24) | ((uint32_t)temp[2] << 16)\  
  133.         | ((uint32_t)temp[3] << 8) | temp[4];  
  134.   
  135.     ret = (ret >> shift) & (((uint64_t)1 << n) - 1);  
  136.   
  137.     result = ret;  
  138.     ptr->bit_pos += n;  
  139.     ptr->cur_bit_pos = ptr->bit_pos & 0x7;  
  140.   
  141. exit:  
  142.     return result;  
  143. }  
  144.   
  145.   
  146. /** 
  147. *  @brief Function parse_codenum() 指数哥伦布编码解析,参考h264标准第9节 
  148. *  @param[in]     buf 
  149. *  @retval        code_num 
  150. *  @pre 
  151. *  @post 
  152. */  
  153. static int parse_codenum(void *buf)  
  154. {  
  155.     uint8_t leading_zero_bits = -1;  
  156.     uint8_t b;  
  157.     uint32_t code_num = 0;  
  158.   
  159.     for (b = 0; !b; leading_zero_bits++)  
  160.     {  
  161.         b = get_1bit(buf);  
  162.     }  
  163.   
  164.     code_num = ((uint32_t)1 << leading_zero_bits) - 1 + get_bits(buf, leading_zero_bits);  
  165.   
  166.     return code_num;  
  167. }  
  168.   
  169. /** 
  170. *  @brief Function parse_ue() 指数哥伦布编码解析 ue(),参考h264标准第9节 
  171. *  @param[in]     buf       sps_pps parse buf 
  172. *  @retval        code_num 
  173. *  @pre 
  174. *  @post 
  175. */  
  176. static int parse_ue(void *buf)  
  177. {  
  178.     return parse_codenum(buf);  
  179. }  
  180.   
  181. /** 
  182. *  @brief Function parse_se() 指数哥伦布编码解析 se(), 参考h264标准第9节 
  183. *  @param[in]     buf       sps_pps parse buf 
  184. *  @retval        code_num 
  185. *  @pre 
  186. *  @post 
  187. */  
  188. static int parse_se(void *buf)  
  189. {  
  190.     int ret = 0;  
  191.     int code_num;  
  192.   
  193.     code_num = parse_codenum(buf);  
  194.     ret = (code_num + 1) >> 1;  
  195.     ret = (code_num & 0x01) ? ret : -ret;  
  196.   
  197.     return ret;  
  198. }  
  199.   
  200. /** 
  201. *  @brief Function get_bit_context_free()  申请的get_bit_context结构内存释放 
  202. *  @param[in]     buf       get_bit_context buf 
  203. *  @retval        none 
  204. *  @pre 
  205. *  @post 
  206. */  
  207. static void get_bit_context_free(void *buf)  
  208. {  
  209.     get_bit_context *ptr = (get_bit_context *)buf;  
  210.   
  211.     if (ptr)  
  212.     {  
  213.         if (ptr->buf)  
  214.         {  
  215.             free(ptr->buf);  
  216.         }  
  217.   
  218.         free(ptr);  
  219.     }  
  220. }  
  221.   
  222. static void *de_emulation_prevention(void *buf)  
  223. {  
  224.     get_bit_context *ptr = NULL;  
  225.     get_bit_context *buf_ptr = (get_bit_context *)buf;  
  226.     int i = 0, j = 0;  
  227.     uint8_t *tmp_ptr = NULL;  
  228.     int tmp_buf_size = 0;  
  229.     int val = 0;  
  230.     if (NULL == buf_ptr)  
  231.     {  
  232.         RPT(RPT_ERR, "NULL ptr");  
  233.         goto exit;  
  234.     }  
  235.     ptr = (get_bit_context *)malloc(sizeof(get_bit_context));  
  236.     if (NULL == ptr)  
  237.     {  
  238.         RPT(RPT_ERR, "NULL ptr");  
  239.         goto exit;  
  240.     }  
  241.     memcpy(ptr, buf_ptr, sizeof(get_bit_context));  
  242.     printf("fun = %s line = %d ptr->buf_size=%d \n", __FUNCTION__, __LINE__, ptr->buf_size);  
  243.     ptr->buf = (uint8_t *)malloc(ptr->buf_size);  
  244.     if (NULL == ptr->buf)  
  245.     {  
  246.         RPT(RPT_ERR, "NULL ptr ");  
  247.         goto exit;  
  248.     }  
  249.     memcpy(ptr->buf, buf_ptr->buf, buf_ptr->buf_size);  
  250.     tmp_ptr = ptr->buf;  
  251.     tmp_buf_size = ptr->buf_size;  
  252.     for (i = 0; i<(tmp_buf_size - 2); i++)  
  253.     {  
  254.         /*检测0x000003*/  
  255.         val = (tmp_ptr[i] ^ 0x00) + (tmp_ptr[i + 1] ^ 0x00) + (tmp_ptr[i + 2] ^ 0x03);  
  256.         if (val == 0)  
  257.         {  
  258.             /*剔除0x03*/  
  259.             for (j = i + 2; j<tmp_buf_size - 1; j++)  
  260.             {  
  261.                 tmp_ptr[j] = tmp_ptr[j + 1];  
  262.             }  
  263.   
  264.             /*相应的bufsize要减小*/  
  265.             ptr->buf_size--;  
  266.         }  
  267.     }  
  268.   
  269.     /*重新计算total_bit*/  
  270.     ptr->total_bit = ptr->buf_size << 3;  
  271.     return (void *)ptr;  
  272.   
  273. exit:  
  274.     get_bit_context_free(ptr);  
  275.     return NULL;  
  276. }  
  277.   
  278. /** 
  279. *  @brief Function get_bit_context_free()  VUI_parameters 解析,原理参考h264标准 
  280. *  @param[in]     buf       get_bit_context buf 
  281. *  @param[in]     vui_ptr   vui解析结果 
  282. *  @retval        0: success, -1 : failure 
  283. *  @pre 
  284. *  @post 
  285. */  
  286. static int vui_parameters_set(void *buf, vui_parameters_t *vui_ptr)  
  287. {  
  288.     int ret = 0;  
  289.     int SchedSelIdx = 0;  
  290.   
  291.     if (NULL == vui_ptr || NULL == buf)  
  292.     {  
  293.         RPT(RPT_ERR, "ERR null pointer\n");  
  294.         ret = -1;  
  295.         goto exit;  
  296.     }  
  297.   
  298.     vui_ptr->aspect_ratio_info_present_flag = get_1bit(buf);  
  299.     if (vui_ptr->aspect_ratio_info_present_flag)  
  300.     {  
  301.         vui_ptr->aspect_ratio_idc = get_bits(buf, 8);  
  302.         if (vui_ptr->aspect_ratio_idc == Extended_SAR)  
  303.         {  
  304.             vui_ptr->sar_width = get_bits(buf, 16);  
  305.             vui_ptr->sar_height = get_bits(buf, 16);  
  306.         }  
  307.     }  
  308.   
  309.     vui_ptr->overscan_info_present_flag = get_1bit(buf);  
  310.     if (vui_ptr->overscan_info_present_flag)  
  311.     {  
  312.         vui_ptr->overscan_appropriate_flag = get_1bit(buf);  
  313.     }  
  314.   
  315.     vui_ptr->video_signal_type_present_flag = get_1bit(buf);  
  316.     if (vui_ptr->video_signal_type_present_flag)  
  317.     {  
  318.         vui_ptr->video_format = get_bits(buf, 3);  
  319.         vui_ptr->video_full_range_flag = get_1bit(buf);  
  320.   
  321.         vui_ptr->colour_description_present_flag = get_1bit(buf);  
  322.         if (vui_ptr->colour_description_present_flag)  
  323.         {  
  324.             vui_ptr->colour_primaries = get_bits(buf, 8);  
  325.             vui_ptr->transfer_characteristics = get_bits(buf, 8);  
  326.             vui_ptr->matrix_coefficients = get_bits(buf, 8);  
  327.         }  
  328.     }  
  329.   
  330.     vui_ptr->chroma_loc_info_present_flag = get_1bit(buf);  
  331.     if (vui_ptr->chroma_loc_info_present_flag)  
  332.     {  
  333.         vui_ptr->chroma_sample_loc_type_top_field = parse_ue(buf);  
  334.         vui_ptr->chroma_sample_loc_type_bottom_field = parse_ue(buf);  
  335.     }  
  336.   
  337.     vui_ptr->timing_info_present_flag = get_1bit(buf);  
  338.     if (vui_ptr->timing_info_present_flag)  
  339.     {  
  340.         vui_ptr->num_units_in_tick = get_bits(buf, 32);  
  341.         vui_ptr->time_scale = get_bits(buf, 32);  
  342.         vui_ptr->fixed_frame_rate_flag = get_1bit(buf);  
  343.     }  
  344.   
  345.     vui_ptr->nal_hrd_parameters_present_flag = get_1bit(buf);  
  346.     if (vui_ptr->nal_hrd_parameters_present_flag)  
  347.     {  
  348.         vui_ptr->cpb_cnt_minus1 = parse_ue(buf);  
  349.         vui_ptr->bit_rate_scale = get_bits(buf, 4);  
  350.         vui_ptr->cpb_size_scale = get_bits(buf, 4);  
  351.   
  352.         for (SchedSelIdx = 0; SchedSelIdx <= vui_ptr->cpb_cnt_minus1; SchedSelIdx++)  
  353.         {  
  354.             vui_ptr->bit_rate_value_minus1[SchedSelIdx] = parse_ue(buf);  
  355.             vui_ptr->cpb_size_value_minus1[SchedSelIdx] = parse_ue(buf);  
  356.             vui_ptr->cbr_flag[SchedSelIdx] = get_1bit(buf);  
  357.         }  
  358.   
  359.         vui_ptr->initial_cpb_removal_delay_length_minus1 = get_bits(buf, 5);  
  360.         vui_ptr->cpb_removal_delay_length_minus1 = get_bits(buf, 5);  
  361.         vui_ptr->dpb_output_delay_length_minus1 = get_bits(buf, 5);  
  362.         vui_ptr->time_offset_length = get_bits(buf, 5);  
  363.     }  
  364.   
  365.   
  366.     vui_ptr->vcl_hrd_parameters_present_flag = get_1bit(buf);  
  367.     if (vui_ptr->vcl_hrd_parameters_present_flag)  
  368.     {  
  369.         vui_ptr->cpb_cnt_minus1 = parse_ue(buf);  
  370.         vui_ptr->bit_rate_scale = get_bits(buf, 4);  
  371.         vui_ptr->cpb_size_scale = get_bits(buf, 4);  
  372.   
  373.         for (SchedSelIdx = 0; SchedSelIdx <= vui_ptr->cpb_cnt_minus1; SchedSelIdx++)  
  374.         {  
  375.             vui_ptr->bit_rate_value_minus1[SchedSelIdx] = parse_ue(buf);  
  376.             vui_ptr->cpb_size_value_minus1[SchedSelIdx] = parse_ue(buf);  
  377.             vui_ptr->cbr_flag[SchedSelIdx] = get_1bit(buf);  
  378.         }  
  379.         vui_ptr->initial_cpb_removal_delay_length_minus1 = get_bits(buf, 5);  
  380.         vui_ptr->cpb_removal_delay_length_minus1 = get_bits(buf, 5);  
  381.         vui_ptr->dpb_output_delay_length_minus1 = get_bits(buf, 5);  
  382.         vui_ptr->time_offset_length = get_bits(buf, 5);  
  383.     }  
  384.   
  385.     if (vui_ptr->nal_hrd_parameters_present_flag \  
  386.         || vui_ptr->vcl_hrd_parameters_present_flag)  
  387.     {  
  388.         vui_ptr->low_delay_hrd_flag = get_1bit(buf);  
  389.     }  
  390.   
  391.     vui_ptr->pic_struct_present_flag = get_1bit(buf);  
  392.   
  393.     vui_ptr->bitstream_restriction_flag = get_1bit(buf);  
  394.     if (vui_ptr->bitstream_restriction_flag)  
  395.     {  
  396.         vui_ptr->motion_vectors_over_pic_boundaries_flag = get_1bit(buf);  
  397.         vui_ptr->max_bytes_per_pic_denom = parse_ue(buf);  
  398.         vui_ptr->max_bits_per_mb_denom = parse_ue(buf);  
  399.         vui_ptr->log2_max_mv_length_horizontal = parse_ue(buf);  
  400.         vui_ptr->log2_max_mv_length_vertical = parse_ue(buf);  
  401.         vui_ptr->num_reorder_frames = parse_ue(buf);  
  402.         vui_ptr->max_dec_frame_buffering = parse_ue(buf);  
  403.     }  
  404.   
  405. exit:  
  406.     return ret;  
  407. }  
  408.   
  409. /*SPS 信息打印,调试使用*/  
  410. #ifdef SPS_PPS_DEBUG  
  411. static void sps_info_print(SPS* sps_ptr)  
  412. {  
  413.     if (NULL != sps_ptr)  
  414.     {  
  415.         RPT(RPT_DBG, "profile_idc: %d", sps_ptr->profile_idc);  
  416.         RPT(RPT_DBG, "constraint_set0_flag: %d", sps_ptr->constraint_set0_flag);  
  417.         RPT(RPT_DBG, "constraint_set1_flag: %d", sps_ptr->constraint_set1_flag);  
  418.         RPT(RPT_DBG, "constraint_set2_flag: %d", sps_ptr->constraint_set2_flag);  
  419.         RPT(RPT_DBG, "constraint_set3_flag: %d", sps_ptr->constraint_set3_flag);  
  420.         RPT(RPT_DBG, "reserved_zero_4bits: %d", sps_ptr->reserved_zero_4bits);  
  421.         RPT(RPT_DBG, "level_idc: %d", sps_ptr->level_idc);  
  422.         RPT(RPT_DBG, "seq_parameter_set_id: %d", sps_ptr->seq_parameter_set_id);  
  423.         RPT(RPT_DBG, "chroma_format_idc: %d", sps_ptr->chroma_format_idc);  
  424.         RPT(RPT_DBG, "separate_colour_plane_flag: %d", sps_ptr->separate_colour_plane_flag);  
  425.         RPT(RPT_DBG, "bit_depth_luma_minus8: %d", sps_ptr->bit_depth_luma_minus8);  
  426.         RPT(RPT_DBG, "bit_depth_chroma_minus8: %d", sps_ptr->bit_depth_chroma_minus8);  
  427.         RPT(RPT_DBG, "qpprime_y_zero_transform_bypass_flag: %d", sps_ptr->qpprime_y_zero_transform_bypass_flag);  
  428.         RPT(RPT_DBG, "seq_scaling_matrix_present_flag: %d", sps_ptr->seq_scaling_matrix_present_flag);  
  429.         //RPT(RPT_INF, "seq_scaling_list_present_flag:%d", sps_ptr->seq_scaling_list_present_flag);   
  430.         RPT(RPT_DBG, "log2_max_frame_num_minus4: %d", sps_ptr->log2_max_frame_num_minus4);  
  431.         RPT(RPT_DBG, "pic_order_cnt_type: %d", sps_ptr->pic_order_cnt_type);  
  432.         RPT(RPT_DBG, "num_ref_frames: %d", sps_ptr->num_ref_frames);  
  433.         RPT(RPT_DBG, "gaps_in_frame_num_value_allowed_flag: %d", sps_ptr->gaps_in_frame_num_value_allowed_flag);  
  434.         RPT(RPT_DBG, "pic_width_in_mbs_minus1: %d", sps_ptr->pic_width_in_mbs_minus1);  
  435.         RPT(RPT_DBG, "pic_height_in_map_units_minus1: %d", sps_ptr->pic_height_in_map_units_minus1);  
  436.         RPT(RPT_DBG, "frame_mbs_only_flag: %d", sps_ptr->frame_mbs_only_flag);  
  437.         RPT(RPT_DBG, "mb_adaptive_frame_field_flag: %d", sps_ptr->mb_adaptive_frame_field_flag);  
  438.         RPT(RPT_DBG, "direct_8x8_inference_flag: %d", sps_ptr->direct_8x8_inference_flag);  
  439.         RPT(RPT_DBG, "frame_cropping_flag: %d", sps_ptr->frame_cropping_flag);  
  440.         RPT(RPT_DBG, "frame_crop_left_offset: %d", sps_ptr->frame_crop_left_offset);  
  441.         RPT(RPT_DBG, "frame_crop_right_offset: %d", sps_ptr->frame_crop_right_offset);  
  442.         RPT(RPT_DBG, "frame_crop_top_offset: %d", sps_ptr->frame_crop_top_offset);  
  443.         RPT(RPT_DBG, "frame_crop_bottom_offset: %d", sps_ptr->frame_crop_bottom_offset);  
  444.         RPT(RPT_DBG, "vui_parameters_present_flag: %d", sps_ptr->vui_parameters_present_flag);  
  445.   
  446.         if (sps_ptr->vui_parameters_present_flag)  
  447.         {  
  448.             RPT(RPT_DBG, "aspect_ratio_info_present_flag: %d", sps_ptr->vui_parameters.aspect_ratio_info_present_flag);  
  449.             RPT(RPT_DBG, "aspect_ratio_idc: %d", sps_ptr->vui_parameters.aspect_ratio_idc);  
  450.             RPT(RPT_DBG, "sar_width: %d", sps_ptr->vui_parameters.sar_width);  
  451.             RPT(RPT_DBG, "sar_height: %d", sps_ptr->vui_parameters.sar_height);  
  452.             RPT(RPT_DBG, "overscan_info_present_flag: %d", sps_ptr->vui_parameters.overscan_info_present_flag);  
  453.             RPT(RPT_DBG, "overscan_info_appropriate_flag: %d", sps_ptr->vui_parameters.overscan_appropriate_flag);  
  454.             RPT(RPT_DBG, "video_signal_type_present_flag: %d", sps_ptr->vui_parameters.video_signal_type_present_flag);  
  455.             RPT(RPT_DBG, "video_format: %d", sps_ptr->vui_parameters.video_format);  
  456.             RPT(RPT_DBG, "video_full_range_flag: %d", sps_ptr->vui_parameters.video_full_range_flag);  
  457.             RPT(RPT_DBG, "colour_description_present_flag: %d", sps_ptr->vui_parameters.colour_description_present_flag);  
  458.             RPT(RPT_DBG, "colour_primaries: %d", sps_ptr->vui_parameters.colour_primaries);  
  459.             RPT(RPT_DBG, "transfer_characteristics: %d", sps_ptr->vui_parameters.transfer_characteristics);  
  460.             RPT(RPT_DBG, "matrix_coefficients: %d", sps_ptr->vui_parameters.matrix_coefficients);  
  461.             RPT(RPT_DBG, "chroma_loc_info_present_flag: %d", sps_ptr->vui_parameters.chroma_loc_info_present_flag);  
  462.             RPT(RPT_DBG, "chroma_sample_loc_type_top_field: %d", sps_ptr->vui_parameters.chroma_sample_loc_type_top_field);  
  463.             RPT(RPT_DBG, "chroma_sample_loc_type_bottom_field: %d", sps_ptr->vui_parameters.chroma_sample_loc_type_bottom_field);  
  464.             RPT(RPT_DBG, "timing_info_present_flag: %d", sps_ptr->vui_parameters.timing_info_present_flag);  
  465.             RPT(RPT_DBG, "num_units_in_tick: %d", sps_ptr->vui_parameters.num_units_in_tick);  
  466.             RPT(RPT_DBG, "time_scale: %d", sps_ptr->vui_parameters.time_scale);  
  467.             RPT(RPT_DBG, "fixed_frame_rate_flag: %d", sps_ptr->vui_parameters.fixed_frame_rate_flag);  
  468.             RPT(RPT_DBG, "nal_hrd_parameters_present_flag: %d", sps_ptr->vui_parameters.nal_hrd_parameters_present_flag);  
  469.             RPT(RPT_DBG, "cpb_cnt_minus1: %d", sps_ptr->vui_parameters.cpb_cnt_minus1);  
  470.             RPT(RPT_DBG, "bit_rate_scale: %d", sps_ptr->vui_parameters.bit_rate_scale);  
  471.             RPT(RPT_DBG, "cpb_size_scale: %d", sps_ptr->vui_parameters.cpb_size_scale);  
  472.             RPT(RPT_DBG, "initial_cpb_removal_delay_length_minus1: %d", sps_ptr->vui_parameters.initial_cpb_removal_delay_length_minus1);  
  473.             RPT(RPT_DBG, "cpb_removal_delay_length_minus1: %d", sps_ptr->vui_parameters.cpb_removal_delay_length_minus1);  
  474.             RPT(RPT_DBG, "dpb_output_delay_length_minus1: %d", sps_ptr->vui_parameters.dpb_output_delay_length_minus1);  
  475.             RPT(RPT_DBG, "time_offset_length: %d", sps_ptr->vui_parameters.time_offset_length);  
  476.             RPT(RPT_DBG, "vcl_hrd_parameters_present_flag: %d", sps_ptr->vui_parameters.vcl_hrd_parameters_present_flag);  
  477.             RPT(RPT_DBG, "low_delay_hrd_flag: %d", sps_ptr->vui_parameters.low_delay_hrd_flag);  
  478.             RPT(RPT_DBG, "pic_struct_present_flag: %d", sps_ptr->vui_parameters.pic_struct_present_flag);  
  479.             RPT(RPT_DBG, "bitstream_restriction_flag: %d", sps_ptr->vui_parameters.bitstream_restriction_flag);  
  480.             RPT(RPT_DBG, "motion_vectors_over_pic_boundaries_flag: %d", sps_ptr->vui_parameters.motion_vectors_over_pic_boundaries_flag);  
  481.             RPT(RPT_DBG, "max_bytes_per_pic_denom: %d", sps_ptr->vui_parameters.max_bytes_per_pic_denom);  
  482.             RPT(RPT_DBG, "max_bits_per_mb_denom: %d", sps_ptr->vui_parameters.max_bits_per_mb_denom);  
  483.             RPT(RPT_DBG, "log2_max_mv_length_horizontal: %d", sps_ptr->vui_parameters.log2_max_mv_length_horizontal);  
  484.             RPT(RPT_DBG, "log2_max_mv_length_vertical: %d", sps_ptr->vui_parameters.log2_max_mv_length_vertical);  
  485.             RPT(RPT_DBG, "num_reorder_frames: %d", sps_ptr->vui_parameters.num_reorder_frames);  
  486.             RPT(RPT_DBG, "max_dec_frame_buffering: %d", sps_ptr->vui_parameters.max_dec_frame_buffering);  
  487.         }  
  488.   
  489.     }  
  490. }  
  491. #endif  
  492.   
  493. /** 
  494. *  @brief Function h264dec_seq_parameter_set()  h264 SPS infomation 解析 
  495. *  @param[in]     buf       buf ptr, 需同步00 00 00 01 X7后传入 
  496. *  @param[in]     sps_ptr   sps指针,保存SPS信息 
  497. *  @retval        0: success, -1 : failure 
  498. *  @pre 
  499. *  @post 
  500. */  
  501. int h264dec_seq_parameter_set(void *buf_ptr, SPS *sps_ptr)  
  502. {  
  503.     SPS *sps = sps_ptr;  
  504.     int ret = 0;  
  505.     int profile_idc = 0;  
  506.     int i, j, last_scale, next_scale, delta_scale;  
  507.     void *buf = NULL;  
  508.   
  509.     if (NULL == buf_ptr || NULL == sps)  
  510.     {  
  511.         RPT(RPT_ERR, "ERR null pointer\n");  
  512.         ret = -1;  
  513.         goto exit;  
  514.     }  
  515.   
  516.     memset((void *)sps, 0, sizeof(SPS));  
  517.     buf = de_emulation_prevention(buf_ptr);  
  518.     if (NULL == buf)  
  519.     {  
  520.         RPT(RPT_ERR, "ERR null pointer\n");  
  521.         ret = -1;  
  522.         goto exit;  
  523.     }  
  524.     sps->profile_idc = get_bits(buf, 8);  
  525.     sps->constraint_set0_flag = get_1bit(buf);  
  526.     sps->constraint_set1_flag = get_1bit(buf);  
  527.     sps->constraint_set2_flag = get_1bit(buf);  
  528.     sps->constraint_set3_flag = get_1bit(buf);  
  529.     sps->reserved_zero_4bits = get_bits(buf, 4);  
  530.     sps->level_idc = get_bits(buf, 8);  
  531.     sps->seq_parameter_set_id = parse_ue(buf);  
  532.     profile_idc = sps->profile_idc;  
  533.     if ((profile_idc == 100) || (profile_idc == 110) || (profile_idc == 122) || (profile_idc == 244)  
  534.         || (profile_idc == 44) || (profile_idc == 83) || (profile_idc == 86) || (profile_idc == 118) || \  
  535.         (profile_idc == 128))  
  536.     {  
  537.         sps->chroma_format_idc = parse_ue(buf);  
  538.         if (sps->chroma_format_idc == 3)  
  539.         {  
  540.             sps->separate_colour_plane_flag = get_1bit(buf);  
  541.         }  
  542.   
  543.         sps->bit_depth_luma_minus8 = parse_ue(buf);  
  544.         sps->bit_depth_chroma_minus8 = parse_ue(buf);  
  545.         sps->qpprime_y_zero_transform_bypass_flag = get_1bit(buf);  
  546.         sps->seq_scaling_matrix_present_flag = get_1bit(buf);  
  547.         if (sps->seq_scaling_matrix_present_flag)  
  548.         {  
  549.             for (i = 0; i < ((sps->chroma_format_idc != 3) ? 8 : 12); i++)  
  550.             {  
  551.                 sps->seq_scaling_list_present_flag[i] = get_1bit(buf);  
  552.                 if (sps->seq_scaling_list_present_flag[i])  
  553.                 {  
  554.                     if (i < 6)  
  555.                     {  
  556.                         for (j = 0; j < 16; j++)  
  557.                         {  
  558.                             last_scale = 8;  
  559.                             next_scale = 8;  
  560.                             if (next_scale != 0)  
  561.                             {  
  562.                                 delta_scale = parse_se(buf);  
  563.                                 next_scale = (last_scale + delta_scale + 256) % 256;  
  564.                                 sps->UseDefaultScalingMatrix4x4Flag[i] = ((j == 0) && (next_scale == 0));  
  565.                             }  
  566.                             sps->ScalingList4x4[i][j] = (next_scale == 0) ? last_scale : next_scale;  
  567.                             last_scale = sps->ScalingList4x4[i][j];  
  568.                         }  
  569.                     }  
  570.                     else  
  571.                     {  
  572.                         int ii = i - 6;  
  573.                         next_scale = 8;  
  574.                         last_scale = 8;  
  575.                         for (j = 0; j < 64; j++)  
  576.                         {  
  577.                             if (next_scale != 0)  
  578.                             {  
  579.                                 delta_scale = parse_se(buf);  
  580.                                 next_scale = (last_scale + delta_scale + 256) % 256;  
  581.                                 sps->UseDefaultScalingMatrix8x8Flag[ii] = ((j == 0) && (next_scale == 0));  
  582.                             }  
  583.                             sps->ScalingList8x8[ii][j] = (next_scale == 0) ? last_scale : next_scale;  
  584.                             last_scale = sps->ScalingList8x8[ii][j];  
  585.                         }  
  586.                     }  
  587.                 }  
  588.             }  
  589.         }  
  590.     }  
  591.     sps->log2_max_frame_num_minus4 = parse_ue(buf);  
  592.     sps->pic_order_cnt_type = parse_ue(buf);  
  593.     if (sps->pic_order_cnt_type == 0)  
  594.     {  
  595.         sps->log2_max_pic_order_cnt_lsb_minus4 = parse_ue(buf);  
  596.     }  
  597.     else if (sps->pic_order_cnt_type == 1)  
  598.     {  
  599.         sps->delta_pic_order_always_zero_flag = get_1bit(buf);  
  600.         sps->offset_for_non_ref_pic = parse_se(buf);  
  601.         sps->offset_for_top_to_bottom_field = parse_se(buf);  
  602.   
  603.         sps->num_ref_frames_in_pic_order_cnt_cycle = parse_ue(buf);  
  604.         for (i = 0; i < sps->num_ref_frames_in_pic_order_cnt_cycle; i++)  
  605.         {  
  606.             sps->offset_for_ref_frame_array[i] = parse_se(buf);  
  607.         }  
  608.     }  
  609.     sps->num_ref_frames = parse_ue(buf);  
  610.     sps->gaps_in_frame_num_value_allowed_flag = get_1bit(buf);  
  611.     sps->pic_width_in_mbs_minus1 = parse_ue(buf);  
  612.     sps->pic_height_in_map_units_minus1 = parse_ue(buf);  
  613.     sps->frame_mbs_only_flag = get_1bit(buf);  
  614.     if (!sps->frame_mbs_only_flag)  
  615.     {  
  616.         sps->mb_adaptive_frame_field_flag = get_1bit(buf);  
  617.     }  
  618.     sps->direct_8x8_inference_flag = get_1bit(buf);  
  619.   
  620.     sps->frame_cropping_flag = get_1bit(buf);  
  621.     if (sps->frame_cropping_flag)  
  622.     {  
  623.         sps->frame_crop_left_offset = parse_ue(buf);  
  624.         sps->frame_crop_right_offset = parse_ue(buf);  
  625.         sps->frame_crop_top_offset = parse_ue(buf);  
  626.         sps->frame_crop_bottom_offset = parse_ue(buf);  
  627.     }  
  628.     sps->vui_parameters_present_flag = get_1bit(buf);  
  629.     if (sps->vui_parameters_present_flag)  
  630.     {  
  631.         vui_parameters_set(buf, &sps->vui_parameters);  
  632.     }  
  633.   
  634. #ifdef SPS_PPS_DEBUG  
  635.     sps_info_print(sps);  
  636. #endif  
  637. exit:  
  638.     get_bit_context_free(buf);  
  639.     return ret;  
  640. }  
  641.   
  642. /** 
  643. *  @brief Function more_rbsp_data()  计算pps串最后一个为1的比特位及其后都是比特0的个数 
  644. *  @param[in]     buf       get_bit_context structure 
  645. *  @retval 
  646. *  @pre 
  647. *  @post 
  648. *  @note  这段代码来自网友的帮助,并没有验证,使用时需注意 
  649. */  
  650. static int more_rbsp_data(void *buf)  
  651. {  
  652.     get_bit_context *ptr = (get_bit_context *)buf;  
  653.     get_bit_context tmp;  
  654.   
  655.     if (NULL == buf)  
  656.     {  
  657.         RPT(RPT_ERR, "NULL pointer, err");  
  658.         return -1;  
  659.     }  
  660.   
  661.     memset(&tmp, 0, sizeof(get_bit_context));  
  662.     memcpy(&tmp, ptr, sizeof(get_bit_context));  
  663.   
  664.     for (tmp.bit_pos = ptr->total_bit - 1; tmp.bit_pos > ptr->bit_pos; tmp.bit_pos -= 2)  
  665.     {  
  666.         if (get_1bit(&tmp))  
  667.         {  
  668.             break;  
  669.         }  
  670.     }  
  671.     return tmp.bit_pos == ptr->bit_pos ? 0 : 1;  
  672. }  
  673.   
  674. /** 
  675. *  @brief Function h264dec_picture_parameter_set()  h264 PPS infomation 解析 
  676. *  @param[in]     buf       buf ptr, 需同步00 00 00 01 X8后传入 
  677. *  @param[in]     pps_ptr   pps指针,保存pps信息 
  678. *  @retval        0: success, -1 : failure 
  679. *  @pre 
  680. *  @post 
  681. *  @note: 用法参考sps解析 
  682. */  
  683. int h264dec_picture_parameter_set(void *buf_ptr, PPS *pps_ptr)  
  684. {  
  685.     PPS *pps = pps_ptr;  
  686.     int ret = 0;  
  687.     void *buf = NULL;  
  688.     int iGroup = 0;  
  689.     int i, j, last_scale, next_scale, delta_scale;  
  690.   
  691.     if (NULL == buf_ptr || NULL == pps_ptr)  
  692.     {  
  693.         RPT(RPT_ERR, "NULL pointer\n");  
  694.         ret = -1;  
  695.         goto exit;  
  696.     }  
  697.   
  698.     memset((void *)pps, 0, sizeof(PPS));  
  699.   
  700.     buf = de_emulation_prevention(buf_ptr);  
  701.     if (NULL == buf)  
  702.     {  
  703.         RPT(RPT_ERR, "ERR null pointer\n");  
  704.         ret = -1;  
  705.         goto exit;  
  706.     }  
  707.   
  708.     pps->pic_parameter_set_id = parse_ue(buf);  
  709.     pps->seq_parameter_set_id = parse_ue(buf);  
  710.     pps->entropy_coding_mode_flag = get_1bit(buf);  
  711.     pps->pic_order_present_flag = get_1bit(buf);  
  712.   
  713.     pps->num_slice_groups_minus1 = parse_ue(buf);  
  714.     if (pps->num_slice_groups_minus1 > 0)  
  715.     {  
  716.         pps->slice_group_map_type = parse_ue(buf);  
  717.         if (pps->slice_group_map_type == 0)  
  718.         {  
  719.             for (iGroup = 0; iGroup <= pps->num_slice_groups_minus1; iGroup++)  
  720.             {  
  721.                 pps->run_length_minus1[iGroup] = parse_ue(buf);  
  722.             }  
  723.         }  
  724.         else if (pps->slice_group_map_type == 2)  
  725.         {  
  726.             for (iGroup = 0; iGroup <= pps->num_slice_groups_minus1; iGroup++)  
  727.             {  
  728.                 pps->top_left[iGroup] = parse_ue(buf);  
  729.                 pps->bottom_right[iGroup] = parse_ue(buf);  
  730.             }  
  731.         }  
  732.         else if (pps->slice_group_map_type == 3 \  
  733.             || pps->slice_group_map_type == 4\  
  734.             || pps->slice_group_map_type == 5)  
  735.         {  
  736.             pps->slice_group_change_direction_flag = get_1bit(buf);  
  737.             pps->slice_group_change_rate_minus1 = parse_ue(buf);  
  738.         }  
  739.         else if (pps->slice_group_map_type == 6)  
  740.         {  
  741.             pps->pic_size_in_map_units_minus1 = parse_ue(buf);  
  742.             for (i = 0; i<pps->pic_size_in_map_units_minus1; i++)  
  743.             {  
  744.                 /*这地方可能有问题,对u(v)理解偏差*/  
  745.                 pps->slice_group_id[i] = get_bits(buf, pps->pic_size_in_map_units_minus1);  
  746.             }  
  747.         }  
  748.     }  
  749.   
  750.     pps->num_ref_idx_10_active_minus1 = parse_ue(buf);  
  751.     pps->num_ref_idx_11_active_minus1 = parse_ue(buf);  
  752.     pps->weighted_pred_flag = get_1bit(buf);  
  753.     pps->weighted_bipred_idc = get_bits(buf, 2);  
  754.     pps->pic_init_qp_minus26 = parse_se(buf); /*relative26*/  
  755.     pps->pic_init_qs_minus26 = parse_se(buf); /*relative26*/  
  756.     pps->chroma_qp_index_offset = parse_se(buf);  
  757.     pps->deblocking_filter_control_present_flag = get_1bit(buf);  
  758.     pps->constrained_intra_pred_flag = get_1bit(buf);  
  759.     pps->redundant_pic_cnt_present_flag = get_1bit(buf);  
  760.   
  761.     if (more_rbsp_data(buf))  
  762.     {  
  763.         pps->transform_8x8_mode_flag = get_1bit(buf);  
  764.         pps->pic_scaling_matrix_present_flag = get_1bit(buf);  
  765.         if (pps->pic_scaling_matrix_present_flag)  
  766.         {  
  767.             for (i = 0; i<6 + 2 * pps->transform_8x8_mode_flag; i++)  
  768.             {  
  769.                 pps->pic_scaling_list_present_flag[i] = get_1bit(buf);  
  770.                 if (pps->pic_scaling_list_present_flag[i])  
  771.                 {  
  772.                     if (i<6)  
  773.                     {  
  774.                         for (j = 0; j<16; j++)  
  775.                         {  
  776.                             next_scale = 8;  
  777.                             last_scale = 8;  
  778.                             if (next_scale != 0)  
  779.                             {  
  780.                                 delta_scale = parse_se(buf);  
  781.                                 next_scale = (last_scale + delta_scale + 256) % 256;  
  782.                                 pps->UseDefaultScalingMatrix4x4Flag[i] = ((j == 0) && (next_scale == 0));  
  783.                             }  
  784.                             pps->ScalingList4x4[i][j] = (next_scale == 0) ? last_scale : next_scale;  
  785.                             last_scale = pps->ScalingList4x4[i][j];  
  786.                         }  
  787.                     }  
  788.                     else  
  789.                     {  
  790.                         int ii = i - 6;  
  791.                         next_scale = 8;  
  792.                         last_scale = 8;  
  793.                         for (j = 0; j<64; j++)  
  794.                         {  
  795.                             if (next_scale != 0)  
  796.                             {  
  797.                                 delta_scale = parse_se(buf);  
  798.                                 next_scale = (last_scale + delta_scale + 256) % 256;  
  799.                                 pps->UseDefaultScalingMatrix8x8Flag[ii] = ((j == 0) && (next_scale == 0));  
  800.                             }  
  801.                             pps->ScalingList8x8[ii][j] = (next_scale == 0) ? last_scale : next_scale;  
  802.                             last_scale = pps->ScalingList8x8[ii][j];  
  803.                         }  
  804.                     }  
  805.                 }  
  806.             }  
  807.   
  808.             pps->second_chroma_qp_index_offset = parse_se(buf);  
  809.         }  
  810.     }  
  811.   
  812. exit:  
  813.     get_bit_context_free(buf);  
  814.     return ret;  
  815. }  
  816.   
  817. // calculation width height and framerate  
  818. int h264_get_width(SPS *sps_ptr)  
  819. {  
  820.     return (sps_ptr->pic_width_in_mbs_minus1 + 1) * 16;  
  821. }  
  822.   
  823. int h264_get_height(SPS *sps_ptr)  
  824. {  
  825.     printf("fun = %s line = %d sps_ptr->frame_mbs_only_flag=%d \n", __FUNCTION__, __LINE__, sps_ptr->frame_mbs_only_flag);  
  826.     return (sps_ptr->pic_height_in_map_units_minus1 + 1) * 16 * (2 - sps_ptr->frame_mbs_only_flag);  
  827. }  
  828.   
  829. int h264_get_format(SPS *sps_ptr)  
  830. {  
  831.     return sps_ptr->frame_mbs_only_flag;  
  832. }  
  833.   
  834.   
  835. int h264_get_framerate(float *framerate, SPS *sps_ptr)  
  836. {  
  837.     int fr;  
  838.     int fr_int = 0;  
  839.     if (sps_ptr->vui_parameters.timing_info_present_flag)  
  840.     {  
  841.         if (sps_ptr->frame_mbs_only_flag)  
  842.         {  
  843.             //*framerate = (float)sps_ptr->vui_parameters.time_scale / (float)sps_ptr->vui_parameters.num_units_in_tick;  
  844.             *framerate = (float)sps_ptr->vui_parameters.time_scale / (float)sps_ptr->vui_parameters.num_units_in_tick / 2.0;  
  845.             //fr_int = sps_ptr->vui_parameters.time_scale / sps_ptr->vui_parameters.num_units_in_tick;  
  846.         }  
  847.         else  
  848.         {  
  849.             *framerate = (float)sps_ptr->vui_parameters.time_scale / (float)sps_ptr->vui_parameters.num_units_in_tick / 2.0;  
  850.             //fr_int = sps_ptr->vui_parameters.time_scale / sps_ptr->vui_parameters.num_units_in_tick / 2;  
  851.         }  
  852.         return 0;  
  853.     }  
  854.     else  
  855.     {  
  856.         return 1;  
  857.     }  
  858. }  
  859.   
  860. void memcpy_sps_data(uint8_t *dst, uint8_t *src, int len)  
  861. {  
  862.     int tmp;  
  863.     for (tmp = 0; tmp < len; tmp++)  
  864.     {  
  865.         //printf("0x%02x ", src[tmp]);  
  866.         dst[(tmp / 4) * 4 + (3 - (tmp % 4))] = src[tmp];  
  867.     }  
  868. }  
  869. /*_*/  
  870. #ifdef __cplusplus   
  871. }  
  872. #endif   


Mux.cpp调用

[cpp]  view plain  copy
  1. /******************************************************************** 
  2. filename:   Mux.cpp 
  3. created:    2016-08-06 
  4. author:     Donyj 
  5. purpose:    MP4编码器,基于开源库mp4v2实现(https://code.google.com/p/mp4v2/)。 
  6. *********************************************************************/  
  7. #include <stdio.h>  
  8. #include<Winsock2.h>  
  9. #pragma comment(lib,"ws2_32.lib")  
  10. #include "MP4Encoder.h"  
  11.   
  12. FILE *fp_h264;  
  13. FILE *fp_AAC;  
  14. static int count_audio = 0;  
  15. int read_h264(unsigned char *buf, int buf_size)  
  16. {  
  17.     int true_size = fread(buf, 1, buf_size, fp_h264);  
  18.     if (true_size > 0){  
  19.         return true_size;  
  20.     }  
  21.     else{  
  22.         //fseek(fp_AAC, 0L, SEEK_SET);  
  23.         //return read_aac(buf, buf_size);  
  24.         return 0;  
  25.     }  
  26. }  
  27.   
  28. int read_aac(unsigned char *buf, int buf_size)  
  29. {  
  30.     unsigned char aac_header[7];  
  31.     int true_size = 0;  
  32.       
  33.     true_size = fread(aac_header, 1, 7, fp_AAC);  
  34.     if (true_size <= 0)  
  35.     {  
  36.         fseek(fp_AAC, 0L, SEEK_SET);  
  37.         return read_aac(buf, buf_size);  
  38.     }  
  39.     else  
  40.     {  
  41.         unsigned int body_size = *(unsigned int *)(aac_header + 3);  
  42.         body_size = ntohl(body_size); //Little Endian  
  43.         body_size = body_size << 6;  
  44.         body_size = body_size >> 19;  
  45.   
  46.         true_size = fread(buf, 1, body_size - 7, fp_AAC);  
  47.   
  48.         return true_size;  
  49.     }  
  50. }  
  51.   
  52. int main(int argc, char** argv)  
  53. {  
  54.     //fp_h264 = fopen("test.h264", "rb");  
  55.     //fp_h264 = fopen("1080.h264", "rb");  
  56.     fp_h264 = fopen("bitstream.h264""rb");  
  57.     fp_AAC = fopen("test.aac""rb");  
  58.   
  59.     MP4Encoder mp4Encoder;  
  60.     // convert H264 file to mp4 file  
  61.     mp4Encoder.MP4FileOpen("test.mp4", 1, 1);  
  62.     mp4Encoder.MP4FileWrite(read_h264, read_aac);  
  63.     mp4Encoder.MP4FileClose();  
  64.   
  65.     fclose(fp_h264);  
  66.     fclose(fp_AAC);  
  67. }  


这里是在Windows平台的代码,MP4V2库编译完成后需要对新建的Mux工作做库和头文件的引入,这里不做介绍。

若是应用平台,请做响应修改!


我的疑问:我在Linux编译成so库,strip后仍然有1M大小,不太适合个别嵌入式项目,正在做相应的裁剪工作,大家若有相关资料,希望能够分享一下!


  • 0
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值