AmAudioRtpFormat::AmAudioRtpFormat(const vector<SdpPayload *>& payloads) : AmAudioFormat(), m_payloads(payloads), m_currentPayload(-1) { for (vector<SdpPayload *>::iterator it = m_payloads.begin(); it != m_payloads.end(); ++it) { DBG("(*it)->payload_type = %i\n",(*it)->payload_type); m_sdpPayloadByPayload[(*it)->payload_type] = *it; } setCurrentPayload(m_payloads[0]->payload_type); }
/* @param wallclock_ts [in] the current ts in the audio buffer */ int AmRtpAudio::receive(unsigned long long system_ts) { int size; unsigned int rtp_ts; int new_payload = -1; if(!fmt.get() || (!playout_buffer.get())) { DBG("audio format not initialized\n"); return RTP_ERROR; } unsigned int wallclock_ts = scaleSystemTS(system_ts); while(true) { size = AmRtpStream::receive((unsigned char*)samples, (unsigned int)AUDIO_BUFFER_SIZE, rtp_ts, new_payload); if(size <= 0) { switch(size){ case 0: break; case RTP_DTMF: case RTP_UNKNOWN_PL: case RTP_PARSE_ERROR: continue; case RTP_TIMEOUT: //FIXME: postRequest(new SchedRequest(AmMediaProcessor::RemoveSession,s)); // post to the session (FIXME: is session always set? seems to be...) session->postEvent(new AmRtpTimeoutEvent()); return -1; case RTP_BUFFER_SIZE: default: ERROR("AmRtpStream::receive() returned %i\n",size); //FIXME: postRequest(new SchedRequest(AmMediaProcessor::ClearSession,s)); // or AmMediaProcessor::instance()->clearSession(session); return -1; break; } break; } if (// don't process if we don't need to // ignore CN COMFORT_NOISE_PAYLOAD_TYPE == new_payload || // ignore packet if payload not found setCurrentPayload(new_payload) ){ playout_buffer->clearLastTs(); continue; } size = decode(size); if(size <= 0){ ERROR("decode() returned %i\n",size); return -1; } // This only works because the possible ratio (Rate/TSRate) // is 2. Rate and TSRate are only different in case of g722. // For g722, TSRate=8000 and Rate=16000 // AmAudioRtpFormat* rtp_fmt = (AmAudioRtpFormat*)fmt.get(); unsigned long long adjusted_rtp_ts = rtp_ts; if(rtp_fmt->getRate() != rtp_fmt->getTSRate()) { adjusted_rtp_ts = (unsigned long long)rtp_ts * (unsigned long long)rtp_fmt->getRate() / (unsigned long long)rtp_fmt->getTSRate(); } playout_buffer->write(wallclock_ts, adjusted_rtp_ts, (ShortSample*)((unsigned char *)samples), PCM16_B2S(size), begin_talk); if(!active) { DBG("switching to active-mode\t(ts=%u;stream=%p)\n", rtp_ts,this); active = true; } } return size; }