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