Home | History | Annotate | Download | only in src
      1 /* ------------------------------------------------------------------
      2  * Copyright (C) 1998-2009 PacketVideo
      3  *
      4  * Licensed under the Apache License, Version 2.0 (the "License");
      5  * you may not use this file except in compliance with the License.
      6  * You may obtain a copy of the License at
      7  *
      8  *      http://www.apache.org/licenses/LICENSE-2.0
      9  *
     10  * Unless required by applicable law or agreed to in writing, software
     11  * distributed under the License is distributed on an "AS IS" BASIS,
     12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
     13  * express or implied.
     14  * See the License for the specific language governing permissions
     15  * and limitations under the License.
     16  * -------------------------------------------------------------------
     17  */
     18 ///////////////////////////////////////////////////////////////////////////////
     19 //
     20 // sequence_gen.cpp
     21 //
     22 //
     23 //
     24 //
     25 ///////////////////////////////////////////////////////////////////////////////
     26 
     27 #include "oscl_assert.h"
     28 #include "sequence_gen.h"
     29 
     30 
     31 SequenceGenerator::SequenceGenerator(int initialSeqNum,
     32                                      uint32 timestampReposDelta)
     33 {
     34     SequenceGenerator::initialSeqNum = initialSeqNum;
     35     SequenceGenerator::timestampReposDelta = timestampReposDelta;
     36 }
     37 
     38 SequenceGenerator::~SequenceGenerator()
     39 {
     40 
     41 }
     42 
     43 bool SequenceGenerator::registerNextObjectFrag(uint stream,
     44         uint objNum,
     45         uint objOffset,
     46         uint objLen,
     47         uint fragLen,
     48         bool* inCompleteFlag,
     49         bool ibRepositionFlag)
     50 {
     51     StreamSequenceInfo* pstream = getStream(stream);
     52 
     53     // check if previously unprovisioned stream
     54     if (pstream->streamId == -1)
     55     {
     56         // initialize
     57         pstream->streamId = stream;
     58         pstream->currSeq = initialSeqNum;
     59         pstream->currObjectNum = objNum;
     60         pstream->currObjectLen = objLen;
     61         pstream->currObjectOffset = objOffset + fragLen;
     62     }
     63 
     64 
     65     else if (pstream->currObjectNum == objNum)
     66     {
     67         // adding data to current object
     68 
     69         // check if data is intended for the current offset
     70         if (objOffset != pstream->currObjectOffset)
     71         {
     72             // lost fragments!
     73 
     74             // skip a sequence number
     75             pstream->currSeq++;
     76 
     77             // correct the position
     78             pstream->currObjectOffset = objOffset;
     79         }
     80 
     81         // account for the new fragment
     82         pstream->currObjectOffset += fragLen;
     83     }
     84     else
     85     {
     86         // starting a new object
     87 
     88         pstream->currObjectOffset += fragLen;
     89 
     90         // check if new object is expected
     91         if (! pstream->objComplete && !ibRepositionFlag)
     92         {
     93             // no - previous object is incomplete
     94             pstream->currSeq++;
     95         }
     96 
     97         // does the new object start at the beginning?
     98         if (objOffset != 0)
     99         {
    100             // first fragment(s) of object is missing - skip a seq num
    101             if (!ibRepositionFlag)
    102                 pstream->currSeq++;
    103             *inCompleteFlag = true;
    104         }
    105 
    106         pstream->currObjectNum = objNum;
    107         pstream->currObjectLen = objLen;
    108         pstream->currObjectOffset = objOffset + fragLen;
    109     }
    110 
    111     // check if the current object is complete
    112     pstream->objComplete =
    113         pstream->currObjectOffset ==
    114         pstream->currObjectLen;
    115 
    116 
    117     return pstream->objComplete;
    118 }
    119 
    120 uint32 SequenceGenerator::generateSequenceNum(uint stream)
    121 {
    122     OSCL_ASSERT(stream < vStreamInfo.size());
    123     return vStreamInfo[stream].currSeq++;
    124 }
    125 
    126 uint32 SequenceGenerator::generateTimestamp(uint stream, uint32 timestamp, bool reposition)
    127 {
    128     StreamSequenceInfo* pInfo = getStream(stream);
    129 
    130     if (reposition)
    131     {
    132 //       pInfo->timestampBase = pInfo->currTimestamp - timestamp + timestampReposDelta;
    133     }
    134 
    135     //OSCL_ASSERT(timestamp + pInfo->timestampBase >= pInfo->currTimestamp);
    136 
    137     return (pInfo->currTimestamp = timestamp + pInfo->timestampBase);
    138 }
    139 
    140 SequenceGenerator::StreamSequenceInfo* SequenceGenerator::getStream(uint stream)
    141 {
    142     // check if the stream array is big enough - if not,
    143     // grow it to sufficient size
    144     if (stream >= vStreamInfo.size())
    145     {
    146         StreamSequenceInfo empty;
    147 
    148         for (uint i = vStreamInfo.size(); i < stream + 1; i++)
    149         {
    150             vStreamInfo.push_back(empty);
    151         }
    152     }
    153 
    154     return &vStreamInfo[stream];
    155 }
    156 
    157 uint32 SequenceGenerator::getMinTimestamp()
    158 {
    159     if (vStreamInfo.size() == 0)
    160     {
    161         return 0;
    162     }
    163 
    164     uint32 min = 0x7FFFFFFF;
    165     Oscl_Vector<StreamSequenceInfo, OsclMemAllocator>::iterator it;
    166 
    167     for (it = vStreamInfo.begin(); it != vStreamInfo.end(); it++)
    168     {
    169         if (it->streamId == -1)
    170         {
    171             continue;
    172         }
    173         if (it->currTimestamp < min)
    174         {
    175             min = it->currTimestamp;
    176         }
    177     }
    178     return min;
    179 }
    180 
    181 // set next seqnum for stream
    182 void   SequenceGenerator::setSeqnum(const uint stream, const uint32 seqnum)
    183 {
    184     Oscl_Vector<StreamSequenceInfo, OsclMemAllocator>::iterator it;
    185     for (it = vStreamInfo.begin(); it != vStreamInfo.end(); it++)
    186     {
    187         if (it->streamId == (int)stream)
    188         {
    189             // since we are interrupting sequence here, also reset object ID to avoid gaps
    190             it->currSeq = seqnum;
    191             it->currObjectOffset = 0;
    192             it->objComplete = true;
    193             break;
    194         }
    195     }
    196 }
    197