librtmp获取视频流和音频流2

来源:互联网 发布:网络电话攻击软件 编辑:程序博客网 时间:2024/05/20 01:45

感谢作者:http://blog.csdn.net/byxdaz/article/details/54710464


在上篇文章中,使用librtmp库中包流函数(比如:RTMP_ReadPacket,RTMP_ClientPacket等)读取视频数据包,音频数据包。但在实际过程中连接rtmp服务器请求视频流时只能获取到I帧,无法获取P帧,B帧,从而导致视频不流畅,关于无法获取到P帧、B帧数据包与rtmp服务器有关。连接crtmpserver服务器获取视频流时只能获取到I帧,无法获取P帧,B帧;而连接香港卫视的直播流对应的rtmp服务器时,就可以获取到P帧。无论那个rtmp服务器通过RTMP_Read可以获取I帧、P帧等。本文重点介绍使用RTMP_Read获取视频流和音频流。

    获取数据流流程:

1、RTMP_SetupURL,指定直播流地址。

2、设置参数,比如:RTMP_SetBufferMS,设置缓存大小

3、RTMP_Connect

4、RTMP_ConnectStream

5、循环使用RTMP_Read读取数据流,将数据流存放到一个内存区域中。

6、按照FLV格式,循环从内存区域中读取数据,解析文件头,meta数据,视频数据,音频数据等。

       主要流程代码:

