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 /*                        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
     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 
    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
    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
    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
    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
    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.
    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
    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
    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
    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
    623 TimeToSampleAtom::resetStateVariables()
    624 {
    625     uint32 sampleNum = 0;
    626     return (resetStateVariables(sampleNum));
    627 }
    628 
    629 int32
    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 
    673 int32 TimeToSampleAtom::resetPeekwithGet()
    674 {
    675     _currPeekSampleCount = _currGetSampleCount;
    676     _currPeekIndex = _currGetIndex ;
    677     _currPeekTimeDelta = _currGetTimeDelta;
    678     return (EVERYTHING_FINE);
    679 }
    680 
    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