/* * 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 #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; }