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;
}