/* * The contents of this file are subject to the Mozilla Public * License Version 1.1 (the "License"); you may not use this file * except in compliance with the License. You may obtain a copy of * the License at http://www.mozilla.org/MPL/ * * Software distributed under the License is distributed on an "AS * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or * implied. See the License for the specific language governing * rights and limitations under the License. * * The Original Code is MPEG4IP. * * The Initial Developer of the Original Code is Cisco Systems Inc. * Portions created by Cisco Systems Inc. are * Copyright (C) Cisco Systems Inc. 2001 - 2004. All Rights Reserved. * * 3GPP features implementation is based on 3GPP's TS26.234-v5.60, * and was contributed by Ximpo Group Ltd. * * Portions created by Ximpo Group Ltd. are * Copyright (C) Ximpo Group Ltd. 2003, 2004. All Rights Reserved. * * Contributor(s): * Dave Mackie dmackie@cisco.com * Ximpo Group Ltd. mp4v2@ximpo.com */ #ifndef __MP4_TRACK_INCLUDED__ #define __MP4_TRACK_INCLUDED__ #include "mp4property.h" // forward declarations class MP4File; class MP4Atom; class MP4Property; class MP4StringProperty; class MP4Track { public: MP4Track(MP4File* pFile, MP4Atom* pTrakAtom); virtual ~MP4Track(); MP4TrackId GetId() { return m_trackId; } const char* GetType(); void SetType(const char* type); MP4File* GetFile() { return m_pFile; } MP4Atom* GetTrakAtom() { return m_pTrakAtom; } void ReadSample( // input parameters MP4SampleId sampleId, // output parameters u_int8_t** ppBytes, u_int32_t* pNumBytes, MP4Timestamp* pStartTime = NULL, MP4Duration* pDuration = NULL, MP4Duration* pRenderingOffset = NULL, bool* pIsSyncSample = NULL); void WriteSample( const u_int8_t* pBytes, u_int32_t numBytes, MP4Duration duration = 0, MP4Duration renderingOffset = 0, bool isSyncSample = true); virtual void FinishWrite(); u_int64_t GetDuration(); // in track timeScale units u_int32_t GetTimeScale(); u_int32_t GetNumberOfSamples(); u_int32_t GetSampleSize(MP4SampleId sampleId); u_int32_t GetMaxSampleSize(); u_int64_t GetTotalOfSampleSizes(); u_int32_t GetAvgBitrate(); // in bps u_int32_t GetMaxBitrate(); // in bps MP4Duration GetFixedSampleDuration(); void SetFixedSampleDuration(MP4Duration duration); void GetSampleTimes(MP4SampleId sampleId, MP4Timestamp* pStartTime, MP4Duration* pDuration); bool IsSyncSample(MP4SampleId sampleId); MP4SampleId GetSampleIdFromTime( MP4Timestamp when, bool wantSyncSample = false, bool rewind = false); MP4ChunkId GetChunkIdFromTime(MP4Timestamp when); MP4Duration GetSampleRenderingOffset(MP4SampleId sampleId); void SetSampleRenderingOffset(MP4SampleId sampleId, MP4Duration renderingOffset); MP4EditId AddEdit( MP4EditId editId = MP4_INVALID_EDIT_ID); void DeleteEdit( MP4EditId editId); MP4Timestamp GetEditStart( MP4EditId editId); MP4Timestamp GetEditTotalDuration( MP4EditId editId); MP4SampleId GetSampleIdFromEditTime( MP4Timestamp editWhen, MP4Timestamp* pStartTime = NULL, MP4Duration* pDuration = NULL); // special operation for use during hint track packet assembly void ReadSampleFragment( MP4SampleId sampleId, u_int32_t sampleOffset, u_int16_t sampleLength, u_int8_t* pDest); // special operations for use during optimization u_int32_t GetNumberOfChunks(); MP4Timestamp GetChunkTime(MP4ChunkId chunkId); void ReadChunk(MP4ChunkId chunkId, u_int8_t** ppChunk, u_int32_t* pChunkSize, MP4Timestamp* pStartTime = NULL, MP4Duration* pDuration = NULL); void RewriteChunk(MP4ChunkId chunkId, u_int8_t* pChunk, u_int32_t chunkSize); protected: bool InitEditListProperties(); FILE* GetSampleFile(MP4SampleId sampleId); u_int64_t GetSampleFileOffset(MP4SampleId sampleId); u_int32_t GetSampleStscIndex(MP4SampleId sampleId); u_int32_t GetChunkStscIndex(MP4ChunkId chunkId); u_int32_t GetChunkSize(MP4ChunkId chunkId); u_int32_t GetSampleCttsIndex(MP4SampleId sampleId, MP4SampleId* pFirstSampleId = NULL); MP4SampleId GetNextSyncSample(MP4SampleId sampleId); MP4SampleId GetSyncSample(MP4SampleId sampleId, bool rewind = false); void UpdateSampleSizes(MP4SampleId sampleId, u_int32_t numBytes); bool IsChunkFull(MP4SampleId sampleId); void UpdateSampleToChunk(MP4SampleId sampleId, MP4ChunkId chunkId, u_int32_t samplesPerChunk); void UpdateChunkOffsets(u_int64_t chunkOffset); void UpdateSampleTimes(MP4Duration duration); void UpdateRenderingOffsets(MP4SampleId sampleId, MP4Duration renderingOffset); void UpdateSyncSamples(MP4SampleId sampleId, bool isSyncSample); MP4Atom* AddAtom(char* parentName, char* childName); void UpdateDurations(MP4Duration duration); MP4Duration ToMovieDuration(MP4Duration trackDuration); void UpdateModificationTimes(); void WriteChunkBuffer(); void CalculateBytesPerSample(); protected: MP4File* m_pFile; MP4Atom* m_pTrakAtom; // moov.trak[] MP4TrackId m_trackId; // moov.trak[].tkhd.trackId MP4StringProperty* m_pTypeProperty; // moov.trak[].mdia.hdlr.handlerType u_int32_t m_lastStsdIndex; FILE* m_lastSampleFile; // for efficient construction of hint track packets MP4SampleId m_cachedReadSampleId; u_int8_t* m_pCachedReadSample; u_int32_t m_cachedReadSampleSize; // for writing MP4SampleId m_writeSampleId; MP4Duration m_fixedSampleDuration; u_int8_t* m_pChunkBuffer; u_int32_t m_chunkBufferSize; u_int32_t m_chunkSamples; MP4Duration m_chunkDuration; // controls for chunking u_int32_t m_samplesPerChunk; MP4Duration m_durationPerChunk; u_int32_t m_bytesPerSample; // controls for AMR chunking int m_isAmr; u_int8_t m_curMode; MP4Integer32Property* m_pTimeScaleProperty; MP4IntegerProperty* m_pTrackDurationProperty; // 32 or 64 bits MP4IntegerProperty* m_pMediaDurationProperty; // 32 or 64 bits MP4IntegerProperty* m_pTrackModificationProperty; // 32 or 64 bits MP4IntegerProperty* m_pMediaModificationProperty; // 32 or 64 bits MP4Integer32Property* m_pStszFixedSampleSizeProperty; MP4Integer32Property* m_pStszSampleCountProperty; void SampleSizePropertyAddValue(uint32_t bytes); uint8_t m_stsz_sample_bits; bool m_have_stz2_4bit_sample; uint8_t m_stz2_4bit_sample_value; MP4IntegerProperty* m_pStszSampleSizeProperty; MP4Integer32Property* m_pStscCountProperty; MP4Integer32Property* m_pStscFirstChunkProperty; MP4Integer32Property* m_pStscSamplesPerChunkProperty; MP4Integer32Property* m_pStscSampleDescrIndexProperty; MP4Integer32Property* m_pStscFirstSampleProperty; MP4Integer32Property* m_pChunkCountProperty; MP4IntegerProperty* m_pChunkOffsetProperty; // 32 or 64 bits MP4Integer32Property* m_pSttsCountProperty; MP4Integer32Property* m_pSttsSampleCountProperty; MP4Integer32Property* m_pSttsSampleDeltaProperty; // for improve sequental timestamp index access u_int32_t m_cachedSttsIndex; MP4SampleId m_cachedSttsSid; MP4Timestamp m_cachedSttsElapsed; MP4Integer32Property* m_pCttsCountProperty; MP4Integer32Property* m_pCttsSampleCountProperty; MP4Integer32Property* m_pCttsSampleOffsetProperty; MP4Integer32Property* m_pStssCountProperty; MP4Integer32Property* m_pStssSampleProperty; MP4Integer32Property* m_pElstCountProperty; MP4IntegerProperty* m_pElstMediaTimeProperty; // 32 or 64 bits MP4IntegerProperty* m_pElstDurationProperty; // 32 or 64 bits MP4Integer16Property* m_pElstRateProperty; MP4Integer16Property* m_pElstReservedProperty; }; MP4ARRAY_DECL(MP4Track, MP4Track*); #endif /* __MP4_TRACK_INCLUDED__ */