zoukankan      html  css  js  c++  java
  • iOS 将视频流(h264)和音频流封装成PS流

    调用方法:

    static  CPSPackager * testObjc = NULL;

    static char *pszBuffer;

     testObjc = new CPSPackager();

     pszBuffer = new char[1024*1024];

    -(NSData *)EncodeDataChangeToPSWithData:(NSData *)encodeData andType:(int)type{

     

        int size = (int)[encodeData length];

        

        int iCount = 0;

     

        char * encodeCharData = (char *)[encodeData bytes];

     

        switch (type) {

            case 1:{

                testObjc->Packet_I_frame(encodeCharData, size, pszBuffer, iCount, 25);

     

            }

                

                break;

            case 2:{

                 testObjc->Packet_P_frame(encodeCharData, size, pszBuffer, iCount);

                

            }

     

                break;

            case 3:{

                

                 testObjc->Packet_Audio_frame(encodeCharData, size, pszBuffer,iCount,true);

                

                         }

     

                break;

                

            default:

                break;

        }

        

        

      NSData *   PsData = [NSData dataWithBytes:pszBuffer length:iCount];

        

        return PsData;

        

     

    }

     

     

     

    下面是.h文件

    #pragma once

     

    #define PS_Packet_Start_Code_Len       4       

    #define PS_Header_Len                  14      //≤ªøº¬«◊÷Ω⁄∂‘∆ÎPS_Header

    #define PS_Header_Len_aligned          20      //øº¬«◊÷Ω⁄∂‘∆Îœ¬µƒPS_Header

     

    #define MAX_PSBUFFER_SIZE 5106

    #define MUX_RATE 0

     

    #define FRAME_BUFFER_MAX    1024*1024*2 // µ•∏ˆH264÷°µƒ◊Ó¥Û≥§∂»

     

    //∑Ω∑®

    #define OFFSET(x) (90000/x)

     

    //¥ÌŒÛ∑µªÿ

    #define  PS_Error_OK              0

    #define  PS_Error_Param          -1

    #define  PS_Error_Stream         -2

    #define  PS_Error_Format         -3

    #define  PS_Error_H264           -4

    #define  PS_Error_Pes_Len        -5

     

    #if (defined(WIN32))

    #define CALLBACK  __stdcall

    #else

    #define CALLBACK  

    #endif

     

    typedef void (CALLBACK * PSOutputCallBack)(char *pData, int size, unsigned long user);

     

    class CFrameBuffer {

    public:

    CFrameBuffer() {

    size = 0;

    pBuffer = new char[FRAME_BUFFER_MAX];

    pPSBuffer = new char[FRAME_BUFFER_MAX];

    };

    ~CFrameBuffer() {

    delete pBuffer;

    delete pPSBuffer;

    };

    char *pBuffer;

    char *pPSBuffer;

    int size;

    };

     

    class CPSPackager {

    public:

    CPSPackager(void);

    ~CPSPackager(void);

     

    bool create(PSOutputCallBack callback, unsigned long user);

    void destroy();

     

     

    PSOutputCallBack m_pFuncOutputCallBack;

    unsigned long m_pUser;

    public:

    unsigned int m_nScrb;

    unsigned int m_nDts;

    unsigned int m_nVideoPts;

     

    int m_nFrameRate;

    bool m_bStarted;

    CFrameBuffer m_buffer;

    bool m_bFindFirstIFrame;

     

    int Packet_I_frame(const char* pSrcBuf, int nSrcLen, char* pDestBuf, int& nDestLen, int nFrameRate);

    int Packet_P_frame(const char* pSrcBuf, int nSrcLen, char* pDestBuf, int& nDestLen, bool addPSHeader = true);

    int Packet_Audio_frame(const char* pSrcBuf, int nSrcLen, char* pDestBuf, int& nDestLen, bool addPSHeader = true);

    int Packet_PS_header(char* pDestBuf, int& nLen, bool bAudio, bool bAligned = false);

    int Packet_PS_map(char* pDestBuf, int& nLen);

    int Packet_frame(const char* pSrcBuf , int nSrcLen , bool isVideo, char* pDestBuf, int& nLen);

    int GeneratePacketsFromFrame(const char* pSrcBuf , int nSrcLen, bool isVideo , char* pDestBuf , int& nLen);

    };

     

     

    这里是cpp文件

    #include "PSPackager.h"

    #include "string.h"

    #include <algorithm>

     

    using namespace std;

     

    static unsigned char DH_IDENTITY[4] = {0x64, 0x68, 0x61, 0x76};

    static unsigned char H264_IDENTITY[4] = {0x00, 0x00, 0x00, 0x01};

    static unsigned char H264_IDENTITY_IDR[5] = {0x00, 0x00, 0x00, 0x01, 0x67};

    static unsigned char PS_header[PS_Packet_Start_Code_Len] = {0x00 , 0x00 , 0x01 , 0xBA};

    // static unsigned char PS_System_Header[PS_Packet_Start_Code_Len] = {0x00 , 0x00 , 0x01 , 0xBB};

    static unsigned char PS_Map_Header[PS_Packet_Start_Code_Len] = {0x00 , 0x00 , 0x01 , 0xBC};

    static unsigned char PS_Audio_Pes_Header[PS_Packet_Start_Code_Len] = {0x00 , 0x00 , 0x01 , 0xC0};

    static unsigned char PS_Video_Pes_Header[PS_Packet_Start_Code_Len] = {0x00 , 0x00 , 0x01 , 0xE0};

     

    CPSPackager::CPSPackager(void) {

    m_nScrb = 60000;

    m_nDts = 0;

    m_nVideoPts = 60000;

    m_nFrameRate = 25;

     

    m_bStarted = false;

    m_bFindFirstIFrame = false;

     

    m_pFuncOutputCallBack = NULL;

    m_pUser = NULL;

    }

     

    CPSPackager::~CPSPackager(void) {

    destroy();

    }

     

    bool CPSPackager::create(PSOutputCallBack callback, unsigned long user) {

    if (callback == NULL)

    return false;

     

    m_pFuncOutputCallBack = callback;

    m_pUser = user;

    return false;

    }

     

    void CPSPackager::destroy() {

    m_pFuncOutputCallBack = NULL;

    m_pUser = NULL;

    }

     

    int CPSPackager::Packet_I_frame(const char* pSrcBuf, int nSrcLen, char* pDestBuf, int& nDestLen, int nFrameRate) {

    if (NULL == pSrcBuf || NULL == pDestBuf)

    return PS_Error_Param;

     

    int nTempLen = 0;

    int nTotalLen = 0;

     

    if (m_nFrameRate != nFrameRate)

    m_nFrameRate = nFrameRate ;

     

    Packet_PS_header(pDestBuf, nTempLen, true, true);

    nTotalLen += nTempLen;

    Packet_PS_map(pDestBuf+nTotalLen, nTempLen);

    nTotalLen += nTempLen;

     

    GeneratePacketsFromFrame(pSrcBuf, nSrcLen, true, pDestBuf+nTotalLen, nTempLen);

    nTotalLen += nTempLen;

    nDestLen = nTotalLen;

    return PS_Error_OK;

    }

     

    int CPSPackager::Packet_P_frame(const char* pSrcBuf , int nSrcLen, char* pDestBuf , int& nDestLen, bool addPSHeader) {

    if ( NULL == pSrcBuf || NULL == pDestBuf )

    return PS_Error_Param;

     

    int nTempLen = 0;

    int nTotalLen = 0;

     

    if (addPSHeader) {

    Packet_PS_header(pDestBuf , nTempLen , true, true);

    nTotalLen += nTempLen;

    }

     

    GeneratePacketsFromFrame(pSrcBuf , nSrcLen , true, pDestBuf + nTotalLen , nTempLen);

    nTotalLen += nTempLen;

    nDestLen = nTotalLen;

     

    return PS_Error_OK ;

    }

     

    int CPSPackager::Packet_Audio_frame(const char* pSrcBuf , int nSrcLen, char* pDestBuf , int& nDestLen, bool addPSHeader) {

    if ( NULL == pSrcBuf || NULL == pDestBuf )

    return PS_Error_Param;

     

    int nTempLen = 0;

    int nTotalLen = 0;

     

    if (addPSHeader) {

    Packet_PS_header(pDestBuf , nTempLen , true, true);

    nTotalLen += nTempLen;

    }

     

    GeneratePacketsFromFrame(pSrcBuf , nSrcLen , false, pDestBuf + nTotalLen , nTempLen);

    nTotalLen += nTempLen;

    nDestLen = nTotalLen;

     

    return PS_Error_OK ;

    }

     

    int CPSPackager::Packet_PS_header(char* pDestBuf, int& nLen , bool bVideo, bool bAligned /* = false */) {

    if ( NULL == pDestBuf)

    return PS_Error_Param;

     

    char temp = 0x00;

    memcpy( pDestBuf, PS_header , PS_Packet_Start_Code_Len);

     

    if (bVideo)

    m_nScrb = m_nVideoPts;

     

    pDestBuf[4]=((0x38&(m_nScrb>>26))|0x44);

    pDestBuf[4]=(pDestBuf[4]|((m_nScrb>>28)&0x03));

     

    pDestBuf[5]=((m_nScrb>>20)&(0xFF));

    temp = ((m_nScrb>>12)&(0xF8));

    pDestBuf[6]=(temp|0x04|((m_nScrb>>13)&0x03));

     

    pDestBuf[7]=((m_nScrb>>5)&(0xFF));

    temp=((((m_nScrb&0x1f)<<3)&0xf8)|0x04);

     

    //system_clock_reference_extension …ËŒ™0  9∏ˆbit∂º÷√ŒªŒ™0 

    pDestBuf[8]=(temp|0x03);

    pDestBuf[9]=0x01;

     

    pDestBuf[10]=(MUX_RATE>>14)&0xff;

    pDestBuf[11]=(MUX_RATE>>6)&0xff;

    pDestBuf[12]=(((MUX_RATE<<2)&0xfc)|0x03);

     

    if ( !bAligned ) {

    pDestBuf[13] = 0xF8;

    nLen = PS_Header_Len;

    } else {

    pDestBuf[13] = 0xFE;

    pDestBuf[14] = 0xFF;

    pDestBuf[15] = 0xFF;

    pDestBuf[16] = 0x00;

    pDestBuf[17] = 0x00;

    pDestBuf[18] = 0x00;

    pDestBuf[19] = 0x00;

    nLen = PS_Header_Len_aligned;

    }

     

    return PS_Error_OK;

    }

     

    int CPSPackager::Packet_PS_map(char* pDestBuf, int& nLen) {

    if ( NULL == pDestBuf)

    return PS_Error_Param;

     

    memcpy( pDestBuf, PS_Map_Header , PS_Packet_Start_Code_Len);

     

    pDestBuf[4] = 0x00;

    pDestBuf[5] = 0x18;

     

    pDestBuf[6] = 0xE1;

    pDestBuf[7] = 0xFF;

     

    pDestBuf[8] = 0x00;

    pDestBuf[9] = 0x00;

     

    pDestBuf[10] = 0x00;

    pDestBuf[11] = 0x08;

     

    //element_info

    pDestBuf[12] = 0x1B;   //H.264

     

    pDestBuf[13] = 0xE0;

    pDestBuf[14] = 0x00;

    pDestBuf[15] = 0x06;

     

    //avc timming and hrd descriptor

    pDestBuf[16] = 0x0a;

    pDestBuf[17] = 0x04;

    pDestBuf[18] = 0x65;

    pDestBuf[19] = 0x6e;

    pDestBuf[20] = 0x67;

    pDestBuf[21] = 0x00;

     

    pDestBuf[22] = 0x90;

    pDestBuf[23] = 0xc0;

    pDestBuf[24] = 0x00;

    pDestBuf[25] = 0x00;

     

    pDestBuf[26] = 0x00;

    pDestBuf[27] = 0x00;

    pDestBuf[28] = 0x00;

    pDestBuf[29] = 0x00;

     

    nLen = 30;

    return PS_Error_OK;

    }

     

    int CPSPackager::Packet_frame(const char* pSrcBuf, int nSrcLen, bool isVideo, char* pDestBuf, int& nLen) {

    if ( NULL == pSrcBuf || NULL == pDestBuf )

    return PS_Error_Param;

     

    int nTempLen = 0;

     

    bool bIncreasePTS = false;

    if (pSrcBuf[0] == 0x00 && 

    pSrcBuf[1] == 0x00 && 

    pSrcBuf[2] == 0x00 && 

    pSrcBuf[3] == 0x01) {

     

    unsigned char c5=pSrcBuf[4];

    unsigned char c6=pSrcBuf[5];

     

    if (((c5 & 0x1F) == 8) || ((c5 & 0x1F) == 5) || (c6 == 0x88 && (c5 & 0x1F) == 1))

    bIncreasePTS = false;

    else

    bIncreasePTS = true;

    }

     

    if (isVideo)

    memcpy( pDestBuf , PS_Video_Pes_Header , PS_Packet_Start_Code_Len);

    else

    memcpy( pDestBuf , PS_Audio_Pes_Header , PS_Packet_Start_Code_Len);

     

    nTempLen = 8 + nSrcLen;

    //PES∞¸µƒ≥§∂»

    pDestBuf[4] = (nTempLen >> 8) & 0xFF;

    pDestBuf[5] = nTempLen & 0xFF;

     

    pDestBuf[6] = 0x88;

    pDestBuf[8] = 0x05;

    if (bIncreasePTS) {

    m_nVideoPts += OFFSET(m_nFrameRate);

    //PTS_DTS_flag = '10';

    pDestBuf[7] = 0x80;

    pDestBuf[9] = ((m_nVideoPts>>29)|0x21);

    pDestBuf[10] = (m_nVideoPts>>22);

    pDestBuf[11] = ((m_nVideoPts>>14)|0x01);

    pDestBuf[12] = (m_nVideoPts>>7);

    pDestBuf[13] = (((m_nVideoPts<<1)&0xFE)|0x01);

    } else {

    //PTS_DTS_flag = '00';

    pDestBuf[7] = 0x00;

    pDestBuf[9]  = 0xFF;

    pDestBuf[10] = 0xFF;

    pDestBuf[11] = 0xFF;

    pDestBuf[12] = 0xFF;

    pDestBuf[13] = 0xFE;

    }

     

    nTempLen = 14 ;

    memcpy(pDestBuf + nTempLen , pSrcBuf , nSrcLen);

    nLen = nTempLen + nSrcLen;

     

    return PS_Error_OK;

    }

     

    int CPSPackager::GeneratePacketsFromFrame(const char* pSrcBuf, int nSrcLen, bool isVideo, char* pDestBuf, int& nLen) {

    int nTotalLen = 0; 

    int nPacketNalLen = 0;

    int rest_len = nSrcLen;

    int nNalCount = 0;

    int nOldIndex = 0;

    int nPacketCount = 0;

     

    while( nSrcLen - nOldIndex > MAX_PSBUFFER_SIZE) {

    Packet_frame(pSrcBuf + nOldIndex , MAX_PSBUFFER_SIZE , isVideo, pDestBuf + nTotalLen , nPacketNalLen );

     

    nOldIndex += MAX_PSBUFFER_SIZE;

    nTotalLen += nPacketNalLen;

    nPacketCount++;

    }

     

    Packet_frame(pSrcBuf + nOldIndex , nSrcLen - nOldIndex , isVideo, pDestBuf + nTotalLen , nPacketNalLen);

     

    nTotalLen += nPacketNalLen;

    nPacketCount++;

    nLen = nTotalLen;

     

    return PS_Error_OK;

    }

  • 相关阅读:
    debian 降级
    linux 常用查看设备命令
    viewstate
    linux图形界面编程基本知识
    Java 不适合编写桌面应用
    temp
    ASP.NET中26个常用性能优化方法
    三层架构与MVC的关系
    分页查询前台HTML+后台asp.net代码
    windows身份验证登入数据库 iis 无法访问数据库
  • 原文地址:https://www.cnblogs.com/graveliang/p/7680517.html
Copyright © 2011-2022 走看看