I'm using a system based on the DM368 IPNC and am attempting to play an inbound RTP stream (uLaw) to the speaker. To do this, I have created an instance of an RTPSource associated with the inbound port. I have also created an instance of the AudioSink (live/audiorecv/AudioSink.cpp) to deliver the RTP to the speaker. Once I initiate the AudioSink->startPlaying, I get the following error reported:
av_server.out: pcm_params.c:2286: snd_pcm_hw_refine: Assertion `pcm && params' failed.
In total there are 3 streams in use: an H264 video out, an RTP audio out and an RTP audio in. The two outbound streams appear to be ok. I only have the issue when I attempt the inbound stream. It makes no difference if I only attempt the inbound stream. At this stage in development, I allow the system to boot, issue the /opt/ipnc/killall.sh to tear down the currently running configuration and then start up av_server.out with:
/opt/ipnc/av_server.out DM368 NTSC AUDIO 8000 G711 64000 TI2A AEWB 1080P H264 4000000 VBR AUTO H264 512000 VBR
AUTO MENUOFF &
Below is a segment of the code I'm running. It is based on wis-streamer.cpp and other examples I could find within the system. Any information on what I've not configured correctly to avoid the Assertion would be greatly appreciated.
/************************************************************************ * M A I N A P P L I C A T I O N ************************************************************************/ int main(int argc, char **argv) { struct optionals myOpt = {0, 0, 0, 0, 0, 0, 0x64001F, 96, "-", "-" }; APPROInput* H264InputDevice = NULL; FramedSource* videoSource; FramedSource* audioSource; struct in_addr destAddr; struct in_addr srcAddr; int videoType = VIDEO_TYPE_H264_CIF; char BuffStr[200]; const unsigned char ttl = 7; // low, in case routers don't admin scope RTPSink *rtpVideoSink; RTPSink *rtpAudioSink; RTPSource *rtpAudioSource; AudioSink *spkrOut; static RTCPInstance* rtcpVideo = NULL; static RTCPInstance* rtcpAudio = NULL; if(argc < 3){ printHelp(); exit(1); } recoverArgs(argc, argv, &myOpt); printf("myOpt.vidPrtFarEnd = %d\n",myOpt.vidPrtFarEnd); printf("myOpt.audOutPrtFarEnd = %d\n",myOpt.audOutPrtFarEnd); printf("myOpt.audInPrtNearEnd = %d\n",myOpt.audInPrtNearEnd); // set the priority of this process setpriority(PRIO_PROCESS, 0, 0); // Create the environment and scheduler needed TaskScheduler *scheduler = BasicTaskScheduler::createNew(); UsageEnvironment *env = BasicUsageEnvironment::createNew(*scheduler); // Initialize the signal handling init_signals(); // Address dest --> send to, src --> receive on destAddr.s_addr = our_inet_addr(myOpt.farEndIp); srcAddr.s_addr = INADDR_ANY; srcAddr.s_addr = our_inet_addr("192.168.60.240"); // Get the port in correct format const Port rtpPort(myOpt.vidPrtFarEnd); const Port rtcpPort(myOpt.vidPrtFarEnd+1); const Port audOutRtpPort(myOpt.audOutPrtFarEnd); const Port audOutRtcpPort(myOpt.audOutPrtFarEnd+1); const Port audInRtpPort(myOpt.audInPrtNearEnd); /* Initialize the shared memory connection */ share_memory_init(LIVE_MSG_TYPE4); /* Get access to the video stream. This is done through the Appro API * by first getting access to the video input and then routing it * to an RTPSink. */ H264InputDevice = APPROInput::createNew(*env, videoType); audioSource = H264InputDevice->audioSource(); videoSource = H264VideoStreamFramer::createNew(*env, H264InputDevice->videoSource()); // Configure output buffer size setVideoRTPSinkBufferSize(); // Get the string info for the RTP extern int GetSprop(void *pBuff, char vType); GetSprop(BuffStr, videoType); // And set up the RTP/RTCP sockets -- TBD need to specify originating port?? Groupsock audOutRtpGroupsock(*env, destAddr, audOutRtpPort, ttl); Groupsock audOutRtcpGroupsock(*env, destAddr, audOutRtcpPort, ttl); Groupsock rtpGroupsock(*env, destAddr, rtpPort, ttl); Groupsock rtcpGroupsock(*env, destAddr, rtcpPort, ttl); Groupsock audInRtpGroupsock(*env, srcAddr, audInRtpPort, ttl); // Incoming audio path:: rtpAudioSource --> spkrOut spkrOut = AudioSink::createNew(*env, "Output", 1024); rtpAudioSource = SimpleRTPSource::createNew(*env, &audInRtpGroupsock, 0, 8000, "audio", 0, 0); // Outgoing audio path:: audioSource --> rtpAudioSink rtpAudioSink = SimpleRTPSink::createNew(*env, &audOutRtpGroupsock, 0, 8000, "audio", "PCMU", 1, 1, 0); // Outgoing video path:: videoSource --> rtpVideoSink rtpVideoSink = H264VideoRTPSink::createNew(*env, &rtpGroupsock, myOpt.payloadFormat, myOpt.profileLevel, BuffStr); // Create (and start) a 'RTCP instance' for the RTP sinks: 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'; rtcpVideo = RTCPInstance::createNew(*env, &rtcpGroupsock, estimatedSessionBandwidth, CNAME, rtpVideoSink, NULL, 0); rtcpAudio = RTCPInstance::createNew(*env, &audOutRtcpGroupsock, 8, CNAME, rtpAudioSink, NULL, 0); /* Last step is to start playing ... */ *env << "Beginning streaming...\n" << "Port: " << myOpt.vidPrtFarEnd; *env << "Starting Video\n"; rtpVideoSink->startPlaying(*videoSource, NULL, NULL); *env << "Starting Audio\n"; rtpAudioSink->startPlaying(*audioSource, NULL, NULL); spkrOut->startPlaying(*rtpAudioSource, NULL, NULL); env->taskScheduler().doEventLoop(&watchVariable); return 0; }