Improve AV-sync when initial delay is set and NetEq has long buffer.
Review URL: https://webrtc-codereview.appspot.com/1324006
git-svn-id: http://webrtc.googlecode.com/svn/trunk@3883 4adac7df-926f-26a2-2b94-8c16560cd09d
diff --git a/webrtc/modules/audio_coding/neteq/dsp.h b/webrtc/modules/audio_coding/neteq/dsp.h
index d6e587e..9371938 100644
--- a/webrtc/modules/audio_coding/neteq/dsp.h
+++ b/webrtc/modules/audio_coding/neteq/dsp.h
@@ -422,24 +422,25 @@
* This function asks NetEQ for more speech/audio data.
*
* Input:
- * - inst : NetEQ instance, i.e. the user that requests more
- * speech/audio data.
- * - outdata : Pointer to a memory space where the output data
- * should be stored.
- * - BGNonly : If non-zero, RecOut will only produce background
- * noise. It will still draw packets from the packet
- * buffer, but they will never be decoded.
+ * - inst : NetEQ instance, i.e. the user that requests more
+ * speech/audio data.
+ * - outdata : Pointer to a memory space where the output data
+ * should be stored.
+ * - BGNonly : If non-zero, RecOut will only produce background
+ * noise. It will still draw packets from the packet
+ * buffer, but they will never be decoded.
+ * - av_sync : 1 if NetEQ is in AV-sync, 0 otherwise.
*
* Output:
- * - inst : Updated user information
- * - len : Number of samples that were outputted from NetEq
+ * - inst : Updated user information
+ * - len : Number of samples that were outputted from NetEq
*
- * Return value : 0 - Ok
- * -1 - Error
+ * Return value : 0 - Ok
+ * -1 - Error
*/
-int WebRtcNetEQ_RecOutInternal(DSPInst_t *inst, int16_t *pw16_outData, int16_t *pw16_len,
- int16_t BGNonly);
+int WebRtcNetEQ_RecOutInternal(DSPInst_t *inst, int16_t *pw16_outData,
+ int16_t *pw16_len, int16_t BGNonly, int av_sync);
/****************************************************************************
* WebRtcNetEQ_Normal(...)
diff --git a/webrtc/modules/audio_coding/neteq/interface/webrtc_neteq_internal.h b/webrtc/modules/audio_coding/neteq/interface/webrtc_neteq_internal.h
index 46be2d1..4eefce0 100644
--- a/webrtc/modules/audio_coding/neteq/interface/webrtc_neteq_internal.h
+++ b/webrtc/modules/audio_coding/neteq/interface/webrtc_neteq_internal.h
@@ -271,6 +271,44 @@
int WebRtcNetEQ_FlushBuffers(void *inst);
+/*****************************************************************************
+ * void WebRtcNetEq_EnableAVSync(...)
+ *
+ * Enable AV-sync. If Enabled, NetEq will screen for sync payloads. For
+ * each sync payload a silence frame is generated.
+ *
+ * Input:
+ * - inst : NetEQ instance
+ * - enable : non-zero to enable, otherwise disabled.
+ *
+ * Output:
+ * - inst : Updated NetEQ instance
+ *
+ */
+
+void WebRtcNetEQ_EnableAVSync(void* inst, int enable);
+
+/****************************************************************************
+ * WebRtcNetEQ_RecInSyncRTP(...)
+ *
+ * Insert a sync packet with the given RTP specification.
+ *
+ * Input:
+ * - inst : NetEQ instance
+ * - rtpInfo : Pointer to RTP info
+ * - receive_timestamp : Receive time (in timestamps of the used codec)
+ *
+ * Output:
+ * - inst : Updated NetEQ instance
+ *
+ * Return value : if succeeded it returns the number of bytes pushed
+ * in, otherwise returns -1.
+ */
+
+int WebRtcNetEQ_RecInSyncRTP(void* inst,
+ WebRtcNetEQ_RTPInfo* rtp_info,
+ uint32_t receive_timestamp);
+
#ifdef __cplusplus
}
#endif
diff --git a/webrtc/modules/audio_coding/neteq/mcu.h b/webrtc/modules/audio_coding/neteq/mcu.h
index 6994a36..1be81c2 100644
--- a/webrtc/modules/audio_coding/neteq/mcu.h
+++ b/webrtc/modules/audio_coding/neteq/mcu.h
@@ -88,6 +88,13 @@
int16_t TSscalingInitialized;
enum TsScaling scalingFactor;
+ /* AV-sync enabled. In AV-sync NetEq screens packets for specific sync
+ * packets. Sync packets are not decoded by a decoder but generate all-zero
+ * signal with the same number of samples as previously decoded payload.
+ * Also in AV-sync mode the sample-size of a sync payload is reported as
+ * previous frame-size. */
+ int av_sync;
+
#ifdef NETEQ_STEREO
int usingStereo;
#endif
@@ -196,6 +203,7 @@
*
* Input:
* - inst : MCU instance
+ * - av_sync : 1 if NetEQ is in AV-sync mode, otherwise 0.
*
* Return value : 0 - Ok
* <0 - Error
@@ -229,12 +237,17 @@
* - MCU_inst : MCU instance
* - RTPpacket : The RTP packet, parsed into NetEQ's internal RTP struct
* - uw32_timeRec : Time stamp for the arrival of the packet (not RTP timestamp)
+ * - av_sync : indicates if AV-sync is enabled, 1 enabled,
+ * 0 disabled.
*
* Return value : 0 - Ok
* -1 - Error
*/
-int WebRtcNetEQ_SplitAndInsertPayload(RTPPacket_t *packet, PacketBuf_t *Buffer_inst,
- SplitInfo_t *split_inst, int16_t *flushed);
+int WebRtcNetEQ_SplitAndInsertPayload(RTPPacket_t* packet,
+ PacketBuf_t* Buffer_inst,
+ SplitInfo_t* split_inst,
+ int16_t* flushed,
+ int av_sync);
/****************************************************************************
* WebRtcNetEQ_GetTimestampScaling(...)
diff --git a/webrtc/modules/audio_coding/neteq/mcu_dsp_common.c b/webrtc/modules/audio_coding/neteq/mcu_dsp_common.c
index 744a131..2c48ec7 100644
--- a/webrtc/modules/audio_coding/neteq/mcu_dsp_common.c
+++ b/webrtc/modules/audio_coding/neteq/mcu_dsp_common.c
@@ -35,3 +35,11 @@
inst->MCUinst.pw16_writeAddress = pw16_shared_mem;
return WebRtcNetEQ_SignalMcu(&inst->MCUinst);
}
+
+int WebRtcNetEQ_IsSyncPayload(const void* payload, int payload_len_bytes) {
+ if (payload_len_bytes != SYNC_PAYLOAD_LEN_BYTES ||
+ memcmp(payload, kSyncPayload, SYNC_PAYLOAD_LEN_BYTES) != 0) {
+ return 0;
+ }
+ return 1;
+}
diff --git a/webrtc/modules/audio_coding/neteq/mcu_dsp_common.h b/webrtc/modules/audio_coding/neteq/mcu_dsp_common.h
index badffa1..b4ab514 100644
--- a/webrtc/modules/audio_coding/neteq/mcu_dsp_common.h
+++ b/webrtc/modules/audio_coding/neteq/mcu_dsp_common.h
@@ -31,6 +31,10 @@
#define SHARED_MEM_SIZE 640
#endif
+#define SYNC_PAYLOAD_LEN_BYTES 7
+static const uint8_t kSyncPayload[SYNC_PAYLOAD_LEN_BYTES] = {
+ 'a', 'v', 's', 'y', 'n', 'c', '\0' };
+
/* Struct to hold the NetEQ instance */
typedef struct
{
@@ -58,4 +62,8 @@
/* The DSP side will call this function to interrupt the MCU side */
int WebRtcNetEQ_DSP2MCUinterrupt(MainInst_t *inst, int16_t *pw16_shared_mem);
+/* Returns 1 if the given payload matches |kSyncPayload| payload, otherwise
+ * 0 is returned. */
+int WebRtcNetEQ_IsSyncPayload(const void* payload, int payload_len_bytes);
+
#endif
diff --git a/webrtc/modules/audio_coding/neteq/packet_buffer.c b/webrtc/modules/audio_coding/neteq/packet_buffer.c
index 39f40ef..83079d7 100644
--- a/webrtc/modules/audio_coding/neteq/packet_buffer.c
+++ b/webrtc/modules/audio_coding/neteq/packet_buffer.c
@@ -12,12 +12,15 @@
* Implementation of the actual packet buffer data structure.
*/
+#include <assert.h>
#include "packet_buffer.h"
#include <string.h> /* to define NULL */
#include "signal_processing_library.h"
+#include "mcu_dsp_common.h"
+
#include "neteq_error_codes.h"
#ifdef NETEQ_DELAY_LOGGING
@@ -140,7 +143,7 @@
int WebRtcNetEQ_PacketBufferInsert(PacketBuf_t *bufferInst, const RTPPacket_t *RTPpacket,
- int16_t *flushed)
+ int16_t *flushed, int av_sync)
{
int nextPos;
int i;
@@ -169,6 +172,43 @@
return (-1);
}
+ /* If we are in AV-sync mode, there is a risk that we have inserted a sync
+ * packet but now received the real version of it. Or because of some timing
+ * we might be overwriting a true payload with sync (I'm not sure why this
+ * should happen in regular case, but in some FEC enabled case happens).
+ * Go through packets and delete the sync version of the packet in hand. Or
+ * if this is sync packet and the regular version of it exists in the buffer
+ * refrain from inserting.
+ *
+ * TODO(turajs): Could we get this for free if we had set the RCU-counter of
+ * the sync packet to a number larger than 2?
+ */
+ if (av_sync) {
+ for (i = 0; i < bufferInst->maxInsertPositions; ++i) {
+ /* Check if sequence numbers match and the payload actually exists. */
+ if (bufferInst->seqNumber[i] == RTPpacket->seqNumber &&
+ bufferInst->payloadLengthBytes[i] > 0) {
+ if (WebRtcNetEQ_IsSyncPayload(RTPpacket->payload,
+ RTPpacket->payloadLen)) {
+ return 0;
+ }
+
+ if (WebRtcNetEQ_IsSyncPayload(bufferInst->payloadLocation[i],
+ bufferInst->payloadLengthBytes[i])) {
+ /* Clear the position in the buffer. */
+ bufferInst->payloadType[i] = -1;
+ bufferInst->payloadLengthBytes[i] = 0;
+
+ /* Reduce packet counter by one. */
+ bufferInst->numPacketsInBuffer--;
+ /* TODO(turajs) if this is the latest packet better we rewind
+ * insertPosition and related variables. */
+ break; /* There should be only one match. */
+ }
+ }
+ }
+ }
+
/* Find a position in the buffer for this packet */
if (bufferInst->numPacketsInBuffer != 0)
{
@@ -406,7 +446,6 @@
int32_t new_diff;
int i;
int16_t rcu_payload_cntr;
-
if (buffer_inst->startPayloadMemory == NULL) {
/* Packet buffer has not been initialized. */
return PBUFFER_NOT_INITIALIZED;
@@ -493,10 +532,19 @@
int WebRtcNetEQ_PacketBufferGetPacketSize(const PacketBuf_t* buffer_inst,
int buffer_pos,
const CodecDbInst_t* codec_database,
- int codec_pos, int last_duration) {
+ int codec_pos, int last_duration,
+ int av_sync) {
if (codec_database->funcDurationEst[codec_pos] == NULL) {
return last_duration;
}
+
+ if (av_sync != 0 &&
+ WebRtcNetEQ_IsSyncPayload(buffer_inst->payloadLocation[buffer_pos],
+ buffer_inst->payloadLengthBytes[buffer_pos])) {
+ // In AV-sync and sync payload, report |last_duration| as current duration.
+ return last_duration;
+ }
+
return (*codec_database->funcDurationEst[codec_pos])(
codec_database->codec_state[codec_pos],
(const uint8_t *)buffer_inst->payloadLocation[buffer_pos],
@@ -504,7 +552,8 @@
}
int32_t WebRtcNetEQ_PacketBufferGetSize(const PacketBuf_t* buffer_inst,
- const CodecDbInst_t* codec_database) {
+ const CodecDbInst_t* codec_database,
+ int av_sync) {
int i, count;
int last_duration;
int last_codec_pos;
@@ -546,9 +595,12 @@
* last_duration to compute a changing duration, we would have to
* iterate through the packets in chronological order by timestamp.
*/
- last_duration = WebRtcNetEQ_PacketBufferGetPacketSize(
- buffer_inst, i, codec_database, codec_pos,
- last_duration);
+ /* Check for error before setting. */
+ int temp_last_duration = WebRtcNetEQ_PacketBufferGetPacketSize(
+ buffer_inst, i, codec_database, codec_pos,
+ last_duration, av_sync);
+ if (temp_last_duration >= 0)
+ last_duration = temp_last_duration;
}
/* Add in the size of this packet. */
size_samples += last_duration;
@@ -560,7 +612,6 @@
if (size_samples < 0) {
size_samples = 0;
}
-
return size_samples;
}
diff --git a/webrtc/modules/audio_coding/neteq/packet_buffer.h b/webrtc/modules/audio_coding/neteq/packet_buffer.h
index afd74db..61ff2b9 100644
--- a/webrtc/modules/audio_coding/neteq/packet_buffer.h
+++ b/webrtc/modules/audio_coding/neteq/packet_buffer.h
@@ -51,7 +51,6 @@
2 for redundant payload */
int *waitingTime;
-
/* Statistics counter */
uint16_t discardedPackets; /* Number of discarded packets */
@@ -104,20 +103,21 @@
* This function inserts an RTP packet into the packet buffer.
*
* Input:
- * - bufferInst : Buffer instance
- * - RTPpacket : An RTP packet struct (with payload, sequence
- * number, etc.)
+ * - bufferInst : Buffer instance
+ * - RTPpacket : An RTP packet struct (with payload, sequence
+ * number, etc.)
+ * - av_sync : 1 indicates AV-sync enabled, 0 disabled.
*
* Output:
- * - bufferInst : Updated buffer instance
- * - flushed : 1 if buffer was flushed, 0 otherwise
+ * - bufferInst : Updated buffer instance
+ * - flushed : 1 if buffer was flushed, 0 otherwise
*
- * Return value : 0 - Ok
- * -1 - Error
+ * Return value : 0 - Ok
+ * -1 - Error
*/
int WebRtcNetEQ_PacketBufferInsert(PacketBuf_t *bufferInst, const RTPPacket_t *RTPpacket,
- int16_t *flushed);
+ int16_t *flushed, int av_sync);
/****************************************************************************
* WebRtcNetEQ_PacketBufferExtract(...)
@@ -183,6 +183,7 @@
* - codec_pos : The codec database entry associated with the payload
* type of the specified buffer.
* - last_duration : The duration of the previous frame.
+ * - av_sync : 1 indicates AV-sync enabled, 0 disabled.
*
* Return value : The buffer size in samples
*/
@@ -190,7 +191,8 @@
int WebRtcNetEQ_PacketBufferGetPacketSize(const PacketBuf_t* buffer_inst,
int buffer_pos,
const CodecDbInst_t* codec_database,
- int codec_pos, int last_duration);
+ int codec_pos, int last_duration,
+ int av_sync);
/****************************************************************************
* WebRtcNetEQ_PacketBufferGetSize(...)
@@ -204,12 +206,14 @@
* Input:
* - buffer_inst : Buffer instance
* - codec_database : Codec database instance
+ * - av_sync : 1 indicates AV-sync enabled, 0 disabled.
*
* Return value : The buffer size in samples
*/
int32_t WebRtcNetEQ_PacketBufferGetSize(const PacketBuf_t* buffer_inst,
- const CodecDbInst_t* codec_database);
+ const CodecDbInst_t* codec_database,
+ int av_sync);
/****************************************************************************
* WebRtcNetEQ_IncrementWaitingTimes(...)
diff --git a/webrtc/modules/audio_coding/neteq/recin.c b/webrtc/modules/audio_coding/neteq/recin.c
index f0dd210..15d618e 100644
--- a/webrtc/modules/audio_coding/neteq/recin.c
+++ b/webrtc/modules/audio_coding/neteq/recin.c
@@ -43,7 +43,8 @@
#endif
temp_bufsize = WebRtcNetEQ_PacketBufferGetSize(&MCU_inst->PacketBuffer_inst,
- &MCU_inst->codec_DB_inst);
+ &MCU_inst->codec_DB_inst,
+ MCU_inst->av_sync);
/*
* Copy from input RTP packet to local copy
* (mainly to enable multiple payloads using RED)
@@ -223,7 +224,7 @@
MCU_inst->current_Codec = -1;
}
i_ok = WebRtcNetEQ_PacketBufferInsert(&MCU_inst->PacketBuffer_inst,
- &RTPpacket[i_k], &flushed);
+ &RTPpacket[i_k], &flushed, MCU_inst->av_sync);
if (i_ok < 0)
{
return RECIN_CNG_ERROR;
@@ -259,7 +260,8 @@
/* Parse the payload and insert it into the buffer */
i_ok = WebRtcNetEQ_SplitAndInsertPayload(&RTPpacket[i_k],
- &MCU_inst->PacketBuffer_inst, &MCU_inst->PayloadSplit_inst, &flushed);
+ &MCU_inst->PacketBuffer_inst, &MCU_inst->PayloadSplit_inst,
+ &flushed, MCU_inst->av_sync);
if (i_ok < 0)
{
return i_ok;
@@ -311,8 +313,8 @@
{
/* Calculate the total speech length carried in each packet */
temp_bufsize = WebRtcNetEQ_PacketBufferGetSize(
- &MCU_inst->PacketBuffer_inst, &MCU_inst->codec_DB_inst)
- - temp_bufsize;
+ &MCU_inst->PacketBuffer_inst, &MCU_inst->codec_DB_inst,
+ MCU_inst->av_sync) - temp_bufsize;
if ((temp_bufsize > 0) && (MCU_inst->BufferStat_inst.Automode_inst.lastPackCNGorDTMF
== 0) && (temp_bufsize
diff --git a/webrtc/modules/audio_coding/neteq/recout.c b/webrtc/modules/audio_coding/neteq/recout.c
index 63abbd1..8f62007 100644
--- a/webrtc/modules/audio_coding/neteq/recout.c
+++ b/webrtc/modules/audio_coding/neteq/recout.c
@@ -96,7 +96,8 @@
int WebRtcNetEQ_RecOutInternal(DSPInst_t *inst, int16_t *pw16_outData,
- int16_t *pw16_len, int16_t BGNonly)
+ int16_t *pw16_len, int16_t BGNonly,
+ int av_sync)
{
int16_t blockLen, payloadLen, len = 0, pos;
@@ -413,25 +414,36 @@
int16_t dec_Len;
if (!BGNonly)
{
+ /* Check if this is a sync payload. */
+ if (av_sync && WebRtcNetEQ_IsSyncPayload(blockPtr,
+ payloadLen)) {
+ /* Zero-stuffing with same size as the last frame. */
+ dec_Len = inst->w16_frameLen;
+ memset(&pw16_decoded_buffer[len], 0, dec_Len *
+ sizeof(pw16_decoded_buffer[len]));
+ } else {
/* Do decoding as normal
*
* blockPtr is pointing to payload, at this point,
- * the most significant bit of *(blockPtr - 1) is a flag if set to 1
- * indicates that the following payload is the redundant payload.
+ * the most significant bit of *(blockPtr - 1) is a flag if
+ * set to 1 indicates that the following payload is the
+ * redundant payload.
*/
if (((*(blockPtr - 1) & DSP_CODEC_RED_FLAG) != 0)
&& (inst->codec_ptr_inst.funcDecodeRCU != NULL))
{
- dec_Len = inst->codec_ptr_inst.funcDecodeRCU(
- inst->codec_ptr_inst.codec_state, blockPtr, payloadLen,
- &pw16_decoded_buffer[len], &speechType);
+ dec_Len = inst->codec_ptr_inst.funcDecodeRCU(
+ inst->codec_ptr_inst.codec_state, blockPtr,
+ payloadLen, &pw16_decoded_buffer[len], &speechType);
}
else
{
- dec_Len = inst->codec_ptr_inst.funcDecode(
- inst->codec_ptr_inst.codec_state, blockPtr, payloadLen,
- &pw16_decoded_buffer[len], &speechType);
+ /* Regular decoding. */
+ dec_Len = inst->codec_ptr_inst.funcDecode(
+ inst->codec_ptr_inst.codec_state, blockPtr,
+ payloadLen, &pw16_decoded_buffer[len], &speechType);
}
+ }
}
else
{
diff --git a/webrtc/modules/audio_coding/neteq/signal_mcu.c b/webrtc/modules/audio_coding/neteq/signal_mcu.c
index ebe035d..b3791d1 100644
--- a/webrtc/modules/audio_coding/neteq/signal_mcu.c
+++ b/webrtc/modules/audio_coding/neteq/signal_mcu.c
@@ -43,9 +43,12 @@
if (codec_pos >= 0) {
codec_pos = inst->codec_DB_inst.position[codec_pos];
if (codec_pos >= 0) {
- return WebRtcNetEQ_PacketBufferGetPacketSize(
- &inst->PacketBuffer_inst, buffer_pos,
- &inst->codec_DB_inst, codec_pos, pack_size_samples);
+ int temp_packet_size_samples = WebRtcNetEQ_PacketBufferGetPacketSize(
+ &inst->PacketBuffer_inst, buffer_pos, &inst->codec_DB_inst,
+ codec_pos, pack_size_samples, inst->av_sync);
+ if (temp_packet_size_samples > 0)
+ return temp_packet_size_samples;
+ return pack_size_samples;
}
}
}
@@ -245,7 +248,7 @@
/* Check packet buffer */
w32_bufsize = WebRtcNetEQ_PacketBufferGetSize(&inst->PacketBuffer_inst,
- &inst->codec_DB_inst);
+ &inst->codec_DB_inst, inst->av_sync);
if (dspInfo.lastMode == MODE_SUCCESS_ACCELERATE || dspInfo.lastMode
== MODE_LOWEN_ACCELERATE || dspInfo.lastMode == MODE_SUCCESS_PREEMPTIVE
diff --git a/webrtc/modules/audio_coding/neteq/split_and_insert.c b/webrtc/modules/audio_coding/neteq/split_and_insert.c
index ce2e821..252d713 100644
--- a/webrtc/modules/audio_coding/neteq/split_and_insert.c
+++ b/webrtc/modules/audio_coding/neteq/split_and_insert.c
@@ -20,8 +20,11 @@
#include "neteq_error_codes.h"
-int WebRtcNetEQ_SplitAndInsertPayload(RTPPacket_t *packet, PacketBuf_t *Buffer_inst,
- SplitInfo_t *split_inst, int16_t *flushed)
+int WebRtcNetEQ_SplitAndInsertPayload(RTPPacket_t* packet,
+ PacketBuf_t* Buffer_inst,
+ SplitInfo_t* split_inst,
+ int16_t* flushed,
+ int av_sync)
{
int i_ok;
@@ -41,7 +44,8 @@
if (split_inst->deltaBytes == NO_SPLIT)
{
/* Not splittable codec */
- i_ok = WebRtcNetEQ_PacketBufferInsert(Buffer_inst, packet, &localFlushed);
+ i_ok = WebRtcNetEQ_PacketBufferInsert(Buffer_inst, packet,
+ &localFlushed, av_sync);
*flushed |= localFlushed;
if (i_ok < 0)
{
@@ -76,7 +80,8 @@
while (len >= (2 * split_size))
{
/* insert every chunk */
- i_ok = WebRtcNetEQ_PacketBufferInsert(Buffer_inst, &temp_packet, &localFlushed);
+ i_ok = WebRtcNetEQ_PacketBufferInsert(Buffer_inst, &temp_packet,
+ &localFlushed, av_sync);
*flushed |= localFlushed;
temp_packet.timeStamp += ((2 * split_size) >> split_inst->deltaTime);
i++;
@@ -92,7 +97,8 @@
/* Insert the rest */
temp_packet.payloadLen = len;
- i_ok = WebRtcNetEQ_PacketBufferInsert(Buffer_inst, &temp_packet, &localFlushed);
+ i_ok = WebRtcNetEQ_PacketBufferInsert(Buffer_inst, &temp_packet,
+ &localFlushed, av_sync);
*flushed |= localFlushed;
if (i_ok < 0)
{
@@ -108,7 +114,8 @@
{
temp_packet.payloadLen = split_inst->deltaBytes;
- i_ok = WebRtcNetEQ_PacketBufferInsert(Buffer_inst, &temp_packet, &localFlushed);
+ i_ok = WebRtcNetEQ_PacketBufferInsert(Buffer_inst, &temp_packet,
+ &localFlushed, av_sync);
*flushed |= localFlushed;
i++;
temp_packet.payload = &(pw16_startPayload[(i * split_inst->deltaBytes) >> 1]);
@@ -127,7 +134,8 @@
{
/* Must be a either an error or a SID frame at the end of the packet. */
temp_packet.payloadLen = len;
- i_ok = WebRtcNetEQ_PacketBufferInsert(Buffer_inst, &temp_packet, &localFlushed);
+ i_ok = WebRtcNetEQ_PacketBufferInsert(Buffer_inst, &temp_packet,
+ &localFlushed, av_sync);
*flushed |= localFlushed;
if (i_ok < 0)
{
diff --git a/webrtc/modules/audio_coding/neteq/webrtc_neteq.c b/webrtc/modules/audio_coding/neteq/webrtc_neteq.c
index 1be0133..31940c8 100644
--- a/webrtc/modules/audio_coding/neteq/webrtc_neteq.c
+++ b/webrtc/modules/audio_coding/neteq/webrtc_neteq.c
@@ -440,6 +440,9 @@
NetEqMainInst->MCUinst.NoOfExpandCalls = 0;
NetEqMainInst->MCUinst.fs = fs;
+ /* Not in AV-sync by default. */
+ NetEqMainInst->MCUinst.av_sync = 0;
+
#ifdef NETEQ_ATEVENT_DECODE
/* init DTMF decoder */
ok = WebRtcNetEQ_DtmfDecoderInit(&(NetEqMainInst->MCUinst.DTMF_inst),fs,560);
@@ -806,7 +809,7 @@
#endif
ok = WebRtcNetEQ_RecOutInternal(&NetEqMainInst->DSPinst, pw16_outData,
- pw16_len, 0 /* not BGN only */);
+ pw16_len, 0 /* not BGN only */, NetEqMainInst->MCUinst.av_sync);
if (ok != 0)
{
NetEqMainInst->ErrorCode = -ok;
@@ -887,7 +890,7 @@
}
ok = WebRtcNetEQ_RecOutInternal(&NetEqMainInst->DSPinst, pw16_outData,
- pw16_len, 0 /* not BGN only */);
+ pw16_len, 0 /* not BGN only */, NetEqMainInst->MCUinst.av_sync);
if (ok != 0)
{
NetEqMainInst->ErrorCode = -ok;
@@ -958,7 +961,7 @@
#endif
ok = WebRtcNetEQ_RecOutInternal(&NetEqMainInst->DSPinst, pw16_outData,
- pw16_len, 1 /* BGN only */);
+ pw16_len, 1 /* BGN only */, NetEqMainInst->MCUinst.av_sync);
if (ok != 0)
{
NetEqMainInst->ErrorCode = -ok;
@@ -1186,7 +1189,8 @@
/* Query packet buffer for number of samples. */
temp32 = WebRtcNetEQ_PacketBufferGetSize(
&NetEqMainInst->MCUinst.PacketBuffer_inst,
- &NetEqMainInst->MCUinst.codec_DB_inst);
+ &NetEqMainInst->MCUinst.codec_DB_inst,
+ NetEqMainInst->MCUinst.av_sync);
/* Divide by sample rate.
* Calculate temp32 * 1000 / fs to get result in ms. */
@@ -1671,3 +1675,21 @@
WebRtcNetEQ_ClearActivityStats(&NetEqMainInst->DSPinst);
}
+
+void WebRtcNetEQ_EnableAVSync(void* inst, int enable) {
+ MainInst_t *NetEqMainInst = (MainInst_t*) inst;
+ NetEqMainInst->MCUinst.av_sync = (enable != 0) ? 1 : 0;
+}
+
+int WebRtcNetEQ_RecInSyncRTP(void* inst, WebRtcNetEQ_RTPInfo* rtp_info,
+ uint32_t receive_timestamp) {
+ MainInst_t *NetEqMainInst = (MainInst_t*) inst;
+ if (NetEqMainInst->MCUinst.av_sync == 0)
+ return -1;
+ if (WebRtcNetEQ_RecInRTPStruct(inst, rtp_info, kSyncPayload,
+ SYNC_PAYLOAD_LEN_BYTES,
+ receive_timestamp) < 0) {
+ return -1;
+ }
+ return SYNC_PAYLOAD_LEN_BYTES;
+}