• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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
PVA_FF_TimeToSampleAtom(uint32 mediaType)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
~PVA_FF_TimeToSampleAtom()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
nextSample(uint32 ts)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
updateLastTSEntry(uint32 ts)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
addDelta(int32 delta)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
addEntry(uint32 count,int32 delta)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
renderToFileStream(MP4_AUTHOR_FF_FILE_IO_WRAP * fp)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
recomputeSize()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