zoukankan      html  css  js  c++  java
  • RTMP推送延时测试

    为什么需要ChangeChunkSize这个函数,RTMP需要通过这个包指定一个ChunkSize??

    pack.m_body[3] = nChunkSize & 0xff; //大字节序
    pack.m_body[2] = nChunkSize >> 8;
    pack.m_body[1] = nChunkSize >> 16;
    pack.m_body[0] = nChunkSize >> 24;
    
    m_pRtmp->m_outChunkSize = nChunkSize;

    SendPacket(unsigned int nPacketType, unsigned int nHeaderType,char *data, unsigned int size, unsigned int nTimestamp)函数调用了

    int nRet = RTMP_SendPacket(m_pRtmp, &packet, TRUE);

    connect函数中调用:

    RTMP_SetupStream(m_pRtmp, nprotocol, &av_host, nport, &av_sockhost, &av_playpath, &av_tcUrl, 0, 0, 
            &av_app, 0, 0, 0, 0, 0, 0, 0, 0, 1, 5);

    RTMP_EnableWrite(m_pRtmp);
    if (!RTMP_Connect(m_pRtmp, NULL))
    if (!RTMP_ConnectStream(m_pRtmp, 0))
    int CVideoDecoder::DecodeSps(unsigned char* pData, int nSize)处理spspps,有一个数据成员szSpsPpsNal用于保存处理结果:
    unsigned char* szSpsPpsNal;

    int CVideoDecoder::DecodeFrame(unsigned char* pData, int nSize, size_t nTimeStamp, video_type eType)

    int nRet = avcodec_decode_video2(m_pCodecCtx, m_pFrame, &got_picture, &m_packet);
    
    if (got_picture)
    { ProcessPicture(m_nImgWidth, m_nImgHeight, m_pFrame, nTimeStamp);
      ……
    }

    int CVideoDecoder::Decode(unsigned char* pData, int nSize, size_t nTimeStamp)解码函数:

    if (zCodeId == 7)
        {
            char zFrameType = *pData++ >> 4;
            // 1:Iframe  7:AVC  关键帧
            if (zFrameType == 1)
            {
                // IFrame, also key frame
                unsigned char zAVCFrameType = *pData++;
                //sps、pps数据
                if (zAVCFrameType == 0)
                {
                    return DecodeSps(pData, nSize - 2);
                }
                else if (zAVCFrameType == 1)//关键帧视频数据
                {
                    return DecodeFrame(pData, nSize - 2, nTimeStamp, TYPE_IDR);
                }
                else if (zAVCFrameType == 2)
                {
                    LOG("[%d] 2 = AVC end of sequence
    ", GetTickCount());
                }
            }
            else if (zFrameType == 2)// 2:Pframe  7:AVC  
            {
    //            LOG("[%d] get P frame..
    ", GetTickCount());
                // P frame 
                pData++; // should always be 1;
                return DecodeFrame(pData, nSize - 2, nTimeStamp, TYPE_P);
            }
            else
            {
                LOG("[%d] Unsupported frame type: %d
    ", GetTickCount(), zFrameType);
                return -1;
            }
        }
        else
        {
            LOG("[%d] Unsupported video type: %d
    ", GetTickCount(), zCodeId);
            return -1;
        }

    int CVideoService::ConnectRTMP(const string& strRtmpUrl)

    m_Rtmp = srs_rtmp_create(strRtmpUrl.c_str());
    if ((ret = srs_rtmp_handshake(m_Rtmp)) != 0)
    if ((ret = srs_rtmp_connect_app(m_Rtmp)) != 0)
    if ((ret = srs_rtmp_play_stream(m_Rtmp)) != 0)

    DWORD GetTickCount(void);    GetTickCount返回(retrieve)从操作系统启动所经过(elapsed)的毫秒数。

    enum的这个用法:

    enum 
    {
        CHANGE_NONE,
        CHANGE_INCREASE,
        CHANGE_DECREASE
    }m_eCurrentChangeState;

    int CVideoService::VideoProcessThreadImpl(void)

    if ((nret = srs_rtmp_read_packet(m_Rtmp, &type, &timestamp, &data, &size)) == 0)//其中的data为char*,并未分配空间,因此可能在这个函数内有内存分配操作

    除了ProcessPicture外,还会调用很多的CEventNotifier::GetEventNotifier().NotifyEvent及NotifyEventSync :

    if (got_picture){
         bNeedShowMessage = true;
         ProcessPicture(nImgWidth, nImgHeight, m_pFrame, nTimeStamp);
         //printf("%d: IFrame decode OK, return; %d, nal len: %d
    ", nTimeStamp, nRet, nNalLen); 
    }
    CEventNotifier::GetEventNotifier().NotifyEvent(pService->m_strDeviceCode, EVENT_VIDEO_REPLAYING, 0);
    CEventNotifier::GetEventNotifier().NotifyEvent(m_strDeviceCode, EVENT_VIDEO_BAND_WIDTH_LOW);
    CEventNotifier::GetEventNotifier().NotifyEventSync(m_strDeviceCode, EVENT_VIDEO_UPDATE_INFO_W_H, (WPARAM)nImgWidth, (LPARAM)nImgHeight);

    类CVideoService有一个 成员变量volatile bool m_bPlaying;但是它好像只在函数int CVideoService::CancelVideoProcess()里被改变。

    如果没有定义#ifdef USE_SRS_LIBRTMP  ,才会在int CVideoService::VideoProcessThreadImpl(void)函数内

    用到CVideoService类的成员变量CVideoDecoder m_pVideoDecoder来进行视频处理解码。其中CVideoDecoder类中包含:

    class CVideoDecoder
    {
            ……
    private:
        AVCodecContext  *m_pCodecCtx;
        AVFrame         *m_pFrame;
        AVPacket m_packet;
        unsigned char* szSpsPpsNal;
        size_t nSpsPpsLen;
        bool m_bFirstFrame;
        int m_nImgWidth;
        int m_nImgHeight;
        string m_strDeviceCode;
    };

    昨天在想GetDownloadSpeedOnTimer这个函数是怎么定时检测调整速度的,原来是在VideoProcessThreadImpl函数内有:

    CGlobalTimerManager::GetTimerManager().SetTimer(TIMER_DOWNLOAD_SPEED_DETECTED, 5 * 1000, CVideoService::GetDownloadSpeedOnTimer, this);

    #else
    int CVideoService::VideoProcessThreadImpl(void)函数内有计算延时的:

    LOG("delay time : %d
    ", GetTickCount() - rPacket.m_nTimeStamp - CControlInfoManage::GetControlInfoManager().GetDiffTime(m_strDeviceCode));

    但是在另一个VideoProcessThreadImpl函数内却没有,此外

    while (RTMP_IsConnected(m_Rtmp) && RTMP_ReadPacket(m_Rtmp, &rPacket))

    前一个用的是srs_rtmp_read_packet

    int CVideoService::ProcessInvokeMessage(RTMPPacket *rPacket)这个函数似乎也是在没有定义#ifdef USE_SRS_LIBRTMP 的时候才定义的。具体作用是什么??

    #ifndef USE_SRS_LIBRTMP
        int ProcessInvokeMessage(RTMPPacket *packet);
    #endif

    RTMP_CONNECT_RESULT CRTMPStream::Connect(const char* szBaseUrl, const char* szSessionId, const char* szPadCode, const char* szstreamName, const char* strPublishCode)

    RTMP_SetupStream(m_pRtmp, nprotocol, &av_host, nport, &av_sockhost, &av_playpath, &av_tcUrl, 0, 0, 
            &av_app, 0, 0, 0, 0, 0, 0, 0, 0, 1, 5);

    CGlobalTimerManager::GetTimerManager()的setTimer和killTimer函数用到参数TIMER_DOWNLOAD_SPEED_DETECTED(一个宏),难道它里面有一个关联容器对各个定时器进行关联??

  • 相关阅读:
    Magento入门开发教程
    Magento文件系统目录结构
    正则匹配获取HTML图片地址,正则匹配获取HTML内容
    php+phpspreadsheet读取Excel数据存入mysql
    PHP遍历一个文件夹下所有文件和子文件夹的函数
    前端实现在线预览pdf、word、xls、ppt等文件
    微服务架构的基础框架选择
    Linux性能优化实战学习笔记:第五十八讲
    Linux性能优化实战学习笔记:第五十六讲
    Linux性能优化实战学习笔记:第五十五讲
  • 原文地址:https://www.cnblogs.com/ph829/p/6652779.html
Copyright © 2011-2022 走看看