📄 rtpjitterbuffer.cxx
字号:
// RTPJitterBuffer.cpp: implementation of the RTPJitterBuffer class.
//
//////////////////////////////////////////////////////////////////////
#ifndef WIN32
#include <stdio.h>
#endif
#include "RTPJitterBuffer.h"
#include "RTPAudioStream.h"
#include "AudioSample.h"
#include "AudioSampleManager.h"
#include "Parameters.h"
#include "RTPPacket.h"
using namespace std;
//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////
RTPJitterBuffer::RTPJitterBuffer()
{
char subFacilityName[100];
sprintf(subFacilityName, "RTPJitterBuffer:%x", this);
tracer.SetSubFacilityName(subFacilityName);
SetTraceLevel();
jitterBufferDepth = DEFAULT_JITTERBUFFER_SIZE;
outputDuration = DEFAULT_JITTERBUFFER_OUTPUTDURATION;
activeAudioStream = NULL;
bRunning = false;
InitializeCriticalSection(&rtpAudioStreamsMutex);
InitializeCriticalSection(&stateMutex);
}
RTPJitterBuffer::~RTPJitterBuffer()
{
tracer.tracef(EE, "RTPJitterBuffer~\n");
Clear();
DeleteCriticalSection(&rtpAudioStreamsMutex);
DeleteCriticalSection(&stateMutex);
tracer.tracef(EE, "~RTPJitterBuffer~\n");
}
int
RTPJitterBuffer::SetTraceLevel()
{
#ifdef WIN32
long SystemMask = 0;
if ((SystemMask = GetRegKeyLong(HKEY_CURRENT_USER, "Software\\Cisco Systems\\MTC\\Tracing", "AllComponents", 0x0)) == 0)
{
SystemMask = GetRegKeyLong(HKEY_CURRENT_USER, "Software\\Cisco Systems\\MTC\\Tracing", "RTPJitterBuffer", 0x100000);
}
tracer.SetSystemMask(SystemMask);
#endif
return 0;
}
int
RTPJitterBuffer::SetJitterBufferDepth(int depth)
{
jitterBufferDepth = depth;
return 0;
}
int
RTPJitterBuffer::SetOutputDuration(int outputDuration)
{
this->outputDuration = outputDuration;
return 0;
}
int
RTPJitterBuffer::Clear()
{
EnterCriticalSection(&rtpAudioStreamsMutex);
while(rtpAudioStreams.size() > 0)
{
RTPAudioStream *audioStream = (*(rtpAudioStreams.begin())).second;
rtpAudioStreams.erase(rtpAudioStreams.begin());
delete audioStream;
}
LeaveCriticalSection(&rtpAudioStreamsMutex);
return 0;
}
int
RTPJitterBuffer::ChooseNewActiveAudioStream()
{
tracer.tracef(EE, "ChooseNewActiveStream\n");
tracer.tracef(ARB, "ChooseNewActiveStream : entering rtpAudioStreamsMutex\n");
EnterCriticalSection(&rtpAudioStreamsMutex);
if (activeAudioStream)
{
tracer.tracef(ARB, "ChooseNewActiveStream : deleting current active stream\n");
rtpAudioStreams.erase(activeAudioStream->SSRC());
delete activeAudioStream;
activeAudioStream = NULL;
}
AUDIO_STREAM_MAP::iterator iter = rtpAudioStreams.begin();
while (iter != rtpAudioStreams.end())
{
RTPAudioStream *rtpAudioStream = (*iter).second;
tracer.tracef(ARB, "ChooseNewActiveStream : found RTP stream : SSRC %u, %d packets, %d ms queued\n", rtpAudioStream->SSRC(), rtpAudioStream->NumQueuedPackets(), rtpAudioStream->JitterBufferDepth());
if (rtpAudioStream->JitterBufferDepth() >= jitterBufferDepth)
{
activeAudioStream = rtpAudioStream;
rtpAudioStreams.erase(activeAudioStream->SSRC());
tracer.tracef(EE, "ChooseNewActiveStream : stream with SSRC=%u chosen as new active stream\n", activeAudioStream->SSRC());
break;
}
iter++;
}
if (activeAudioStream)
{
// remove all other rtp streams since we chose one stream as active
Clear();
rtpAudioStreams[activeAudioStream->SSRC()] = activeAudioStream;
}
LeaveCriticalSection(&rtpAudioStreamsMutex);
tracer.tracef(ARB, "ChooseNewActiveStream : left rtpAudioStreamsMutex\n");
tracer.tracef(EE, "~ChooseNewActiveStream\n");
return 0;
}
int
RTPJitterBuffer::StartTransform()
{
tracer.tracef(EE, "StartTransform\n");
EnterCriticalSection(&stateMutex);
if (bRunning)
{
tracer.tracef(ARB, "StartTransform : Already Running\n");
}
else
{
Clear();
activeAudioStream = NULL;
bRunning = true;
}
LeaveCriticalSection(&stateMutex);
tracer.tracef(EE, "~StartTransform\n");
return 0;
}
int
RTPJitterBuffer::StopTransform()
{
tracer.tracef(EE, "StopTransform\n");
EnterCriticalSection(&stateMutex);
bRunning = false;
LeaveCriticalSection(&stateMutex);
tracer.tracef(EE, "~StopTransform\n");
return 0;
}
int
RTPJitterBuffer::TransformAudioSamples(std::vector<std::pair<AudioSample *, AudioSource *> > &data, AudioSample **ppAudioSample)
{
return 0;
}
int
RTPJitterBuffer::RenderAudioSamples(std::vector<std::pair<AudioSample *, AudioSource *> > &data)
{
tracer.tracef(DET, "RenderAudioSamples\n");
EnterCriticalSection(&stateMutex);
if (!bRunning)
{
LeaveCriticalSection(&stateMutex);
tracer.tracef(EE, "RenderAudioSamples : bRunning = false. Sleeping %d\n", outputDuration);
#ifdef WIN32
Sleep(outputDuration);
#else
vusleep(outputDuration*1000);
#endif
}
else
{
LeaveCriticalSection(&stateMutex);
AudioSample *audioSample = data[0].first;
RTPPacket *packetHeader = audioSample->RTPHeader();
if (!packetHeader)
{
tracer.tracef(DET, "~RenderAudioSamples : packet with no RTP header\n");
return -10;
}
unsigned long ssrc = packetHeader->Ssrc();
tracer.tracef(DET, "RenderAudioSamples : RTP packet : ssrc %u, seqno %u, timestamp %u\n", ssrc, packetHeader->SeqNo(), packetHeader->Timestamp());
tracer.tracef(DET, "RenderAudioSamples : Entering rtpAudioStreamsMutex\n");
EnterCriticalSection(&rtpAudioStreamsMutex);
AUDIO_STREAM_MAP::iterator iter;
iter = rtpAudioStreams.find(ssrc);
if (iter == rtpAudioStreams.end())
{
tracer.tracef(DET, "RenderAudioSamples : no previous stream with that ssrc. creating new one\n");
RTPAudioStream *rtpAudioStream = new RTPAudioStream(ssrc);
rtpAudioStreams[ssrc] = rtpAudioStream;
rtpAudioStream->SetTracer(&tracer);
iter = rtpAudioStreams.find(ssrc);
}
((*iter).second)->InsertRTPPacket(audioSample);
tracer.tracef(DET, "RenderAudioSamples : put packet into RTP stream : SSRC %d, %d ms in %d packets\n", ((*iter).second)->SSRC(), ((*iter).second)->JitterBufferDepth(), ((*iter).second)->NumQueuedPackets());
LeaveCriticalSection(&rtpAudioStreamsMutex);
tracer.tracef(DET, "RenderAudioSamples : Left rtpAudioStreamsMutex\n");
}
tracer.tracef(DET, "~RenderAudioSamples\n");
return 0;
}
int
RTPJitterBuffer::GenerateData(AudioSample **ppAudioSample)
{
tracer.tracef(DET, "GenerateData\n");
int result = 0;
EnterCriticalSection(&stateMutex);
if (!bRunning)
{
LeaveCriticalSection(&stateMutex);
tracer.tracef(EE, "GenerateData : bRunning = false\n");
(AudioSampleManager::GetInstance())->GetAudioSample(ppAudioSample);
(*ppAudioSample)->SetDataSize(0);
(*ppAudioSample)->SetSilenceDuration(outputDuration);
(*ppAudioSample)->SetFormat(WaveFormat::GetWaveFormat(WaveFormat_PCM_16_8_1));
}
else
{
LeaveCriticalSection(&stateMutex);
if (activeAudioStream == NULL || activeAudioStream->NumQueuedPackets() < 1)
{
tracer.tracef(DET, "GenerateData : Choosing new active stream\n");
ChooseNewActiveAudioStream();
}
if (activeAudioStream)
{
tracer.tracef(DET, "GenerateData : activeAudioStream is SSRC %d, %d ms in %d packets\n", activeAudioStream->SSRC(), activeAudioStream->JitterBufferDepth(), activeAudioStream->NumQueuedPackets());
activeAudioStream->GiveNextRTPPacket(ppAudioSample);
if (*ppAudioSample == NULL)
{
tracer.tracef(DET, "GenerateData : GiveNextRTPPacket returned NULL. sending silence\n");
(AudioSampleManager::GetInstance())->GetAudioSample(ppAudioSample);
(*ppAudioSample)->SetDataSize(0);
(*ppAudioSample)->SetSilenceDuration(outputDuration);
(*ppAudioSample)->SetFormat(WaveFormat::GetWaveFormat(WaveFormat_PCM_16_8_1));
}
else
{
RTPPacket *rtpHeader = (*ppAudioSample)->RTPHeader();
tracer.tracef(DET, "GenerateData : packet : ssrc %u, seqno %u\n", rtpHeader->Ssrc(), rtpHeader->SeqNo());
}
}
else
{
tracer.tracef(DET, "GenerateData : sending silence\n");
(AudioSampleManager::GetInstance())->GetAudioSample(ppAudioSample);
(*ppAudioSample)->SetDataSize(0);
(*ppAudioSample)->SetSilenceDuration(outputDuration);
(*ppAudioSample)->SetFormat(WaveFormat::GetWaveFormat(WaveFormat_PCM_16_8_1));
}
}
tracer.tracef(DET, "~GenerateData\n");
return 0;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -