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;
}
Sir StopRTProcess() is called when i get DONT STREAM message,what am i missing please tell