/*
 *  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.
 */

/*
 * Implementation of the actual packet buffer data structure.
 */

#include "packet_buffer.h"

#include <string.h> /* to define NULL */

#include "signal_processing_library.h"

#include "neteq_error_codes.h"

#ifdef NETEQ_DELAY_LOGGING
/* special code for offline delay logging */
#include "delay_logging.h"
#include <stdio.h>

extern FILE *delay_fid2; /* file pointer to delay log file */
extern WebRtc_UWord32 tot_received_packets;
#endif /* NETEQ_DELAY_LOGGING */


int WebRtcNetEQ_PacketBufferInit(PacketBuf_t *bufferInst, int maxNoOfPackets,
                                 WebRtc_Word16 *pw16_memory, int memorySize)
{
    int i;
    int pos = 0;

    /* Sanity check */
    if ((memorySize < PBUFFER_MIN_MEMORY_SIZE) || (pw16_memory == NULL)
        || (maxNoOfPackets < 2) || (maxNoOfPackets > 600))
    {
        /* Invalid parameters */
        return (PBUFFER_INIT_ERROR);
    }

    /* Clear the buffer instance */
    WebRtcSpl_MemSetW16((WebRtc_Word16*) bufferInst, 0,
        sizeof(PacketBuf_t) / sizeof(WebRtc_Word16));

    /* Clear the buffer memory */
    WebRtcSpl_MemSetW16((WebRtc_Word16*) pw16_memory, 0, memorySize);

    /* Set maximum number of packets */
    bufferInst->maxInsertPositions = maxNoOfPackets;

    /* Initialize array pointers */
    /* After each pointer has been set, the index pos is advanced to point immediately
     * after the the recently allocated vector. Note that one step for the pos index
     * corresponds to a WebRtc_Word16.
     */

    bufferInst->timeStamp = (WebRtc_UWord32*) &pw16_memory[pos];
    pos += maxNoOfPackets << 1; /* advance maxNoOfPackets * WebRtc_UWord32 */

    bufferInst->payloadLocation = (WebRtc_Word16**) &pw16_memory[pos];
    pos += maxNoOfPackets * (sizeof(WebRtc_Word16*) / sizeof(WebRtc_Word16)); /* advance */

    bufferInst->seqNumber = (WebRtc_UWord16*) &pw16_memory[pos];
    pos += maxNoOfPackets; /* advance maxNoOfPackets * WebRtc_UWord16 */

    bufferInst->payloadType = &pw16_memory[pos];
    pos += maxNoOfPackets; /* advance maxNoOfPackets * WebRtc_Word16 */

    bufferInst->payloadLengthBytes = &pw16_memory[pos];
    pos += maxNoOfPackets; /* advance maxNoOfPackets * WebRtc_Word16 */

    bufferInst->rcuPlCntr = &pw16_memory[pos];
    pos += maxNoOfPackets; /* advance maxNoOfPackets * WebRtc_Word16 */

    bufferInst->waitingTime = (int*) (&pw16_memory[pos]);
    /* Advance maxNoOfPackets * sizeof(waitingTime element). */
    pos += maxNoOfPackets *
        sizeof(*bufferInst->waitingTime) / sizeof(*pw16_memory);

    /* The payload memory starts after the slot arrays */
    bufferInst->startPayloadMemory = &pw16_memory[pos];
    bufferInst->currentMemoryPos = bufferInst->startPayloadMemory;
    bufferInst->memorySizeW16 = (memorySize - pos); /* Remaining memory */

    /* Initialize each payload slot as empty with infinite delay */
    for (i = 0; i < bufferInst->maxInsertPositions; i++)
    {
        bufferInst->payloadType[i] = -1;
    }

    /* Reset buffer parameters */
    bufferInst->numPacketsInBuffer = 0;
    bufferInst->packSizeSamples = 0;
    bufferInst->insertPosition = 0;

    /* Reset buffer statistics */
    bufferInst->discardedPackets = 0;

    return (0);
}


