如何一次又一次地创建和销毁rtsp服务器Live 555 [英] How to create and destroy rtsp server again and again Live 555

查看:308
本文介绍了如何一次又一次地创建和销毁rtsp服务器Live 555的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想从文件中进行RTSP流传输,所以我使用了实时555库.在实时555测试目录"testMpeg2TransportStreamer"程序中,流式传输TS格式文件是什么,我将整个代码放入线程中每当客户端请求流式传输线程开始工作,并且当客户端说不要流"时,线程在关闭线程时都会关闭,我也写了代码Medium :: close(rtsp服务器的指针),因此要关闭rtsp服务器,这是可行的对于第一个STREAM和DONT STREAM请求很好,但是在DONT STREAM请求之后,当客户端对STREAM说时,我调试了代码,发现它无法创建rtsp服务器. 然后我使用了另一种方法,即在第一个STREAM请求中仅创建一次rtsp服务器,并且直到我的整个程序退出时才关闭它,但这也失败了.有人可以提出任何其他建议吗? 我的代码如下:-

I want a to do RTSP streaming from a file,so i used live 555 libraries.In live 555 test directories "testMpeg2TransportStreamer" program to stream a TS format file,what i did is,i put the whole code in thread so whenever the client request the streaming the thread start working and when client says DONT STREAM then the thread is closed on closing the thread i also wrote the code Medium::close(pointer of rtsp server),so to close the rtsp server,this works fine for the first STREAM and DONT STREAM request but after the DONT STREAM request when the client says to STREAM i debugged the code and found that the it fails to create the rtsp server. Then i used another approach that to create rtsp server only once at the first STREAM request and not to close it till my whole program exits but this also fails.Can anyone suggest any other way my code is as follows:-

#define TRANSPORT_PACKET_SIZE 188
#define TRANSPORT_PACKETS_PER_NETWORK_PACKET 7

#define IMPLEMENT_RTSP_SERVER 
// To stream using "source-specific multicast" (SSM), uncomment the following:
//#define USE_SSM 1
#ifdef USE_SSM
Boolean const isSSM = True;
#else
Boolean const isSSM = False;
#endif

