You cannot select more than 25 topics
			Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
		
		
		
		
		
			
		
			
				
	
	
		
			110 lines
		
	
	
		
			3.4 KiB
		
	
	
	
		
			C++
		
	
			
		
		
	
	
			110 lines
		
	
	
		
			3.4 KiB
		
	
	
	
		
			C++
		
	
#include "WebRtcJitterBuffer.h"
 | 
						|
 | 
						|
#define TAG "WebRtcJitterBuffer"
 | 
						|
 | 
						|
static volatile int running = 0;
 | 
						|
 | 
						|
WebRtcJitterBuffer::WebRtcJitterBuffer(AudioCodec &codec) :
 | 
						|
  neteq(NULL), webRtcCodec(codec)
 | 
						|
{
 | 
						|
  running = 1;
 | 
						|
}
 | 
						|
 | 
						|
int WebRtcJitterBuffer::init() {
 | 
						|
  webrtc::NetEq::Config config;
 | 
						|
  config.sample_rate_hz = 8000;
 | 
						|
 | 
						|
  neteq = webrtc::NetEq::Create(config);
 | 
						|
 | 
						|
  if (neteq == NULL) {
 | 
						|
    __android_log_print(ANDROID_LOG_WARN, TAG, "Failed to construct NetEq!");
 | 
						|
    return -1;
 | 
						|
  }
 | 
						|
 | 
						|
  if (neteq->RegisterExternalDecoder(&webRtcCodec, webrtc::kDecoderPCMu, 0) != 0) {
 | 
						|
    __android_log_print(ANDROID_LOG_WARN, TAG, "Failed to register external codec!");
 | 
						|
    return -1;
 | 
						|
  }
 | 
						|
 | 
						|
  pthread_t thread;
 | 
						|
  pthread_create(&thread, NULL, &WebRtcJitterBuffer::collectStats, this);
 | 
						|
 | 
						|
  return 0;
 | 
						|
}
 | 
						|
 | 
						|
WebRtcJitterBuffer::~WebRtcJitterBuffer() {
 | 
						|
  if (neteq != NULL) {
 | 
						|
    delete neteq;
 | 
						|
  }
 | 
						|
}
 | 
						|
 | 
						|
void WebRtcJitterBuffer::addAudio(RtpPacket *packet, uint32_t tick) {
 | 
						|
  webrtc::WebRtcRTPHeader header;
 | 
						|
  header.header.payloadType    = packet->getPayloadType();
 | 
						|
  header.header.sequenceNumber = packet->getSequenceNumber();
 | 
						|
  header.header.timestamp      = packet->getTimestamp();
 | 
						|
  header.header.ssrc           = packet->getSsrc();
 | 
						|
 | 
						|
  uint8_t *payload = (uint8_t*)malloc(packet->getPayloadLen());
 | 
						|
  memcpy(payload, packet->getPayload(), packet->getPayloadLen());
 | 
						|
 | 
						|
  if (neteq->InsertPacket(header, payload, packet->getPayloadLen(), tick) != 0) {
 | 
						|
    __android_log_print(ANDROID_LOG_WARN, TAG, "neteq->InsertPacket() failed!");
 | 
						|
  }
 | 
						|
}
 | 
						|
 | 
						|
int WebRtcJitterBuffer::getAudio(short *rawData, int maxRawData) {
 | 
						|
  int samplesPerChannel = 0;
 | 
						|
  int numChannels       = 0;
 | 
						|
 | 
						|
  if (neteq->GetAudio(maxRawData, rawData, &samplesPerChannel, &numChannels, NULL) != 0) {
 | 
						|
    __android_log_print(ANDROID_LOG_WARN, TAG, "neteq->GetAudio() failed!");
 | 
						|
  }
 | 
						|
 | 
						|
  return samplesPerChannel;
 | 
						|
}
 | 
						|
 | 
						|
void WebRtcJitterBuffer::stop() {
 | 
						|
  running = 0;
 | 
						|
}
 | 
						|
 | 
						|
void WebRtcJitterBuffer::collectStats() {
 | 
						|
  while (running) {
 | 
						|
    webrtc::NetEqNetworkStatistics stats;
 | 
						|
    neteq->NetworkStatistics(&stats);
 | 
						|
 | 
						|
    __android_log_print(ANDROID_LOG_WARN, "WebRtcJitterBuffer",
 | 
						|
                        "Jitter Stats:\n{\n" \
 | 
						|
                        "  current_buffer_size_ms:   %d,\n" \
 | 
						|
                        "  preferred_buffer_size_ms: %d\n" \
 | 
						|
                        "  jitter_peaks_found:       %d\n" \
 | 
						|
                        "  packet_loss_rate:         %d\n" \
 | 
						|
                        "  packet_discard_rate:      %d\n" \
 | 
						|
                        "  expand_rate:              %d\n" \
 | 
						|
                        "  preemptive_rate:          %d\n" \
 | 
						|
                        "  accelerate_rate:          %d\n" \
 | 
						|
                        "  clockdrift_ppm:           %d\n" \
 | 
						|
                        "  added_zero_samples:       %d\n" \
 | 
						|
                        "}",
 | 
						|
                        stats.current_buffer_size_ms,
 | 
						|
                        stats.preferred_buffer_size_ms,
 | 
						|
                        stats.jitter_peaks_found,
 | 
						|
                        stats.packet_loss_rate,
 | 
						|
                        stats.packet_discard_rate,
 | 
						|
                        stats.expand_rate,
 | 
						|
                        stats.preemptive_rate,
 | 
						|
                        stats.accelerate_rate,
 | 
						|
                        stats.clockdrift_ppm,
 | 
						|
                        stats.added_zero_samples);
 | 
						|
    sleep(30);
 | 
						|
  }
 | 
						|
}
 | 
						|
 | 
						|
void* WebRtcJitterBuffer::collectStats(void *context) {
 | 
						|
  WebRtcJitterBuffer* jitterBuffer = static_cast<WebRtcJitterBuffer*>(context);
 | 
						|
  jitterBuffer->collectStats();
 | 
						|
 | 
						|
  return 0;
 | 
						|
}
 | 
						|
 |