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