int WebRtcNetEQ_PacketBufferFlush(PacketBuf_t *bufferInst)
{
    int i;

    /* Sanity check */
    if (bufferInst->startPayloadMemory == NULL)
    {
        /* Packet buffer has not been initialized */
        /* Don't do the flushing operation, since we do not
         know the state of the struct variables */
        return (0);
    }

    /* Set all payload lengths to zero */
    WebRtcSpl_MemSetW16(bufferInst->payloadLengthBytes, 0, bufferInst->maxInsertPositions);

    /* Reset buffer variables */
    bufferInst->numPacketsInBuffer = 0;
    bufferInst->currentMemoryPos = bufferInst->startPayloadMemory;
    bufferInst->insertPosition = 0;

    /* Clear all slots, starting with the last one */
    for (i = (bufferInst->maxInsertPositions - 1); i >= 0; i--)
    {
        bufferInst->payloadType[i] = -1;
        bufferInst->timeStamp[i] = 0;
        bufferInst->seqNumber[i] = 0;
    }

    return (0);
}


int WebRtcNetEQ_PacketBufferInsert(PacketBuf_t *bufferInst, const RTPPacket_t *RTPpacket,
                                   WebRtc_Word16 *flushed)
{
    int nextPos;
    int i;

#ifdef NETEQ_DELAY_LOGGING
    /* special code for offline delay logging */
    int temp_var;
#endif /* NETEQ_DELAY_LOGGING */

    /* Initialize to "no flush" */
    *flushed = 0;

    /* Sanity check */
    if (bufferInst->startPayloadMemory == NULL)
    {
        /* packet buffer has not been initialized */
        return (-1);
    }

    /* Sanity check for payload length
     (payloadLen in bytes and memory size in WebRtc_Word16) */
    if ((RTPpacket->payloadLen > (bufferInst->memorySizeW16 << 1)) || (RTPpacket->payloadLen
        <= 0))
    {
        /* faulty or too long payload length */
        return (-1);
    }

    /* Find a position in the buffer for this packet */
    if (bufferInst->numPacketsInBuffer != 0)
    {
        /* Get the next slot */
        bufferInst->insertPosition++;
        if (bufferInst->insertPosition >= bufferInst->maxInsertPositions)
        {
            /* "Wrap around" and start from the beginning */
            bufferInst->insertPosition = 0;
        }

        /* Check if there is enough space for the new packet */
        if (bufferInst->currentMemoryPos + ((RTPpacket->payloadLen + 1) >> 1)
            >= &bufferInst->startPayloadMemory[bufferInst->memorySizeW16])
        {
            WebRtc_Word16 *tempMemAddress;

            /*
             * Payload does not fit at the end of the memory, put it in the beginning
             * instead
             */
            bufferInst->currentMemoryPos = bufferInst->startPayloadMemory;

            /*
             * Now, we must search for the next non-empty payload,
             * finding the one with the lowest start address for the payload
             */
            tempMemAddress = &bufferInst->startPayloadMemory[bufferInst->memorySizeW16];
            nextPos = -1;

            /* Loop through all slots again */
            for (i = 0; i < bufferInst->maxInsertPositions; i++)
            {
                /* Look for the non-empty slot with the lowest
                 payload location address */
                if (bufferInst->payloadLengthBytes[i] != 0 && bufferInst->payloadLocation[i]
                    < tempMemAddress)
                {
                    tempMemAddress = bufferInst->payloadLocation[i];
                    nextPos = i;
                }
            }

            /* Check that we did find a previous payload */
            if (nextPos == -1)
            {
                /* The buffer is corrupt => flush and return error */
                WebRtcNetEQ_PacketBufferFlush(bufferInst);
                *flushed = 1;
                return (-1);
            }
        }
        else
        {
            /* Payload fits at the end of memory. */

            /* Find the next non-empty slot. */
            nextPos = bufferInst->insertPosition + 1;

            /* Increase nextPos until a non-empty slot is found or end of array is encountered*/
            while ((bufferInst->payloadLengthBytes[nextPos] == 0) && (nextPos
                < bufferInst->maxInsertPositions))
            {
                nextPos++;
            }

            if (nextPos == bufferInst->maxInsertPositions)
            {
                /*
                 * Reached the end of the array, so there must be a packet in the first
                 * position instead
                 */
                nextPos = 0;

                /* Increase nextPos until a non-empty slot is found */
                while (bufferInst->payloadLengthBytes[nextPos] == 0)
                {
                    nextPos++;
                }
            }
        } /* end if-else */

        /*
         * Check if the new payload will extend into a payload later in memory.
         * If so, the buffer is full.
         */
        if ((bufferInst->currentMemoryPos <= bufferInst->payloadLocation[nextPos])
            && ((&bufferInst->currentMemoryPos[(RTPpacket->payloadLen + 1) >> 1])
                > bufferInst->payloadLocation[nextPos]))
        {
            /* Buffer is full, so the buffer must be flushed */
            WebRtcNetEQ_PacketBufferFlush(bufferInst);
            *flushed = 1;
        }

        if (bufferInst->payloadLengthBytes[bufferInst->insertPosition] != 0)
        {
            /* All positions are already taken and entire buffer should be flushed */
            WebRtcNetEQ_PacketBufferFlush(bufferInst);
            *flushed = 1;
        }

    }
    else
    {
        /* Buffer is empty, just insert the packet at the beginning */
        bufferInst->currentMemoryPos = bufferInst->startPayloadMemory;
        bufferInst->insertPosition = 0;
    }

    /* Insert packet in the found position */
    if (RTPpacket->starts_byte1 == 0)
    {
        /* Payload is 16-bit aligned => just copy it */

        WEBRTC_SPL_MEMCPY_W16(bufferInst->currentMemoryPos,
            RTPpacket->payload, (RTPpacket->payloadLen + 1) >> 1);
    }
    else
    {
        /* Payload is not 16-bit aligned => align it during copy operation */
        for (i = 0; i < RTPpacket->payloadLen; i++)
        {
            /* copy the (i+1)-th byte to the i-th byte */

            WEBRTC_SPL_SET_BYTE(bufferInst->currentMemoryPos,
                (WEBRTC_SPL_GET_BYTE(RTPpacket->payload, (i + 1))), i);
        }
    }

    /* Copy the packet information */
    bufferInst->payloadLocation[bufferInst->insertPosition] = bufferInst->currentMemoryPos;
    bufferInst->payloadLengthBytes[bufferInst->insertPosition] = RTPpacket->payloadLen;
    bufferInst->payloadType[bufferInst->insertPosition] = RTPpacket->payloadType;
    bufferInst->seqNumber[bufferInst->insertPosition] = RTPpacket->seqNumber;
    bufferInst->timeStamp[bufferInst->insertPosition] = RTPpacket->timeStamp;
    bufferInst->rcuPlCntr[bufferInst->insertPosition] = RTPpacket->rcuPlCntr;
    bufferInst->rcuPlCntr[bufferInst->insertPosition] = 0;
    bufferInst->waitingTime[bufferInst->insertPosition] = 0;
    /* Update buffer parameters */
    bufferInst->numPacketsInBuffer++;
    bufferInst->currentMemoryPos += (RTPpacket->payloadLen + 1) >> 1;

#ifdef NETEQ_DELAY_LOGGING
    /* special code for offline delay logging */
    if (*flushed)
    {
        temp_var = NETEQ_DELAY_LOGGING_SIGNAL_FLUSH;
        fwrite( &temp_var, sizeof(int), 1, delay_fid2 );
    }
    temp_var = NETEQ_DELAY_LOGGING_SIGNAL_RECIN;
    fwrite( &temp_var, sizeof(int), 1, delay_fid2 );
    fwrite( &RTPpacket->timeStamp, sizeof(WebRtc_UWord32), 1, delay_fid2 );
    fwrite( &RTPpacket->seqNumber, sizeof(WebRtc_UWord16), 1, delay_fid2 );
    fwrite( &RTPpacket->payloadType, sizeof(int), 1, delay_fid2 );
    fwrite( &RTPpacket->payloadLen, sizeof(WebRtc_Word16), 1, delay_fid2 );
    tot_received_packets++;
#endif /* NETEQ_DELAY_LOGGING */

    return (0);
}


