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 SampleTableAtom Class                          */
21/*     -------------------------------------------------------------------       */
22/*********************************************************************************/
23/*
24    This SampleTableAtom Class contains all the time and data indexing of the
25    media samples in a track.
26*/
27
28
29#ifndef SAMPLETABLEATOM_H_INCLUDED
30#define SAMPLETABLEATOM_H_INCLUDED
31
32#ifndef OSCL_FILE_IO_H_INCLUDED
33#include "oscl_file_io.h"
34#endif
35
36#ifndef ATOM_H_INCLUDED
37#include "atom.h"
38#endif
39
40#ifndef TIMETOSAMPLEATOM_H_INCLUDED
41#include "timetosampleatom.h"
42#endif
43
44#ifndef COMPOSITIONOFFSETATOM_H_INCLUDED
45#include "compositionoffsetatom.h"
46#endif
47
48#ifndef SAMPLESIZEATOM_H_INCLUDED
49#include "samplesizeatom.h"
50#endif
51
52#ifndef CHUNKOFFSETATOM_H_INCLUDED
53#include "chunkoffsetatom.h"
54#endif
55
56#ifndef SAMPLETOCHUNKATOM_H_INCLUDED
57#include "sampletochunkatom.h"
58#endif
59
60#ifndef SAMPLEDESCRIPTIONATOM_H_INCLUDED
61#include "sampledescriptionatom.h"
62#endif
63
64#ifndef SYNCSAMPLEATOM_H_INCLUDED
65#include "syncsampleatom.h"
66#endif
67
68#ifndef ESDESCRIPTOR_H_INCLUDED
69#include "esdescriptor.h"
70#endif
71
72#ifndef ATOMDEFS_H_INCLUDED
73#include "atomdefs.h"
74#endif
75
76#ifndef OSCL_MEDIA_DATA_H_INCLUDED
77#include "oscl_media_data.h"
78#endif
79
80#ifndef PV_GAU_H_INCLUDED
81#include "pv_gau.h"
82#endif
83
84#ifndef AVCSAMPLEDEPENDENCYTYPE_H_INCLUDED
85#include "avcsampledependencytype.h"
86#endif
87
88#ifndef AVCSAMPLETOGROUPBOX_H_INCLUDED
89#include "avcsampletogroupbox.h"
90#endif
91
92#ifndef AVCSAMPLEDEPENDENCY_H_INCLUDED
93#include "avcsampledependency.h"
94#endif
95
96//Macro to give number of frames that one must go back
97//in order to retrieve sample number corresponding to requested timestamp
98#define BACK_TRAVERSE_FRAME_COUNT 10
99
100class AVCSampleEntry;
101
102class SampleTableAtom : public Atom
103{
104
105    public:
106        SampleTableAtom(MP4_FF_FILE *fp,
107                        uint32 mediaType,
108                        OSCL_wString& filename,
109                        uint32 size,
110                        uint32 type,
111                        bool oPVContentDownloadable = false,
112                        uint32 parsingMode = 0);
113
114        virtual ~SampleTableAtom();
115
116        // Member gets and sets
117        TimeToSampleAtom &getTimeToSampleAtom()
118        {
119            return *_ptimeToSampleAtom;
120        }
121        TimeToSampleAtom &getMutableTimeToSampleAtom()
122        {
123            return *_ptimeToSampleAtom;
124        }
125
126        const SampleDescriptionAtom &getSampleDescriptionAtom() const
127        {
128            return *_psampleDescriptionAtom;
129        }
130        SampleDescriptionAtom &getMutableSampleDescriptionAtom()
131        {
132            return *_psampleDescriptionAtom;
133        }
134
135        SampleSizeAtom &getSampleSizeAtom()
136        {
137            return *_psampleSizeAtom;
138        }
139        SampleSizeAtom &getMutableSampleSizeAtom()
140        {
141            return *_psampleSizeAtom;
142        }
143
144        const SampleToChunkAtom &getSampleToChunkAtom() const
145        {
146            return *_psampleToChunkAtom;
147        }
148        SampleToChunkAtom &getMutableSampleToChunkAtom()
149        {
150            return *_psampleToChunkAtom;
151        }
152
153        const ChunkOffsetAtom &getChunkOffsetAtom() const
154        {
155            return *_pchunkOffsetAtom;
156        }
157        ChunkOffsetAtom &getMutableChunkOffsetAtom()
158        {
159            return *_pchunkOffsetAtom;
160        }
161
162        void  resetPlayBack();
163        void  resetTrackToEOT();
164        int32 resetPlayBackbyTime(int32 time, bool oDependsOn);
165        int32 queryRepositionTime(int32 time, bool oDependsOn, bool bBeforeRequestedTime);
166
167        int32 IsResetNeeded(int32 time);
168
169        uint32 getTimestampForSampleNumber(uint32 sampleNumber);
170        int32 getCttsOffsetForSampleNumber(uint32 sampleNumber);
171        int32 getCttsOffsetForSampleNumberPeek(uint32 sampleNumber);
172        int32 getCttsOffsetForSampleNumberGet(uint32 sampleNumber);
173        int32 getSampleSizeAt(int32 sampleNum)
174        {
175            return getSampleSizeAtom().getSampleSizeAt(sampleNum);
176        }
177
178        // Get the type of SampleEntry atom (i.e. MPEG_SAMPLE_ENTRY, ... '<protocol>', etc.)
179        uint32 getSampleProtocol()
180        {
181            if (_psampleDescriptionAtom != NULL)
182            {
183                return _psampleDescriptionAtom->getSampleProtocol(_SDIndex);
184            }
185            else
186            {
187                return 0;
188            }
189        }
190
191        // Return the ESID for the track - undefined if a HINT track
192        uint32 getESID() const
193        {
194            if (_psampleDescriptionAtom != NULL)
195            {
196                return _psampleDescriptionAtom->getESID(_SDIndex);
197            }
198            else
199            {
200                return 0;
201            }
202        }
203
204        // Return the first ESDescriptor for the track - undefined if a HINT track
205        const ESDescriptor *getESDescriptor() const
206        {
207            if (_psampleDescriptionAtom != NULL)
208            {
209                return _psampleDescriptionAtom->getESDescriptor(_SDIndex);
210            }
211            else
212            {
213                return NULL;
214            }
215        }
216
217        uint32 getNumSampleEntries()
218        {
219            if (_psampleDescriptionAtom != NULL)
220            {
221                return _psampleDescriptionAtom->getNumSampleEntries();
222            }
223            else
224            {
225                return 0;
226            }
227        }
228
229        uint32 getMaxBufferSizeDB() const
230        {
231            if (_psampleDescriptionAtom != NULL)
232            {
233                return _psampleDescriptionAtom->getMaxBufferSizeDB();
234            }
235            else
236            {
237                return 0;
238            }
239        }
240
241        // Getting and setting the Mpeg4 VOL header
242        DecoderSpecificInfo *getDecoderSpecificInfo() const
243        {
244            if (_psampleDescriptionAtom != NULL)
245            {
246                return _psampleDescriptionAtom->getDecoderSpecificInfo(_SDIndex);
247            }
248            else
249            {
250                return NULL;
251            }
252        }
253
254        DecoderSpecificInfo *getDecoderSpecificInfoForSDI(uint32 index) const
255        {
256            if (_psampleDescriptionAtom != NULL)
257            {
258                return _psampleDescriptionAtom->getDecoderSpecificInfo(index);
259            }
260            else
261            {
262                return NULL;
263            }
264        }
265
266        void getMIMEType(OSCL_String& aMimeType)
267        {
268            if (_psampleDescriptionAtom != NULL)
269            {
270                _psampleDescriptionAtom->getMIMEType(aMimeType);
271            }
272        }
273
274        uint8  getObjectTypeIndication()
275        {
276            if (_psampleDescriptionAtom != NULL)
277            {
278                return _psampleDescriptionAtom->getObjectTypeIndication();
279            }
280            else
281            {
282                return 0;
283            }
284        }
285
286
287        int32 getAverageBitrate()
288        {
289            if (_psampleDescriptionAtom != NULL)
290            {
291                return _psampleDescriptionAtom->getAverageBitrate();
292            }
293            else
294            {
295                return 0;
296            }
297        }
298
299        int32 getHeight()
300        {
301            if (_psampleDescriptionAtom != NULL)
302            {
303                return _psampleDescriptionAtom->getHeight();
304            }
305            else
306            {
307                return 0;
308            }
309
310        }
311
312        int32 getWidth()
313        {
314            if (_psampleDescriptionAtom != NULL)
315            {
316                return _psampleDescriptionAtom->getWidth();
317            }
318            else
319            {
320                return 0;
321            }
322        }
323
324        //PASP
325        uint32 getHspacing()
326        {
327            if (_psampleDescriptionAtom != NULL)
328            {
329                return _psampleDescriptionAtom->getHspacing();
330            }
331            else
332            {
333                return 0;
334            }
335        }
336
337        uint32 getVspacing()
338        {
339            if (_psampleDescriptionAtom != NULL)
340            {
341                return _psampleDescriptionAtom->getVspacing();
342            }
343            else
344            {
345                return 0;
346            }
347        }
348
349        // Gets for optional member atoms
350        int32 getTimestampForRandomAccessPoints(uint32 *num, uint32 *tsBuf, uint32* numBuf, uint32* offsetBuf);
351        const SyncSampleAtom *getSyncSampleAtom() const
352        {
353            return _psyncSampleAtom;
354        }
355
356        // Returns next video frame
357        int32 getNextSample(uint8 *buf, int32 &size, uint32 &index, uint32 &SampleOffset);
358
359        int32 getMediaSample(uint32 sampleNumber, uint8 *buf, int32 &size, uint32 &index, uint32 &SampleOffset);
360
361        // Returns next I-frame at time ts (in milliseconds) - or the very next I-frame in the stream
362        int32 getNextSampleAtTime(uint32 ts, uint8 *buf, int32 &size, uint32 &index, uint32 &SampleOffset);
363
364        MP4_ERROR_CODE getKeyMediaSampleNumAt(uint32 aKeySampleNum,
365                                              GAU    *pgau);
366        int32 getPrevKeyMediaSample(uint32 inputtimestamp, uint32 &aKeySampleNum, uint32 *n, GAU    *pgau);
367        int32 getNextKeyMediaSample(uint32 inputtimestamp, uint32 &aKeySampleNum, uint32 *n, GAU    *pgau);
368
369        // Returns the timestamp (in milliseconds) for the last sample returned
370        // This is mainly to be used when seeking in the bitstream - you request a frame at timestamp
371        // X, but the actual frame you get is Y, this method returns the timestamp for Y so you know which
372        // audio sample to request.
373        int32 getTimestampForCurrentSample();
374
375        // Returns the sample number of the last samplle returned
376        // Used when requesting a hint sample for a specific randomly accessed sample
377        int32 getSampleNumberForCurrentSample()
378        {
379            return _currentPlaybackSampleNumber;
380        }
381        int32 getSampleNumberAdjustedWithCTTS(uint32 aTs, int32 aSampleNumber);
382
383        void advance()
384        {
385            _currentPlaybackSampleNumber++;    // Advances the currentPlayback number
386        }
387        void advance(int32 sampleNum)
388        {
389            _currentPlaybackSampleNumber = sampleNum;    // Advances the currentPlayback number to sampleNum
390        }
391        void seek(int32 baseLayerSampleNum); // Seeks to the base-layer sample in the hint track
392
393
394        // TS offset value for the start of the media track.  The STTS
395        // Atom only holds TS deltas.  For a track that does not begin at 0s, we need to hold an
396        // offset timestamp value.
397        void setTrackTSOffset(uint32 ts)
398        {
399            _trackStartTSOffset = ts;
400        }
401
402        int32 updateFileSize(uint32 filesize);
403
404        uint32 getSampleDescriptionIndex()
405        {
406            return _SDIndex;
407        }
408
409        int32 getNextBundledAccessUnits(uint32 *n,
410                                        GAU    *pgau);
411
412        int32 peekNextBundledAccessUnits(uint32 *n,
413                                         MediaMetaInfo *mInfo);
414
415        int32 getNextNSamples(uint32 startSampleNum,
416                              uint32 *n,
417                              GAU *pgau);
418
419
420        int32 peekNextNSamples(uint32 startSampleNum,
421                               uint32 *n,
422                               MediaMetaInfo    *mInfo);
423
424        uint32 getSampleCount()
425        {
426            if (_psampleSizeAtom != NULL)
427            {
428                return (_psampleSizeAtom->getSampleCount());
429            }
430            else
431            {
432                return 0;
433            }
434        }
435
436        bool IsSyncSample(uint32 sampleNum)
437        {
438            if (_psyncSampleAtom != NULL)
439            {
440                return (_psyncSampleAtom->IsSyncSample(sampleNum));
441            }
442            else
443            {
444                return false;
445            }
446        }
447
448        uint32 getNumKeyFrames()
449        {
450            if (_psyncSampleAtom != NULL)
451            {
452                return (_psyncSampleAtom->getEntryCount());
453            }
454            else
455            {
456                if (_psampleSizeAtom != NULL)
457                {
458                    return (_psampleSizeAtom->getSampleCount());
459                }
460                else
461                    return 0;
462            }
463        }
464        SampleEntry *getTextSampleEntryAt(uint32 index)
465        {
466            if (_psampleDescriptionAtom != NULL)
467            {
468                return (_psampleDescriptionAtom->getTextSampleEntryAt(index));
469            }
470            else
471            {
472                return NULL;
473            }
474        }
475
476        int32 getOffsetByTime(uint32 ts, int32* sampleFileOffset);
477
478        int32 getNumAMRFramesPerSample()
479        {
480            return _numAMRFramesPerSample;
481        }
482
483        MP4_ERROR_CODE getMaxTrackTimeStamp(uint32 fileSize, uint32& timeStamp);
484
485        MP4_ERROR_CODE getSampleNumberClosestToTimeStamp(uint32 &sampleNumber,
486                uint32 timeStamp,
487                uint32 sampleOffset = 0);
488
489        AVCSampleEntry* getAVCSampleEntry(uint32 index)
490        {
491            if (_psampleDescriptionAtom != NULL)
492            {
493                return (_psampleDescriptionAtom->getAVCSampleEntry(index));
494            }
495            return (NULL);
496        }
497
498        uint32 getAVCNALLengthSize(uint32 index)
499        {
500            if (_psampleDescriptionAtom != NULL)
501            {
502                return (_psampleDescriptionAtom->getAVCNALLengthSize(index));
503            }
504            return 0;
505        }
506
507        uint32 getNumAVCSampleEntries()
508        {
509            if (_psampleDescriptionAtom != NULL)
510            {
511                return (_psampleDescriptionAtom->getNumAVCSampleEntries());
512            }
513            return 0;
514        }
515        bool isMultipleSampleDescriptionAvailable()
516        {
517            return _oMultipleSampleDescription;
518        }
519
520        int32 getSample(uint32 sampleNum, uint8 *buf, int32 &size, uint32 &index, uint32 &SampleOffset);
521        int32 getTimestampForRandomAccessPointsBeforeAfter(uint32 ts, uint32 *tsBuf, uint32* numBuf,
522                uint32& numsamplestoget,
523                uint32 howManyKeySamples);
524
525        uint32 getTrackLevelOMA2DRMInfoSize()
526        {
527            if (_psampleDescriptionAtom != NULL)
528            {
529                return (_psampleDescriptionAtom->getTrackLevelOMA2DRMInfoSize());
530            }
531            return 0;
532        }
533
534        uint8* getTrackLevelOMA2DRMInfo()
535        {
536            if (_psampleDescriptionAtom != NULL)
537            {
538                return (_psampleDescriptionAtom->getTrackLevelOMA2DRMInfo());
539            }
540            return NULL;
541        }
542
543    private:
544
545        TimeToSampleAtom        *_ptimeToSampleAtom;
546        CompositionOffsetAtom   *_pcompositionOffsetAtom;
547        SampleDescriptionAtom *_psampleDescriptionAtom;
548        SampleSizeAtom        *_psampleSizeAtom;
549        SampleToChunkAtom     *_psampleToChunkAtom;
550        ChunkOffsetAtom       *_pchunkOffsetAtom;
551        AVCSampleDependencyType *_pavcSampleDependencyType;
552        AVCSampleToGroup        *_pavcSampleToGroup;
553        AVCSampleDependency     *_pavcSampleDependency;
554
555        // Optional member atoms
556        SyncSampleAtom        *_psyncSampleAtom;
557
558        uint32 _currentPlaybackSampleTimestamp;
559        int32 _currentPlaybackSampleNumber;
560
561        // TS offset value for the start of the media track.  The STTS
562        // Atom only holds TS deltas.  For a track that does not begin at 0s, we need to hold an
563        // offset timestamp value.
564        uint32 _trackStartTSOffset;
565
566        uint32 _SDIndex;
567
568        OSCL_wHeapString<OsclMemAllocator> _filename;
569        MP4_FF_FILE *_pinput;
570
571        uint32  _fileSize;
572        uint32  _IsUpdateFileSize;
573
574        int32 _numAMRFramesPerSample;
575
576        uint8 *_pAMRTempBuffer;
577        bool  _oResidualSample;
578        int32 _remainingFramesInSample;
579        uint32 _amrTempBufferOffset;
580        int32  _amrFrameDelta;
581        int32  _amrFrameTimeStamp;
582        int32  _amrSampleSize;
583
584        uint32 SamplesCount;
585        MP4_FF_FILE *_commonFilePtr;
586
587        bool _oPVContentDownloadable;
588        uint32 _parsingMode;
589        PVLogger *iLogger, *iStateVarLogger, *iParsedDataLogger, *iDiagnosticsLogger;
590        bool _oMultipleSampleDescription;
591
592        OSCL_wStackString<16> _defaultMimeType;
593        uint32 _currChunkOffset;
594
595};
596
597#endif // SAMPLETABLEATOM_H_INCLUDED
598
599