[cpp] view plain copy
  1. #define ONE_PACKET_PCM_DATA_LEN         320  
  2.   
  3. //ACC音频ADTS  
  4. typedef struct tagAACDecoderSpecific  
  5. {  
  6.     unsigned char nAudioFortmatType;    //音频编码类型(0:Liner PCM platform endian,1:PCM,2:mp3,4:Nellymoser 16-kHz mono,5:Nellymoser 8-kHz mono,6:Nellymoser,7:G.711 A-law logarithmic PCM,8:G.711 mu-law logarithmic PCM,9:reserved,10:?AAC,14:MP3 8-Khz,15:Device-specific sound)  
  7.     unsigned char nAudioSampleType; //音频采样率(0:5.5kHz,1:11KHz,2:22 kHz,3:44 kHz)  
  8.     unsigned char nAudioSizeType;   //音频采样精度(0:8bits,1:16bits)  
  9.     unsigned char nAudioStereo;//是否立体声(0:sndMono,1:sndStereo)  
  10.     unsigned char nAccPacketType;  
  11. }AACDecoderSpecific;  
  12.   
  13. typedef struct tagAACAudioSpecificConfig  
  14. {  
  15.     unsigned char nAudioObjectType;  
  16.     unsigned char nSampleFrequencyIndex;  
  17.     unsigned char nChannels;  
  18.     unsigned char nFrameLengthFlag;  
  19.     unsigned char nDependOnCoreCoder;  
  20.     unsigned char nExtensionFlag;  
  21. }AACAudioSpecificConfig;  
  22.   
  23. int         m_nImageWidth;  
  24.     int         m_nImageHeight;  
  25.     int         m_nFrameRate;  
  26.     char        m_szSPSData[512];  
  27.     int         m_nSPSDataLength;  
  28.     bool        m_bFindSPSData;  
  29.     char        m_szPPSData[512];  
  30.     int         m_nPPSDataLength;  
  31.     bool        m_bFindPPSData;  
  32.     bool        m_bSendSPSData;  
  33.     bool        m_bSendPPSData;  
  34.     bool        m_bRequireSendIFrame;  
  35.     AAC2PCM     m_aacOjbect;  
  36.     CammPoFrameDataProcess m_cfdCammPoFrameDataProcess;  
  37.     bool        m_bInitCammPoFrameDataProcess;  
  38.     FlvToStream m_ftsFlvToStream;//flv内存文件类  
  39.   
  40.     char *m_pVideoTempBuffer;//视频流缓存区  
  41.     unsigned int   m_nVideoTempBufferSize;  
  42.     unsigned int   m_nVideoTempBufferActualSize;  
  43.     int         m_nDelayTime;  
  44.     AACAudioSpecificConfig m_ascAudioSpecificConfig;  
  45.     char m_szSPSDataTmp[512];  
  46.     SPS m_spsFlag;  
  47.     unsigned long long m_ullBaseTimeStamps;  
  48.     uint32_t m_ullStartTimeStamps;  
  49.     uint32_t m_ullCurrentTimeStamps;  
  50.     uint32_t m_ullDiffTimeStamps;  
  51.     uint32_t m_uPacketStartTimeStamps;  
  52.     uint32_t m_uPacketCurrentTimeStamps;  
  53.     uint32_t m_uPacketDiffTimeStamps;  
  54.     uint32_t m_uPacketLastTimeStamps;  
  55.     uint32_t m_uPacketTempTimeStamps;  
  56.     bool m_bFindNextIFrame;  
  57.     unsigned int m_nPackTiemStampSecondTmp;  
  58.     int m_nTempBufferSize;  
  59.     char *m_pTempBuffer;  
  60.     unsigned char start_code[4];  
  61.     bool m_bRawAcc; //ACC原始数据音频包  
  62.     bool m_bAccObjectInit;  
  63.     char *m_pAccTempBuffer;     //acc音频流缓冲区  
  64.     unsigned int   m_nAccTempBufferSize;  
  65.     unsigned int   m_nAccTempBufferActualSize;  
  66.     char *m_pPcmLineBuffer;     //pcm音频流缓存区  
  67.     unsigned int m_nPcmLineBufferSize;  
  68.     unsigned int m_nPcmLineBufferActualSize;  
  69.     unsigned int m_nPcmLineBufferReadPos;  
  70.     unsigned int m_nPcmLineBufferWritePos;  
  71.     unsigned char m_ucTempPcmData[ONE_PACKET_PCM_DATA_LEN+1];  
  72.     char *m_pG726TempBuffer;  
  73.     unsigned int m_nG726TempBufferSize;  
  74.       
  75.       
  76. RTMP *  m_rtmp;  
  77. m_rtmp = RTMP_Alloc();  
  78.       
  79. RTMP_Init(m_rtmp);  
  80. //10秒  
  81.     RTMP_SetBufferMS(m_rtmp,10 * 1000);  
  82.     if (!RTMP_Connect(m_rtmp, NULL)){  
  83.         RTMP_Log(RTMP_LOGERROR, "Connect Err\n");  
  84.         RTMP_Free(m_rtmp);  
  85.         m_rtmp = NULL;  
  86.         return -1;  
  87.     }  
  88.     if (!RTMP_ConnectStream(m_rtmp, 0)){  
  89.         RTMP_Log(RTMP_LOGERROR, "ConnectStream Err\n");  
  90.         RTMP_Close(m_rtmp);  
  91.         RTMP_Free(m_rtmp);  
  92.         m_rtmp = NULL;  
  93.         return -1;  
  94.     }  
  95.       
  96.     int nRead = 0;  
  97.     int bufsize = 1024*1024;              
  98.     char *buf = new char[bufsize];  
  99.     memset(buf,0,bufsize);  
  100.     long countbufsize = 0;  
  101.     m_ftsFlvToStream.Init(bufsize*10);  
  102.     bool bIsOnePackage = false;  
  103.     int  nTagType = 0;  
  104.     int nTimeStamp = 0;  
  105.     int nWriteRawData = 0;  
  106.     int nDiffTimeStamp = 0;  
  107.     bool bFirstTickCount = true;  
  108.     DWORD dwStart = 0;  
  109.     DWORD dwNow = 0;  
  110.     DWORD dwDiffTickCountTmp = 0;  
  111.     int   nTimeSpan = 0;  
  112.     bool bFirstStartTimeStamp = true;  
  113.     int  nStartTimeStampTmp = 0;  
  114.     int  nStopTimeStampTmp = 0;  
  115.     int  nDiffTimeStampTmp = 0;  
  116.     while (IsRunning() && !IsException())  
  117.     {  
  118.         nRead = RTMP_Read(m_rtmp,buf,bufsize);  
  119.         if(nRead == 0 || RTMP_IsTimedout(m_rtmp))  
  120.         {  
  121.             SetException(true);  
  122.             //回调设备状态  
  123.             if(m_pDeviceAnswerCallback != NULL)  
  124.             {  
  125.                 m_pDeviceAnswerCallback(DVRNetSDK_ErrorCode_Exception,m_nDeviceAnswerUserData1,m_nDeviceAnswerUserData2);  
  126.             }  
  127.             break;  
  128.         }  
  129.         if(bFirstTickCount)  
  130.         {  
  131.             dwStart = GetTickCount();  
  132.             dwNow = dwStart;  
  133.             dwDiffTickCountTmp = 0;  
  134.             bFirstTickCount = false;  
  135.         }  
  136.         else  
  137.         {  
  138.             dwNow = GetTickCount();  
  139.             dwDiffTickCountTmp = dwNow - dwStart;  
  140.         }  
  141.   
  142.         //获取到数据,写入到内存缓冲区  
  143.         nWriteRawData = m_ftsFlvToStream.WriteRawData(buf,nRead);  
  144.         if(nWriteRawData == 2)  
  145.         {  
  146.             //空间不够  
  147.             while(true)  
  148.             {  
  149.                 //循环读数据,解析数据  
  150.                 bIsOnePackage = m_ftsFlvToStream.IsOnePackageData();  
  151.                 if(bIsOnePackage)  
  152.                 {  
  153.                     //读取数据  
  154.                     m_ftsFlvToStream.ReadFrameData(nTagType,nTimeStamp,m_pTempBuffer,m_nTempBufferSize);  
  155.                     //解析数据  
  156.                     ParseFrameData(nTagType,nTimeStamp,m_pTempBuffer,m_nTempBufferSize);  
  157.                 }  
  158.                 else  
  159.                 {  
  160.                     break;  
  161.                 }  
  162.             }  
  163.         }  
  164.         else  
  165.         {  
  166.             if(m_ftsFlvToStream.GetBufferEmptySize() >= bufsize)  
  167.             {  
  168.                 //缓存区有太大多数据,丢弃  
  169.                 int nStartTimeStampTmp2 = 0;  
  170.                 int nStopTimeStampTmp2 = 0;  
  171.                 nDiffTimeStamp = m_ftsFlvToStream.GetDiffTime(nStartTimeStampTmp2,nStopTimeStampTmp2);  
  172.                 if(nDiffTimeStamp >= 3000)  
  173.                 {  
  174.                     m_ftsFlvToStream.SkipToLastFrame(0);  
  175.                 }  
  176.                 else  
  177.                 {  
  178.                     while(true)  
  179.                     {  
  180.                         //循环读数据,解析数据  
  181.                         bIsOnePackage = m_ftsFlvToStream.IsOnePackageData();  
  182.                         if(bIsOnePackage)  
  183.                         {  
  184.                             //读取数据  
  185.                             m_ftsFlvToStream.ReadFrameData(nTagType,nTimeStamp,m_pTempBuffer,m_nTempBufferSize);  
  186.                             //解析数据  
  187.                             ParseFrameData(nTagType,nTimeStamp,m_pTempBuffer,m_nTempBufferSize);  
  188.                         }  
  189.                         else  
  190.                         {  
  191.                             break;  
  192.                         }  
  193.                     }  
  194.                 }  
  195.             }  
  196.             else  
  197.             {  
  198.                 //解析数据  
  199.                 bIsOnePackage = m_ftsFlvToStream.IsOnePackageData();  
  200.                 if(bIsOnePackage)  
  201.                 {  
  202.                     //读取数据  
  203.                     m_ftsFlvToStream.ReadFrameData(nTagType,nTimeStamp,m_pTempBuffer,m_nTempBufferSize);  
  204.                     //解析数据  
  205.                     ParseFrameData(nTagType,nTimeStamp,m_pTempBuffer,m_nTempBufferSize);  
  206.                 }  
  207.             }  
  208.         }  
  209.         if(bFirstStartTimeStamp)  
  210.         {  
  211.             nStartTimeStampTmp = 0;  
  212.             nStopTimeStampTmp = 0;  
  213.             nDiffTimeStampTmp = 0;  
  214.             bFirstStartTimeStamp = false;  
  215.         }  
  216.         else  
  217.         {  
  218.             int nStartTimeStampTmp1 = 0;  
  219.             int nStopTimeStampTmp1 = 0;  
  220.             m_ftsFlvToStream.GetDiffTime(nStartTimeStampTmp1,nStopTimeStampTmp1);  
  221.             nStopTimeStampTmp = nStopTimeStampTmp1;  
  222.             nDiffTimeStampTmp = nStopTimeStampTmp - nStartTimeStampTmp;  
  223.         }  
  224.         nTimeSpan = GetTickCount() - dwNow;  
  225.         if(dwDiffTickCountTmp >= (nDiffTimeStampTmp+nTimeSpan))  
  226.         {  
  227.             Sleep(10);  
  228.         }  
  229.         else  
  230.         {  
  231.             Sleep(25);  
  232.         }  
  233.     }  
  234.   
  235.     //释放空间  
  236.     if(buf != NULL)  
  237.     {  
  238.         delete []buf;  
  239.     }  
  240.         if(m_rtmp != NULL)  
  241.     {  
  242.         RTMP_DeleteStream(m_rtmp);  
  243.     }  
  244.       
  245.       
  246.       
  247.       
  248.     //数据解析  
  249. int ParseFrameData(int nTagType,int nTimeStamp,char * pTempBuffer,int nTempBufferSize)  
  250. {  
  251.     int nFrameType = 0;  
  252.     unsigned char result = 0;  
  253.     unsigned char nAVCPacketType = 0;  
  254.     char *data = NULL;  
  255.   
  256.     if(m_uPacketStartTimeStamps == 0)  
  257.     {  
  258.         m_uPacketStartTimeStamps = nTimeStamp;  
  259.         m_uPacketCurrentTimeStamps = m_uPacketStartTimeStamps;  
  260.     }  
  261.     else  
  262.     {  
  263.         m_uPacketStartTimeStamps = m_uPacketCurrentTimeStamps;  
  264.         m_uPacketCurrentTimeStamps = nTimeStamp;  
  265.     }  
  266.     m_uPacketDiffTimeStamps = m_uPacketCurrentTimeStamps - m_uPacketStartTimeStamps;  
  267.     m_ullStartTimeStamps = m_ullCurrentTimeStamps;  
  268.     m_ullCurrentTimeStamps = RTMP_GetTime();  
  269.     m_ullDiffTimeStamps = m_ullCurrentTimeStamps - m_ullStartTimeStamps;  
  270.   
  271.     if(nTagType == RTMP_PACKET_TYPE_INFO)  
  272.     {  
  273.         int nVideoCodecId = 0;  
  274.         int nVideoWidth = 0;  
  275.         int nVideoHeight = 0;  
  276.         int nVideoFrameRate = 25;  
  277.         int nAudioCodecId = 0;  
  278.         int nAudioSampleRate = 0;  
  279.         int nAudioSampleSize = 0;  
  280.         bool bStereo = false;           //立体声  
  281.         int nFileSize = 0;  
  282.         ParseScriptTag(pTempBuffer, nTempBufferSize, nVideoCodecId, nVideoWidth, nVideoHeight, nVideoFrameRate, nAudioCodecId, nAudioSampleRate, nAudioSampleSize, bStereo, nFileSize);  
  283.         m_nImageWidth = nVideoWidth;  
  284.         m_nImageHeight = nVideoHeight;  
  285.         m_nFrameRate = nVideoFrameRate;  
  286.         if(m_nImageWidth != 0 && m_nImageHeight != 0)  
  287.         {  
  288.             m_nDelayTime = 15 < 1000.0/m_nFrameRate ? 1000.0/m_nFrameRate:15;  
  289.             //头帧码流回调  
  290.             HeaderFrameStreamCallback();  
  291.         }  
  292.     }  
  293.     else if(nTagType == RTMP_PACKET_TYPE_VIDEO)  
  294.     {  
  295.         data = pTempBuffer;  
  296.         result = pTempBuffer[0];  
  297.         nAVCPacketType = pTempBuffer[1];  
  298.         bool bIsKeyFrame = false;  
  299.         nFrameType = 11;  
  300.         if (result == 0x17)//I frame  
  301.         {  
  302.             bIsKeyFrame = true;  
  303.             nFrameType = 10;  
  304.         }  
  305.         else if (result == 0x27)  
  306.         {  
  307.             nFrameType = 11;  
  308.         }  
  309.         else  
  310.         {  
  311.             return 0;  
  312.         }             
  313.         if (nAVCPacketType == 0)  
  314.         {  
  315.             //AVCsequence header  
  316.             //Access to SPS  
  317.             int spsnum = data[10] & 0x1f;  
  318.             int number_sps = 11;  
  319.             int count_sps = 1;  
  320.             while (count_sps <= spsnum){  
  321.                 int spslen = (data[number_sps] & 0x000000FF) << 8 | (data[number_sps + 1] & 0x000000FF);  
  322.                 number_sps += 2;  
  323.                 memset(m_szSPSData, 0, sizeof(m_szSPSData));  
  324.                 memcpy(m_szSPSData, start_code, 4);  
  325.                 memcpy(m_szSPSData + 4, data + number_sps, spslen);  
  326.                 m_nSPSDataLength = 4 + spslen;  
  327.                 memcpy(m_szSPSDataTmp, m_szSPSData, sizeof(m_szSPSData));  
  328.                 m_bFindSPSData = true;  
  329.                 //如果没有获取图像宽高,帧率  
  330.                 if (0 == m_nImageWidth)  
  331.                 {  
  332.                     //分析sps  
  333.                     get_bit_context spsRawData;  
  334.                     spsRawData.buf = (unsigned char *)m_szSPSDataTmp + 5;  
  335.                     spsRawData.buf_size = m_nSPSDataLength - 5;  
  336.                     spsRawData.bit_pos = 0;  
  337.                     spsRawData.cur_bit_pos = 0;  
  338.                     spsRawData.total_bit = 0;  
  339.                     int nSpsParseRet = h264dec_seq_parameter_set(&spsRawData, &m_spsFlag);  
  340.                     if (0 == nSpsParseRet)  
  341.                     {  
  342.                         //解析成功  
  343.                         m_nImageWidth = (m_spsFlag.pic_width_in_mbs_minus1 + 1) * 16;  
  344.                         m_nImageHeight = (m_spsFlag.pic_height_in_map_units_minus1 + 1) * 16;  
  345.                         m_nFrameRate = m_spsFlag.vui_parameters.time_scale / m_spsFlag.vui_parameters.num_units_in_tick;  
  346.                         m_nDelayTime = 15 < 1000.0/m_nFrameRate ? 1000.0/m_nFrameRate:15;  
  347.                         //头帧码流回调  
  348.                         HeaderFrameStreamCallback();  
  349.                     }  
  350.                 }  
  351.   
  352.                 number_sps += spslen;  
  353.                 count_sps++;  
  354.             }  
  355.             //Get PPS  
  356.             int ppsnum = data[number_sps] & 0x1f;  
  357.             int number_pps = number_sps + 1;  
  358.             int count_pps = 1;  
  359.             while (count_pps <= ppsnum){  
  360.                 int ppslen = (data[number_pps] & 0x000000FF) << 8 | data[number_pps + 1] & 0x000000FF;  
  361.                 number_pps += 2;  
  362.                 memset(m_szPPSData, 0, sizeof(m_szPPSData));  
  363.                 memcpy(m_szPPSData, start_code, 4);  
  364.                 memcpy(m_szPPSData+4, data + number_pps, ppslen);  
  365.                 m_nPPSDataLength = 4 + ppslen;  
  366.                 m_bFindPPSData = true;  
  367.   
  368.                 number_pps += ppslen;  
  369.                 count_pps++;  
  370.             }  
  371.         }  
  372.         else if (nAVCPacketType == 1)  
  373.         {  
  374.             //AVC NALU  
  375.             int len = 0;  
  376.             int num = 5;  
  377.             int nNALVNumbers = 0;  
  378.             while (num < nTempBufferSize)  
  379.             {  
  380.                 len = (data[num] & 0x000000FF) << 24 | (data[num + 1] & 0x000000FF) << 16 | (data[num + 2] & 0x000000FF) << 8 | data[num + 3] & 0x000000FF;  
  381.                 if(len > nTempBufferSize)  
  382.                 {  
  383.                     break;  
  384.                 }  
  385.                 num += 4;  
  386.   
  387.                 if((len+4+8) >m_nVideoTempBufferSize-1)  
  388.                 {  
  389.                     m_nVideoTempBufferSize = len + 1024*5;  
  390.                     delete []m_pVideoTempBuffer;  
  391.                     m_pVideoTempBuffer = new char[m_nVideoTempBufferSize];  
  392.                 }  
  393.                 if(m_pVideoTempBuffer != NULL)  
  394.                 {     
  395.                     //8个字节时间戳  
  396.                     unsigned long long ullTimeStamps = 0;  
  397.                     if (!m_bSendSPSData && m_bFindSPSData)  
  398.                     {  
  399.                         ullTimeStamps = m_ullBaseTimeStamps + nTimeStamp;  
  400.                         memcpy(m_pVideoTempBuffer,&ullTimeStamps,8);  
  401.                         m_nVideoTempBufferActualSize = 8;  
  402.                         memcpy(m_pVideoTempBuffer+m_nVideoTempBufferActualSize,m_szSPSData,m_nSPSDataLength);  
  403.                         m_nVideoTempBufferActualSize +=m_nSPSDataLength;  
  404.                         if(m_pCallback != NULL)  
  405.                         {  
  406.                             //回调码流  
  407.                             //m_pCallback(m_szDeviceID,m_uiChannel,0,0,e_DVRNET_FrameType_Video_IFrame,m_pVideoTempBuffer,m_nVideoTempBufferActualSize,m_uiCallbackUserData1,m_uiCallbackUserData2);  
  408.                         }  
  409.                         //m_bSendSPSData = true;  
  410.                     }  
  411.                     if (!m_bSendPPSData && m_bFindPPSData)  
  412.                     {  
  413.                         ullTimeStamps = m_ullBaseTimeStamps + nTimeStamp;  
  414.                         memcpy(m_pVideoTempBuffer,&ullTimeStamps,8);  
  415.                         m_nVideoTempBufferActualSize = 8;  
  416.                         memcpy(m_pVideoTempBuffer+m_nVideoTempBufferActualSize,m_szPPSData,m_nPPSDataLength);  
  417.                         m_nVideoTempBufferActualSize +=m_nPPSDataLength;  
  418.                         if(m_pCallback != NULL)  
  419.                         {  
  420.                             //回调码流  
  421.                             //m_pCallback(m_szDeviceID,m_uiChannel,0,0,e_DVRNET_FrameType_Video_IFrame,m_pVideoTempBuffer,m_nVideoTempBufferActualSize,m_uiCallbackUserData1,m_uiCallbackUserData2);  
  422.                         }  
  423.                         //m_bSendPPSData = true;  
  424.                     }  
  425.                     //8个字节时间戳  
  426.                     /* 
  427.                     ullTimeStamps = m_ullBaseTimeStamps + nTimeStamp + nNALVNumbers; 
  428.                     memcpy(m_pVideoTempBuffer,&ullTimeStamps,8); 
  429.                     m_nVideoTempBufferActualSize = 8; 
  430.                     memcpy(m_pVideoTempBuffer+m_nVideoTempBufferActualSize,start_code,4); 
  431.                     m_nVideoTempBufferActualSize +=4; 
  432.                     memcpy(m_pVideoTempBuffer+m_nVideoTempBufferActualSize,data + num,len); 
  433.                     m_nVideoTempBufferActualSize +=len; 
  434.                     */  
  435.                     ullTimeStamps = m_ullBaseTimeStamps + nTimeStamp + nNALVNumbers;  
  436.                     memcpy(m_pVideoTempBuffer,&ullTimeStamps,8);  
  437.                     m_nVideoTempBufferActualSize = 8;  
  438.                     memcpy(m_pVideoTempBuffer+m_nVideoTempBufferActualSize,start_code,4);  
  439.                     m_nVideoTempBufferActualSize +=4;  
  440.                     if (!m_bSendSPSData && m_bFindSPSData)  
  441.                     {  
  442.                         memcpy(m_pVideoTempBuffer+m_nVideoTempBufferActualSize,m_szSPSData,m_nSPSDataLength);  
  443.                         m_nVideoTempBufferActualSize +=m_nSPSDataLength;  
  444.                         m_bSendSPSData = true;  
  445.                     }  
  446.                     if (!m_bSendPPSData && m_bFindPPSData)  
  447.                     {  
  448.                         memcpy(m_pVideoTempBuffer+m_nVideoTempBufferActualSize,m_szPPSData,m_nPPSDataLength);  
  449.                         m_nVideoTempBufferActualSize +=m_nPPSDataLength;  
  450.                         m_bSendPPSData = true;  
  451.                     }  
  452.                     memcpy(m_pVideoTempBuffer+m_nVideoTempBufferActualSize,data + num,len);  
  453.                     m_nVideoTempBufferActualSize +=len;  
  454.   
  455.                     if(m_pCallback != NULL)  
  456.                     {  
  457.                         //启动缓存区读写线程  
  458.                         if(!m_bInitCammPoFrameDataProcess)  
  459.                         {  
  460.                             int nMaxFrameNum = 25;  
  461.                             if(m_nFrameRate > 0 && m_nFrameRate < 80)  
  462.                             {  
  463.                                 nMaxFrameNum = m_nFrameRate;  
  464.                             }  
  465.                             m_cfdCammPoFrameDataProcess.Init(Max_Video_Width*Max_Video_Width*5,1000,m_nFrameRate);  
  466.                             m_cfdCammPoFrameDataProcess.SetDeviceID(m_szDeviceID);  
  467.                             m_cfdCammPoFrameDataProcess.SetChannel(m_uiChannel);  
  468.                             m_cfdCammPoFrameDataProcess.SetRealAVStreamDataCallback(m_pCallback,m_uiCallbackUserData1,m_uiCallbackUserData2);  
  469.                             m_cfdCammPoFrameDataProcess.StartThread();  
  470.                             m_bInitCammPoFrameDataProcess = true;  
  471.                         }                                         
  472.                         //回调码流  
  473.                         if(m_cfdCammPoFrameDataProcess.RemainWriteFrameNum() > 0)  
  474.                         {  
  475.                             TraceDebug("rtmp client llTimeStampsTmp=%lld,frameType=%d,framenum=%d,frametime=%d\n",ullTimeStamps,nFrameType,m_cfdCammPoFrameDataProcess.RemainWriteFrameNum(),m_cfdCammPoFrameDataProcess.m_fbVideoFrameBuffer.GetBufferFrameTime());  
  476.                             if(m_bFindNextIFrame)  
  477.                             {  
  478.                                 if(bIsKeyFrame)  
  479.                                 {  
  480.                                     m_bFindNextIFrame = false;  
  481.                                     m_cfdCammPoFrameDataProcess.WriteFrameData(nFrameType,(unsigned char *)m_pVideoTempBuffer,m_nVideoTempBufferActualSize);  
  482.                                 }  
  483.                             }  
  484.                             else  
  485.                             {  
  486.                                 m_cfdCammPoFrameDataProcess.WriteFrameData(nFrameType,(unsigned char *)m_pVideoTempBuffer,m_nVideoTempBufferActualSize);  
  487.                             }  
  488.                         }  
  489.                         else  
  490.                         {  
  491.                             m_cfdCammPoFrameDataProcess.m_fbVideoFrameBuffer.ResetToSaveVideoIFrame();  
  492.                             m_bFindNextIFrame = true;  
  493.                             //Sleep(15);  
  494.                         }                                     
  495.                         //m_pCallback(m_szDeviceID,m_uiChannel,0,0,nFrameType,pVideoTempBuffer,nVideoTempBufferActualSize,m_uiCallbackUserData1,m_uiCallbackUserData2);  
  496.                     }  
  497.                 }  
  498.                 num +=len;  
  499.                 nNALVNumbers++;  
  500.             }  
  501.         }  
  502.         else if (nAVCPacketType == 2)  
  503.         {  
  504.             //AVC end of sequence (lower level NALU sequence ender is not required or supported)  
  505.         }  
  506.   
  507.     }  
  508.     else if(nTagType == RTMP_PACKET_TYPE_AUDIO)  
  509.     {     
  510.         nFrameType = 9;  
  511.         data = pTempBuffer;  
  512.         //判断是否ACC音频同步包,还是ACC原始数据音频包  
  513.         if (!m_bRawAcc && nTempBufferSize>=4)  
  514.         {  
  515.             //ACC音频同步包(1bytes+3bytes AccAudioData) (4bytes 包含了AACDecoderSpecific和AudioSpecificConfig)  
  516.             AACDecoderSpecific adsAACDecoderSpecific = { 0 };  
  517.             adsAACDecoderSpecific.nAudioFortmatType = (data[0] & 0xf0) >> 4;  //音频编码类型(0:Liner PCM platform endian,1:PCM,2:mp3,4:Nellymoser 16-kHz mono,5:Nellymoser 8-kHz mono,6:Nellymoser,7:G.711 A-law logarithmic PCM,8:G.711 mu-law logarithmic PCM,9:reserved,10:?AAC,14:MP3 8-Khz,15:Device-specific sound)  
  518.             adsAACDecoderSpecific.nAudioSampleType = (data[0] & 0x0c) >> 2;   //音频采样率(0:5.5kHz,1:11KHz,2:22 kHz,3:44 kHz)  
  519.             adsAACDecoderSpecific.nAudioSizeType = (data[0] & 0x02) >> 1; //音频采样精度(0:8bits,1:16bits)  
  520.             adsAACDecoderSpecific.nAudioStereo = data[0] & 0x01;//是否立体声(0:sndMono,1:sndStereo)  
  521.             if (adsAACDecoderSpecific.nAudioFortmatType == 10)  
  522.             {  
  523.                 //The following values are defined:  
  524.                 //0 = AAC sequence header  
  525.                 //1 = AAC raw  
  526.                 adsAACDecoderSpecific.nAccPacketType = data[1];  
  527.                 unsigned short audioSpecificConfig = 0;  
  528.                 audioSpecificConfig = (data[2] & 0xff) << 8;  
  529.                 audioSpecificConfig += 0x00ff & data[3];  
  530.                 m_ascAudioSpecificConfig.nAudioObjectType = (audioSpecificConfig & 0xF800) >> 11;  
  531.                 m_ascAudioSpecificConfig.nSampleFrequencyIndex = (audioSpecificConfig & 0x0780) >> 7;  
  532.                 m_ascAudioSpecificConfig.nChannels = (audioSpecificConfig & 0x78) >> 3;  
  533.                 m_ascAudioSpecificConfig.nFrameLengthFlag = (audioSpecificConfig & 0x04) >> 2;  
  534.                 m_ascAudioSpecificConfig.nDependOnCoreCoder = (audioSpecificConfig & 0x02) >> 1;  
  535.                 m_ascAudioSpecificConfig.nExtensionFlag = audioSpecificConfig & 0x01;  
  536.                 m_bRawAcc = true;  
  537.             }  
  538.             else if (adsAACDecoderSpecific.nAudioFortmatType == 11)  
  539.             {  
  540.                 //speex类型数据时,后面的4位数据不起作用,固定的是16KHZ,单声道,16bit/sample  
  541.                 adsAACDecoderSpecific.nAudioStereo = 0;  
  542.                 adsAACDecoderSpecific.nAudioSizeType = 1;  
  543.                 adsAACDecoderSpecific.nAudioSampleType = 4;  
  544.                 m_bRawAcc = true;  
  545.             }  
  546.         }  
  547.         else  
  548.         {  
  549.             //raw data 获取 audio payload  
  550.             if (nTempBufferSize > 2 && data[1] == 1)  
  551.             {  
  552.                 //写ADTS数据到文件  
  553.                 char szADTSTemp[8] = { 0 };  
  554.                 CreateADTS(m_ascAudioSpecificConfig, nTempBufferSize - 2 + 7, szADTSTemp);  
  555.                 //转换aac数据到g726  
  556.                 memcpy(m_pAccTempBuffer, szADTSTemp, 7);  
  557.                 memcpy(m_pAccTempBuffer + 7, pTempBuffer + 2, nTempBufferSize - 2);  
  558.                 m_nAccTempBufferSize = 7 + nTempBufferSize - 2;  
  559.                 if (!m_bAccObjectInit)  
  560.                 {  
  561.                     m_aacOjbect.init(m_ascAudioSpecificConfig.nAudioObjectType, GetSampleRate(m_ascAudioSpecificConfig.nSampleFrequencyIndex));  
  562.                     m_bAccObjectInit = true;  
  563.                 }  
  564.                 if((m_nPcmLineBufferSize-m_nPcmLineBufferWritePos) <= 4096)  
  565.                 {  
  566.                     //移动数据,pcm缓冲区  
  567.                     int kk = 0;  
  568.                     for(int k=m_nPcmLineBufferReadPos; k<m_nPcmLineBufferWritePos; k++)  
  569.                     {  
  570.                         m_pPcmLineBuffer[kk] = m_pPcmLineBuffer[k];  
  571.                         kk++;  
  572.                     }  
  573.                     m_nPcmLineBufferReadPos = 0;  
  574.                     m_nPcmLineBufferWritePos = kk;  
  575.                 }  
  576.                 char *pTmp = m_pPcmLineBuffer + m_nPcmLineBufferWritePos;  
  577.                 m_nPcmLineBufferActualSize = 0;  
  578.                 int nAccConvertResult = m_aacOjbect.convert2PCM((unsigned char *)m_pAccTempBuffer, m_nAccTempBufferSize,(unsigned char *)pTmp, m_nPcmLineBufferActualSize);  
  579.                 if(nAccConvertResult == 0)  
  580.                 {  
  581.                     m_nPcmLineBufferWritePos += m_nPcmLineBufferActualSize;  
  582.                     //从pcm缓冲区读取数据  
  583.                     while((m_nPcmLineBufferWritePos - m_nPcmLineBufferReadPos) >= ONE_PACKET_PCM_DATA_LEN)  
  584.                     {  
  585.                         memcpy(m_ucTempPcmData,m_pPcmLineBuffer+m_nPcmLineBufferReadPos,ONE_PACKET_PCM_DATA_LEN);  
  586.                         m_nPcmLineBufferReadPos +=ONE_PACKET_PCM_DATA_LEN;  
  587.                         //音频PCM转换G726  
  588.                         size_t buf_sizeG726 = 0;  
  589.                         nAccConvertResult = m_aacOjbect.Pcm2G726(m_ucTempPcmData,ONE_PACKET_PCM_DATA_LEN,(unsigned char *)m_pG726TempBuffer+8,buf_sizeG726);  
  590.                         if(nAccConvertResult == 0)  
  591.                         {  
  592.                             if(m_pCallback != NULL)  
  593.                             {  
  594.                                 //8个字节时间戳  
  595.                                 unsigned long long ullTimeStamps = 0;  
  596.                                 ullTimeStamps = m_ullBaseTimeStamps + nTimeStamp;  
  597.                                 memcpy(m_pG726TempBuffer,&ullTimeStamps,8);  
  598.                                 buf_sizeG726 +=8;  
  599.                                 //回调码流  
  600.                                 if(m_bInitCammPoFrameDataProcess)  
  601.                                 {  
  602.                                     if(m_cfdCammPoFrameDataProcess.RemainWriteFrameNum() > 0)  
  603.                                     {  
  604.                                         m_cfdCammPoFrameDataProcess.WriteFrameData(nFrameType,(unsigned char *)m_pG726TempBuffer,buf_sizeG726);  
  605.                                     }  
  606.                                 }  
  607.   
  608.                                 //m_pCallback(m_szDeviceID,m_uiChannel,0,0,nFrameType,m_pG726TempBuffer,buf_sizeG726,m_uiCallbackUserData1,m_uiCallbackUserData2);  
  609.                             }  
  610.                         }  
  611.                     }  
  612.                 }  
  613.             }  
  614.             else if (nTempBufferSize > 4 && data[1] == 0)  
  615.             {  
  616.                 int jjjjj = 0;  
  617.             }  
  618.         }  
  619.         //The actual audio content for the pkt-> m_body+1, size is pkt-> m_nBodySize-1. Here is the voice of Speex code.  
  620.     }  
  621.   
  622.     return 0;  
  623. }  

       FlvToStream类,FLV内存文件解析类。

      FlvToStream.h

