Hello, I was trying to write a test program that contains a ServerMediaSession subclass which encapsulates a PassiveServerMediaSubsession (the contents of which could be as simple as code from the testH264VideoStreamer test program). However I am getting errors at runtime (on Windows specifically). I am seeing a "BasicTaskScheduler::SingleStep(): select fails: No error socket numbers used in the select call: 120(r) 128(r)". If I don't initialize an RTCPInstance I get a an access violation after the sink starts playing in RTPInterface.cpp line 215.
Is this scenario off limits or poor practice? I've had success with trying to do this with OnDemand based subsessions, but not Passive. Alternatively, I did try instead subclassing PassiveServerMediaSubsession, and that works - but the first has the advantage of not having to have already created the groupsocks and RTPSink. I'm really just trying to understand how to best write something more formal. Then main could be as simple as: // Begin by setting up our usage environment: TaskScheduler* scheduler = BasicTaskScheduler::createNew(); UsageEnvironment* env = BasicUsageEnvironment::createNew(*scheduler); RTSPServer* rtspServer = RTSPServer::createNew(*env, 8554); if (rtspServer == NULL) { *env << "Failed to create RTSP server: " << env->getResultMsg() << "\n"; exit(1); } ServerMediaSession* sms = ServerMediaSessionSubClass:: createNew(*env, "testStream", "test.264"); rtspServer->addServerMediaSession(sms); char* url = rtspServer->rtspURL(sms); *env << "Play this stream using the URL \"" << url << "\"\n"; delete[] url; env->taskScheduler().doEventLoop(); // does not return And then in the SMS subclass constructor: // Create 'groupsocks' for RTP and RTCP: struct in_addr destinationAddress; destinationAddress.s_addr = chooseRandomIPv4SSMAddress(env); // Note: This is a multicast address. If you wish instead to stream // using unicast, then you should use the "testOnDemandRTSPServer" // test program - not this test program - as a model. const unsigned short rtpPortNum = 18888; const unsigned short rtcpPortNum = rtpPortNum + 1; const unsigned char ttl = 255; const Port rtpPort(rtpPortNum); const Port rtcpPort(rtcpPortNum); Groupsock rtpGroupsock(env, destinationAddress, rtpPort, ttl); rtpGroupsock.multicastSendOnly(); // we're a SSM source Groupsock rtcpGroupsock(env, destinationAddress, rtcpPort, ttl); rtcpGroupsock.multicastSendOnly(); // we're a SSM source // Create a 'H264 Video RTP' sink from the RTP 'groupsock': OutPacketBuffer::maxSize = 100000; RTPSink* videoSink = H264VideoRTPSink::createNew(env, &rtpGroupsock, 96); // Create (and start) a 'RTCP instance' for this RTP sink: const unsigned estimatedSessionBandwidth = 500; // 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 */, True /* we're a SSM source */); // Note: This starts RTCP running automatically addSubsession(PassiveServerMediaSubsession::createNew(*videoSink, rtcp)); // Open the input file as a 'byte-stream file source': ByteStreamFileSource* fileSource = ByteStreamFileSource::createNew(env, inputFileName); FramedSource* videoES = fileSource; // Create a framer for the Video Elementary Stream: H264VideoStreamFramer* videoSource = H264VideoStreamFramer::createNew(env, videoES); videoSink->startPlaying(*videoSource, NULL, NULL);
_______________________________________________ live-devel mailing list live-devel@lists.live555.com http://lists.live555.com/mailman/listinfo/live-devel