⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 rtpjitterbuffer.cxx

📁 rtp在linux下的实现
💻 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 + -