[cpp] view plain copy
  1. //帧缓冲区  
  2.   
  3. #ifndef  __FlvToStream_H__  
  4. #define  __FlvToStream_H__  
  5.   
  6. #pragma once  
  7.   
  8. #include <iostream>  
  9. #include <stdio.h>  
  10. #include <stdlib.h>  
  11. #include <string.h>  
  12.   
  13. using namespace std;  
  14.   
  15. //int h264space = 0x01000000;//H264内容间隔标识00000001  
  16.   
  17. #define HTON16(x)  ((x>>8&0xff)|(x<<8&0xff00))  
  18. #define HTON24(x)  ((x>>16&0xff)|(x<<16&0xff0000)|x&0xff00)  
  19. #define HTON32(x)  ((x>>24&0xff)|(x>>8&0xff00)|\  
  20.     (x << 8 & 0xff0000) | (x << 24 & 0xff000000))  
  21.   
  22. class FlvToStream  
  23. {  
  24. public:  
  25.     FlvToStream(void);  
  26.     virtual ~FlvToStream(void);  
  27.   
  28.     //初始化  
  29.     int Init(int nAllocSize);  
  30.       
  31.     //反初始化  
  32.     int UnInit();  
  33.   
  34.     //写数据  
  35.     int WriteRawData(char *pBuffer,int nBufferSize);  
  36.   
  37.     //是否有一包完整数据  
  38.     bool IsOnePackageData();  
  39.   
  40.     //读取数据  
  41.     int ReadFrameData(int & nFrameType,int & nTimeStamp,char *pBuffer,int & nBufferSize);  
  42.   
  43.     /* 
  44.     功能:跳转至最后一帧数据 
  45.     参数:nLastFrameDataType,数据帧类型,0:帧;1:视频主帧;2:视频虚帧;3:音频帧 
  46.     */  
  47.     void SkipToLastFrame(int nLastFrameDataType);  
  48.   
  49.     //获取帧数据时间差(总数据差)  
  50.     int  GetDiffTime(int & nStartTimeStamp,int & nStopTimeStamp);  
  51.   
  52.     //获取剩余空间  
  53.     unsigned int  GetBufferEmptySize();  
  54. protected:  
  55.     //调整位置  
  56.     void Resize();  
  57.   
  58.     //清除  
  59.     void Clear();  
  60.   
  61.     //读字节数据   
  62.     bool Read8(int &i8, char *pBuffer);  
  63.     bool Read16(int &i16,char *pBuffer);  
  64.     bool Read24(int &i24, char *pBuffer);  
  65.     bool Read32(int &i32, char *pBuffer);  
  66.     bool ReadTime(int &itime, char *pBuffer);  
  67.   
  68.     bool Peek8(int &i8, char *pBuffer);  
  69.   
  70.     bool ReadHead();  
  71.   
  72.     void VideoParse(int datalength);  
  73.     void AudioParse(int datalength);  
  74.     void MediaInfoParse(int datalength);  
  75.   
  76.     char *m_pAllocBuffer;  
  77.     unsigned int   m_nAllocBufferSize;  
  78.     unsigned int   m_nAllocBufferEmptySize;  
  79.     unsigned int   m_nReadPos;  
  80.     unsigned int   m_nWritePos;  
  81.     bool  m_bReadFileHeader;  
  82.     bool  m_bPreviousTagSize0Read;  
  83.     char *m_pTempBuffer;                    //流缓存区  
  84.     unsigned int   m_nTempBufferSize;  
  85.     int   m_nFrameType;  
  86.     int   m_nDateStamp;  
  87.     //FILE *h264file;  
  88. };  
  89.   
  90. #endif  
FlvToStream.cpp

[cpp] view plain copy
  1. #include "stdafx.h"  
  2. #include "FlvToStream.h"  
  3.   
  4. #define     Max_Video_Width             1024                //视频宽度  
  5. #define     Max_Video_Height            720                 //视频高度  
  6.   
  7. FlvToStream::FlvToStream(void)  
  8. {  
  9.     m_pAllocBuffer = NULL;  
  10.     m_nAllocBufferSize = 0;  
  11.     m_nAllocBufferEmptySize = 0;  
  12.     m_nReadPos = 0;  
  13.     m_nWritePos = 0;  
  14.     m_bReadFileHeader = false;  
  15.     m_bPreviousTagSize0Read = false;  
  16.     m_pTempBuffer = NULL;  
  17.     m_nTempBufferSize = 0;  
  18. }  
  19.   
  20. FlvToStream::~FlvToStream(void)  
  21. {  
  22.     UnInit();  
  23. }  
  24.   
  25. //初始化  
  26. int FlvToStream::Init(int nAllocSize)  
  27. {  
  28.     m_nAllocBufferSize = nAllocSize;  
  29.     m_nAllocBufferEmptySize = m_nAllocBufferSize;  
  30.     m_nReadPos = 0;  
  31.     m_nWritePos = 0;  
  32.     if(m_pAllocBuffer != NULL)  
  33.     {  
  34.         delete []m_pAllocBuffer;  
  35.     }  
  36.     m_pAllocBuffer = new char[m_nAllocBufferSize*1];  
  37.     memset(m_pAllocBuffer,0,sizeof(char)*(m_nAllocBufferSize*1));  
  38.     m_bReadFileHeader = false;  
  39.     m_bPreviousTagSize0Read = false;  
  40.     m_pTempBuffer = new  char[Max_Video_Width * Max_Video_Height+1];  
  41.     m_nTempBufferSize = Max_Video_Width * Max_Video_Height+1;  
  42.     //h264file = fopen("FlvToStream.h264", "wb");  
  43.   
  44.     return 0;  
  45. }  
  46.   
  47. //反初始化  
  48. int FlvToStream::UnInit()  
  49. {  
  50.     if(m_pAllocBuffer != NULL)  
  51.     {  
  52.         delete []m_pAllocBuffer;  
  53.         m_pAllocBuffer = NULL;  
  54.     }  
  55.     if(m_pTempBuffer != NULL)  
  56.     {  
  57.         delete []m_pTempBuffer;  
  58.         m_pTempBuffer = NULL;  
  59.     }  
  60.   
  61.     return 0;  
  62. }  
  63.   
  64. //调整位置  
  65. void FlvToStream::Resize()  
  66. {  
  67.     int n = 0;  
  68.     for(n=m_nReadPos;n<m_nWritePos;n++)  
  69.     {  
  70.         m_pAllocBuffer[n-m_nReadPos] = m_pAllocBuffer[n];  
  71.     }  
  72.     unsigned int nTmp = m_nWritePos-m_nReadPos;  
  73.     m_nReadPos = 0;  
  74.     m_nWritePos = nTmp;  
  75.     m_nAllocBufferEmptySize = m_nAllocBufferSize - nTmp;  
  76. }  
  77.   
  78. //清除  
  79. void FlvToStream::Clear()  
  80. {  
  81.     m_nAllocBufferEmptySize = m_nAllocBufferSize;  
  82.     m_nReadPos = 0;  
  83.     m_nWritePos = 0;  
  84. }  
  85. //写数据  
  86. int FlvToStream::WriteRawData(char *pBuffer,int nBufferSize)  
  87. {  
  88.     unsigned int nTmp = m_nWritePos-m_nReadPos;  
  89.     if(nBufferSize > (m_nAllocBufferSize-m_nWritePos))  
  90.     {  
  91.         if(nBufferSize <= (m_nAllocBufferSize - nTmp))  
  92.         {  
  93.             //调整位置(线性缓冲区)  
  94.             Resize();  
  95.         }  
  96.         else  
  97.         {  
  98.             return 2;//空间不够  
  99.         }  
  100.     }  
  101.     if((m_nAllocBufferSize - m_nWritePos) < nBufferSize)  
  102.     {  
  103.         return 2;  
  104.     }  
  105.   
  106.     memcpy(m_pAllocBuffer+m_nWritePos,pBuffer,nBufferSize);  
  107.     m_nWritePos +=nBufferSize;  
  108.     nTmp = m_nWritePos-m_nReadPos;  
  109.     m_nAllocBufferEmptySize = m_nAllocBufferSize - nTmp;  
  110.   
  111.     return 0;  
  112. }  
  113.   
  114. //读取数据  
  115. int FlvToStream::ReadFrameData(int & nFrameType,int & nTimeStamp,char *pBuffer,int & nBufferSize)  
  116. {  
  117.     nFrameType = m_nFrameType;  
  118.     nTimeStamp = m_nDateStamp;  
  119.     nBufferSize = m_nTempBufferSize;  
  120.     memcpy(pBuffer,m_pAllocBuffer+m_nReadPos,nBufferSize);  
  121.     //更新位置  
  122.     m_nReadPos = m_nReadPos+nBufferSize+4;//4个字节tag size  
  123.     unsigned int nTmp = m_nWritePos-m_nReadPos;  
  124.     m_nAllocBufferEmptySize = m_nAllocBufferSize - nTmp;  
  125.   
  126.     return 0;  
  127. }  
  128.   
  129. /* 
  130. 功能:跳转至最后一帧数据 
  131. 参数:nLastFrameDataType,数据帧类型,0:帧;1:视频主帧;2:视频虚帧;3:音频帧 
  132. */  
  133. void FlvToStream::SkipToLastFrame(int nLastFrameDataType)  
  134. {  
  135.     int nFrameType = 0;  
  136.     int nTimeStamp = 0;  
  137.     int nBufferSize = 0;  
  138.     unsigned int nTmp = 0;  
  139.     while(true)  
  140.     {  
  141.         if(IsOnePackageData())  
  142.         {  
  143.             //读取数据  
  144.             nFrameType = m_nFrameType;  
  145.             nTimeStamp = m_nDateStamp;  
  146.             nBufferSize = m_nTempBufferSize;  
  147.             //更新位置  
  148.             m_nReadPos = m_nReadPos+nBufferSize+4;//4个字节tag size  
  149.             nTmp = m_nWritePos-m_nReadPos;  
  150.             m_nAllocBufferEmptySize = m_nAllocBufferSize - nTmp;  
  151.         }  
  152.         else  
  153.         {  
  154.             break;  
  155.         }  
  156.     }  
  157. }  
  158.   
  159. //获取帧数据时间差  
  160. int  FlvToStream::GetDiffTime(int & nStartTimeStamp,int & nStopTimeStamp)  
  161. {  
  162.     unsigned int nReadPosOld = m_nReadPos;  
  163.     unsigned int nWritePosOld = m_nWritePos;  
  164.     bool     bReadFileHeaderOld = m_bReadFileHeader;  
  165.     bool     bPreviousTagSize0Read = m_bPreviousTagSize0Read;  
  166.     int nFrameType = 0;  
  167.     int nFirstTimeStamp = 0;  
  168.     int nTimeStamp = 0;  
  169.     int nBufferSize = 0;  
  170.     unsigned int nTmp = 0;  
  171.     bool bFirstFrame = false;  
  172.     while(true)  
  173.     {  
  174.         if(IsOnePackageData())  
  175.         {  
  176.             //读取数据  
  177.             nFrameType = m_nFrameType;  
  178.             nTimeStamp = m_nDateStamp;  
  179.             nBufferSize = m_nTempBufferSize;  
  180.             if(!bFirstFrame)  
  181.             {  
  182.                 nFirstTimeStamp = nTimeStamp;  
  183.                 nStartTimeStamp = nTimeStamp;  
  184.                 nStopTimeStamp = nTimeStamp;  
  185.                 bFirstFrame = true;  
  186.             }  
  187.             else  
  188.             {  
  189.                 nStopTimeStamp = nTimeStamp;  
  190.             }  
  191.             //更新位置  
  192.             m_nReadPos = m_nReadPos+nBufferSize+4;//4个字节tag size  
  193.             nTmp = m_nWritePos-m_nReadPos;  
  194.             m_nAllocBufferEmptySize = m_nAllocBufferSize - nTmp;  
  195.         }  
  196.         else  
  197.         {  
  198.             break;  
  199.         }  
  200.     }  
  201.     //恢复位置  
  202.     m_bReadFileHeader = bReadFileHeaderOld;  
  203.     m_bPreviousTagSize0Read =  bPreviousTagSize0Read;  
  204.     m_nReadPos = nReadPosOld;  
  205.     m_nWritePos = nWritePosOld;  
  206.     nTmp = m_nWritePos-m_nReadPos;  
  207.     m_nAllocBufferEmptySize = m_nAllocBufferSize - nTmp;  
  208.     int nDiffTimeStamp = nTimeStamp - nFirstTimeStamp;  
  209.     return nDiffTimeStamp;  
  210. }  
  211.   
  212. //获取剩余空间  
  213. unsigned int  FlvToStream::GetBufferEmptySize()  
  214. {  
  215.     return m_nAllocBufferEmptySize;  
  216. }  
  217. bool FlvToStream::Read8(int &i8,char *pBuffer)  
  218. {  
  219.     if(m_nReadPos > m_nWritePos || (m_nWritePos - m_nReadPos) < 1)  
  220.         return false;  
  221.   
  222.     memcpy(&i8,m_pAllocBuffer+m_nReadPos,1);  
  223.     m_nReadPos +=1;  
  224.     m_nAllocBufferEmptySize +=1;  
  225.     return true;  
  226. }  
  227.   
  228. bool FlvToStream::Read16(int &i16,char *pBuffer)  
  229. {  
  230.     if(m_nReadPos > m_nWritePos || (m_nWritePos - m_nReadPos) < 2)  
  231.         return false;  
  232.   
  233.     memcpy(&i16,m_pAllocBuffer+m_nReadPos,2);  
  234.     m_nReadPos +=2;  
  235.     m_nAllocBufferEmptySize +=2;  
  236.     i16 = HTON16(i16);  
  237.     return true;  
  238. }  
  239.   
  240. bool FlvToStream::Read24(int &i24,char *pBuffer)  
  241. {  
  242.     if(m_nReadPos > m_nWritePos || (m_nWritePos - m_nReadPos) < 3)  
  243.         return false;  
  244.   
  245.     memcpy(&i24,m_pAllocBuffer+m_nReadPos,3);  
  246.     m_nReadPos +=3;  
  247.     m_nAllocBufferEmptySize +=3;  
  248.     i24 = HTON24(i24);  
  249.     return true;  
  250. }  
  251.   
  252. bool FlvToStream::Read32(int &i32,char *pBuffer)  
  253. {  
  254.     if(m_nReadPos > m_nWritePos || (m_nWritePos - m_nReadPos) < 4)  
  255.         return false;  
  256.   
  257.     memcpy(&i32,m_pAllocBuffer+m_nReadPos,4);  
  258.     m_nReadPos +=4;  
  259.     m_nAllocBufferEmptySize +=4;  
  260.     i32 = HTON32(i32);  
  261.     return true;  
  262. }  
  263.   
  264. bool FlvToStream::Peek8(int &i8,char *pBuffer)  
  265. {  
  266.     if(m_nReadPos > m_nWritePos || (m_nWritePos - m_nReadPos) < 1)  
  267.         return false;  
  268.   
  269.     memcpy(&i8,m_pAllocBuffer+m_nReadPos,1);  
  270.     return true;  
  271. }  
  272.   
  273. bool FlvToStream::ReadTime(int &itime,char *pBuffer)  
  274. {  
  275.     int temp = 0;  
  276.     if(m_nReadPos > m_nWritePos || (m_nWritePos - m_nReadPos) < 4)  
  277.         return false;  
  278.   
  279.     memcpy(&temp,m_pAllocBuffer+m_nReadPos,4);  
  280.     m_nReadPos +=4;  
  281.     m_nAllocBufferEmptySize +=4;  
  282.     itime = HTON24(temp);  
  283.     itime |= (temp & 0xff000000);  
  284.     return true;  
  285. }  
  286.   
  287. bool FlvToStream::ReadHead()  
  288. {  
  289.     int headlength = 0;  
  290.     int filetype = 0;  
  291.     unsigned int nReadPosOld = m_nReadPos;  
  292.     unsigned int nAllocBufferEmptySizeOld = m_nAllocBufferEmptySize;  
  293.   
  294.     if (!Read24(filetype, m_pAllocBuffer))  
  295.         return false;  
  296.     int typel = 'flv';  
  297.     int typeh = 'FLV';  
  298.     if (filetype != typeh && filetype != typel)  
  299.     {  
  300.         //printf("not flv file\n");  
  301.         return false;  
  302.     }  
  303.   
  304.     m_nReadPos +=2;  
  305.     m_nAllocBufferEmptySize +=2;  
  306.     if (!Read32(headlength, m_pAllocBuffer))  
  307.         return false;  
  308.     //printf("headlength:%d\n", headlength);  
  309.     /////////跳过头部长度/////  
  310.     m_nReadPos = nReadPosOld;  
  311.     m_nAllocBufferEmptySize = nAllocBufferEmptySizeOld;  
  312.     m_nReadPos +=headlength;  
  313.     m_nAllocBufferEmptySize +=headlength;  
  314.     return true;  
  315. }  
  316.   
  317. //是否有一包完整数据  
  318. bool FlvToStream::IsOnePackageData()  
  319. {  
  320.     //首先读取文件头  
  321.     if(!m_bReadFileHeader)  
  322.     {  
  323.         m_bReadFileHeader = ReadHead();  
  324.         if(!m_bReadFileHeader)  
  325.         {  
  326.             return false;  
  327.         }  
  328.     }  
  329.     //读取文件数据  
  330.     unsigned int nDataSize = m_nWritePos - m_nReadPos;  
  331.     if(!m_bPreviousTagSize0Read)  
  332.     {  
  333.         //读取PriviousTagSize 0    4字节  
  334.         if(nDataSize > 4)  
  335.         {  
  336.             m_nReadPos +=4;  
  337.             m_nAllocBufferEmptySize +=4;  
  338.             m_bPreviousTagSize0Read = true;  
  339.         }  
  340.         else  
  341.         {  
  342.             return false;  
  343.         }  
  344.     }  
  345.   
  346.     //读取Tag1 ... N  
  347.     nDataSize = m_nWritePos - m_nReadPos;  
  348.     if(nDataSize > 11)  
  349.     {  
  350.         //读取tag类型,数据区长度,时间戳,时间戳扩展,StreamsID,数据区  
  351.         int type = 0;  
  352.         int time = 0;  
  353.         int htime = 0;  
  354.         int datalength = 0;  
  355.         int info = 0;  
  356.         unsigned int nReadPosOld = m_nReadPos;  
  357.         //char buff[256] = { 0 };  
  358.         if (!Read8(type, m_pAllocBuffer))  
  359.         {  
  360.             m_nReadPos = nReadPosOld;  
  361.             return false;  
  362.         }  
  363.         if (!Read24(datalength, m_pAllocBuffer))  
  364.         {  
  365.             m_nReadPos = nReadPosOld;  
  366.             return false;  
  367.         }  
  368.         if(nDataSize < (datalength+11+4))  
  369.         {  
  370.             m_nReadPos = nReadPosOld;  
  371.             return false;  
  372.         }  
  373.   
  374.         if (!ReadTime(time, m_pAllocBuffer))  
  375.         {  
  376.             m_nReadPos = nReadPosOld;  
  377.             return false;  
  378.         }  
  379.         m_nFrameType = type;  
  380.         m_nDateStamp = time;  
  381.         m_nTempBufferSize = datalength;  
  382.         ////////跳过StreamID////////////////  
  383.         m_nReadPos +=3;  
  384.         m_nAllocBufferEmptySize +=3;  
  385.         if (type == 9)  
  386.         {  
  387.             //视频  
  388.             VideoParse(datalength);  
  389.         }  
  390.         else if(type == 8)  
  391.         {  
  392.             //音频  
  393.             AudioParse(datalength);  
  394.         }  
  395.         else if(type == 18)  
  396.         {  
  397.             //脚本  
  398.             MediaInfoParse(datalength);  
  399.         }  
  400.         else  
  401.         {  
  402.             //保留  
  403.             int jjj = 0;  
  404.         }  
  405.   
  406.         return true;  
  407.     }  
  408.     else  
  409.     {  
  410.         return false;  
  411.     }  
  412. }  
  413.   
  414. void FlvToStream::AudioParse(int datalength)  
  415. {  
  416.   
  417. }  
  418.   
  419. void FlvToStream::MediaInfoParse(int datalength)  
  420. {  
  421.   
  422. }  
  423.   
  424. void FlvToStream::VideoParse(int datelength)  
  425. {  
  426.     /* 
  427.     int h264space = 0x01000000;//H264内容间隔标识00000001 
  428.     unsigned int nReadPosOld = m_nReadPos; 
  429.     int info = 0; 
  430.     Read8(info, m_pAllocBuffer); 
  431.     int avctype = 0; 
  432.     Read8(avctype, m_pAllocBuffer); 
  433.     m_nReadPos +=3; 
  434.     int templength = 0; 
  435.     char*tempbuff = NULL; 
  436.     if (avctype == 0) 
  437.     { 
  438.         m_nReadPos +=6; 
  439.         Read16(templength, m_pAllocBuffer); 
  440.         printf("sssize:%d\n", templength); 
  441.  
  442.         tempbuff = (char*)malloc(templength); 
  443.         //fread(tempbuff, 1, templength, m_pAllocBuffer); 
  444.         memcpy(tempbuff,m_pAllocBuffer+m_nReadPos,templength); 
  445.         m_nReadPos +=templength; 
  446.         fwrite(&h264space, 1, 4, h264file); 
  447.         fwrite(tempbuff, 1, templength, h264file); 
  448.         free(tempbuff); 
  449.  
  450.         Read8(templength, m_pAllocBuffer);//ppsnum 
  451.  
  452.         Read16(templength, m_pAllocBuffer);//ppssize 
  453.         printf("ppsize:%d\n", templength); 
  454.  
  455.         tempbuff = (char*)malloc(templength); 
  456.         //fread(tempbuff, 1, templength, flvfile); 
  457.         memcpy(tempbuff,m_pAllocBuffer+m_nReadPos,templength); 
  458.         m_nReadPos +=templength; 
  459.         fwrite(&h264space, 1, 4, h264file); 
  460.         fwrite(tempbuff, 1, templength, h264file); 
  461.         free(tempbuff); 
  462.     } 
  463.     else 
  464.     { 
  465.         //  Read32(templength,flvfile); 
  466.         //  tempbuff=(char*)malloc(templength); 
  467.         //  fread(tempbuff,1,templength,flvfile); 
  468.         //  fwrite(&h264space,1,4,h264file); 
  469.         //  fwrite(tempbuff,1,templength,h264file); 
  470.         //  free(tempbuff); 
  471.         //可能存在多个nal,需全部读取 
  472.         int countsize = 2 + 3; 
  473.         while (countsize<datelength) 
  474.         { 
  475.             Read32(templength, m_pAllocBuffer); 
  476.             tempbuff = (char*)malloc(templength); 
  477.             //fread(tempbuff, 1, templength, flvfile); 
  478.             memcpy(tempbuff,m_pAllocBuffer+m_nReadPos,templength); 
  479.             m_nReadPos +=templength; 
  480.             fwrite(&h264space, 1, 4, h264file); 
  481.             fwrite(tempbuff, 1, templength, h264file); 
  482.             free(tempbuff); 
  483.             countsize += (templength + 4); 
  484.         } 
  485.     } 
  486.  
  487.     m_nReadPos = nReadPosOld; 
  488.     */  
  489. }  


原创粉丝点击