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     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