高复用率的RTSPClient组件EasyRTSPClient设计流程概述

2017-09-12 09:10 出处:csdn 人气: 评论(0

EasyRTSPClient 设计过程

概述

EasyRTSPClient 基于live555构建而成. 今天讲讲EasyRTSPClient的设计过程

EasyRTSPClient,主要包括以下部分:
1. 创建live555对象, 连接相机和收流
2. 解析收到的视频分辨率
3. 将SDP、音视频流、分辨率及其它相关信息通过回调函数进行回调
4. 回调连接、断线状态
5. 根据参数执行是否重连

创建live555对象,连接相机和收流

网上很多介绍的都是使用testRTSPClient来做客户端, 这个是没有问题的,但有一点需要注意的是demo中的代码,都是阻塞式的,如下:

env->taskScheduler().doEventLoop(&eventLoopWatchVariable);

这样就在主线程中阻塞了, 如果我需要它退出,该怎样实现呢?
有两种方法,目的是相同的,实现方式略有不同罢了:
1. 外部改变eventLoopWatchVariable的值为1
2. 通过BasicTaskScheduler0::doEventLoop(char* watchVariable)的实现可以看出, 这里实际上是进行一个无限循环. 当 watchVariable的值不为0时就退出. 所以我们可以自己创建一个线程,在线程内部实现调用 pTaskScheduler0->SingleStep(0), 即可实现对该线程的自由控制; 相当于1个线程对应1路到摄像机的取流;

解析视频分辨率

解析分辨率主要是sps_pps.h .c实现,是从VLC中提取出来的相关代码, 可正常解析H264,H265的分辨率;

回调SDP, 音视频流,分辨率及其它相关信息

在Live555的continueAfterDESCRIBE的回调函数中, 解析出SDP信息进行回调
void continueAfterDESCRIBE(RTSPClient* rtspClient, int resultCode, char* resultString)

if (NULL != sdpDescription)
{
    if (NULL != pClient)        pClient->SetSDP(sdpDescription, (int)strlen(sdpDescription));

    char *sprop_parameter_sets = strstr(sdpDescription, "sprop-parameter-sets=");
    if (NULL != sprop_parameter_sets)
    {
        AnalysisH264SPSPPS(pClient, sprop_parameter_sets+21);
    }
    else
    {
        sprop_parameter_sets = strstr(sdpDescription, "sprop-sps=");
        if (NULL != sprop_parameter_sets)
        {
            AnalysisH265SPSPPS(pClient, sprop_parameter_sets);
        }
    }

    //回调出媒体信息
    MediaSubsessionIterator iter(*scs.session);
    MediaSubsession* subsession;
    while ((subsession = iter.next()) != NULL) 
    {
        if (strcmp(subsession->mediumName(), "video") == 0)
        {
            if (strcmp(subsession->codecName(), "H264") == 0)
            {
                mediainfo.videoCodec = VIDEO_CODEC_H264;
            }
            else if (strcmp(subsession->codecName(), "H265") == 0)
            {
                mediainfo.videoCodec = VIDEO_CODEC_H265;
            }
            else if (strcmp(subsession->codecName(), "MP4V-ES") == 0)
            {
                mediainfo.videoCodec = VIDEO_CODEC_MPEG4;
            }
            else if (strcmp(subsession->codecName(), "JPEG") == 0)
            {
                mediainfo.videoCodec = VIDEO_CODEC_MJPEG;
            }
            mediainfo.videoFps = (float)subsession->videoFPS();
            mediainfo.videoWidth = pClient->params.width;
            mediainfo.videoHeight = pClient->params.height;
        }

        if (strcmp(subsession->mediumName(), "audio") == 0)
        {

        }
    }

    if (NULL != clientObj && NULL !=clientObj->callback)
    {
        RTSPClientCallBack pRtspCallback = (RTSPClientCallBack )clientObj->callback;
        if (NULL != pRtspCallback)
        {
            pRtspCallback(clientObj->channelInfo.id, (int *)clientObj->userPtr, MEDIA_TYPE_CODEC_INFO, (char*)&mediainfo, NULL);
        }
    }
}

回调连接、断线状态

断线状态的检测, 这里使用了一个时间对比的方式. 即用当前时间减去上一次获取到音视频流的时间,如果大于指定时长,则认为断线;

根据参数执行是否重连

检查重连参数,如果需要重连,则销毁当前的所有对象,再创建新的对象, 继续开始新的循环

if (NULL != pClient->rtspClient)
{
    Medium::close(pClient->rtspClient);
    pClient->rtspClient = NULL;
}
if (NULL != pClient->env)
{
    pClient->env->reclaim();
    pClient->env = NULL;
}
if (NULL != pClient->scheduler)
{
    delete pClient->scheduler;
    pClient->scheduler = NULL;
}

if (NULL != pClient->auth)
{
    delete pClient->auth;
    pClient->auth = NULL;
}

if (NULL == pClient->scheduler)     pClient->scheduler = BasicTaskScheduler::createNew();
if (NULL == pClient->scheduler)     break;
if (NULL == pClient->env)           pClient->env = BasicUsageEnvironment::createNew(*pClient->scheduler);
if (NULL == pClient->env)           break;

if (NULL == pClient->rtspClient)    pClient->rtspClient = LiveRTSPClient::createNew(*pClient->env, pClient->channelInfo.url, RTSP_CLIENT_VERBOSITY_LEVEL, RTSP_CLIENT_NAME, 0, (void *)pClient);
if (NULL == pClient->rtspClient)    break;

今天主要概述了EasyRTSPClient的设计流程, 下一篇将开始着重讲解具体实现细节;

以下是我写的基于live555的两个应用:

关于EasyRTSPClient

EasyRTSPClient是一套非常稳定、易用、支持重连的RTSPClient工具,SDK形式提供,接口调用非常简单,再也不用像调用live555那样处理整个RTSP OPTIONS/DESCRIBE/SETUP/PLAY的复杂流程,担心内存释放的问题了,全平台支持(包括Windows/Linux 32&64,ARM各平台,Android,iOS),支持RTP Over TCP/UDP,支持断线重连,连续维护与迭代超过5年,能够接入市面上99%以上的IPC,调用简单且成熟稳定!

关于EasyIPCamera

EasyIPCamera是一套非常稳定、易用、支持多种平台(包括Windows/Linux 32&64,Android,ARM hisiv100/hisiv200/hisiv400等平台)的RTSP Server组件,适用于IPCamera、内网RTSP服务等小型RTSP流媒体服务器,接口调用非常简单成熟,无需关注RTSPServer中关于客户端监听接入、音视频多路复用、RTSP具体流程、RTP打包与发送等相关问题,支持多种音视频格式,再也不用像调用live555 RTSPServer那样处理整个RTSP OPTIONS/DESCRIBE/SETUP/PLAY/RTP/RTCP的复杂流程和担心内存释放的问题了!

获取更多信息

邮件:support@easydarwin.org

WEB:www.EasyDarwin.org

Copyright © EasyDarwin.org 2012-2017

EasyDarwin

本文标签: RTSPClientEasyDarwinlive555

相关文章

网站内容来源于互联网,仅供用于技术学习,请遵循相关法律 规,如有侵权,请联系管理员删除

Copyright © 2002-2017 JISHUX. 技术栈 版权所有

京ICP备15061484号-3