int WebRtcNetEQ_PacketBufferExtract(PacketBuf_t *bufferInst, RTPPacket_t *RTPpacket,
                                    int bufferPosition, int *waitingTime)
{

    /* Sanity check */
    if (bufferInst->startPayloadMemory == NULL)
    {
        /* packet buffer has not been initialized */
        return (PBUFFER_NOT_INITIALIZED);
    }

    if (bufferPosition < 0 || bufferPosition >= bufferInst->maxInsertPositions)
    {
        /* buffer position is outside valid range */
        return (NETEQ_OTHER_ERROR);
    }

    /* Check that there is a valid payload in the specified position */
    if (bufferInst->payloadLengthBytes[bufferPosition] <= 0)
    {
        /* The position does not contain a valid payload */
        RTPpacket->payloadLen = 0; /* Set zero length */
        return (PBUFFER_NONEXISTING_PACKET); /* Return error */
    }

    /* Payload exists => extract payload data */

    /* Copy the actual data payload to RTP packet struct */

    WEBRTC_SPL_MEMCPY_W16((WebRtc_Word16*) RTPpacket->payload,
        bufferInst->payloadLocation[bufferPosition],
        (bufferInst->payloadLengthBytes[bufferPosition] + 1) >> 1); /*length in WebRtc_Word16*/

    /* Copy payload parameters */
    RTPpacket->payloadLen = bufferInst->payloadLengthBytes[bufferPosition];
    RTPpacket->payloadType = bufferInst->payloadType[bufferPosition];
    RTPpacket->seqNumber = bufferInst->seqNumber[bufferPosition];
    RTPpacket->timeStamp = bufferInst->timeStamp[bufferPosition];
    RTPpacket->rcuPlCntr = bufferInst->rcuPlCntr[bufferPosition];
    *waitingTime = bufferInst->waitingTime[bufferPosition];
    RTPpacket->starts_byte1 = 0; /* payload is 16-bit aligned */

    /* Clear the position in the packet buffer */
    bufferInst->payloadType[bufferPosition] = -1;
    bufferInst->payloadLengthBytes[bufferPosition] = 0;
    bufferInst->seqNumber[bufferPosition] = 0;
    bufferInst->timeStamp[bufferPosition] = 0;
    bufferInst->waitingTime[bufferPosition] = 0;
    bufferInst->payloadLocation[bufferPosition] = bufferInst->startPayloadMemory;

    /* Reduce packet counter with one */
    bufferInst->numPacketsInBuffer--;

    return (0);
}


