142 lines
4.2 KiB
C
142 lines
4.2 KiB
C
/*
|
|
* Copyright (c) 2011 The WebRTC project authors. All Rights Reserved.
|
|
*
|
|
* Use of this source code is governed by a BSD-style license
|
|
* that can be found in the LICENSE file in the root of the source
|
|
* tree. An additional intellectual property rights grant can be found
|
|
* in the file PATENTS. All contributing project authors may
|
|
* be found in the AUTHORS file in the root of the source tree.
|
|
*/
|
|
|
|
/*
|
|
* Split an RTP payload (if possible and suitable) and insert into packet buffer.
|
|
*/
|
|
|
|
#include "mcu.h"
|
|
|
|
#include <string.h>
|
|
|
|
#include "signal_processing_library.h"
|
|
|
|
#include "neteq_error_codes.h"
|
|
|
|
int WebRtcNetEQ_SplitAndInsertPayload(RTPPacket_t *packet, PacketBuf_t *Buffer_inst,
|
|
SplitInfo_t *split_inst, WebRtc_Word16 *flushed)
|
|
{
|
|
|
|
int i_ok;
|
|
int len;
|
|
int i;
|
|
RTPPacket_t temp_packet;
|
|
WebRtc_Word16 localFlushed = 0;
|
|
const WebRtc_Word16 *pw16_startPayload;
|
|
*flushed = 0;
|
|
|
|
len = packet->payloadLen;
|
|
|
|
/* Copy to temp packet that can be modified. */
|
|
|
|
WEBRTC_SPL_MEMCPY_W8(&temp_packet,packet,sizeof(RTPPacket_t));
|
|
|
|
if (split_inst->deltaBytes == NO_SPLIT)
|
|
{
|
|
/* Not splittable codec */
|
|
i_ok = WebRtcNetEQ_PacketBufferInsert(Buffer_inst, packet, &localFlushed);
|
|
*flushed |= localFlushed;
|
|
if (i_ok < 0)
|
|
{
|
|
return PBUFFER_INSERT_ERROR5;
|
|
}
|
|
}
|
|
else if (split_inst->deltaBytes < -10)
|
|
{
|
|
/* G711, PCM16B or G722, use "soft splitting" */
|
|
int split_size = packet->payloadLen;
|
|
int mult = WEBRTC_SPL_ABS_W32(split_inst->deltaBytes) - 10;
|
|
|
|
/* Find "chunk size" >= 20 ms and < 40 ms
|
|
* split_inst->deltaTime in this case contains the number of bytes per
|
|
* timestamp unit times 2
|
|
*/
|
|
while (split_size >= ((80 << split_inst->deltaTime) * mult))
|
|
{
|
|
split_size >>= 1;
|
|
}
|
|
|
|
/* Make the size an even value. */
|
|
if (split_size > 1)
|
|
{
|
|
split_size >>= 1;
|
|
split_size *= 2;
|
|
}
|
|
|
|
temp_packet.payloadLen = split_size;
|
|
pw16_startPayload = temp_packet.payload;
|
|
i = 0;
|
|
while (len >= (2 * split_size))
|
|
{
|
|
/* insert every chunk */
|
|
i_ok = WebRtcNetEQ_PacketBufferInsert(Buffer_inst, &temp_packet, &localFlushed);
|
|
*flushed |= localFlushed;
|
|
temp_packet.timeStamp += ((2 * split_size) >> split_inst->deltaTime);
|
|
i++;
|
|
temp_packet.payload = &(pw16_startPayload[(i * split_size) >> 1]);
|
|
temp_packet.starts_byte1 = temp_packet.starts_byte1 ^ (split_size & 0x1);
|
|
|
|
len -= split_size;
|
|
if (i_ok < 0)
|
|
{
|
|
return PBUFFER_INSERT_ERROR1;
|
|
}
|
|
}
|
|
|
|
/* Insert the rest */
|
|
temp_packet.payloadLen = len;
|
|
i_ok = WebRtcNetEQ_PacketBufferInsert(Buffer_inst, &temp_packet, &localFlushed);
|
|
*flushed |= localFlushed;
|
|
if (i_ok < 0)
|
|
{
|
|
return PBUFFER_INSERT_ERROR2;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
/* Frame based codec, use hard splitting. */
|
|
i = 0;
|
|
pw16_startPayload = temp_packet.payload;
|
|
while (len >= split_inst->deltaBytes)
|
|
{
|
|
|
|
temp_packet.payloadLen = split_inst->deltaBytes;
|
|
i_ok = WebRtcNetEQ_PacketBufferInsert(Buffer_inst, &temp_packet, &localFlushed);
|
|
*flushed |= localFlushed;
|
|
i++;
|
|
temp_packet.payload = &(pw16_startPayload[(i * split_inst->deltaBytes) >> 1]);
|
|
temp_packet.timeStamp += split_inst->deltaTime;
|
|
temp_packet.starts_byte1 = temp_packet.starts_byte1 ^ (split_inst->deltaBytes
|
|
& 0x1);
|
|
|
|
if (i_ok < 0)
|
|
{
|
|
return PBUFFER_INSERT_ERROR3;
|
|
}
|
|
len -= split_inst->deltaBytes;
|
|
|
|
}
|
|
if (len > 0)
|
|
{
|
|
/* 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);
|
|
*flushed |= localFlushed;
|
|
if (i_ok < 0)
|
|
{
|
|
return PBUFFER_INSERT_ERROR4;
|
|
}
|
|
}
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|