• 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 /*     -------------------------------------------------------------------       */
20 /*                        MPEG-4 TimeToSampleAtom Class                          */
21 /*     -------------------------------------------------------------------       */
22 /*********************************************************************************/
23 /*
24     This TimeToSampleAtom Class contains a compact version of a table that allows
25     indexing from decoding to sample number.
26 */
27 
28 
29 #define IMPLEMENT_TimeToSampleAtom
30 
31 #include "timetosampleatom.h"
32 #include "atomutils.h"
33 #include "atomdefs.h"
34 
35 // Stream-in ctor
TimeToSampleAtom(MP4_FF_FILE * fp,uint32 mediaType,uint32 size,uint32 type,OSCL_wString & filename,uint32 parsingMode)36 TimeToSampleAtom::TimeToSampleAtom(MP4_FF_FILE *fp,
37                                    uint32 mediaType,
38                                    uint32 size,
39                                    uint32 type,
40                                    OSCL_wString& filename,
41                                    uint32 parsingMode)
42         : FullAtom(fp, size, type)
43 {
44 
45     _psampleCountVec = NULL;
46     _psampleDeltaVec = NULL;
47 
48     _currGetSampleCount = 0;
49     _currGetIndex = -1;
50     _currGetTimeDelta = 0;
51     _currPeekSampleCount = 0;
52     _currPeekIndex = -1;
53     _currPeekTimeDelta = 0;
54 
55     _mediaType = mediaType;
56     _parsed_entry_cnt = 0;
57     _fileptr = NULL;
58     _parsing_mode = 0;
59     _parsing_mode = parsingMode;
60 
61     _stbl_buff_size = MAX_CACHED_TABLE_ENTRIES_FILE;
62     _next_buff_number = 0;
63     _curr_buff_number = 0;
64     _curr_entry_point = 0;
65     _stbl_fptr_vec = NULL;
66 
67     iLogger = PVLogger::GetLoggerObject("mp4ffparser");
68     iStateVarLogger = PVLogger::GetLoggerObject("mp4ffparser_mediasamplestats");
69     iParsedDataLogger = PVLogger::GetLoggerObject("mp4ffparser_parseddata");
70 
71 
72     if (_success)
73     {
74         if (!AtomUtils::read32(fp, _entryCount))
75         {
76             _success = false;
77         }
78         PVMF_MP4FFPARSER_LOGPARSEDINFO((0, "TimeToSampleAtom::TimeToSampleAtom- _entryCount =%d", _entryCount));
79         uint32 dataSize = _size - (DEFAULT_FULL_ATOM_SIZE + 4);
80 
81         uint32 entrySize = (4 + 4);
82 
83         if ((_entryCount*entrySize) > dataSize)
84         {
85             _success = false;
86         }
87 
88         if (_success)
89         {
90             if (_entryCount > 0)
91             {
92 
93                 if (parsingMode == 1)
94                 {
95                     // cache size is 4K so that optimization should work if entry_count is greater than 4K
96                     if ((_entryCount > _stbl_buff_size))
97                     {
98                         uint32 fptrBuffSize = (_entryCount / _stbl_buff_size) + 1;
99 
100                         PV_MP4_FF_ARRAY_NEW(NULL, uint32, (fptrBuffSize), _stbl_fptr_vec);
101                         if (_stbl_fptr_vec == NULL)
102                         {
103                             _success = false;
104                             _mp4ErrorCode = MEMORY_ALLOCATION_FAILED;
105                             return;
106                         }
107 
108                         PV_MP4_FF_ARRAY_NEW(NULL, uint32, (_stbl_buff_size), _psampleCountVec);
109                         if (_psampleCountVec == NULL)
110                         {
111                             _success = false;
112                             _mp4ErrorCode = MEMORY_ALLOCATION_FAILED;
113                             return;
114                         }
115                         PV_MP4_FF_ARRAY_NEW(NULL, uint32, (_stbl_buff_size), _psampleDeltaVec);
116                         if (_psampleDeltaVec == NULL)
117                         {
118                             PV_MP4_ARRAY_DELETE(NULL, _psampleDeltaVec);
119                             _psampleDeltaVec = NULL;
120                             _success = false;
121                             _mp4ErrorCode = MEMORY_ALLOCATION_FAILED;
122                             return;
123                         }
124                         for (uint32 idx = 0; idx < _stbl_buff_size; idx++)  //initialization
125                         {
126                             _psampleCountVec[idx] = 0;
127                             _psampleDeltaVec[idx] = 0;
128                         }
129 
130                         OsclAny* ptr = (MP4_FF_FILE *)(oscl_malloc(sizeof(MP4_FF_FILE)));
131                         if (ptr == NULL)
132                         {
133                             _success = false;
134                             _mp4ErrorCode = MEMORY_ALLOCATION_FAILED;
135                             return;
136                         }
137                         _fileptr = OSCL_PLACEMENT_NEW(ptr, MP4_FF_FILE());
138                         _fileptr->_fileServSession = fp->_fileServSession;
139                         _fileptr->_pvfile.SetCPM(fp->_pvfile.GetCPM());
140                         if (AtomUtils::OpenMP4File(filename,
141                                                    Oscl_File::MODE_READ | Oscl_File::MODE_BINARY,
142                                                    _fileptr) != 0)
143                         {
144                             _success = false;
145                             _mp4ErrorCode = FILE_OPEN_FAILED;
146                         }
147 
148                         _fileptr->_fileSize = fp->_fileSize;
149 
150                         int32 _head_offset = AtomUtils::getCurrentFilePosition(fp);
151                         AtomUtils::seekFromCurrPos(fp, dataSize);
152                         AtomUtils::seekFromStart(_fileptr, _head_offset);
153                         return;
154                     }
155                     else
156                     {
157                         _parsing_mode = 0;
158                         _stbl_buff_size = _entryCount;
159                     }
160                 }
161                 else
162                 {
163                     _stbl_buff_size = _entryCount;
164                 }
165 
166                 PV_MP4_FF_ARRAY_NEW(NULL, uint32, (_entryCount), _psampleCountVec);
167                 if (_psampleCountVec == NULL)
168                 {
169                     _success = false;
170                     _mp4ErrorCode = MEMORY_ALLOCATION_FAILED;
171                     return;
172                 }
173                 PV_MP4_FF_ARRAY_NEW(NULL, uint32, (_entryCount), _psampleDeltaVec);
174                 if (_psampleDeltaVec == NULL)
175                 {
176                     PV_MP4_ARRAY_DELETE(NULL, _psampleDeltaVec);
177                     _psampleDeltaVec = NULL;
178                     _success = false;
179                     _mp4ErrorCode = MEMORY_ALLOCATION_FAILED;
180                     return;
181                 }
182                 for (uint32 idx = 0; idx < _entryCount; idx++)  //initialization
183                 {
184                     _psampleCountVec[idx] = 0;
185                     _psampleDeltaVec[idx] = 0;
186                 }
187 
188                 uint32 number = 0;
189                 uint32 delta = 0;
190                 for (_parsed_entry_cnt = 0; _parsed_entry_cnt < _entryCount; _parsed_entry_cnt++)
191                 {
192                     if (!AtomUtils::read32(fp, number))
193                     {
194                         _success = false;
195                         break;
196                     }
197                     if (!AtomUtils::read32(fp, delta))
198                     {
199                         _success = false;
200                         break;
201                     }
202                     _psampleCountVec[_parsed_entry_cnt] = (number);
203                     _psampleDeltaVec[_parsed_entry_cnt] = (delta);
204                 }
205             }
206         }
207 
208         if (!_success)
209         {
210             _mp4ErrorCode = READ_TIME_TO_SAMPLE_ATOM_FAILED;
211         }
212     }
213     else
214     {
215         if (_mp4ErrorCode != ATOM_VERSION_NOT_SUPPORTED)
216             _mp4ErrorCode = READ_TIME_TO_SAMPLE_ATOM_FAILED;
217     }
218 }
219 
ParseEntryUnit(uint32 entry_cnt)220 bool TimeToSampleAtom::ParseEntryUnit(uint32 entry_cnt)
221 {
222 
223     const uint32 threshold = 1024;
224     entry_cnt += threshold;
225 
226     if (entry_cnt > _entryCount)
227         entry_cnt = _entryCount;
228 
229     uint32 number, delta;
230     while (_parsed_entry_cnt < entry_cnt)
231     {
232         _curr_entry_point = _parsed_entry_cnt % _stbl_buff_size;
233         _curr_buff_number = _parsed_entry_cnt / _stbl_buff_size;
234 
235         if (_curr_buff_number  == _next_buff_number)
236         {
237             uint32 currFilePointer = AtomUtils::getCurrentFilePosition(_fileptr);
238             _stbl_fptr_vec[_curr_buff_number] = currFilePointer;
239             _next_buff_number++;
240         }
241 
242         if (!_curr_entry_point)
243         {
244             uint32 currFilePointer = _stbl_fptr_vec[_curr_buff_number];
245             AtomUtils::seekFromStart(_fileptr, currFilePointer);
246         }
247 
248         if (!AtomUtils::read32(_fileptr, number))
249         {
250             return false;
251         }
252         if (!AtomUtils::read32(_fileptr, delta))
253         {
254             return false;
255         }
256         _psampleCountVec[_curr_entry_point] = (number);
257         _psampleDeltaVec[_curr_entry_point] = (delta);
258         _parsed_entry_cnt++;
259     }
260     return true;
261 }
262 
263 // Destructor
~TimeToSampleAtom()264 TimeToSampleAtom::~TimeToSampleAtom()
265 {
266     if (_psampleCountVec != NULL)
267         PV_MP4_ARRAY_DELETE(NULL, _psampleCountVec);
268 
269     if (_psampleDeltaVec != NULL)
270         PV_MP4_ARRAY_DELETE(NULL, _psampleDeltaVec);
271 
272     if (_stbl_fptr_vec != NULL)
273         PV_MP4_ARRAY_DELETE(NULL, _stbl_fptr_vec);
274 
275     if (_fileptr != NULL)
276     {
277         if (_fileptr->IsOpen())
278         {
279             AtomUtils::CloseMP4File(_fileptr);
280         }
281         oscl_free(_fileptr);
282     }
283 }
284 
285 // Return the number of samples  at index
286 uint32
getSampleCountAt(int32 index)287 TimeToSampleAtom::getSampleCountAt(int32 index)
288 {
289     if (_psampleCountVec == NULL)
290     {
291         return (uint32) PV_ERROR;
292     }
293 
294     if (index < (int32)_entryCount)
295     {
296         if (_parsing_mode == 1)
297             CheckAndParseEntry(index);
298 
299         return (int32)(_psampleCountVec[index%_stbl_buff_size]);
300     }
301     else
302     {
303         PVMF_MP4FFPARSER_LOGERROR((0, "ERROR =>TimeToSampleAtom::getSampleCountAt index = %d", index));
304         return (uint32) PV_ERROR;
305     }
306 }
307 
308 // Return sample delta at index
309 int32
getSampleDeltaAt(int32 index)310 TimeToSampleAtom::getSampleDeltaAt(int32 index)
311 {
312     if (_psampleDeltaVec == NULL)
313     {
314         return PV_ERROR;
315     }
316 
317     if (index < (int32)_entryCount)
318     {
319         if (_parsing_mode == 1)
320             CheckAndParseEntry(index);
321 
322         return (int32)(_psampleDeltaVec[index%_stbl_buff_size]);
323     }
324     else
325     {
326         PVMF_MP4FFPARSER_LOGERROR((0, "ERROR =>TimeToSampleAtom::getSampleDeltaAt index = %d", index));
327         return PV_ERROR;
328     }
329 }
330 
331 // Return the samples corresponding to the timestamp ts.  If there is not a sample
332 // exactly at ts, the very next sample is used.
333 // This atom maintains timestamp deltas between samples, i.e. delta[i] is the
334 // timestamp difference between sample[i] and sample[i+1].  It is implicit that
335 // sample[0] occurs at timestamp ts=0.
336 int32
getSampleNumberFromTimestamp(uint32 ts,bool oAlwaysRetSampleCount)337 TimeToSampleAtom::getSampleNumberFromTimestamp(uint32 ts, bool oAlwaysRetSampleCount)
338 {
339     // It is assumed that sample 0 has a ts of 0 - i.e. the first
340     // entry in the table starts with the delta between sample 1 and sample 0
341     uint32 sampleCount = 0;
342     uint32 timeCount = 0;
343 
344     if ((_psampleDeltaVec == NULL) ||
345             (_psampleCountVec == NULL) ||
346             (_entryCount      == 0))
347     {
348         return PV_ERROR;
349     }
350 
351     for (uint32 i = 0; i < _entryCount; i++)
352     {
353         if (_parsing_mode == 1)
354             CheckAndParseEntry(i);
355 
356         if (ts < timeCount)
357         { // found range that the sample is in - need to backtrack
358             if (_parsing_mode == 1)
359                 CheckAndParseEntry(i - 1);
360 
361             uint32 samples = _psampleCountVec[(i-1)%_stbl_buff_size];
362             sampleCount -= samples;
363             timeCount -= _psampleDeltaVec[(i-1)%_stbl_buff_size] * samples;
364             while (timeCount <= ts)
365             {
366                 timeCount += _psampleDeltaVec[(i-1)%_stbl_buff_size];
367                 sampleCount += 1;
368             }
369 
370             if (timeCount > ts)
371             {
372                 if (sampleCount > 0)
373                 {
374                     sampleCount--;
375                 }
376                 return sampleCount;
377             }
378         }
379         else if (ts == timeCount)
380         { // Found sample at ts
381             return sampleCount;
382         }
383         else
384         { // Sample not yet found - advance
385             uint32 samples = _psampleCountVec[i%_stbl_buff_size]; //number of samples at this index
386             sampleCount += samples;
387             timeCount += _psampleDeltaVec[i%_stbl_buff_size] * samples;
388         }
389     }
390 
391     // Timestamp is in last run of samples (or possibly beyond)
392     // - need to backtrack to beginning of last run to find it
393     uint32 samples = _psampleCountVec[(_entryCount-1)%_stbl_buff_size];
394     uint32 delta = _psampleDeltaVec[(_entryCount-1)%_stbl_buff_size];
395     sampleCount -= samples;
396     timeCount -= delta * samples;
397 
398     for (uint32 count = 0; count < (samples - 1); count++)
399     {
400         timeCount += delta;
401         sampleCount += 1;
402 
403         if (timeCount > ts)
404         {
405             if (sampleCount > 0)
406             {
407                 sampleCount--;
408             }
409             return sampleCount;
410         }
411         else if (timeCount == ts)
412         {
413             return sampleCount;
414         }
415     }
416 
417 
418     sampleCount += 1;
419     if (ts >= timeCount)
420     {
421         if (oAlwaysRetSampleCount)
422         {
423             return sampleCount;
424         }
425         else
426         {
427             if (_mediaType == MEDIA_TYPE_VISUAL)
428             {
429                 return sampleCount;
430             }
431         }
432     }
433 
434     // Went past last sample in last run of samples - not a valid timestamp
435     return PV_ERROR;
436 }
437 
438 // Returns the timestamp (ms) for the current sample given by num.  This is used when
439 // randomly accessing a frame and the timestamp has not been accumulated. It is implicit
440 // that sample[0] occurs at timestamp ts=0.
getTimestampForSampleNumber(uint32 num)441 int32 TimeToSampleAtom::getTimestampForSampleNumber(uint32 num)
442 {
443     if ((_psampleDeltaVec == NULL) ||
444             (_psampleCountVec == NULL) ||
445             (_entryCount == 0))
446     {
447         return PV_ERROR;
448     }
449     // It is assumed that sample 0 has a ts of 0 - i.e. the first
450     // entry in the table starts with the delta between sample 1 and sample 0
451     if (num == 0)
452         return 0;
453 
454     uint32 sampleCount = 0;
455     int32 ts = 0; // Timestamp value to return
456     for (uint32 i = 0; i < _entryCount; i++)
457     {
458         if (_parsing_mode == 1)
459             CheckAndParseEntry(i);
460 
461         if (num <= (sampleCount + _psampleCountVec[i%_stbl_buff_size]))
462         { // Sample num within current entry
463             int32 count = num - sampleCount;
464             ts += _psampleDeltaVec[i%_stbl_buff_size] * count;
465             PVMF_MP4FFPARSER_LOGMEDIASAMPELSTATEVARIABLES((0, "TimeToSampleAtom::getTimestampForSampleNumber- Time Stamp =%d", ts));
466             return ts;
467         }
468         else
469         {
470             sampleCount += _psampleCountVec[i%_stbl_buff_size];
471             ts += (_psampleDeltaVec[i%_stbl_buff_size] * _psampleCountVec[i%_stbl_buff_size]);
472         }
473     }
474 
475     // Went past end of list - not a valid sample number
476     return PV_ERROR;
477 }
478 
479 // Returns the timestamp delta (ms) for the current sample given by num.  This value
480 // is the difference in timestamps between the sample (num) and the previous sample
481 // in the track.  It is implicit that sample[0] occurs at timestamp ts=0.
482 int32
getTimeDeltaForSampleNumber(uint32 num)483 TimeToSampleAtom::getTimeDeltaForSampleNumber(uint32 num)
484 {
485     // It is assumed that sample 0 has a ts of 0 - i.e. the first
486     // entry in the table starts with the delta between sample 1 and sample 0
487     if ((_psampleDeltaVec == NULL) ||
488             (_psampleCountVec == NULL) ||
489             (_entryCount == 0))
490     {
491         return PV_ERROR;
492     }
493 
494     if (num == 0)
495         return 0;
496 
497     uint32 sampleCount = 0;
498     for (uint32 i = 0; i < _entryCount; i++)
499     {
500         if (_parsing_mode == 1)
501             CheckAndParseEntry(i);
502 
503         if (num <= (sampleCount + _psampleCountVec[i%_stbl_buff_size]))
504         { // Sample num within current entry
505             return (_psampleDeltaVec[i%_stbl_buff_size]);
506         }
507         else
508         {
509             sampleCount += _psampleCountVec[i%_stbl_buff_size];
510         }
511     }
512 
513     // Went past end of list - not a valid sample number
514     return PV_ERROR;
515 }
516 
517 
518 
519 
520 // Returns the timestamp delta (ms) for the current sample given by num.  This value
521 // is the difference in timestamps between the sample (num) and the previous sample
522 // in the track.  It is implicit that sample[0] occurs at timestamp ts=0.
523 int32
getTimeDeltaForSampleNumberPeek(uint32 sampleNum)524 TimeToSampleAtom::getTimeDeltaForSampleNumberPeek(uint32 sampleNum)
525 {
526     // It is assumed that sample 0 has a ts of 0 - i.e. the first
527     // entry in the table starts with the delta between sample 1 and sample 0
528     if ((_psampleDeltaVec == NULL) ||
529             (_psampleCountVec == NULL) ||
530             (_entryCount == 0))
531     {
532         return PV_ERROR;
533     }
534 
535     // note that sampleNum is a zero based index while _currGetSampleCount is 1 based index
536     if (sampleNum < _currPeekSampleCount)
537     {
538         return (_currPeekTimeDelta);
539     }
540     else
541     {
542         do
543         {
544             _currPeekIndex++;
545             if (_parsing_mode)
546                 CheckAndParseEntry(_currPeekIndex);
547 
548             _currPeekSampleCount += _psampleCountVec[_currPeekIndex%_stbl_buff_size];
549             _currPeekTimeDelta    = _psampleDeltaVec[_currPeekIndex%_stbl_buff_size];
550         }
551         while (_currPeekSampleCount == 0);
552 
553         PVMF_MP4FFPARSER_LOGMEDIASAMPELSTATEVARIABLES((0, "TimeToSampleAtom::getTimeDeltaForSampleNumberPeek- _currPeekIndex =%d", _currPeekIndex));
554         PVMF_MP4FFPARSER_LOGMEDIASAMPELSTATEVARIABLES((0, "TimeToSampleAtom::getTimeDeltaForSampleNumberPeek- _currPeekSampleCount =%d", _currPeekSampleCount));
555         PVMF_MP4FFPARSER_LOGMEDIASAMPELSTATEVARIABLES((0, "TimeToSampleAtom::getTimeDeltaForSampleNumberPeek- _currPeekTimeDelta =%d", _currPeekTimeDelta));
556 
557         if (sampleNum < _currPeekSampleCount)
558         {
559             return (_currPeekTimeDelta);
560         }
561         else
562         {
563             PVMF_MP4FFPARSER_LOGERROR((0, "ERROR =>TimeToSampleAtom::getTimeDeltaForSampleNumberPeek sampleNum = %d", sampleNum));
564             return (PV_ERROR);
565         }
566     }
567 
568 
569 }
570 
571 // Returns the timestamp delta (ms) for the current sample given by num.  This value
572 // is the difference in timestamps between the sample (num) and the previous sample
573 // in the track.  It is implicit that sample[0] occurs at timestamp ts=0.
574 int32
getTimeDeltaForSampleNumberGet(uint32 sampleNum)575 TimeToSampleAtom::getTimeDeltaForSampleNumberGet(uint32 sampleNum)
576 {
577     // It is assumed that sample 0 has a ts of 0 - i.e. the first
578     // entry in the table starts with the delta between sample 1 and sample 0
579     if ((_psampleDeltaVec == NULL) ||
580             (_psampleCountVec == NULL) ||
581             (_entryCount == 0))
582     {
583         return PV_ERROR;
584     }
585 
586     // note that sampleNum is a zero based index while _currGetSampleCount is 1 based index
587     if (sampleNum < _currGetSampleCount)
588     {
589         return (_currGetTimeDelta);
590     }
591     else
592     {
593 
594         do
595         {
596             _currGetIndex++;
597             if (_parsing_mode)
598                 CheckAndParseEntry(_currGetIndex);
599             _currGetSampleCount += _psampleCountVec[_currGetIndex%_stbl_buff_size];
600             _currGetTimeDelta    = _psampleDeltaVec[_currGetIndex%_stbl_buff_size];
601         }
602         while (_currGetSampleCount == 0);
603 
604         PVMF_MP4FFPARSER_LOGMEDIASAMPELSTATEVARIABLES((0, "TimeToSampleAtom::getTimeDeltaForSampleNumberGet- _currGetIndex =%d", _currGetIndex));
605         PVMF_MP4FFPARSER_LOGMEDIASAMPELSTATEVARIABLES((0, "TimeToSampleAtom::getTimeDeltaForSampleNumberGet- _currGetSampleCount =%d", _currGetSampleCount));
606         PVMF_MP4FFPARSER_LOGMEDIASAMPELSTATEVARIABLES((0, "TimeToSampleAtom::getTimeDeltaForSampleNumberGet- _currGetTimeDelta =%d", _currGetTimeDelta));
607 
608         if (sampleNum < _currGetSampleCount)
609         {
610             return (_currGetTimeDelta);
611         }
612         else
613         {
614             PVMF_MP4FFPARSER_LOGERROR((0, "ERROR =>TimeToSampleAtom::getTimeDeltaForSampleNumberGet sampleNum = %d", sampleNum));
615             return (PV_ERROR);
616         }
617     }
618 
619 
620 }
621 
622 int32
resetStateVariables()623 TimeToSampleAtom::resetStateVariables()
624 {
625     uint32 sampleNum = 0;
626     return (resetStateVariables(sampleNum));
627 }
628 
629 int32
resetStateVariables(uint32 sampleNum)630 TimeToSampleAtom::resetStateVariables(uint32 sampleNum)
631 {
632     _currGetSampleCount = 0;
633     _currGetIndex = -1;
634     _currGetTimeDelta = 0;
635     _currPeekSampleCount = 0;
636     _currPeekIndex = -1;
637     _currPeekTimeDelta = 0;
638 
639     // It is assumed that sample 0 has a ts of 0 - i.e. the first
640     // entry in the table starts with the delta between sample 1 and sample 0
641     if ((_psampleDeltaVec == NULL) ||
642             (_psampleCountVec == NULL) ||
643             (_entryCount == 0))
644     {
645         return PV_ERROR;
646     }
647 
648 
649     for (uint32 i = 0; i < _entryCount; i++)
650     {
651         if (_parsing_mode)
652             CheckAndParseEntry(i);
653 
654         _currPeekIndex++;
655         _currPeekSampleCount += _psampleCountVec[i%_stbl_buff_size];
656         _currPeekTimeDelta    = _psampleDeltaVec[i%_stbl_buff_size];
657 
658         _currGetIndex++;
659         _currGetSampleCount += _psampleCountVec[i%_stbl_buff_size];
660         _currGetTimeDelta    = _psampleDeltaVec[i%_stbl_buff_size];
661 
662         if (sampleNum <= _currPeekSampleCount)
663         {
664             return (EVERYTHING_FINE);
665         }
666 
667     }
668 
669     // Went past end of list - not a valid sample number
670     return PV_ERROR;
671 }
672 
resetPeekwithGet()673 int32 TimeToSampleAtom::resetPeekwithGet()
674 {
675     _currPeekSampleCount = _currGetSampleCount;
676     _currPeekIndex = _currGetIndex ;
677     _currPeekTimeDelta = _currGetTimeDelta;
678     return (EVERYTHING_FINE);
679 }
680 
CheckAndParseEntry(uint32 i)681 void TimeToSampleAtom::CheckAndParseEntry(uint32 i)
682 {
683     if (i >= _parsed_entry_cnt)
684     {
685         ParseEntryUnit(i);
686     }
687     else
688     {
689         uint32 entryLoc = i / _stbl_buff_size;
690         if (_curr_buff_number != entryLoc)
691         {
692             _parsed_entry_cnt = entryLoc * _stbl_buff_size;
693             while (_parsed_entry_cnt <= i)
694                 ParseEntryUnit(_parsed_entry_cnt);
695         }
696     }
697 }
698 
699