int WebRtcNetEQ_PacketBufferFindLowestTimestamp(PacketBuf_t *bufferInst,
                                                WebRtc_UWord32 currentTS,
                                                WebRtc_UWord32 *timestamp,
                                                int *bufferPosition, int eraseOldPkts,
                                                WebRtc_Word16 *payloadType)
{
    WebRtc_Word32 timeStampDiff = WEBRTC_SPL_WORD32_MAX; /* Smallest diff found */
    WebRtc_Word32 newDiff;
    int i;
    WebRtc_Word16 rcuPlCntr;

    /* Sanity check */
    if (bufferInst->startPayloadMemory == NULL)
    {
        /* packet buffer has not been initialized */
        return (PBUFFER_NOT_INITIALIZED);
    }

    /* Initialize all return values */
    *timestamp = 0;
    *payloadType = -1; /* indicates that no packet was found */
    *bufferPosition = -1; /* indicates that no packet was found */
    rcuPlCntr = WEBRTC_SPL_WORD16_MAX; /* indicates that no packet was found */

    /* Check if buffer is empty */
    if (bufferInst->numPacketsInBuffer <= 0)
    {
        /* Empty buffer */
        return (0);
    }

    /* Loop through all slots in buffer */
    for (i = 0; i < bufferInst->maxInsertPositions; i++)
    {
        /* Calculate difference between this slot and currentTS */
        newDiff = (WebRtc_Word32) (bufferInst->timeStamp[i] - currentTS);

        /* Check if payload should be discarded */
        if ((newDiff < 0) /* payload is too old */
            && (newDiff > -30000) /* account for TS wrap-around */
            && (eraseOldPkts) /* old payloads should be discarded */
            && (bufferInst->payloadLengthBytes[i] > 0)) /* the payload exists */
        {
            /* Throw away old packet */

            /* Clear the position in the buffer */
            bufferInst->payloadType[i] = -1;
            bufferInst->payloadLengthBytes[i] = 0;

            /* Reduce packet counter by one */
            bufferInst->numPacketsInBuffer--;

            /* Increase discard counter for in-call statistics */
            bufferInst->discardedPackets++;
        }
        else if (((newDiff < timeStampDiff) || ((newDiff == timeStampDiff)
            && (bufferInst->rcuPlCntr[i] < rcuPlCntr))) && (bufferInst->payloadLengthBytes[i]
            > 0))
        {
            /*
             * New diff is smaller than previous diffs or we have a candidate with a timestamp
             * as previous candidate but better RCU-counter; and the payload exists.
             */

            /* Save this position as the best candidate */
            *bufferPosition = i;
            timeStampDiff = newDiff;
            *payloadType = bufferInst->payloadType[i];
            rcuPlCntr = bufferInst->rcuPlCntr[i];
        }
    } /* end of for loop */

    /* check that we did find a real position */
    if (*bufferPosition >= 0)
    {
        /* get the timestamp for the best position */
        *timestamp = bufferInst->timeStamp[*bufferPosition];
    }

    return 0;
}


