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 This PVA_FF_TimeToSampleAtom Class contains a compact version of a table that allows 20 indexing from decoding to sample number. 21 */ 22 23 24 #define IMPLEMENT_TimeToSampleAtom 25 26 #include "timetosampleatom.h" 27 #include "atomutils.h" 28 #include "a_atomdefs.h" 29 30 typedef Oscl_Vector<uint32, OsclMemAllocator> uint32VecType; 31 typedef Oscl_Vector<int32, OsclMemAllocator> int32VecType; 32 // Constructor 33 PVA_FF_TimeToSampleAtom::PVA_FF_TimeToSampleAtom(uint32 mediaType) 34 : PVA_FF_FullAtom(TIME_TO_SAMPLE_ATOM, (uint8)0, (uint32)0), 35 _mediaType(mediaType) 36 { 37 // Initializing members and vectors 38 _firstEntry = true; 39 _entryCount = 0; 40 _lastTSUpdated = false; // used in movie fragment mode not to update table before rendering 41 42 PV_MP4_FF_NEW(fp->auditCB, uint32VecType, (), _psampleCountVec); 43 PV_MP4_FF_NEW(fp->auditCB, int32VecType, (), _psampleDeltaVec); 44 45 recomputeSize(); 46 } 47 48 // Destructor 49 PVA_FF_TimeToSampleAtom::~PVA_FF_TimeToSampleAtom() 50 { 51 // DO CLEANUP OF VECTORS!!! 52 PV_MP4_FF_TEMPLATED_DELETE(NULL, uint32VecType, Oscl_Vector, _psampleCountVec); 53 PV_MP4_FF_TEMPLATED_DELETE(NULL, int32VecType, Oscl_Vector, _psampleDeltaVec); 54 } 55 56 void 57 PVA_FF_TimeToSampleAtom::nextSample(uint32 ts) 58 { 59 switch (_mediaType) 60 { 61 case MEDIA_TYPE_AUDIO: // sample fp an IMediaSample 62 case MEDIA_TYPE_VISUAL: // sample fp an IMediaSample 63 case MEDIA_TYPE_TEXT: // sample fp an IMediatextSample for timed text 64 { 65 if (_firstEntry) 66 { 67 _currentTimestamp = ts; 68 _firstEntry = false; 69 } 70 else 71 { 72 // Calculate delta 73 int32 delta = ts - _currentTimestamp; 74 _currentTimestamp = ts; 75 76 // Add entry to table 77 addDelta(delta); 78 } 79 } 80 break; 81 82 case MEDIA_TYPE_UNKNOWN: 83 default: 84 break; 85 } 86 } 87 88 // in movie fragment mode set the actual duration of 89 // last sample 90 void 91 PVA_FF_TimeToSampleAtom::updateLastTSEntry(uint32 ts) 92 { 93 if (((uint32) _mediaType == MEDIA_TYPE_AUDIO) || 94 ((uint32) _mediaType == MEDIA_TYPE_VISUAL)) 95 { 96 int32 delta = ts - _currentTimestamp; 97 addDelta(delta); 98 } 99 100 _lastTSUpdated = true; 101 } 102 103 // Add delta to the table - logic contained within if shoudl just update table entries 104 // or if should add new entries 105 void 106 PVA_FF_TimeToSampleAtom::addDelta(int32 delta) 107 { 108 // Entries are calculated as difference between current ts and previous ts. Therefore 109 // the first entry to the table fp made when the second sample fp received 110 if (_entryCount == 0) 111 { 112 // Add first delta entry 113 addEntry(1, delta); 114 } 115 else 116 { 117 int32 lastDelta = (*_psampleDeltaVec)[_entryCount - 1]; 118 if (delta == lastDelta) 119 { 120 // Only need to replace count entry (increment it) 121 uint32 count = (*_psampleCountVec)[_entryCount - 1]; 122 _psampleCountVec->pop_back(); 123 _psampleCountVec->push_back(count + 1); // incrementing count 124 } 125 else 126 { 127 // deltas differ - add new entry 128 addEntry(1, delta); 129 } 130 } 131 } 132 133 // Add entry to the vector 134 void 135 PVA_FF_TimeToSampleAtom::addEntry(uint32 count, int32 delta) 136 { 137 _psampleDeltaVec->push_back(delta); 138 _psampleCountVec->push_back(count); 139 _entryCount++; 140 recomputeSize(); 141 } 142 143 144 // Rendering the PVA_FF_Atom in proper format (bitlengths, etc.) to an ostream 145 bool 146 PVA_FF_TimeToSampleAtom::renderToFileStream(MP4_AUTHOR_FF_FILE_IO_WRAP *fp) 147 { 148 int32 rendered = 0; 149 150 if (!renderAtomBaseMembers(fp)) 151 { 152 return false; 153 } 154 rendered += getDefaultSize(); 155 156 // This is required to comply with w3850 Sec 13.2.3.16 157 // "Note that the time to sample atoms must give durations for all 158 // samples including the last one" 159 if (_lastTSUpdated == false) 160 { 161 if (_entryCount > 0) 162 { 163 (*_psampleCountVec)[_entryCount - 1] += 1; 164 } 165 } 166 167 if (!PVA_FF_AtomUtils::render32(fp, getEntryCount())) 168 { 169 return false; 170 } 171 rendered += 4; 172 173 // Render the vectors of counts and deltas 174 if ((_psampleCountVec->size() < _entryCount) || 175 (_psampleDeltaVec->size() < _entryCount)) 176 { 177 return false; 178 } 179 for (uint32 i = 0; i < _entryCount; i++) 180 { 181 if (!PVA_FF_AtomUtils::render32(fp, (*_psampleCountVec)[i])) 182 { 183 return false; 184 } 185 if (!PVA_FF_AtomUtils::render32(fp, (*_psampleDeltaVec)[i])) 186 { 187 return false; 188 } 189 rendered += 8; 190 } 191 192 return true; 193 } 194 195 196 void 197 PVA_FF_TimeToSampleAtom::recomputeSize() 198 { 199 // Include size of all base atom members 200 int32 size = getDefaultSize(); 201 202 size += 4; // For entryCount 203 204 // Inlclude size of entries in vectors 205 for (uint32 i = 0; i < _entryCount; i++) 206 { 207 size += 8; 208 } 209 210 _size = size; 211 212 // Update the size of the parent atom 213 if (_pparent != NULL) 214 { 215 _pparent->recomputeSize(); 216 } 217 } 218