/********************Global variable***************************/
UsageEnvironment* env=NULL;
FramedSource* videoSource;
RTPSink* videoSink;
DeviceSourceFICard* fileSource;
FICardDeviceParameters fi_params;
HANDLE          g_hRtpComThread;
DWORD           g_dwRtpComThreadID;
char            g_ExitEventLoop;
void play(); // forward
RTSPServer* rtspServer=NULL;
ServerMediaSession* sms;
int initLm555Settings(void)
{
scheduler = BasicTaskScheduler::createNew();
  env = BasicUsageEnvironment::createNew(*scheduler);
 destinationAddressStr//make it global
#ifdef USE_SSM
    = "232.255.42.42";
#else
    = "239.255.42.42";
const unsigned short rtpPortNum = 18888;//make it global
  rtpPortNum1=rtpPortNum;
 const unsigned short rtcpPortNum = rtpPortNum+1;
  const unsigned char ttl = 7;
 struct in_addr destinationAddress;
  destinationAddress.s_addr = our_inet_addr(destinationAddressStr);
  const Port rtpPort(rtpPortNum);
  const Port rtcpPort(rtcpPortNum);

  Groupsock rtpGroupsock(*env, destinationAddress, rtpPort, ttl);
  rtpGroupsock.multicastSendOnly();

  Groupsock rtcpGroupsock(*env, destinationAddress, rtcpPort, ttl);
  rtcpGroupsock.multicastSendOnly();
#ifdef USE_SSM
  rtpGroupsock.multicastSendOnly();
  rtcpGroupsock.multicastSendOnly();
#endif
 g_ExitEventLoop = 0;
videoSink =
    SimpleRTPSink::createNew(*env, &rtpGroupsock, 33, 90000, "video", "MP2T",
                 1, True, False /*no 'M' bit*/);
setSendBufferTo(*env, rtpGroupsock.socketNum(), 1024 * 1024);
  setSendBufferTo(*env, rtpGroupsock.socketNum(), 1024 * 1024);

  // Create (and start) a 'RTCP instance' for this RTP sink:
  const unsigned estimatedSessionBandwidth = 5000; // in kbps; for RTCP b/w share
  const unsigned maxCNAMElen = 100;
  unsigned char CNAME[maxCNAMElen+1];
  gethostname((char*)CNAME, maxCNAMElen);
  CNAME[maxCNAMElen] = '\0'; // just in case

  RTCPInstance* rtcp =
    RTCPInstance::createNew(*env, &rtcpGroupsock,
                estimatedSessionBandwidth, CNAME,
                videoSink, NULL /* we're a server */, isSSM);
 UserAuthenticationDatabase* authDB = NULL; 
      portNumBits rtspServerPortNum = 554;
      unsigned reclamationTestSeconds=65U;
rtspServer = RTSPServer::createNew(*env,rtspServerPortNum, authDB, reclamationTestSeconds); 
    if (rtspServer == NULL)
    {
        *env << "Failed to create RTSP server: " <<env->getResultMsg()<<"\n";

        rtspServerPortNum = 8554;
        rtspServer = RTSPServer::createNew(*env,rtspServerPortNum);
        if (rtspServer == NULL)
        {
return 0;
        }
Boolean const inputStreamIsRawUDP = False; 
char const* descriptionString={"Session streamed by \"testOnDemandRT\""};
sms=ServerMediaSession::createNew(*env, streamName, streamName,descriptionString);
sms->addSubsession(MPEG2TransportUDPServerMediaSubsession::createNew(*env,destinationAddressStr,rtpPortNum1,inputStreamIsRawUDP));
    rtspServer->addServerMediaSession(sms);

    char* url = rtspServer->rtspURL(sms);
*env << "Play this stream using the URL \"" << url << "\"\n";
    delete[] url;
if (rtspServer->setUpTunnelingOverHTTP(sport) || rtspServer->setUpTunnelingOverHTTP(sport) || rtspServer->setUpTunnelingOverHTTP(sport))
        {
out<<"\n\n\n(We use port "<<rtspServer->httpServerPortNum()<<" for optional RTSP-over-HTTP tunneling.)\n";

        } 
        else
        {
             pDailyLogger->LogInfoString("(RTSP-over-HTTP tunneling is not available.)");
            cout<<"\n\n\n(RTSP-over-HTTP tunneling is not available.)";
        }
  play();
  env->taskScheduler().doEventLoop(&g_ExitEventLoop);
Medium::close(rtspServer);
 Medium::close(rtcp);
  Medium::close(videoSink);
 rtpGroupsock.removeAllDestinations();
  rtcpGroupsock.removeAllDestinations();

  env->reclaim();


  delete scheduler;



    pDailyLogger->LogDebugString("OUT::initLm555Settings Thread");

    return 0; // only to prevent compiler warning
}
void afterPlaying(void* /*clientData*/) {
  *env << "...done reading from file\n";

  videoSink->stopPlaying();
 Medium::close(videoSource);
  play();
}
void play() {
  // Open the input file as a 'byte-stream file source':

  fi_params.nFICardFrameSize = TRANSPORT_PACKETS_PER_NETWORK_PACKET * TRANSPORT_PACKET_SIZE;
  fi_params.pfnGetRTPPayload = GetRTPPayload;
  fi_params.socketNum = videoSink->groupsockBeingUsed().socketNum();

  DeviceParameters temp;

    fileSource = DeviceSourceFICard::createNew(*env, fi_params, temp);
  if (fileSource == NULL) {
    *env << "Unable to open Foresight card as a byte-stream file source\n";
    exit(1);
  }
  FramedSource* videoES = fileSource;
 videoSource = MPEG1or2VideoStreamDiscreteFramer::createNew(*env, videoES);
*env << "Beginning to read from file...\n";
  videoSink->startPlaying(*videoSource, afterPlaying, videoSink);
}
void StartRTPProcess(void)
{

    g_hRtpComThread = CreateThread((LPSECURITY_ATTRIBUTES) NULL, 0,
        (LPTHREAD_START_ROUTINE)initLm555Settings, 0, 0, &g_dwRtpComThreadID);

    if(g_hRtpComThread) SetThreadPriority(g_hRtpComThread, THREAD_PRIORITY_LOWEST/*THREAD_PRIORITY_NORMAL*/);

}
int StopRTProcess(void) 
{
  g_ExitEventLoop = 1;

     g_ExitEventLoop = 0;
  g_hRtpComThread = 0;
  g_dwRtpComThreadID = 0;
}

当我收到DONT STREAM消息时,将调用StopRTProcess()先生,我想念的是什么

Sir StopRTProcess() is called when i get DONT STREAM message,what am i missing please tell

推荐答案

可能您的RTSP服务器套接字没有关闭.关闭媒体后,删除媒体对象和RTSPServer对象.

Probably your RTSP server sockets are not getting closed. After closing media delete media objects and RTSPServer Object.

这篇关于如何一次又一次地创建和销毁rtsp服务器Live 555的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