WebRtc_Word32 WebRtcNetEQ_PacketBufferGetSize(const PacketBuf_t *bufferInst)
{
    int i, count;
    WebRtc_Word32 sizeSamples;

    count = 0;

    /* Loop through all slots in the buffer */
    for (i = 0; i < bufferInst->maxInsertPositions; i++)
    {
        /* Only count the packets with non-zero size */
        if (bufferInst->payloadLengthBytes[i] != 0)
        {
            count++;
        }
    }

    /*
     * Calculate buffer size as number of packets times packet size
     * (packet size is that of the latest decoded packet)
     */
    sizeSamples = WEBRTC_SPL_MUL_16_16(bufferInst->packSizeSamples, count);

    /* Sanity check; size cannot be negative */
    if (sizeSamples < 0)
    {
        sizeSamples = 0;
    }

    return sizeSamples;
}

void WebRtcNetEQ_IncrementWaitingTimes(PacketBuf_t *buffer_inst) {
  int i;
  /* Loop through all slots in the buffer. */
  for (i = 0; i < buffer_inst->maxInsertPositions; ++i) {
    /* Only increment waiting time for the packets with non-zero size. */
    if (buffer_inst->payloadLengthBytes[i] != 0) {
      buffer_inst->waitingTime[i]++;
    }
  }
}

int WebRtcNetEQ_GetDefaultCodecSettings(const enum WebRtcNetEQDecoder *codecID,
                                        int noOfCodecs, int *maxBytes, int *maxSlots)
{
    int i;
    int ok = 0;
    WebRtc_Word16 w16_tmp;
    WebRtc_Word16 codecBytes;
    WebRtc_Word16 codecBuffers;

    /* Initialize return variables to zero */
    *maxBytes = 0;
    *maxSlots = 0;

    /* Loop through all codecs supplied to function */
    for (i = 0; i < noOfCodecs; i++)
    {
        /* Find current codec and set parameters accordingly */

        if (codecID[i] == kDecoderPCMu)
        {
            codecBytes = 1680; /* Up to 210ms @ 64kbps */
            codecBuffers = 30; /* Down to 5ms frames */
        }
        else if (codecID[i] == kDecoderPCMa)
        {
            codecBytes = 1680; /* Up to 210ms @ 64kbps */
            codecBuffers = 30; /* Down to 5ms frames */
        }
        else if (codecID[i] == kDecoderILBC)
        {
            codecBytes = 380; /* 200ms @ 15.2kbps (20ms frames) */
            codecBuffers = 10;
        }
        else if (codecID[i] == kDecoderISAC)
        {
            codecBytes = 960; /* 240ms @ 32kbps (60ms frames) */
            codecBuffers = 8;
        }
        else if (codecID[i] == kDecoderISACswb)
        {
            codecBytes = 1560; /* 240ms @ 52kbps (30ms frames) */
            codecBuffers = 8;
        }
        else if (codecID[i] == kDecoderPCM16B)
        {
            codecBytes = 3360; /* 210ms */
            codecBuffers = 15;
        }
        else if (codecID[i] == kDecoderPCM16Bwb)
        {
            codecBytes = 6720; /* 210ms */
            codecBuffers = 15;
        }
        else if (codecID[i] == kDecoderPCM16Bswb32kHz)
        {
            codecBytes = 13440; /* 210ms */
            codecBuffers = 15;
        }
        else if (codecID[i] == kDecoderPCM16Bswb48kHz)
        {
            codecBytes = 20160; /* 210ms */
            codecBuffers = 15;
        }
        else if (codecID[i] == kDecoderG722)
        {
            codecBytes = 1680; /* 210ms @ 64kbps */
            codecBuffers = 15;
        }
        else if (codecID[i] == kDecoderRED)
        {
            codecBytes = 0; /* Should not be max... */
            codecBuffers = 0;
        }
        else if (codecID[i] == kDecoderAVT)
        {
            codecBytes = 0; /* Should not be max... */
            codecBuffers = 0;
        }
        else if (codecID[i] == kDecoderCNG)
        {
            codecBytes = 0; /* Should not be max... */
            codecBuffers = 0;
        }
        else if (codecID[i] == kDecoderG729)
        {
            codecBytes = 210; /* 210ms @ 8kbps */
            codecBuffers = 20; /* max 200ms supported for 10ms frames */
        }
        else if (codecID[i] == kDecoderG729_1)
        {
            codecBytes = 840; /* 210ms @ 32kbps */
            codecBuffers = 10; /* max 200ms supported for 20ms frames */
        }
        else if (codecID[i] == kDecoderG726_16)
        {
            codecBytes = 400; /* 200ms @ 16kbps */
            codecBuffers = 10;
        }
        else if (codecID[i] == kDecoderG726_24)
        {
            codecBytes = 600; /* 200ms @ 24kbps */
            codecBuffers = 10;
        }
        else if (codecID[i] == kDecoderG726_32)
        {
            codecBytes = 800; /* 200ms @ 32kbps */
            codecBuffers = 10;
        }
        else if (codecID[i] == kDecoderG726_40)
        {
            codecBytes = 1000; /* 200ms @ 40kbps */
            codecBuffers = 10;
        }
        else if (codecID[i] == kDecoderG722_1_16)
        {
            codecBytes = 420; /* 210ms @ 16kbps */
            codecBuffers = 10;
        }
        else if (codecID[i] == kDecoderG722_1_24)
        {
            codecBytes = 630; /* 210ms @ 24kbps */
            codecBuffers = 10;
        }
        else if (codecID[i] == kDecoderG722_1_32)
        {
            codecBytes = 840; /* 210ms @ 32kbps */
            codecBuffers = 10;
        }
        else if (codecID[i] == kDecoderG722_1C_24)
        {
            codecBytes = 630; /* 210ms @ 24kbps */
            codecBuffers = 10;
        }
        else if (codecID[i] == kDecoderG722_1C_32)
        {
            codecBytes = 840; /* 210ms @ 32kbps */
            codecBuffers = 10;
        }
        else if (codecID[i] == kDecoderG722_1C_48)
        {
            codecBytes = 1260; /* 210ms @ 48kbps */
            codecBuffers = 10;
        }
        else if (codecID[i] == kDecoderSPEEX_8)
        {
            codecBytes = 1250; /* 210ms @ 50kbps */
            codecBuffers = 10;
        }
        else if (codecID[i] == kDecoderSPEEX_16)
        {
            codecBytes = 1250; /* 210ms @ 50kbps */
            codecBuffers = 10;
        }
        else if (codecID[i] == kDecoderGSMFR)
        {
            codecBytes = 340; /* 200ms */
            codecBuffers = 10;
        }
        else if (codecID[i] == kDecoderAMR)
        {
            codecBytes = 384; /* 240ms @ 12.2kbps+headers (60ms frames) */
            codecBuffers = 10;
        }
        else if (codecID[i] == kDecoderAMRWB)
        {
            codecBytes = 744;
            codecBuffers = 10;
        }
        else if (codecID[i] == kDecoderArbitrary)
        {
            codecBytes = 6720; /* Assume worst case uncompressed WB 210ms */
            codecBuffers = 15;
        }
        else
        {
            /*Unknow codec */
            codecBytes = 0;
            codecBuffers = 0;
            ok = CODEC_DB_UNKNOWN_CODEC;
        }

        /* Update max variables */
        *maxBytes = WEBRTC_SPL_MAX((*maxBytes), codecBytes);
        *maxSlots = WEBRTC_SPL_MAX((*maxSlots), codecBuffers);

    } /* end of for loop */

    /*
     * Add size needed by the additional pointers for each slot inside struct,
     * as indicated on each line below.
     */
    w16_tmp = (sizeof(WebRtc_UWord32) /* timeStamp */
    + sizeof(WebRtc_Word16*) /* payloadLocation */
    + sizeof(WebRtc_UWord16) /* seqNumber */
    + sizeof(WebRtc_Word16)  /* payloadType */
    + sizeof(WebRtc_Word16)  /* payloadLengthBytes */
    + sizeof(WebRtc_Word16)  /* rcuPlCntr   */
    + sizeof(int));          /* waitingTime */
    /* Add the extra size per slot to the memory count */
    *maxBytes += w16_tmp * (*maxSlots);

    return ok;
}

