/*
 * 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 - 2005.  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
 *              Alix Marchandise-Franquet alix@cisco.com
 *              Ximpo Group Ltd.          mp4v2@ximpo.com
 *              Bill May                  wmay@cisco.com
 */

#include "src/impl.h"

namespace mp4v2 { namespace impl {

///////////////////////////////////////////////////////////////////////////////

MP4File::MP4File( ) :
    m_file             ( NULL )
    , m_fileOriginalSize ( 0 )
    , m_createFlags      ( 0 )
{
    this->Init();
}

/**
 * Initialize member variables (shared among constructors)
 */
void MP4File::Init()
{
    m_pRootAtom = NULL;
    m_odTrackId = MP4_INVALID_TRACK_ID;

    m_useIsma = false;

    m_pModificationProperty = NULL;
    m_pTimeScaleProperty = NULL;
    m_pDurationProperty = NULL;

    m_memoryBuffer = NULL;
    m_memoryBufferSize = 0;
    m_memoryBufferPosition = 0;
    m_initialSeekOffset = 0;

    m_numReadBits = 0;
    m_bufReadBits = 0;
    m_numWriteBits = 0;
    m_bufWriteBits = 0;
    m_editName = NULL;
    m_trakName[0] = '\0';
}

MP4File::~MP4File()
{
    delete m_pRootAtom;
    for( uint32_t i = 0; i < m_pTracks.Size(); i++ )
        delete m_pTracks[i];
    MP4Free( m_memoryBuffer ); // just in case
    CHECK_AND_FREE( m_editName );
    delete m_file;
}

const std::string &
MP4File::GetFilename() const
{
    // No one should call this unless Read, etc. has
    // succeeded and m_file exists since this method really
    // only exists for the public API.  This helps us
    // guarantee that MP4GetFilename always returns a valid
    // string given a valid MP4FileHandle
    ASSERT(m_file);
    return m_file->name;
}

void MP4File::Read( const char* name, const MP4FileProvider* provider )
{
    Open( name, File::MODE_READ, provider );
    ReadFromFile();
    CacheProperties();
}

void MP4File::Create( const char*            fileName,
                      uint32_t               flags,
                      const MP4FileProvider* provider,
                      int                    add_ftyp,
                      int                    add_iods,
                      char*                  majorBrand,
                      uint32_t               minorVersion,
                      char**                 supportedBrands,
                      uint32_t               supportedBrandsCount )
{
    m_createFlags = flags;
    Open( fileName, File::MODE_CREATE, provider );

    // generate a skeletal atom tree
    m_pRootAtom = MP4Atom::CreateAtom(*this, NULL, NULL);
    m_pRootAtom->Generate();

    if (add_ftyp != 0) {
        MakeFtypAtom(majorBrand, minorVersion,
                     supportedBrands, supportedBrandsCount);
    }

    CacheProperties();

    // create mdat, and insert it after ftyp, and before moov
    (void)InsertChildAtom(m_pRootAtom, "mdat",
                          add_ftyp != 0 ? 1 : 0);

    // start writing
    m_pRootAtom->BeginWrite();
    if (add_iods != 0) {
        (void)AddChildAtom("moov", "iods");
    }
}

bool MP4File::Use64Bits (const char *atomName)
{
    uint32_t atomid = ATOMID(atomName);
    if (atomid == ATOMID("mdat") || atomid == ATOMID("stbl")) {
        return (m_createFlags & MP4_CREATE_64BIT_DATA) == MP4_CREATE_64BIT_DATA;
    }
    if (atomid == ATOMID("mvhd") ||
            atomid == ATOMID("tkhd") ||
            atomid == ATOMID("mdhd")) {
        return (m_createFlags & MP4_CREATE_64BIT_TIME) == MP4_CREATE_64BIT_TIME;
    }
    return false;
}

void MP4File::Check64BitStatus (const char *atomName)
{
    uint32_t atomid = ATOMID(atomName);

    if (atomid == ATOMID("mdat") || atomid == ATOMID("stbl")) {
        m_createFlags |= MP4_CREATE_64BIT_DATA;
    } else if (atomid == ATOMID("mvhd") ||
               atomid == ATOMID("tkhd") ||
               atomid == ATOMID("mdhd")) {
        m_createFlags |= MP4_CREATE_64BIT_TIME;
    }
}


bool MP4File::Modify( const char* fileName )
{
    Open( fileName, File::MODE_MODIFY, NULL );
    ReadFromFile();

    // find the moov atom
    MP4Atom* pMoovAtom = m_pRootAtom->FindAtom("moov");
    uint32_t numAtoms;

    if (pMoovAtom == NULL) {
        // there isn't one, odd but we can still proceed
        log.warningf("%s: \"%s\": no moov atom, can't modify",
                     __FUNCTION__, GetFilename().c_str());
        return false;
        //pMoovAtom = AddChildAtom(m_pRootAtom, "moov");
    } else {
        numAtoms = m_pRootAtom->GetNumberOfChildAtoms();

        // work backwards thru the top level atoms
        int32_t i;
        bool lastAtomIsMoov = true;
        MP4Atom* pLastAtom = NULL;

        for (i = numAtoms - 1; i >= 0; i--) {
            MP4Atom* pAtom = m_pRootAtom->GetChildAtom(i);
            const char* type = pAtom->GetType();

            // get rid of any trailing free or skips
            if (!strcmp(type, "free") || !strcmp(type, "skip")) {
                m_pRootAtom->DeleteChildAtom(pAtom);
                // Make sure to deallocate the atom before removing.
                delete pAtom;
                continue;
            }

            if (strcmp(type, "moov")) {
                if (pLastAtom == NULL) {
                    pLastAtom = pAtom;
                    lastAtomIsMoov = false;
                }
                continue;
            }

            // now at moov atom

            // multiple moov atoms?!?
            if (pAtom != pMoovAtom) {
                throw new Exception(
                    "Badly formed mp4 file, multiple moov atoms",
                    __FILE__,__LINE__,__FUNCTION__);
            }

            if (lastAtomIsMoov) {
                // position to start of moov atom,
                // effectively truncating file
                // prior to adding new mdat
                SetPosition(pMoovAtom->GetStart());

            } else { // last atom isn't moov
                // need to place a free atom
                MP4Atom* pFreeAtom = MP4Atom::CreateAtom(*this, NULL, "free");

                // in existing position of the moov atom
                m_pRootAtom->InsertChildAtom(pFreeAtom, i);
                m_pRootAtom->DeleteChildAtom(pMoovAtom);
                m_pRootAtom->AddChildAtom(pMoovAtom);

                // write free atom to disk
                SetPosition(pMoovAtom->GetStart());
                pFreeAtom->SetSize(pMoovAtom->GetSize());
                pFreeAtom->Write();

                // finally set our file position to the end of the last atom
                SetPosition(pLastAtom->GetEnd());
            }

            break;
        }
        ASSERT(i != -1);
    }

    CacheProperties();  // of moov atom

    numAtoms = m_pRootAtom->GetNumberOfChildAtoms();

    // insert another mdat prior to moov atom (the last atom)
    MP4Atom* pMdatAtom = InsertChildAtom(m_pRootAtom, "mdat", numAtoms - 1);

    // start writing new mdat
    pMdatAtom->BeginWrite(Use64Bits("mdat"));
    return true;
}

void MP4File::Optimize( const char* srcFileName, const char* dstFileName )
{
    File* src = NULL;
    File* dst = NULL;

    // compute destination filename
    string dname;
    if( dstFileName ) {
        dname = dstFileName;
    } else {
        // No destination given, so let's kludge together a temporary file.
        // We'll try to create it in the same directory as the srcFileName, since
        // it's more likely that directory is writable.  In the absence of that,
        // we'll create it in "./", which is the default pathnameTemp() provides.
        string s(srcFileName);
        size_t pos = s.find_last_of("\\/");
        const char *d;
        if (pos == string::npos) {
            d = ".";
        } else {
            s = s.substr(0, pos);
            d = s.c_str();
        }
        FileSystem::pathnameTemp( dname, d, "tmp", ".mp4" );
    }

    try {
        // file source to optimize
        Open( srcFileName, File::MODE_READ, NULL );
        ReadFromFile();
        CacheProperties(); // of moov atom

        src = m_file;
        m_file = NULL;

        // optimized file destination
        Open( dname.c_str(), File::MODE_CREATE, NULL );
        dst = m_file;

        SetIntegerProperty( "moov.mvhd.modificationTime", MP4GetAbsTimestamp() );

        // writing meta info in the optimal order
        ((MP4RootAtom*)m_pRootAtom)->BeginOptimalWrite();

        // write data in optimal order
        RewriteMdat( *src, *dst );

        // finish writing
        ((MP4RootAtom*)m_pRootAtom)->FinishOptimalWrite();

    }
    catch (...) {
        // cleanup and rethrow.  Without this, we'd leak memory and an open file handle(s).
       if(src == NULL && dst == NULL)
            delete m_file;// We didn't make it far enough to have m_file go to src or dst.

        m_file = NULL;
        delete dst;
        delete src;
        throw;
    }

    // cleanup
    delete dst;
    delete src;
    m_file = NULL;

    // move temporary file into place
    if( !dstFileName )
        Rename( dname.c_str(), srcFileName );
}

void MP4File::RewriteMdat( File& src, File& dst )
{
    uint32_t numTracks = m_pTracks.Size();

    MP4ChunkId* chunkIds = new MP4ChunkId[numTracks];
    MP4ChunkId* maxChunkIds = new MP4ChunkId[numTracks];
    MP4Timestamp* nextChunkTimes = new MP4Timestamp[numTracks];

    for( uint32_t i = 0; i < numTracks; i++ ) {
        chunkIds[i] = 1;
        maxChunkIds[i] = m_pTracks[i]->GetNumberOfChunks();
        nextChunkTimes[i] = MP4_INVALID_TIMESTAMP;
    }

    for( ;; ) {
        uint32_t nextTrackIndex = (uint32_t)-1;
        MP4Timestamp nextTime = MP4_INVALID_TIMESTAMP;

        for( uint32_t i = 0; i < numTracks; i++ ) {
            if( chunkIds[i] > maxChunkIds[i] )
                continue;

            if( nextChunkTimes[i] == MP4_INVALID_TIMESTAMP ) {
                MP4Timestamp chunkTime = m_pTracks[i]->GetChunkTime( chunkIds[i] );
                nextChunkTimes[i] = MP4ConvertTime( chunkTime, m_pTracks[i]->GetTimeScale(), GetTimeScale() );
            }

            // time is not earliest so far
            if( nextChunkTimes[i] > nextTime )
                continue;

            // prefer hint tracks to media tracks if times are equal
            if( nextChunkTimes[i] == nextTime && strcmp( m_pTracks[i]->GetType(), MP4_HINT_TRACK_TYPE ))
                continue;

            // this is our current choice of tracks
            nextTime = nextChunkTimes[i];
            nextTrackIndex = i;
        }

        if( nextTrackIndex == (uint32_t)-1 )
            break;

        uint8_t* pChunk;
        uint32_t chunkSize;

        // point into original mp4 file for read chunk call
        m_file = &src;
        m_pTracks[nextTrackIndex]->ReadChunk( chunkIds[nextTrackIndex], &pChunk, &chunkSize );

        // point back at the new mp4 file for write chunk
        m_file = &dst;
        m_pTracks[nextTrackIndex]->RewriteChunk( chunkIds[nextTrackIndex], pChunk, chunkSize );

        MP4Free( pChunk );

        chunkIds[nextTrackIndex]++;
        nextChunkTimes[nextTrackIndex] = MP4_INVALID_TIMESTAMP;
    }

    delete [] chunkIds;
    delete [] maxChunkIds;
    delete [] nextChunkTimes;
}

void MP4File::Open( const char* name, File::Mode mode, const MP4FileProvider* provider )
{
    ASSERT( !m_file );

    m_file = new File( name, mode, provider ? new io::CustomFileProvider( *provider ) : NULL );
    if( m_file->open() ) {
        ostringstream msg;
        msg << "open(" << name << ") failed";
        throw new Exception( msg.str(), __FILE__, __LINE__, __FUNCTION__);
    }

    switch( mode ) {
        case File::MODE_READ:
        case File::MODE_MODIFY:
            m_fileOriginalSize = m_file->size;
            break;

        case File::MODE_CREATE:
        default:
            m_fileOriginalSize = 0;
            break;
    }
}

void MP4File::ReadFromFile()
{
    // ensure we start at beginning of file or at specified seek offset.
    SetPosition(m_initialSeekOffset);

    // create a new root atom
    ASSERT(m_pRootAtom == NULL);
    m_pRootAtom = MP4Atom::CreateAtom(*this, NULL, NULL);

    uint64_t fileSize = GetSize();

    m_pRootAtom->SetStart(0);
    m_pRootAtom->SetSize(fileSize);
    m_pRootAtom->SetEnd(fileSize);

    m_pRootAtom->Read();

    // create MP4Track's for any tracks in the file
    GenerateTracks();
}

void MP4File::GenerateTracks()
{
    uint32_t trackIndex = 0;

    while (true) {
        char trackName[32];
        snprintf(trackName, sizeof(trackName), "moov.trak[%u]", trackIndex);

        // find next trak atom
        MP4Atom* pTrakAtom = m_pRootAtom->FindAtom(trackName);

        // done, no more trak atoms
        if (pTrakAtom == NULL) {
            break;
        }

        // find track id property
        MP4Integer32Property* pTrackIdProperty = NULL;
        (void)pTrakAtom->FindProperty(
            "trak.tkhd.trackId",
            (MP4Property**)&pTrackIdProperty);

        // find track type property
        MP4StringProperty* pTypeProperty = NULL;
        (void)pTrakAtom->FindProperty(
            "trak.mdia.hdlr.handlerType",
            (MP4Property**)&pTypeProperty);

        // ensure we have the basics properties
        if (pTrackIdProperty && pTypeProperty) {

            m_trakIds.Add(pTrackIdProperty->GetValue());

            MP4Track* pTrack = NULL;
            try {
                if (!strcmp(pTypeProperty->GetValue(), MP4_HINT_TRACK_TYPE)) {
                    pTrack = new MP4RtpHintTrack(*this, *pTrakAtom);
                } else {
                    pTrack = new MP4Track(*this, *pTrakAtom);
                }
                m_pTracks.Add(pTrack);
            }
            catch( Exception* x ) {
                log.errorf(*x);
                delete x;
            }

            // remember when we encounter the OD track
            if (pTrack && !strcmp(pTrack->GetType(), MP4_OD_TRACK_TYPE)) {
                if (m_odTrackId == MP4_INVALID_TRACK_ID) {
                    m_odTrackId = pTrackIdProperty->GetValue();
                } else {
                    log.warningf("%s: \"%s\": multiple OD tracks present",
                                 __FUNCTION__, GetFilename().c_str() );
                }
            }
        } else {
            m_trakIds.Add(0);
        }

        trackIndex++;
    }
}

void MP4File::CacheProperties()
{
    FindIntegerProperty("moov.mvhd.modificationTime",
                        (MP4Property**)&m_pModificationProperty);

    FindIntegerProperty("moov.mvhd.timeScale",
                        (MP4Property**)&m_pTimeScaleProperty);

    FindIntegerProperty("moov.mvhd.duration",
                        (MP4Property**)&m_pDurationProperty);
}

void MP4File::BeginWrite()
{
    m_pRootAtom->BeginWrite();
}

void MP4File::FinishWrite(uint32_t options)
{
    // remove empty moov.udta.meta.ilst
    {
        MP4Atom* ilst = FindAtom( "moov.udta.meta.ilst" );
        if( ilst ) {
            if( ilst->GetNumberOfChildAtoms() == 0 ) {
                ilst->GetParentAtom()->DeleteChildAtom( ilst );
                delete ilst;
            }
        }
    }

    // remove empty moov.udta.meta
    {
        MP4Atom* meta = FindAtom( "moov.udta.meta" );
        if( meta ) {
            if( meta->GetNumberOfChildAtoms() == 0 ) {
                meta->GetParentAtom()->DeleteChildAtom( meta );
                delete meta;
            }
            else if( meta->GetNumberOfChildAtoms() == 1 ) {
                if( ATOMID( meta->GetChildAtom( 0 )->GetType() ) == ATOMID( "hdlr" )) {
                    meta->GetParentAtom()->DeleteChildAtom( meta );
                    delete meta;
                }
            }
        }
    }

    // remove empty moov.udta.name
    {
        MP4Atom* name = FindAtom( "moov.udta.name" );
        if( name ) {
            unsigned char *val = NULL;
            uint32_t valSize = 0;
            GetBytesProperty("moov.udta.name.value", (uint8_t**)&val, &valSize);
            if( valSize == 0 ) {
                name->GetParentAtom()->DeleteChildAtom( name );
                delete name;
            }
        }
    }

    // remove empty moov.udta
    {
        MP4Atom* udta = FindAtom( "moov.udta" );
        if( udta ) {
            if( udta->GetNumberOfChildAtoms() == 0 ) {
                udta->GetParentAtom()->DeleteChildAtom( udta );
                delete udta;
            }
        }
    }

    // for all tracks, flush chunking buffers
    for( uint32_t i = 0; i < m_pTracks.Size(); i++ ) {
        ASSERT( m_pTracks[i] );
        m_pTracks[i]->FinishWrite(options);
    }

    // ask root atom to write
    m_pRootAtom->FinishWrite();

    // finished all writes, if position < size then file has shrunk and
    // we mark remaining bytes as free atom; otherwise trailing garbage remains.
    if( GetPosition() < GetSize() ) {
        MP4RootAtom* root = (MP4RootAtom*)FindAtom( "" );
        ASSERT( root );

        // compute size of free atom; always has 8 bytes of overhead
        uint64_t size = GetSize() - GetPosition();
        if( size < 8 )
            size = 0;
        else
            size -= 8;

        MP4FreeAtom* freeAtom = (MP4FreeAtom*)MP4Atom::CreateAtom( *this, NULL, "free" );
        ASSERT( freeAtom );
        freeAtom->SetSize( size );
        root->AddChildAtom( freeAtom );
        freeAtom->Write();
    }
}

void MP4File::UpdateDuration(MP4Duration duration)
{
    MP4Duration currentDuration = GetDuration();
    if (duration > currentDuration) {
        SetDuration(duration);
    }
}

void MP4File::Dump( bool dumpImplicits )
{
    log.dump(0, MP4_LOG_VERBOSE1, "\"%s\": Dumping meta-information...", m_file->name.c_str() );
    m_pRootAtom->Dump( 0, dumpImplicits);
}

void MP4File::Close(uint32_t options)
{
    if( IsWriteMode() ) {
        SetIntegerProperty( "moov.mvhd.modificationTime", MP4GetAbsTimestamp() );
        FinishWrite(options);
    }

    delete m_file;
    m_file = NULL;
}

void MP4File::SetInitialSeekOffset(int64_t seekOffset) {
    m_initialSeekOffset = seekOffset;
}

void MP4File::Rename(const char* oldFileName, const char* newFileName)
{
    if( FileSystem::rename( oldFileName, newFileName ))
        throw new PlatformException( sys::getLastErrorStr(), sys::getLastError(), __FILE__, __LINE__, __FUNCTION__ );
}

void MP4File::ProtectWriteOperation(const char* file,
                                    int         line,
                                    const char* func )
{
    if( !IsWriteMode() )
        throw new Exception( "operation not permitted in read mode", file, line, func );
}

MP4Track* MP4File::GetTrack(MP4TrackId trackId)
{
    return m_pTracks[FindTrackIndex(trackId)];
}

MP4Atom* MP4File::FindAtom(const char* name)
{
    MP4Atom* pAtom = NULL;
    if (!name || !strcmp(name, "")) {
        pAtom = m_pRootAtom;
    } else {
        pAtom = m_pRootAtom->FindAtom(name);
    }
    return pAtom;
}

MP4Atom* MP4File::AddChildAtom(
    const char* parentName,
    const char* childName)
{
    return AddChildAtom(FindAtom(parentName), childName);
}

MP4Atom* MP4File::AddChildAtom(
    MP4Atom* pParentAtom,
    const char* childName)
{
    return InsertChildAtom(pParentAtom, childName,
                           pParentAtom->GetNumberOfChildAtoms());
}

MP4Atom* MP4File::InsertChildAtom(
    const char* parentName,
    const char* childName,
    uint32_t index)
{
    return InsertChildAtom(FindAtom(parentName), childName, index);
}

MP4Atom* MP4File::InsertChildAtom(
    MP4Atom* pParentAtom,
    const char* childName,
    uint32_t index)
{
    MP4Atom* pChildAtom = MP4Atom::CreateAtom(*this, pParentAtom, childName);

    ASSERT(pParentAtom);
    pParentAtom->InsertChildAtom(pChildAtom, index);

    pChildAtom->Generate();

    return pChildAtom;
}

MP4Atom* MP4File::AddDescendantAtoms(
    const char* ancestorName,
    const char* descendantNames)
{
    return AddDescendantAtoms(FindAtom(ancestorName), descendantNames);
}

MP4Atom* MP4File::AddDescendantAtoms(
    MP4Atom* pAncestorAtom, const char* descendantNames)
{
    ASSERT(pAncestorAtom);

    MP4Atom* pParentAtom = pAncestorAtom;
    MP4Atom* pChildAtom = NULL;

    while (true) {
        char* childName = MP4NameFirst(descendantNames);

        if (childName == NULL) {
            break;
        }

        descendantNames = MP4NameAfterFirst(descendantNames);

        pChildAtom = pParentAtom->FindChildAtom(childName);

        if (pChildAtom == NULL) {
            pChildAtom = AddChildAtom(pParentAtom, childName);
        }

        pParentAtom = pChildAtom;

        MP4Free(childName);
    }

    return pChildAtom;
}

bool MP4File::FindProperty(const char* name,
                           MP4Property** ppProperty, uint32_t* pIndex)
{
    if( pIndex )
        *pIndex = 0; // set the default answer for index
    return m_pRootAtom->FindProperty(name, ppProperty, pIndex);
}

void MP4File::FindIntegerProperty(const char* name,
                                  MP4Property** ppProperty, uint32_t* pIndex)
{
    if (!FindProperty(name, ppProperty, pIndex)) {
        ostringstream msg;
        msg << "no such property - " << name;
        throw new Exception(msg.str(), __FILE__, __LINE__, __FUNCTION__);
    }

    switch ((*ppProperty)->GetType()) {
    case Integer8Property:
    case Integer16Property:
    case Integer24Property:
    case Integer32Property:
    case Integer64Property:
        break;
    default:
        ostringstream msg;
        msg << "type mismatch - property " << name << " type " << (*ppProperty)->GetType();
        throw new Exception(msg.str(), __FILE__, __LINE__, __FUNCTION__);
    }
}

uint64_t MP4File::GetIntegerProperty(const char* name)
{
    MP4Property* pProperty;
    uint32_t index;

    FindIntegerProperty(name, &pProperty, &index);

    return ((MP4IntegerProperty*)pProperty)->GetValue(index);
}

void MP4File::SetIntegerProperty(const char* name, uint64_t value)
{
    ProtectWriteOperation(__FILE__, __LINE__, __FUNCTION__);

    MP4Property* pProperty = NULL;
    uint32_t index = 0;

    FindIntegerProperty(name, &pProperty, &index);

    ((MP4IntegerProperty*)pProperty)->SetValue(value, index);
}

void MP4File::FindFloatProperty(const char* name,
                                MP4Property** ppProperty, uint32_t* pIndex)
{
    if (!FindProperty(name, ppProperty, pIndex)) {
        ostringstream msg;
        msg << "no such property - " << name;
        throw new Exception(msg.str(), __FILE__, __LINE__, __FUNCTION__);
    }
    if ((*ppProperty)->GetType() != Float32Property) {
        ostringstream msg;
        msg << "type mismatch - property " << name << " type " << (*ppProperty)->GetType();
        throw new Exception(msg.str(), __FILE__, __LINE__, __FUNCTION__);
    }
}

float MP4File::GetFloatProperty(const char* name)
{
    MP4Property* pProperty;
    uint32_t index;

    FindFloatProperty(name, &pProperty, &index);

    return ((MP4Float32Property*)pProperty)->GetValue(index);
}

void MP4File::SetFloatProperty(const char* name, float value)
{
    ProtectWriteOperation(__FILE__, __LINE__, __FUNCTION__);

    MP4Property* pProperty;
    uint32_t index;

    FindFloatProperty(name, &pProperty, &index);

    ((MP4Float32Property*)pProperty)->SetValue(value, index);
}

void MP4File::FindStringProperty(const char* name,
                                 MP4Property** ppProperty, uint32_t* pIndex)
{
    if (!FindProperty(name, ppProperty, pIndex)) {
        ostringstream msg;
        msg << "no such property - " << name;
        throw new Exception(msg.str(), __FILE__, __LINE__, __FUNCTION__);
    }
    if ((*ppProperty)->GetType() != StringProperty) {
        ostringstream msg;
        msg << "type mismatch - property " << name << " type " << (*ppProperty)->GetType();
        throw new Exception(msg.str(), __FILE__, __LINE__, __FUNCTION__);
    }
}

const char* MP4File::GetStringProperty(const char* name)
{
    MP4Property* pProperty;
    uint32_t index;

    FindStringProperty(name, &pProperty, &index);

    return ((MP4StringProperty*)pProperty)->GetValue(index);
}

void MP4File::SetStringProperty(const char* name, const char* value)
{
    ProtectWriteOperation(__FILE__, __LINE__, __FUNCTION__);

    MP4Property* pProperty;
    uint32_t index;

    FindStringProperty(name, &pProperty, &index);

    ((MP4StringProperty*)pProperty)->SetValue(value, index);
}

void MP4File::FindBytesProperty(const char* name,
                                MP4Property** ppProperty, uint32_t* pIndex)
{
    if (!FindProperty(name, ppProperty, pIndex)) {
        ostringstream msg;
        msg << "no such property " << name;
        throw new Exception(msg.str(), __FILE__, __LINE__, __FUNCTION__);
    }
    if ((*ppProperty)->GetType() != BytesProperty) {
        ostringstream msg;
        msg << "type mismatch - property " << name << " - type " <<  (*ppProperty)->GetType();
        throw new Exception(msg.str(), __FILE__, __LINE__, __FUNCTION__);
    }
}

void MP4File::GetBytesProperty(const char* name,
                               uint8_t** ppValue, uint32_t* pValueSize)
{
    MP4Property* pProperty;
    uint32_t index;

    FindBytesProperty(name, &pProperty, &index);

    ((MP4BytesProperty*)pProperty)->GetValue(ppValue, pValueSize, index);
}

void MP4File::SetBytesProperty(const char* name,
                               const uint8_t* pValue, uint32_t valueSize)
{
    ProtectWriteOperation(__FILE__, __LINE__, __FUNCTION__);

    MP4Property* pProperty;
    uint32_t index;

    FindBytesProperty(name, &pProperty, &index);

    ((MP4BytesProperty*)pProperty)->SetValue(pValue, valueSize, index);
}


// track functions

MP4TrackId MP4File::AddTrack(const char* type, uint32_t timeScale)
{
    ProtectWriteOperation(__FILE__, __LINE__, __FUNCTION__);

    // create and add new trak atom
    MP4Atom* pTrakAtom = AddChildAtom("moov", "trak");
    ASSERT(pTrakAtom);

    // allocate a new track id
    MP4TrackId trackId = AllocTrackId();

    m_trakIds.Add(trackId);

    // set track id
    MP4Integer32Property* pInteger32Property = NULL;
    (void)pTrakAtom->FindProperty("trak.tkhd.trackId",
                                  (MP4Property**)&pInteger32Property);
    ASSERT(pInteger32Property);
    pInteger32Property->SetValue(trackId);

    // set track type
    const char* normType = MP4NormalizeTrackType(type);

    // sanity check for user defined types
    if (strlen(normType) > 4) {
        log.warningf("%s: \"%s\": type truncated to four characters",
                     __FUNCTION__, GetFilename().c_str());
        // StringProperty::SetValue() will do the actual truncation
    }

    MP4StringProperty* pStringProperty = NULL;
    (void)pTrakAtom->FindProperty("trak.mdia.hdlr.handlerType",
                                  (MP4Property**)&pStringProperty);
    ASSERT(pStringProperty);
    pStringProperty->SetValue(normType);

    // set track time scale
    pInteger32Property = NULL;
    (void)pTrakAtom->FindProperty("trak.mdia.mdhd.timeScale",
                                  (MP4Property**)&pInteger32Property);
    ASSERT(pInteger32Property);
    pInteger32Property->SetValue(timeScale ? timeScale : 1000);

    // now have enough to create MP4Track object
    MP4Track* pTrack = NULL;
    if (!strcmp(normType, MP4_HINT_TRACK_TYPE)) {
        pTrack = new MP4RtpHintTrack(*this, *pTrakAtom);
    } else {
        pTrack = new MP4Track(*this, *pTrakAtom);
    }
    m_pTracks.Add(pTrack);

    // mark non-hint tracks as enabled
    if (strcmp(normType, MP4_HINT_TRACK_TYPE)) {
        SetTrackIntegerProperty(trackId, "tkhd.flags", 1);
    }

    // mark track as contained in this file
    // LATER will provide option for external data references
    AddDataReference(trackId, NULL);

    return trackId;
}

void MP4File::AddTrackToIod(MP4TrackId trackId)
{
    MP4DescriptorProperty* pDescriptorProperty = NULL;
    (void)m_pRootAtom->FindProperty("moov.iods.esIds",
                                    (MP4Property**)&pDescriptorProperty);
    ASSERT(pDescriptorProperty);

    MP4Descriptor* pDescriptor =
        pDescriptorProperty->AddDescriptor(MP4ESIDIncDescrTag);
    ASSERT(pDescriptor);

    MP4Integer32Property* pIdProperty = NULL;
    (void)pDescriptor->FindProperty("id",
                                    (MP4Property**)&pIdProperty);
    ASSERT(pIdProperty);

    pIdProperty->SetValue(trackId);
}

void MP4File::RemoveTrackFromIod(MP4TrackId trackId, bool shallHaveIods)
{
    MP4DescriptorProperty* pDescriptorProperty = NULL;
    if (!m_pRootAtom->FindProperty("moov.iods.esIds",(MP4Property**)&pDescriptorProperty)
        || pDescriptorProperty == NULL)
        return;

    for (uint32_t i = 0; i < pDescriptorProperty->GetCount(); i++) {
        /* static */
        char name[32];
        snprintf(name, sizeof(name), "esIds[%u].id", i);

        MP4Integer32Property* pIdProperty = NULL;
        (void)pDescriptorProperty->FindProperty(name,
                                                (MP4Property**)&pIdProperty);
        // wmay ASSERT(pIdProperty);

        if (pIdProperty != NULL &&
                pIdProperty->GetValue() == trackId) {
            pDescriptorProperty->DeleteDescriptor(i);
            break;
        }
    }
}

void MP4File::AddTrackToOd(MP4TrackId trackId)
{
    if (!m_odTrackId) {
        return;
    }

    AddTrackReference(MakeTrackName(m_odTrackId, "tref.mpod"), trackId);
}

void MP4File::RemoveTrackFromOd(MP4TrackId trackId)
{
    if (!m_odTrackId) {
        return;
    }

    RemoveTrackReference(MakeTrackName(m_odTrackId, "tref.mpod"), trackId);
}

/*
 * Try to obtain the properties of this reference track, if not found then return
 * NULL in *ppCountProperty and *ppTrackIdProperty.
 */
void MP4File::GetTrackReferenceProperties(const char* trefName,
        MP4Property** ppCountProperty, MP4Property** ppTrackIdProperty)
{
    char propName[1024];

    snprintf(propName, sizeof(propName), "%s.%s", trefName, "entryCount");
    (void)m_pRootAtom->FindProperty(propName, ppCountProperty);

    snprintf(propName, sizeof(propName), "%s.%s", trefName, "entries.trackId");
    (void)m_pRootAtom->FindProperty(propName, ppTrackIdProperty);
}

void MP4File::AddTrackReference(const char* trefName, MP4TrackId refTrackId)
{
    MP4Integer32Property* pCountProperty = NULL;
    MP4Integer32Property* pTrackIdProperty = NULL;

    GetTrackReferenceProperties(trefName,
                                (MP4Property**)&pCountProperty,
                                (MP4Property**)&pTrackIdProperty);

    if (pCountProperty && pTrackIdProperty) {
        pTrackIdProperty->AddValue(refTrackId);
        pCountProperty->IncrementValue();
    }
}

uint32_t MP4File::FindTrackReference(const char* trefName,
                                     MP4TrackId refTrackId)
{
    MP4Integer32Property* pCountProperty = NULL;
    MP4Integer32Property* pTrackIdProperty = NULL;

    GetTrackReferenceProperties(trefName,
                                (MP4Property**)&pCountProperty,
                                (MP4Property**)&pTrackIdProperty);

    if (pCountProperty && pTrackIdProperty) {
        for (uint32_t i = 0; i < pCountProperty->GetValue(); i++) {
            if (refTrackId == pTrackIdProperty->GetValue(i)) {
                return i + 1;   // N.B. 1 not 0 based index
            }
        }
    }
    return 0;
}

void MP4File::RemoveTrackReference(const char* trefName, MP4TrackId refTrackId)
{
    MP4Integer32Property* pCountProperty = NULL;
    MP4Integer32Property* pTrackIdProperty = NULL;

    GetTrackReferenceProperties(trefName,
                                (MP4Property**)&pCountProperty,
                                (MP4Property**)&pTrackIdProperty);

    if (pCountProperty && pTrackIdProperty) {
        for (uint32_t i = 0; i < pCountProperty->GetValue(); i++) {
            if (refTrackId == pTrackIdProperty->GetValue(i)) {
                pTrackIdProperty->DeleteValue(i);
                pCountProperty->IncrementValue(-1);
            }
        }
    }
}

void MP4File::AddDataReference(MP4TrackId trackId, const char* url)
{
    MP4Atom* pDrefAtom =
        FindAtom(MakeTrackName(trackId, "mdia.minf.dinf.dref"));
    ASSERT(pDrefAtom);

    MP4Integer32Property* pCountProperty = NULL;
    (void)pDrefAtom->FindProperty("dref.entryCount",
                                  (MP4Property**)&pCountProperty);
    ASSERT(pCountProperty);
    pCountProperty->IncrementValue();

    MP4Atom* pUrlAtom = AddChildAtom(pDrefAtom, "url ");

    if (url && url[0] != '\0') {
        pUrlAtom->SetFlags(pUrlAtom->GetFlags() & 0xFFFFFE);

        MP4StringProperty* pUrlProperty = NULL;
        (void)pUrlAtom->FindProperty("url .location",
                                     (MP4Property**)&pUrlProperty);
        ASSERT(pUrlProperty);
        pUrlProperty->SetValue(url);
    } else {
        pUrlAtom->SetFlags(pUrlAtom->GetFlags() | 1);
    }
}

MP4TrackId MP4File::AddSystemsTrack(const char* type, uint32_t timeScale)
{
    const char* normType = MP4NormalizeTrackType(type);

    // TBD if user type, fix name to four chars, and warn

    MP4TrackId trackId = AddTrack(type, timeScale);

    (void)InsertChildAtom(MakeTrackName(trackId, "mdia.minf"), "nmhd", 0);

    (void)AddChildAtom(MakeTrackName(trackId, "mdia.minf.stbl.stsd"), "mp4s");

    AddDescendantAtoms(MakeTrackName(trackId, NULL), "udta.name");

    // stsd is a unique beast in that it has a count of the number
    // of child atoms that needs to be incremented after we add the mp4s atom
    MP4Integer32Property* pStsdCountProperty;
    FindIntegerProperty(
        MakeTrackName(trackId, "mdia.minf.stbl.stsd.entryCount"),
        (MP4Property**)&pStsdCountProperty);
    pStsdCountProperty->IncrementValue();

    SetTrackIntegerProperty(trackId,
                            "mdia.minf.stbl.stsd.mp4s.esds.ESID",
                            0
                           );

    SetTrackIntegerProperty(trackId,
                            "mdia.minf.stbl.stsd.mp4s.esds.decConfigDescr.objectTypeId",
                            MP4SystemsV1ObjectType);

    SetTrackIntegerProperty(trackId,
                            "mdia.minf.stbl.stsd.mp4s.esds.decConfigDescr.streamType",
                            ConvertTrackTypeToStreamType(normType));

    return trackId;
}

MP4TrackId MP4File::AddODTrack()
{
    // until a demonstrated need emerges
    // we limit ourselves to one object description track
    if (m_odTrackId != MP4_INVALID_TRACK_ID) {
        throw new Exception("object description track already exists",__FILE__, __LINE__, __FUNCTION__);
    }

    m_odTrackId = AddSystemsTrack(MP4_OD_TRACK_TYPE);

    AddTrackToIod(m_odTrackId);

    (void)AddDescendantAtoms(MakeTrackName(m_odTrackId, NULL), "tref.mpod");

    return m_odTrackId;
}

MP4TrackId MP4File::AddSceneTrack()
{
    MP4TrackId trackId = AddSystemsTrack(MP4_SCENE_TRACK_TYPE);

    AddTrackToIod(trackId);
    AddTrackToOd(trackId);

    return trackId;
}

bool MP4File::ShallHaveIods()
{
    // NULL terminated list of brands which require the IODS atom
    const char* brandsWithIods[] = {
        "mp42",
        "isom",
        NULL
    };

    MP4FtypAtom* ftyp = (MP4FtypAtom*)m_pRootAtom->FindAtom( "ftyp" );
    if( !ftyp )
        return false;

    // check major brand
    const char* brand = ftyp->majorBrand.GetValue();
    for( uint32_t i = 0; brandsWithIods[i] != NULL; i++ ) {
        if( !strcasecmp( brandsWithIods[i], brand ))
            return true;
    }

    // check compatible brands
    uint32_t max = ftyp->compatibleBrands.GetCount();
    for( uint32_t i = 0; i < max; i++ ) {
        brand = ftyp->compatibleBrands.GetValue( i );
        for( uint32_t j = 0; brandsWithIods[j] != NULL ; j++) {
            if( !strcasecmp( brandsWithIods[j], brand ))
                return true;
        }
    }

    return false;
}

void MP4File::SetAmrVendor(
    MP4TrackId trackId,
    uint32_t vendor)
{
    SetTrackIntegerProperty(trackId,
                            "mdia.minf.stbl.stsd.*.damr.vendor",
                            vendor);
}

void MP4File::SetAmrDecoderVersion(
    MP4TrackId trackId,
    uint8_t decoderVersion)
{

    SetTrackIntegerProperty(trackId,
                            "mdia.minf.stbl.stsd.*.damr.decoderVersion",
                            decoderVersion);
}

void MP4File::SetAmrModeSet(
    MP4TrackId trackId,
    uint16_t modeSet)
{
    SetTrackIntegerProperty(trackId,
                            "mdia.minf.stbl.stsd.*.damr.modeSet",
                            modeSet);
}
uint16_t MP4File::GetAmrModeSet(MP4TrackId trackId)
{
    return GetTrackIntegerProperty(trackId,
                                   "mdia.minf.stbl.stsd.*.damr.modeSet");
}

MP4TrackId MP4File::AddAmrAudioTrack(
    uint32_t timeScale,
    uint16_t modeSet,
    uint8_t modeChangePeriod,
    uint8_t framesPerSample,
    bool isAmrWB)
{

    uint32_t fixedSampleDuration = (timeScale * 20)/1000; // 20mSec/Sample

    MP4TrackId trackId = AddTrack(MP4_AUDIO_TRACK_TYPE, timeScale);

    AddTrackToOd(trackId);

    SetTrackFloatProperty(trackId, "tkhd.volume", 1.0);

    (void)InsertChildAtom(MakeTrackName(trackId, "mdia.minf"), "smhd", 0);

    (void)AddChildAtom(MakeTrackName(trackId, "mdia.minf.stbl.stsd"), isAmrWB ? "sawb" : "samr");

    // stsd is a unique beast in that it has a count of the number
    // of child atoms that needs to be incremented after we add the mp4a atom
    MP4Integer32Property* pStsdCountProperty;
    FindIntegerProperty(
        MakeTrackName(trackId, "mdia.minf.stbl.stsd.entryCount"),
        (MP4Property**)&pStsdCountProperty);
    pStsdCountProperty->IncrementValue();

    SetTrackIntegerProperty(trackId,
                            "mdia.minf.stbl.stsd.*.timeScale",
                            timeScale);

    SetTrackIntegerProperty(trackId,
                            "mdia.minf.stbl.stsd.*.damr.modeSet",
                            modeSet);

    SetTrackIntegerProperty(trackId,
                            "mdia.minf.stbl.stsd.*.damr.modeChangePeriod",
                            modeChangePeriod);

    SetTrackIntegerProperty(trackId,
                            "mdia.minf.stbl.stsd.*.damr.framesPerSample",
                            framesPerSample);


    m_pTracks[FindTrackIndex(trackId)]->
    SetFixedSampleDuration(fixedSampleDuration);

    return trackId;
}

MP4TrackId MP4File::AddULawAudioTrack(    uint32_t timeScale)
{
    uint32_t fixedSampleDuration = (timeScale * 20)/1000; // 20mSec/Sample

    MP4TrackId trackId = AddTrack(MP4_AUDIO_TRACK_TYPE, timeScale);

    AddTrackToOd(trackId);

    SetTrackFloatProperty(trackId, "tkhd.volume", 1.0);

    (void)InsertChildAtom(MakeTrackName(trackId, "mdia.minf"), "smhd", 0);

    (void)AddChildAtom(MakeTrackName(trackId, "mdia.minf.stbl.stsd"), "ulaw");

    // stsd is a unique beast in that it has a count of the number
    // of child atoms that needs to be incremented after we add the mp4a atom
    MP4Integer32Property* pStsdCountProperty;
    FindIntegerProperty(
        MakeTrackName(trackId, "mdia.minf.stbl.stsd.entryCount"),
        (MP4Property**)&pStsdCountProperty);
    pStsdCountProperty->IncrementValue();

    SetTrackIntegerProperty(trackId,
                            "mdia.minf.stbl.stsd.ulaw.timeScale",
                            timeScale<<16);

    m_pTracks[FindTrackIndex(trackId)]->SetFixedSampleDuration(fixedSampleDuration);

    return trackId;
}

MP4TrackId MP4File::AddALawAudioTrack(    uint32_t timeScale)
{
    uint32_t fixedSampleDuration = (timeScale * 20)/1000; // 20mSec/Sample

    MP4TrackId trackId = AddTrack(MP4_AUDIO_TRACK_TYPE, timeScale);

    AddTrackToOd(trackId);

    SetTrackFloatProperty(trackId, "tkhd.volume", 1.0);

    (void)InsertChildAtom(MakeTrackName(trackId, "mdia.minf"), "smhd", 0);

    (void)AddChildAtom(MakeTrackName(trackId, "mdia.minf.stbl.stsd"), "alaw");

    // stsd is a unique beast in that it has a count of the number
    // of child atoms that needs to be incremented after we add the mp4a atom
    MP4Integer32Property* pStsdCountProperty;
    FindIntegerProperty(
        MakeTrackName(trackId, "mdia.minf.stbl.stsd.entryCount"),
        (MP4Property**)&pStsdCountProperty);
    pStsdCountProperty->IncrementValue();

    SetTrackIntegerProperty(trackId,
                            "mdia.minf.stbl.stsd.alaw.timeScale",
                            timeScale<<16);

    m_pTracks[FindTrackIndex(trackId)]->SetFixedSampleDuration(fixedSampleDuration);

    return trackId;
}

MP4TrackId MP4File::AddAudioTrack(
    uint32_t timeScale,
    MP4Duration sampleDuration,
    uint8_t audioType)
{
    MP4TrackId trackId = AddTrack(MP4_AUDIO_TRACK_TYPE, timeScale);

    AddTrackToOd(trackId);

    SetTrackFloatProperty(trackId, "tkhd.volume", 1.0);

    (void)InsertChildAtom(MakeTrackName(trackId, "mdia.minf"), "smhd", 0);

    (void)AddChildAtom(MakeTrackName(trackId, "mdia.minf.stbl.stsd"), "mp4a");

    AddDescendantAtoms(MakeTrackName(trackId, NULL), "udta.name");

    // stsd is a unique beast in that it has a count of the number
    // of child atoms that needs to be incremented after we add the mp4a atom
    MP4Integer32Property* pStsdCountProperty;
    FindIntegerProperty(
        MakeTrackName(trackId, "mdia.minf.stbl.stsd.entryCount"),
        (MP4Property**)&pStsdCountProperty);
    pStsdCountProperty->IncrementValue();

    SetTrackIntegerProperty(trackId,
                            "mdia.minf.stbl.stsd.mp4a.timeScale", timeScale << 16);

    SetTrackIntegerProperty(trackId,
                            "mdia.minf.stbl.stsd.mp4a.esds.ESID",
                            0
                           );

    SetTrackIntegerProperty(trackId,
                            "mdia.minf.stbl.stsd.mp4a.esds.decConfigDescr.objectTypeId",
                            audioType);

    SetTrackIntegerProperty(trackId,
                            "mdia.minf.stbl.stsd.mp4a.esds.decConfigDescr.streamType",
                            MP4AudioStreamType);

    m_pTracks[FindTrackIndex(trackId)]->
    SetFixedSampleDuration(sampleDuration);

    return trackId;
}

MP4TrackId MP4File::AddAC3AudioTrack(
    uint32_t samplingRate,
    uint8_t fscod,
    uint8_t bsid,
    uint8_t bsmod,
    uint8_t acmod,
    uint8_t lfeon,
    uint8_t bit_rate_code)
{
    MP4TrackId trackId = AddTrack(MP4_AUDIO_TRACK_TYPE, samplingRate);

    AddTrackToOd(trackId);

    SetTrackFloatProperty(trackId, "tkhd.volume", 1.0);

    InsertChildAtom(MakeTrackName(trackId, "mdia.minf"), "smhd", 0);

    AddChildAtom(MakeTrackName(trackId, "mdia.minf.stbl.stsd"), "ac-3");

    // Set Ac3 settings
    MP4Integer16Property* pSampleRateProperty = NULL;
    FindIntegerProperty(
        MakeTrackName(trackId, "mdia.minf.stbl.stsd.ac-3.samplingRate"),
        (MP4Property**)&pSampleRateProperty);
    if (pSampleRateProperty) {
        pSampleRateProperty->SetValue(samplingRate);
    } else {
        throw new Exception("no ac-3.samplingRate property", __FILE__, __LINE__, __FUNCTION__);
    }

    MP4BitfieldProperty* pBitfieldProperty = NULL;

    FindProperty(MakeTrackName(trackId, "mdia.minf.stbl.stsd.ac-3.dac3.fscod"),
                               (MP4Property**)&pBitfieldProperty);
    if (pBitfieldProperty) {
        pBitfieldProperty->SetValue(fscod);
        pBitfieldProperty = NULL;
    } else {
        throw new Exception("no dac3.fscod property", __FILE__, __LINE__, __FUNCTION__);
    }

    FindProperty(MakeTrackName(trackId, "mdia.minf.stbl.stsd.ac-3.dac3.bsid"),
                               (MP4Property**)&pBitfieldProperty);
    if (pBitfieldProperty) {
        pBitfieldProperty->SetValue(bsid);
        pBitfieldProperty = NULL;
    } else {
        throw new Exception("no dac3.bsid property", __FILE__, __LINE__, __FUNCTION__);
    }

    FindProperty(MakeTrackName(trackId, "mdia.minf.stbl.stsd.ac-3.dac3.bsmod"),
                               (MP4Property**)&pBitfieldProperty);
    if (pBitfieldProperty) {
        pBitfieldProperty->SetValue(bsmod);
        pBitfieldProperty = NULL;
    } else {
        throw new Exception("no dac3.bsmod property", __FILE__, __LINE__, __FUNCTION__);
    }

    FindProperty(MakeTrackName(trackId, "mdia.minf.stbl.stsd.ac-3.dac3.acmod"),
                               (MP4Property**)&pBitfieldProperty);
    if (pBitfieldProperty) {
        pBitfieldProperty->SetValue(acmod);
        pBitfieldProperty = NULL;
    } else {
        throw new Exception("no dac3.acmod property", __FILE__, __LINE__, __FUNCTION__);
    }

    FindProperty(MakeTrackName(trackId, "mdia.minf.stbl.stsd.ac-3.dac3.lfeon"),
                               (MP4Property**)&pBitfieldProperty);
    if (pBitfieldProperty) {
        pBitfieldProperty->SetValue(lfeon);
        pBitfieldProperty = NULL;
    } else {
        throw new Exception("no dac3.lfeon property", __FILE__, __LINE__, __FUNCTION__);
    }

    FindProperty(MakeTrackName(trackId, "mdia.minf.stbl.stsd.ac-3.dac3.bit_rate_code"),
                               (MP4Property**)&pBitfieldProperty);
    if (pBitfieldProperty) {
        pBitfieldProperty->SetValue(bit_rate_code);
        pBitfieldProperty = NULL;
    } else {
        throw new Exception("no dac3.bit_rate_code property", __FILE__, __LINE__, __FUNCTION__);
    }

    AddDescendantAtoms(MakeTrackName(trackId, NULL), "udta.name");

    // stsd is a unique beast in that it has a count of the number
    // of child atoms that needs to be incremented after we add the mp4a atom
    MP4Integer32Property* pStsdCountProperty;
    FindIntegerProperty(
        MakeTrackName(trackId, "mdia.minf.stbl.stsd.entryCount"),
        (MP4Property**)&pStsdCountProperty);
    pStsdCountProperty->IncrementValue();

    m_pTracks[FindTrackIndex(trackId)]->
        SetFixedSampleDuration(1536);

    return trackId;
}

MP4TrackId MP4File::AddEncAudioTrack(uint32_t timeScale,
                                     MP4Duration sampleDuration,
                                     uint8_t audioType,
                                     uint32_t scheme_type,
                                     uint16_t scheme_version,
                                     uint8_t  key_ind_len,
                                     uint8_t  iv_len,
                                     bool      selective_enc,
                                     const char *kms_uri,
                                     bool use_ismacryp
                                    )
{
    uint32_t original_fmt = 0;

    MP4TrackId trackId = AddTrack(MP4_AUDIO_TRACK_TYPE, timeScale);

    AddTrackToOd(trackId);

    SetTrackFloatProperty(trackId, "tkhd.volume", 1.0);

    (void)InsertChildAtom(MakeTrackName(trackId, "mdia.minf"), "smhd", 0);

    (void)AddChildAtom(MakeTrackName(trackId, "mdia.minf.stbl.stsd"), "enca");

    // stsd is a unique beast in that it has a count of the number
    // of child atoms that needs to be incremented after we add the enca atom
    MP4Integer32Property* pStsdCountProperty;
    FindIntegerProperty(MakeTrackName(trackId, "mdia.minf.stbl.stsd.entryCount"),
                        (MP4Property**)&pStsdCountProperty);
    pStsdCountProperty->IncrementValue();


    /* set all the ismacryp-specific values */
    // original format is mp4a
    if (use_ismacryp) {
        original_fmt = ATOMID("mp4a");
        SetTrackIntegerProperty(trackId,
                                "mdia.minf.stbl.stsd.enca.sinf.frma.data-format",
                                original_fmt);

        (void)AddChildAtom(MakeTrackName(trackId, "mdia.minf.stbl.stsd.enca.sinf"),
                           "schm");
        (void)AddChildAtom(MakeTrackName(trackId, "mdia.minf.stbl.stsd.enca.sinf"),
                           "schi");
        (void)AddChildAtom(MakeTrackName(trackId, "mdia.minf.stbl.stsd.enca.sinf.schi"),
                           "iKMS");
        (void)AddChildAtom(MakeTrackName(trackId, "mdia.minf.stbl.stsd.enca.sinf.schi"),
                           "iSFM");
        SetTrackIntegerProperty(trackId,
                                "mdia.minf.stbl.stsd.enca.sinf.schm.scheme_type",
                                scheme_type);

        SetTrackIntegerProperty(trackId,
                                "mdia.minf.stbl.stsd.enca.sinf.schm.scheme_version",
                                scheme_version);

        SetTrackStringProperty(trackId,
                               "mdia.minf.stbl.stsd.enca.sinf.schi.iKMS.kms_URI",
                               kms_uri);

        SetTrackIntegerProperty(trackId,
                                "mdia.minf.stbl.stsd.enca.sinf.schi.iSFM.selective-encryption",
                                selective_enc);

        SetTrackIntegerProperty(trackId,
                                "mdia.minf.stbl.stsd.enca.sinf.schi.iSFM.key-indicator-length",
                                key_ind_len);

        SetTrackIntegerProperty(trackId,
                                "mdia.minf.stbl.stsd.enca.sinf.schi.iSFM.IV-length",
                                iv_len);
        /* end ismacryp */
    }

    SetTrackIntegerProperty(trackId,
                            "mdia.minf.stbl.stsd.enca.timeScale", timeScale);

    SetTrackIntegerProperty(trackId,
                            "mdia.minf.stbl.stsd.enca.esds.ESID",
                            0
                           );

    SetTrackIntegerProperty(trackId,
                            "mdia.minf.stbl.stsd.enca.esds.decConfigDescr.objectTypeId",
                            audioType);

    SetTrackIntegerProperty(trackId,
                            "mdia.minf.stbl.stsd.enca.esds.decConfigDescr.streamType",
                            MP4AudioStreamType);

    m_pTracks[FindTrackIndex(trackId)]->
    SetFixedSampleDuration(sampleDuration);

    return trackId;
}

MP4TrackId MP4File::AddCntlTrackDefault (uint32_t timeScale,
        MP4Duration sampleDuration,
        const char *type)
{
    MP4TrackId trackId = AddTrack(MP4_CNTL_TRACK_TYPE, timeScale);

    (void)InsertChildAtom(MakeTrackName(trackId, "mdia.minf"), "nmhd", 0);
    (void)AddChildAtom(MakeTrackName(trackId, "mdia.minf.stbl.stsd"), type);

    // stsd is a unique beast in that it has a count of the number
    // of child atoms that needs to be incremented after we add the mp4v atom
    MP4Integer32Property* pStsdCountProperty;
    FindIntegerProperty(
        MakeTrackName(trackId, "mdia.minf.stbl.stsd.entryCount"),
        (MP4Property**)&pStsdCountProperty);
    pStsdCountProperty->IncrementValue();

    SetTrackIntegerProperty(trackId,
                            "mdia.minf.stbl.stsz.sampleSize", sampleDuration);

    m_pTracks[FindTrackIndex(trackId)]->
    SetFixedSampleDuration(sampleDuration);

    return trackId;
}

MP4TrackId MP4File::AddHrefTrack (uint32_t timeScale,
                                  MP4Duration sampleDuration,
                                  const char *base_url)
{
    MP4TrackId trackId = AddCntlTrackDefault(timeScale, sampleDuration, "href");

    if (base_url != NULL) {
        (void)AddChildAtom(MakeTrackName(trackId, "mdia.minf.stbl.stsd.href"),
                           "burl");
        SetTrackStringProperty(trackId, "mdia.minf.stbl.stsd.href.burl.base_url",
                               base_url);
    }

    return trackId;
}

MP4TrackId MP4File::AddVideoTrackDefault(
    uint32_t timeScale,
    MP4Duration sampleDuration,
    uint16_t width,
    uint16_t height,
    const char *videoType)
{
    MP4TrackId trackId = AddTrack(MP4_VIDEO_TRACK_TYPE, timeScale);

    AddTrackToOd(trackId);

    SetTrackFloatProperty(trackId, "tkhd.width", width);
    SetTrackFloatProperty(trackId, "tkhd.height", height);

    (void)InsertChildAtom(MakeTrackName(trackId, "mdia.minf"), "vmhd", 0);

    (void)AddChildAtom(MakeTrackName(trackId, "mdia.minf.stbl.stsd"), videoType);

    // stsd is a unique beast in that it has a count of the number
    // of child atoms that needs to be incremented after we add the mp4v atom
    MP4Integer32Property* pStsdCountProperty;
    FindIntegerProperty(
        MakeTrackName(trackId, "mdia.minf.stbl.stsd.entryCount"),
        (MP4Property**)&pStsdCountProperty);
    pStsdCountProperty->IncrementValue();

    SetTrackIntegerProperty(trackId,
                            "mdia.minf.stbl.stsz.sampleSize", sampleDuration);

    m_pTracks[FindTrackIndex(trackId)]->
    SetFixedSampleDuration(sampleDuration);

    return trackId;
}
MP4TrackId MP4File::AddMP4VideoTrack(
    uint32_t timeScale,
    MP4Duration sampleDuration,
    uint16_t width,
    uint16_t height,
    uint8_t videoType)
{
    MP4TrackId trackId = AddVideoTrackDefault(timeScale,
                         sampleDuration,
                         width,
                         height,
                         "mp4v");

    SetTrackIntegerProperty(trackId,
                            "mdia.minf.stbl.stsd.mp4v.width", width);
    SetTrackIntegerProperty(trackId,
                            "mdia.minf.stbl.stsd.mp4v.height", height);

    SetTrackIntegerProperty(trackId,
                            "mdia.minf.stbl.stsd.mp4v.esds.ESID",
                            0
                           );

    SetTrackIntegerProperty(trackId,
                            "mdia.minf.stbl.stsd.mp4v.esds.decConfigDescr.objectTypeId",
                            videoType);

    SetTrackIntegerProperty(trackId,
                            "mdia.minf.stbl.stsd.mp4v.esds.decConfigDescr.streamType",
                            MP4VisualStreamType);

    return trackId;
}

// ismacrypted
MP4TrackId MP4File::AddEncVideoTrack(uint32_t timeScale,
                                     MP4Duration sampleDuration,
                                     uint16_t width,
                                     uint16_t height,
                                     uint8_t videoType,
                                     mp4v2_ismacrypParams *icPp,
                                     const char *oFormat
                                    )
{
    uint32_t original_fmt = 0;

    MP4TrackId trackId = AddVideoTrackDefault(timeScale,
                         sampleDuration,
                         width,
                         height,
                         "encv");

    SetTrackIntegerProperty(trackId,
                            "mdia.minf.stbl.stsd.encv.width", width);
    SetTrackIntegerProperty(trackId,
                            "mdia.minf.stbl.stsd.encv.height", height);

    /* set all the ismacryp-specific values */

    original_fmt = ATOMID(oFormat);

    SetTrackIntegerProperty(trackId,
                            "mdia.minf.stbl.stsd.encv.sinf.frma.data-format",
                            original_fmt);

    (void)AddChildAtom(MakeTrackName(trackId, "mdia.minf.stbl.stsd.encv.sinf"),
                       "schm");
    (void)AddChildAtom(MakeTrackName(trackId, "mdia.minf.stbl.stsd.encv.sinf"),
                       "schi");
    (void)AddChildAtom(MakeTrackName(trackId, "mdia.minf.stbl.stsd.encv.sinf.schi"),
                       "iKMS");
    (void)AddChildAtom(MakeTrackName(trackId, "mdia.minf.stbl.stsd.encv.sinf.schi"),
                       "iSFM");

    SetTrackIntegerProperty(trackId,
                            "mdia.minf.stbl.stsd.encv.sinf.schm.scheme_type",
                            icPp->scheme_type);

    SetTrackIntegerProperty(trackId,
                            "mdia.minf.stbl.stsd.encv.sinf.schm.scheme_version",
                            icPp->scheme_version);

    SetTrackStringProperty(trackId,
                           "mdia.minf.stbl.stsd.encv.sinf.schi.iKMS.kms_URI",
                           icPp->kms_uri);

    SetTrackIntegerProperty(trackId,
                            "mdia.minf.stbl.stsd.encv.sinf.schi.iSFM.selective-encryption",
                            icPp->selective_enc);

    SetTrackIntegerProperty(trackId,
                            "mdia.minf.stbl.stsd.encv.sinf.schi.iSFM.key-indicator-length",
                            icPp->key_ind_len);

    SetTrackIntegerProperty(trackId,
                            "mdia.minf.stbl.stsd.encv.sinf.schi.iSFM.IV-length",
                            icPp->iv_len);

    SetTrackIntegerProperty(trackId,
                            "mdia.minf.stbl.stsd.encv.esds.ESID",
                            0
                           );

    SetTrackIntegerProperty(trackId,
                            "mdia.minf.stbl.stsd.encv.esds.decConfigDescr.objectTypeId",
                            videoType);

    SetTrackIntegerProperty(trackId,
                            "mdia.minf.stbl.stsd.encv.esds.decConfigDescr.streamType",
                            MP4VisualStreamType);

    return trackId;
}

MP4TrackId MP4File::AddH264VideoTrack(
    uint32_t timeScale,
    MP4Duration sampleDuration,
    uint16_t width,
    uint16_t height,
    uint8_t AVCProfileIndication,
    uint8_t profile_compat,
    uint8_t AVCLevelIndication,
    uint8_t sampleLenFieldSizeMinusOne)
{
    MP4TrackId trackId = AddVideoTrackDefault(timeScale,
                         sampleDuration,
                         width,
                         height,
                         "avc1");

    SetTrackIntegerProperty(trackId,
                            "mdia.minf.stbl.stsd.avc1.width", width);
    SetTrackIntegerProperty(trackId,
                            "mdia.minf.stbl.stsd.avc1.height", height);

    SetTrackIntegerProperty(trackId,
                            "mdia.minf.stbl.stsd.avc1.avcC.AVCProfileIndication",
                            AVCProfileIndication);
    SetTrackIntegerProperty(trackId,
                            "mdia.minf.stbl.stsd.avc1.avcC.profile_compatibility",
                            profile_compat);
    SetTrackIntegerProperty(trackId,
                            "mdia.minf.stbl.stsd.avc1.avcC.AVCLevelIndication",
                            AVCLevelIndication);
    SetTrackIntegerProperty(trackId,
                            "mdia.minf.stbl.stsd.avc1.avcC.lengthSizeMinusOne",
                            sampleLenFieldSizeMinusOne);

    return trackId;
}

MP4TrackId MP4File::AddEncH264VideoTrack(
    uint32_t timeScale,
    MP4Duration sampleDuration,
    uint16_t width,
    uint16_t height,
    MP4Atom *srcAtom,
    mp4v2_ismacrypParams *icPp)

{

    uint32_t original_fmt = 0;
    MP4Atom *avcCAtom;

    MP4TrackId trackId = AddVideoTrackDefault(timeScale,
                         sampleDuration,
                         width,
                         height,
                         "encv");

    SetTrackIntegerProperty(trackId, "mdia.minf.stbl.stsd.encv.width", width);
    SetTrackIntegerProperty(trackId, "mdia.minf.stbl.stsd.encv.height", height);

    (void)AddChildAtom(MakeTrackName(trackId, "mdia.minf.stbl.stsd.encv"), "avcC");

    // create default values
    avcCAtom = FindAtom(MakeTrackName(trackId, "mdia.minf.stbl.stsd.encv.avcC"));

    // export source atom
    ((MP4AvcCAtom *) srcAtom)->Clone((MP4AvcCAtom *)avcCAtom);

    /* set all the ismacryp-specific values */

    (void)AddChildAtom(MakeTrackName(trackId, "mdia.minf.stbl.stsd.encv.sinf"), "schm");
    (void)AddChildAtom(MakeTrackName(trackId, "mdia.minf.stbl.stsd.encv.sinf"), "schi");
    (void)AddChildAtom(MakeTrackName(trackId, "mdia.minf.stbl.stsd.encv.sinf.schi"), "iKMS");
    (void)AddChildAtom(MakeTrackName(trackId, "mdia.minf.stbl.stsd.encv.sinf.schi"), "iSFM");

    // per ismacrypt E&A V1.1 section 9.1.2.1 'avc1' is renamed '264b'
    // avc1 must not appear as a sample entry name or original format name
    original_fmt = ATOMID("264b");
    SetTrackIntegerProperty(trackId, "mdia.minf.stbl.stsd.encv.sinf.frma.data-format",
                            original_fmt);

    SetTrackIntegerProperty(trackId, "mdia.minf.stbl.stsd.encv.sinf.schm.scheme_type",
                            icPp->scheme_type);

    SetTrackIntegerProperty(trackId, "mdia.minf.stbl.stsd.encv.sinf.schm.scheme_version",
                            icPp->scheme_version);

    SetTrackStringProperty(trackId, "mdia.minf.stbl.stsd.encv.sinf.schi.iKMS.kms_URI",
                           icPp->kms_uri);

    SetTrackIntegerProperty(trackId, "mdia.minf.stbl.stsd.encv.sinf.schi.iSFM.selective-encryption",
                            icPp->selective_enc);

    SetTrackIntegerProperty(trackId, "mdia.minf.stbl.stsd.encv.sinf.schi.iSFM.key-indicator-length",
                            icPp->key_ind_len);

    SetTrackIntegerProperty(trackId, "mdia.minf.stbl.stsd.encv.sinf.schi.iSFM.IV-length",
                            icPp->iv_len);


    return trackId;
}


void MP4File::AddH264SequenceParameterSet (MP4TrackId trackId,
        const uint8_t *pSequence,
        uint16_t sequenceLen)
{
    const char *format;
    MP4Atom *avcCAtom;

    // get 4cc media format - can be avc1 or encv for ismacrypted track
    format = GetTrackMediaDataName(trackId);

    if (!strcasecmp(format, "avc1"))
        avcCAtom = FindAtom(MakeTrackName(trackId, "mdia.minf.stbl.stsd.avc1.avcC"));
    else if (!strcasecmp(format, "encv"))
        avcCAtom = FindAtom(MakeTrackName(trackId, "mdia.minf.stbl.stsd.encv.avcC"));
    else
        // huh?  unknown track format
        return;


    MP4BitfieldProperty *pCount;
    MP4Integer16Property *pLength;
    MP4BytesProperty *pUnit;
    if ((avcCAtom->FindProperty("avcC.numOfSequenceParameterSets",
                                (MP4Property **)&pCount) == false) ||
            (avcCAtom->FindProperty("avcC.sequenceEntries.sequenceParameterSetLength",
                                    (MP4Property **)&pLength) == false) ||
            (avcCAtom->FindProperty("avcC.sequenceEntries.sequenceParameterSetNALUnit",
                                    (MP4Property **)&pUnit) == false)) {
        log.errorf("%s: \"%s\": Could not find avcC properties",
                   __FUNCTION__, GetFilename().c_str() );
        return;
    }
    uint32_t count = pCount->GetValue();

    if (count > 0) {
        // see if we already exist
        for (uint32_t index = 0; index < count; index++) {
            if (pLength->GetValue(index) == sequenceLen) {
                uint8_t *seq;
                uint32_t seqlen;
                pUnit->GetValue(&seq, &seqlen, index);
                if (memcmp(seq, pSequence, sequenceLen) == 0) {
                    free(seq);
                    return;
                }
                free(seq);
            }
        }
    }
    pLength->AddValue(sequenceLen);
    pUnit->AddValue(pSequence, sequenceLen);
    pCount->IncrementValue();

    return;
}
void MP4File::AddH264PictureParameterSet (MP4TrackId trackId,
        const uint8_t *pPict,
        uint16_t pictLen)
{
    MP4Atom *avcCAtom =
        FindAtom(MakeTrackName(trackId,
                               "mdia.minf.stbl.stsd.avc1.avcC"));
    MP4Integer8Property *pCount;
    MP4Integer16Property *pLength;
    MP4BytesProperty *pUnit;
    if ((avcCAtom->FindProperty("avcC.numOfPictureParameterSets",
                                (MP4Property **)&pCount) == false) ||
            (avcCAtom->FindProperty("avcC.pictureEntries.pictureParameterSetLength",
                                    (MP4Property **)&pLength) == false) ||
            (avcCAtom->FindProperty("avcC.pictureEntries.pictureParameterSetNALUnit",
                                    (MP4Property **)&pUnit) == false)) {
        log.errorf("%s: \"%s\": Could not find avcC picture table properties",
                   __FUNCTION__, GetFilename().c_str());
        return;
    }

    ASSERT(pCount);
    uint32_t count = pCount->GetValue();

    if (count > 0) {
        // see if we already exist
        for (uint32_t index = 0; index < count; index++) {
            if (pLength->GetValue(index) == pictLen) {
                uint8_t *seq;
                uint32_t seqlen;
                pUnit->GetValue(&seq, &seqlen, index);
                if (memcmp(seq, pPict, pictLen) == 0) {
                    log.verbose1f("\"%s\": picture matches %d",
                                  GetFilename().c_str(), index);
                    free(seq);
                    return;
                }
                free(seq);
            }
        }
    }
    pLength->AddValue(pictLen);
    pUnit->AddValue(pPict, pictLen);
    pCount->IncrementValue();
    log.verbose1f("\"%s\": new picture added %d", GetFilename().c_str(),
                  pCount->GetValue());

    return;
}
void  MP4File::SetH263Vendor(
    MP4TrackId trackId,
    uint32_t vendor)
{
    SetTrackIntegerProperty(trackId,
                            "mdia.minf.stbl.stsd.s263.d263.vendor",
                            vendor);
}

void MP4File::SetH263DecoderVersion(
    MP4TrackId trackId,
    uint8_t decoderVersion)
{
    SetTrackIntegerProperty(trackId,
                            "mdia.minf.stbl.stsd.s263.d263.decoderVersion",
                            decoderVersion);
}

void MP4File::SetH263Bitrates(
    MP4TrackId trackId,
    uint32_t avgBitrate,
    uint32_t maxBitrate)
{
    SetTrackIntegerProperty(trackId,
                            "mdia.minf.stbl.stsd.s263.d263.bitr.avgBitrate",
                            avgBitrate);

    SetTrackIntegerProperty(trackId,
                            "mdia.minf.stbl.stsd.s263.d263.bitr.maxBitrate",
                            maxBitrate);

}

MP4TrackId MP4File::AddH263VideoTrack(
    uint32_t timeScale,
    MP4Duration sampleDuration,
    uint16_t width,
    uint16_t height,
    uint8_t h263Level,
    uint8_t h263Profile,
    uint32_t avgBitrate,
    uint32_t maxBitrate)

{
    MP4TrackId trackId = AddVideoTrackDefault(timeScale,
                         sampleDuration,
                         width,
                         height,
                         "s263");

    SetTrackIntegerProperty(trackId,
                            "mdia.minf.stbl.stsd.s263.width", width);
    SetTrackIntegerProperty(trackId,
                            "mdia.minf.stbl.stsd.s263.height", height);

    SetTrackIntegerProperty(trackId,
                            "mdia.minf.stbl.stsd.s263.d263.h263Level", h263Level);

    SetTrackIntegerProperty(trackId,
                            "mdia.minf.stbl.stsd.s263.d263.h263Profile", h263Profile);

    // Add the bitr atom
    (void)AddChildAtom(MakeTrackName(trackId, "mdia.minf.stbl.stsd.s263.d263"),
                       "bitr");

    SetTrackIntegerProperty(trackId,
                            "mdia.minf.stbl.stsd.s263.d263.bitr.avgBitrate", avgBitrate);

    SetTrackIntegerProperty(trackId,
                            "mdia.minf.stbl.stsd.s263.d263.bitr.maxBitrate", maxBitrate);


    SetTrackIntegerProperty(trackId,
                            "mdia.minf.stbl.stsz.sampleSize", sampleDuration);

    return trackId;

}

MP4TrackId MP4File::AddHintTrack(MP4TrackId refTrackId)
{
    // validate reference track id
    (void)FindTrackIndex(refTrackId);

    MP4TrackId trackId =
        AddTrack(MP4_HINT_TRACK_TYPE, GetTrackTimeScale(refTrackId));

    (void)InsertChildAtom(MakeTrackName(trackId, "mdia.minf"), "hmhd", 0);

    (void)AddChildAtom(MakeTrackName(trackId, "mdia.minf.stbl.stsd"), "rtp ");

    // stsd is a unique beast in that it has a count of the number
    // of child atoms that needs to be incremented after we add the rtp atom
    MP4Integer32Property* pStsdCountProperty;
    FindIntegerProperty(
        MakeTrackName(trackId, "mdia.minf.stbl.stsd.entryCount"),
        (MP4Property**)&pStsdCountProperty);
    pStsdCountProperty->IncrementValue();

    SetTrackIntegerProperty(trackId,
                            "mdia.minf.stbl.stsd.rtp .tims.timeScale",
                            GetTrackTimeScale(trackId));

    (void)AddDescendantAtoms(MakeTrackName(trackId, NULL), "tref.hint");

    AddTrackReference(MakeTrackName(trackId, "tref.hint"), refTrackId);

    (void)AddDescendantAtoms(MakeTrackName(trackId, NULL), "udta.hnti.sdp ");

    (void)AddDescendantAtoms(MakeTrackName(trackId, NULL), "udta.hinf");

    return trackId;
}

MP4TrackId MP4File::AddTextTrack(MP4TrackId refTrackId)
{
    // validate reference track id
    (void)FindTrackIndex(refTrackId);

    MP4TrackId trackId =
        AddTrack(MP4_TEXT_TRACK_TYPE, GetTrackTimeScale(refTrackId));

    (void)InsertChildAtom(MakeTrackName(trackId, "mdia.minf"), "gmhd", 0);

    (void)AddChildAtom(MakeTrackName(trackId, "mdia.minf.stbl.stsd"), "text");

    // stsd is a unique beast in that it has a count of the number
    // of child atoms that needs to be incremented after we add the text atom
    MP4Integer32Property* pStsdCountProperty;
    FindIntegerProperty(
        MakeTrackName(trackId, "mdia.minf.stbl.stsd.entryCount"),
        (MP4Property**)&pStsdCountProperty);
    pStsdCountProperty->IncrementValue();

    return trackId;
}

MP4TrackId MP4File::AddSubtitleTrack(uint32_t timescale,
                                     uint16_t width,
                                     uint16_t height)
{
    MP4TrackId trackId =
        AddTrack(MP4_SUBTITLE_TRACK_TYPE, timescale);

    InsertChildAtom(MakeTrackName(trackId, "mdia.minf"), "nmhd", 0);

    AddChildAtom(MakeTrackName(trackId, "mdia.minf.stbl.stsd"), "tx3g");

    SetTrackFloatProperty(trackId, "tkhd.width", width);
    SetTrackFloatProperty(trackId, "tkhd.height", height);

    // Hardcoded crap... add the ftab atom and add one font entry
    MP4Atom* pFtabAtom = AddChildAtom(MakeTrackName(trackId, "mdia.minf.stbl.stsd.tx3g"), "ftab");

    ((MP4Integer16Property*)pFtabAtom->GetProperty(0))->IncrementValue();

    MP4Integer16Property* pfontID = (MP4Integer16Property*)((MP4TableProperty*)pFtabAtom->GetProperty(1))->GetProperty(0);
    pfontID->AddValue(1);

    MP4StringProperty* pName = (MP4StringProperty*)((MP4TableProperty*)pFtabAtom->GetProperty(1))->GetProperty(1);
    pName->AddValue("Arial");

    SetTrackIntegerProperty(trackId, "mdia.minf.stbl.stsd.tx3g.fontID", 1);

    // stsd is a unique beast in that it has a count of the number
    // of child atoms that needs to be incremented after we add the tx3g atom
    MP4Integer32Property* pStsdCountProperty;
    FindIntegerProperty(
        MakeTrackName(trackId, "mdia.minf.stbl.stsd.entryCount"),
        (MP4Property**)&pStsdCountProperty);
    pStsdCountProperty->IncrementValue();

    return trackId;
}

MP4TrackId MP4File::AddSubpicTrack(uint32_t timescale,
                                     uint16_t width,
                                     uint16_t height)
{
    MP4TrackId trackId =
        AddTrack(MP4_SUBPIC_TRACK_TYPE, timescale);

    InsertChildAtom(MakeTrackName(trackId, "mdia.minf"), "nmhd", 0);

    (void)AddChildAtom(MakeTrackName(trackId, "mdia.minf.stbl.stsd"), "mp4s");

    SetTrackFloatProperty(trackId, "tkhd.width", width);
    SetTrackFloatProperty(trackId, "tkhd.height", height);
    SetTrackIntegerProperty(trackId, "tkhd.layer", 0);

    // stsd is a unique beast in that it has a count of the number
    // of child atoms that needs to be incremented after we add the mp4s atom
    MP4Integer32Property* pStsdCountProperty;
    FindIntegerProperty(
        MakeTrackName(trackId, "mdia.minf.stbl.stsd.entryCount"),
        (MP4Property**)&pStsdCountProperty);
    pStsdCountProperty->IncrementValue();

    SetTrackIntegerProperty(trackId,
                            "mdia.minf.stbl.stsd.mp4s.esds.ESID",
                            0
                           );

    SetTrackIntegerProperty(trackId,
                            "mdia.minf.stbl.stsd.mp4s.esds.decConfigDescr.objectTypeId",
                            MP4SubpicObjectType);

    SetTrackIntegerProperty(trackId,
                            "mdia.minf.stbl.stsd.mp4s.esds.decConfigDescr.streamType",
                            MP4NeroSubpicStreamType);
    return trackId;
}

MP4TrackId MP4File::AddChapterTextTrack(MP4TrackId refTrackId, uint32_t timescale)
{
    // validate reference track id
    (void)FindTrackIndex(refTrackId);

    if (0 == timescale)
    {
        timescale = GetTrackTimeScale(refTrackId);
    }

    MP4TrackId trackId = AddTrack(MP4_TEXT_TRACK_TYPE, timescale);

    (void)InsertChildAtom(MakeTrackName(trackId, "mdia.minf"), "gmhd", 0);

    (void)AddChildAtom(MakeTrackName(trackId, "mdia.minf.stbl.stsd"), "text");

    // stsd is a unique beast in that it has a count of the number
    // of child atoms that needs to be incremented after we add the text atom
    MP4Integer32Property* pStsdCountProperty;
    FindIntegerProperty(
        MakeTrackName(trackId, "mdia.minf.stbl.stsd.entryCount"),
        (MP4Property**)&pStsdCountProperty);
    pStsdCountProperty->IncrementValue();

    // add a "text" atom to the generic media header
    // this is different to the stsd "text" atom added above
    // truth be told, it's not clear what this second "text" atom does,
    // but all iTunes Store movies (with chapter markers) have it,
    // as do all movies with chapter tracks made by hand in QuickTime Pro
    (void)AddChildAtom(MakeTrackName(trackId, "mdia.minf.gmhd"), "text");

    // disable the chapter text track
    // it won't display anyway, as it has zero display size,
    // but nonetheless it's good to disable it
    // the track still operates as a chapter track when disabled
    MP4Atom *pTkhdAtom = FindAtom(MakeTrackName(trackId, "tkhd"));
    if (pTkhdAtom) {
        pTkhdAtom->SetFlags(0xE);
    }

    // add a "chapter" track reference to our reference track,
    // pointing to this new chapter track
    (void)AddDescendantAtoms(MakeTrackName(refTrackId, NULL), "tref.chap");
    AddTrackReference(MakeTrackName(refTrackId, "tref.chap"), trackId);

    return trackId;
}

MP4TrackId MP4File::AddPixelAspectRatio(MP4TrackId trackId, uint32_t hSpacing, uint32_t vSpacing)
{
    // validate reference track id
    (void)FindTrackIndex(trackId);
    const char *format = GetTrackMediaDataName (trackId);

    if (!strcasecmp(format, "avc1"))
    {
        (void)AddChildAtom(MakeTrackName(trackId, "mdia.minf.stbl.stsd.avc1"), "pasp");
        SetTrackIntegerProperty(trackId, "mdia.minf.stbl.stsd.avc1.pasp.hSpacing", hSpacing);
        SetTrackIntegerProperty(trackId, "mdia.minf.stbl.stsd.avc1.pasp.vSpacing", vSpacing);
    }
    else if (!strcasecmp(format, "mp4v"))
    {
        (void)AddChildAtom(MakeTrackName(trackId, "mdia.minf.stbl.stsd.mp4v"), "pasp");
        SetTrackIntegerProperty(trackId, "mdia.minf.stbl.stsd.mp4v.pasp.hSpacing", hSpacing);
        SetTrackIntegerProperty(trackId, "mdia.minf.stbl.stsd.mp4v.pasp.vSpacing", vSpacing);
    }

    return trackId;
}

MP4TrackId MP4File::AddColr(MP4TrackId trackId,
                            uint16_t primariesIndex,
                            uint16_t transferFunctionIndex,
                            uint16_t matrixIndex)
{
    // validate reference track id
    (void)FindTrackIndex(trackId);
    const char *format = GetTrackMediaDataName (trackId);

    if (!strcasecmp(format, "avc1"))
    {
        AddChildAtom(MakeTrackName(trackId, "mdia.minf.stbl.stsd.avc1"), "colr");
        SetTrackIntegerProperty(trackId, "mdia.minf.stbl.stsd.avc1.colr.primariesIndex", primariesIndex);
        SetTrackIntegerProperty(trackId, "mdia.minf.stbl.stsd.avc1.colr.transferFunctionIndex", transferFunctionIndex);
        SetTrackIntegerProperty(trackId, "mdia.minf.stbl.stsd.avc1.colr.matrixIndex", matrixIndex);
    }
    else if (!strcasecmp(format, "mp4v"))
    {
        AddChildAtom(MakeTrackName(trackId, "mdia.minf.stbl.stsd.mp4v"), "colr");
        SetTrackIntegerProperty(trackId, "mdia.minf.stbl.stsd.mp4v.colr.primariesIndex", primariesIndex);
        SetTrackIntegerProperty(trackId, "mdia.minf.stbl.stsd.mp4v.colr.transferFunctionIndex", transferFunctionIndex);
        SetTrackIntegerProperty(trackId, "mdia.minf.stbl.stsd.mp4v.colr.matrixIndex", matrixIndex);
    }

    return trackId;
}


void MP4File::AddChapter(MP4TrackId chapterTrackId, MP4Duration chapterDuration, const char *chapterTitle)
{
    if (MP4_INVALID_TRACK_ID == chapterTrackId)
    {
        throw new Exception("No chapter track given",__FILE__, __LINE__, __FUNCTION__);
    }

    uint32_t sampleLength = 0;
    uint8_t  sample[1040] = {0};
    int textLen = 0;
    char *text = (char *)&(sample[2]);

    if(chapterTitle != NULL)
    {
        textLen = min((uint32_t)strlen(chapterTitle), (uint32_t)MP4V2_CHAPTER_TITLE_MAX);
        if (0 < textLen)
        {
            strncpy(text, chapterTitle, textLen);
        }
    }
    else
    {
        MP4Track * pChapterTrack = GetTrack(chapterTrackId);
        snprintf( text, 1023, "Chapter %03d", pChapterTrack->GetNumberOfSamples() + 1 );
        textLen = (uint32_t)strlen(text);
    }

    sampleLength = textLen + 2 + 12; // Account for text length code and other marker

    // 2-byte length marker
    sample[0] = (textLen >> 8) & 0xff;
    sample[1] = textLen & 0xff;

    int x = 2 + textLen;

    // Modifier Length Marker
    sample[x] = 0x00;
    sample[x+1] = 0x00;
    sample[x+2] = 0x00;
    sample[x+3] = 0x0C;

    // Modifier Type Code
    sample[x+4] = 'e';
    sample[x+5] = 'n';
    sample[x+6] = 'c';
    sample[x+7] = 'd';

    // Modifier Value
    sample[x+8] = 0x00;
    sample[x+9] = 0x00;
    sample[x+10] = (256 >> 8) & 0xff;
    sample[x+11] = 256 & 0xff;

    WriteSample(chapterTrackId, sample, sampleLength, chapterDuration);
}

void MP4File::AddNeroChapter(MP4Timestamp chapterStart, const char * chapterTitle)
{
    MP4Atom * pChpl = FindAtom("moov.udta.chpl");
    if (!pChpl)
    {
        pChpl = AddDescendantAtoms("", "moov.udta.chpl");
    }

    MP4Integer32Property * pCount = (MP4Integer32Property*)pChpl->GetProperty(3);
    pCount->IncrementValue();

    char buffer[256];

    if (0 == chapterTitle)
    {
        snprintf( buffer, 255, "Chapter %03d", pCount->GetValue() );
    }
    else
    {
        int len = min((uint32_t)strlen(chapterTitle), (uint32_t)255);
        strncpy( buffer, chapterTitle, len );
        buffer[len] = 0;
    }

    MP4TableProperty * pTable;
    if (pChpl->FindProperty("chpl.chapters", (MP4Property **)&pTable))
    {
        MP4Integer64Property * pStartTime = (MP4Integer64Property *) pTable->GetProperty(0);
        MP4StringProperty * pName = (MP4StringProperty *) pTable->GetProperty(1);
        if (pStartTime && pTable)
        {
            pStartTime->AddValue(chapterStart);
            pName->AddValue(buffer);
        }
    }
}

MP4TrackId MP4File::FindChapterReferenceTrack(MP4TrackId chapterTrackId, char * trackName, int trackNameSize)
{
    for (uint32_t i = 0; i < m_pTracks.Size(); i++)
    {
        if( MP4_IS_VIDEO_TRACK_TYPE( m_pTracks[i]->GetType() ) ||
            MP4_IS_AUDIO_TRACK_TYPE( m_pTracks[i]->GetType() ) )
        {
            MP4TrackId refTrackId = m_pTracks[i]->GetId();
            char *name = MakeTrackName(refTrackId, "tref.chap");
            if( FindTrackReference( name, chapterTrackId ) )
            {
                if( 0 != trackName )
                {
                    int nameLen = min((uint32_t)strlen(name), (uint32_t)trackNameSize);
                    strncpy(trackName, name, nameLen);
                    trackName[nameLen] = 0;
                }

                return m_pTracks[i]->GetId();
            }
        }
    }

    return MP4_INVALID_TRACK_ID;
}

MP4TrackId MP4File::FindChapterTrack(char * trackName, int trackNameSize)
{
    for (uint32_t i = 0; i < m_pTracks.Size(); i++)
    {
        if( !strcasecmp(MP4_TEXT_TRACK_TYPE, m_pTracks[i]->GetType()) )
        {
            MP4TrackId refTrackId = FindChapterReferenceTrack(m_pTracks[i]->GetId(), trackName, trackNameSize);
            if (MP4_INVALID_TRACK_ID != refTrackId)
            {
                return m_pTracks[i]->GetId();
            }
        }
    }

    return MP4_INVALID_TRACK_ID;
}

MP4ChapterType MP4File::DeleteChapters(MP4ChapterType chapterType, MP4TrackId chapterTrackId)
{
    MP4ChapterType deletedType = MP4ChapterTypeNone;

    if (MP4ChapterTypeAny == chapterType || MP4ChapterTypeNero == chapterType)
    {
        MP4Atom * pChpl = FindAtom("moov.udta.chpl");
        if (pChpl)
        {
            MP4Atom * pParent = pChpl->GetParentAtom();
            pParent->DeleteChildAtom(pChpl);
            deletedType = MP4ChapterTypeNero;
        }
    }

    if (MP4ChapterTypeAny == chapterType || MP4ChapterTypeQt == chapterType)
    {
        char trackName[128] = {0};

        // no text track given, find a suitable
        if (MP4_INVALID_TRACK_ID == chapterTrackId)
        {
            chapterTrackId = FindChapterTrack(trackName, 127);
        }

        if (MP4_INVALID_TRACK_ID != chapterTrackId)
        {
            FindChapterReferenceTrack(chapterTrackId, trackName, 127);
        }

        if (MP4_INVALID_TRACK_ID != chapterTrackId && 0 != trackName[0])
        {
            // remove the reference
            MP4Atom * pChap = FindAtom( trackName );
            if( pChap )
            {
                MP4Atom * pTref = pChap->GetParentAtom();
                if( pTref )
                {
                    pTref->DeleteChildAtom( pChap );

                    MP4Atom* pParent = pTref->GetParentAtom();
                    pParent->DeleteChildAtom( pTref );
                }
            }

            // remove the chapter track
            DeleteTrack(chapterTrackId);
            deletedType = MP4ChapterTypeNone == deletedType ? MP4ChapterTypeQt : MP4ChapterTypeAny;
        }
    }
    return deletedType;
}

MP4ChapterType MP4File::GetChapters(MP4Chapter_t ** chapterList, uint32_t * chapterCount, MP4ChapterType fromChapterType)
{
    *chapterList = 0;
    *chapterCount = 0;

    if (MP4ChapterTypeAny == fromChapterType || MP4ChapterTypeQt == fromChapterType)
    {
        uint8_t * sample = 0;
        uint32_t sampleSize = 0;
        MP4Timestamp startTime = 0;
        MP4Duration duration = 0;

        // get the chapter track
        MP4TrackId chapterTrackId = FindChapterTrack();
        if (MP4_INVALID_TRACK_ID == chapterTrackId)
        {
            if (MP4ChapterTypeQt == fromChapterType)
            {
                return MP4ChapterTypeNone;
            }
        }
        else
        {
            // get infos about the chapters
            MP4Track * pChapterTrack = GetTrack(chapterTrackId);
            uint32_t counter = pChapterTrack->GetNumberOfSamples();

            if (0 < counter)
            {
                uint32_t timescale = pChapterTrack->GetTimeScale();
                MP4Chapter_t * chapters = (MP4Chapter_t*)MP4Malloc(sizeof(MP4Chapter_t) * counter);

                // process all chapter sample
                for (uint32_t i = 0; i < counter; ++i)
                {
                    // get the sample corresponding to the starttime
                    MP4SampleId sampleId = pChapterTrack->GetSampleIdFromTime(startTime + duration, true);
                    pChapterTrack->ReadSample(sampleId, &sample, &sampleSize);

                    // get the starttime and duration
                    pChapterTrack->GetSampleTimes(sampleId, &startTime, &duration);

                    // we know that sample+2 contains the title (sample[0] and sample[1] is the length)
                    const char * title = (const char *)&(sample[2]);
                    int titleLen = min((uint32_t)((sample[0] << 8) | sample[1]), (uint32_t)MP4V2_CHAPTER_TITLE_MAX);
                    strncpy(chapters[i].title, title, titleLen);
                    chapters[i].title[titleLen] = 0;

                    // write the duration (in milliseconds)
                    chapters[i].duration = MP4ConvertTime(duration, timescale, MP4_MILLISECONDS_TIME_SCALE);

                    // we're done with this sample
                    MP4Free(sample);
                    sample = 0;
                }

                *chapterList = chapters;
                *chapterCount = counter;

                // we got chapters so we are done
                return MP4ChapterTypeQt;
            }
        }
    }

    if (MP4ChapterTypeAny == fromChapterType || MP4ChapterTypeNero == fromChapterType)
    {
        MP4Atom * pChpl = FindAtom("moov.udta.chpl");
        if (!pChpl)
        {
            return MP4ChapterTypeNone;
        }

        MP4Integer32Property * pCounter = 0;
        if (!pChpl->FindProperty("chpl.chaptercount", (MP4Property **)&pCounter))
        {
            log.warningf("%s: \"%s\": Nero chapter count does not exist",
                         __FUNCTION__, GetFilename().c_str());
            return MP4ChapterTypeNone;
        }

        uint32_t counter = pCounter->GetValue();
        if (0 == counter)
        {
            log.warningf("%s: \"%s\": No Nero chapters available",
                         __FUNCTION__, GetFilename().c_str());
            return MP4ChapterTypeNone;
        }

        MP4TableProperty * pTable = 0;
        MP4Integer64Property * pStartTime = 0;
        MP4StringProperty * pName = 0;
        MP4Duration chapterDurationSum = 0;
        const char * name = 0;

        if (!pChpl->FindProperty("chpl.chapters", (MP4Property **)&pTable))
        {
            log.warningf("%s: \"%s\": Nero chapter list does not exist",
                         __FUNCTION__, GetFilename().c_str());
            return MP4ChapterTypeNone;
        }

        if (0 == (pStartTime = (MP4Integer64Property *) pTable->GetProperty(0)))
        {
            log.warningf("%s: \"%s\": List of Chapter starttimes does not exist",
                         __FUNCTION__, GetFilename().c_str());
            return MP4ChapterTypeNone;
        }
        if (0 == (pName = (MP4StringProperty *) pTable->GetProperty(1)))
        {
            log.warningf("%s: \"%s\": List of Chapter titles does not exist",
                         __FUNCTION__, GetFilename().c_str());
            return MP4ChapterTypeNone;
        }

        MP4Chapter_t * chapters = (MP4Chapter_t*)MP4Malloc(sizeof(MP4Chapter_t) * counter);

        // get the name of the first chapter
        name = pName->GetValue();

        // process remaining chapters
        uint32_t i, j;
        for (i = 0, j = 1; i < counter; ++i, ++j)
        {
            // insert the chapter title
            uint32_t len = min((uint32_t)strlen(name), (uint32_t)MP4V2_CHAPTER_TITLE_MAX);
            strncpy(chapters[i].title, name, len);
            chapters[i].title[len] = 0;

            // calculate the duration
            MP4Duration duration = 0;
            if (j < counter)
            {
                duration = MP4ConvertTime(pStartTime->GetValue(j),
                                          (MP4_NANOSECONDS_TIME_SCALE / 100),
                                          MP4_MILLISECONDS_TIME_SCALE) - chapterDurationSum;

                // now get the name of the chapter (to be written next)
                name = pName->GetValue(j);
            }
            else
            {
                // last chapter
                duration = MP4ConvertTime(GetDuration(), GetTimeScale(), MP4_MILLISECONDS_TIME_SCALE) - chapterDurationSum;
            }

            // sum up the chapter duration
            chapterDurationSum += duration;

            // insert the chapter duration
            chapters[i].duration = duration;
        }

        *chapterList = chapters;
        *chapterCount = counter;

        return MP4ChapterTypeNero;
    }

    return MP4ChapterTypeNone;
}

MP4ChapterType MP4File::SetChapters(MP4Chapter_t * chapterList, uint32_t chapterCount, MP4ChapterType toChapterType)
{
    MP4ChapterType setType = MP4ChapterTypeNone;

    // first remove any existing chapters
    DeleteChapters(toChapterType, MP4_INVALID_TRACK_ID);

    if( MP4ChapterTypeAny == toChapterType || MP4ChapterTypeNero == toChapterType )
    {
        MP4Duration duration = 0;
        for( uint32_t i = 0; i < chapterCount; ++i )
        {
            AddNeroChapter(duration, chapterList[i].title);
            duration += 10 * MP4_MILLISECONDS_TIME_SCALE * chapterList[i].duration;
        }

        setType = MP4ChapterTypeNero;
    }

    if (MP4ChapterTypeAny == toChapterType || MP4ChapterTypeQt == toChapterType)
    {
        // find the first video or audio track
        MP4TrackId refTrack = MP4_INVALID_TRACK_ID;
        for( uint32_t i = 0; i < m_pTracks.Size(); i++ )
        {
            if( MP4_IS_VIDEO_TRACK_TYPE( m_pTracks[i]->GetType() ) ||
                MP4_IS_AUDIO_TRACK_TYPE( m_pTracks[i]->GetType() ) )
            {
                refTrack = m_pTracks[i]->GetId();
                break;
            }
        }

        if( refTrack == MP4_INVALID_TRACK_ID )
        {
            return setType;
        }

        // create the chapter track
        MP4TrackId chapterTrack = AddChapterTextTrack(refTrack, MP4_MILLISECONDS_TIME_SCALE);

        for( uint32_t i = 0 ; i < chapterCount; ++i )
        {
            // create and write the chapter track sample
            AddChapter( chapterTrack, chapterList[i].duration, chapterList[i].title );
        }

        setType = MP4ChapterTypeNone == setType ? MP4ChapterTypeQt : MP4ChapterTypeAny;
    }

    return setType;
}

MP4ChapterType MP4File::ConvertChapters(MP4ChapterType toChapterType)
{
    MP4ChapterType sourceType = MP4ChapterTypeNone;
    const char* errMsg = 0;

    if( MP4ChapterTypeQt == toChapterType )
    {
        sourceType = MP4ChapterTypeNero;
        errMsg = "Could not find Nero chapter markers";
    }
    else if( MP4ChapterTypeNero == toChapterType )
    {
        sourceType = MP4ChapterTypeQt;
        errMsg = "Could not find QuickTime chapter markers";
    }
    else
    {
        return MP4ChapterTypeNone;
    }

    MP4Chapter_t * chapters = 0;
    uint32_t chapterCount = 0;

    GetChapters(&chapters, &chapterCount, sourceType);
    if (0 == chapterCount)
    {
        log.warningf("%s: \"%s\": %s", __FUNCTION__, GetFilename().c_str(),
                     errMsg);
        return MP4ChapterTypeNone;
    }

    SetChapters(chapters, chapterCount, toChapterType);

    MP4Free(chapters);

    return toChapterType;
}

void MP4File::ChangeMovieTimeScale(uint32_t timescale)
{
    uint32_t origTimeScale = GetTimeScale();
    if (timescale == origTimeScale) {
        // already done
        return;
    }

    MP4Duration movieDuration = GetDuration();

    // set movie header timescale and duration
    SetTimeScale(timescale);
    SetDuration(MP4ConvertTime(movieDuration, origTimeScale, timescale));

    // set track header duration (calculated with movie header timescale)
    uint32_t trackCount = GetNumberOfTracks();
    for (uint32_t i = 0; i < trackCount; ++i)
    {
        MP4Track * track = GetTrack(FindTrackId(i));
        MP4Atom & trackAtom = track->GetTrakAtom();
        MP4IntegerProperty * duration;

        if (trackAtom.FindProperty("trak.tkhd.duration", (MP4Property**)&duration))
        {
            duration->SetValue(MP4ConvertTime(duration->GetValue(), origTimeScale, timescale));
        }
    }
}

void MP4File::DeleteTrack(MP4TrackId trackId)
{
    ProtectWriteOperation(__FILE__, __LINE__, __FUNCTION__);

    uint32_t trakIndex = FindTrakAtomIndex(trackId);
    uint16_t trackIndex = FindTrackIndex(trackId);
    MP4Track* pTrack = m_pTracks[trackIndex];

    MP4Atom& trakAtom = pTrack->GetTrakAtom();

    MP4Atom* pMoovAtom = FindAtom("moov");
    ASSERT(pMoovAtom);

    RemoveTrackFromIod(trackId, ShallHaveIods());
    RemoveTrackFromOd(trackId);

    if (trackId == m_odTrackId) {
        m_odTrackId = 0;
    }

    pMoovAtom->DeleteChildAtom(&trakAtom);

    m_trakIds.Delete(trakIndex);

    m_pTracks.Delete(trackIndex);

    delete pTrack;
    delete &trakAtom;
}

uint32_t MP4File::GetNumberOfTracks(const char* type, uint8_t subType)
{
    if (type == NULL) {
        return m_pTracks.Size();
    }

    uint32_t typeSeen = 0;
    const char* normType = MP4NormalizeTrackType(type);

    for (uint32_t i = 0; i < m_pTracks.Size(); i++) {
        if (!strcmp(normType, m_pTracks[i]->GetType())) {
            if (subType) {
                if (strcmp(normType, MP4_AUDIO_TRACK_TYPE) == 0) {
                    if (subType != GetTrackEsdsObjectTypeId(m_pTracks[i]->GetId())) {
                        continue;
                    }
                } else if (strcmp(normType, MP4_VIDEO_TRACK_TYPE)) {
                    if (subType != GetTrackEsdsObjectTypeId(m_pTracks[i]->GetId())) {
                        continue;
                    }
                }
                // else unknown subtype, ignore it
            }
            typeSeen++;
        }
    }
    return typeSeen;
}

MP4TrackId MP4File::AllocTrackId()
{
    MP4TrackId trackId =
        GetIntegerProperty("moov.mvhd.nextTrackId");

    if (trackId <= 0xFFFF) {
        // check that nextTrackid is correct
        try {
            (void)FindTrackIndex(trackId);
            // ERROR, this trackId is in use
        }
        catch (Exception* x) {
            // OK, this trackId is not in use, proceed
            delete x;
            SetIntegerProperty("moov.mvhd.nextTrackId", trackId + 1);
            return trackId;
        }
    }

    // we need to search for a track id
    for (trackId = 1; trackId <= 0xFFFF; trackId++) {
        try {
            (void)FindTrackIndex(trackId);
            // KEEP LOOKING, this trackId is in use
        }
        catch (Exception* x) {
            // OK, this trackId is not in use, proceed
            delete x;
            return trackId;
        }
    }

    // extreme case where mp4 file has 2^16 tracks in it
    throw new Exception("too many existing tracks", __FILE__, __LINE__, __FUNCTION__);
    return MP4_INVALID_TRACK_ID;        // to keep MSVC happy
}

MP4TrackId MP4File::FindTrackId(uint16_t trackIndex,
                                const char* type, uint8_t subType)
{
    if (type == NULL) {
        return m_pTracks[trackIndex]->GetId();
    }

    uint32_t typeSeen = 0;
    const char* normType = MP4NormalizeTrackType(type);

    for (uint32_t i = 0; i < m_pTracks.Size(); i++) {
        if (!strcmp(normType, m_pTracks[i]->GetType())) {
            if (subType) {
                if (strcmp(normType, MP4_AUDIO_TRACK_TYPE) == 0) {
                    if (subType != GetTrackEsdsObjectTypeId(m_pTracks[i]->GetId())) {
                        continue;
                    }
                } else if (strcmp(normType, MP4_VIDEO_TRACK_TYPE) == 0) {
                    if (subType != GetTrackEsdsObjectTypeId(m_pTracks[i]->GetId())) {
                        continue;
                    }
                }
                // else unknown subtype, ignore it
            }

            if (trackIndex == typeSeen) {
                return m_pTracks[i]->GetId();
            }

            typeSeen++;
        }
    }

    ostringstream msg;
    msg << "Track index doesn't exist - track " << trackIndex << " type " << type;
    throw new Exception(msg.str(),__FILE__, __LINE__, __FUNCTION__);
    return MP4_INVALID_TRACK_ID; // satisfy MS compiler
}

uint16_t MP4File::FindTrackIndex(MP4TrackId trackId)
{
    for (uint32_t i = 0; i < m_pTracks.Size() && i <= 0xFFFF; i++) {
        if (m_pTracks[i]->GetId() == trackId) {
            return (uint16_t)i;
        }
    }

    ostringstream msg;
    msg << "Track id " << trackId << " doesn't exist";
    throw new Exception(msg.str(),__FILE__, __LINE__, __FUNCTION__);
    return (uint16_t)-1; // satisfy MS compiler
}

uint16_t MP4File::FindTrakAtomIndex(MP4TrackId trackId)
{
    if (trackId) {
        for (uint32_t i = 0; i < m_trakIds.Size(); i++) {
            if (m_trakIds[i] == trackId) {
                return i;
            }
        }
    }

    ostringstream msg;
    msg << "Track id " << trackId << " doesn't exist";
    throw new Exception(msg.str(),__FILE__, __LINE__, __FUNCTION__);
    return (uint16_t)-1; // satisfy MS compiler
}

uint32_t MP4File::GetSampleSize(MP4TrackId trackId, MP4SampleId sampleId)
{
    return m_pTracks[FindTrackIndex(trackId)]->GetSampleSize(sampleId);
}

uint32_t MP4File::GetTrackMaxSampleSize(MP4TrackId trackId)
{
    return m_pTracks[FindTrackIndex(trackId)]->GetMaxSampleSize();
}

MP4SampleId MP4File::GetSampleIdFromTime(MP4TrackId trackId,
        MP4Timestamp when, bool wantSyncSample)
{
    return m_pTracks[FindTrackIndex(trackId)]->
           GetSampleIdFromTime(when, wantSyncSample);
}

MP4Timestamp MP4File::GetSampleTime(
    MP4TrackId trackId, MP4SampleId sampleId)
{
    MP4Timestamp timestamp;
    m_pTracks[FindTrackIndex(trackId)]->
    GetSampleTimes(sampleId, &timestamp, NULL);
    return timestamp;
}

MP4Duration MP4File::GetSampleDuration(
    MP4TrackId trackId, MP4SampleId sampleId)
{
    MP4Duration duration;
    m_pTracks[FindTrackIndex(trackId)]->
    GetSampleTimes(sampleId, NULL, &duration);
    return duration;
}

MP4Duration MP4File::GetSampleRenderingOffset(
    MP4TrackId trackId, MP4SampleId sampleId)
{
    return m_pTracks[FindTrackIndex(trackId)]->
           GetSampleRenderingOffset(sampleId);
}

bool MP4File::GetSampleSync(MP4TrackId trackId, MP4SampleId sampleId)
{
    return m_pTracks[FindTrackIndex(trackId)]->IsSyncSample(sampleId);
}

void MP4File::ReadSample(
    MP4TrackId    trackId,
    MP4SampleId   sampleId,
    uint8_t**     ppBytes,
    uint32_t*     pNumBytes,
    MP4Timestamp* pStartTime,
    MP4Duration*  pDuration,
    MP4Duration*  pRenderingOffset,
    bool*         pIsSyncSample,
    bool*         hasDependencyFlags,
    uint32_t*     dependencyFlags )
{
    m_pTracks[FindTrackIndex(trackId)]->ReadSample(
        sampleId,
        ppBytes,
        pNumBytes,
        pStartTime,
        pDuration,
        pRenderingOffset,
        pIsSyncSample,
        hasDependencyFlags,
        dependencyFlags );
}

void MP4File::WriteSample(
    MP4TrackId     trackId,
    const uint8_t* pBytes,
    uint32_t       numBytes,
    MP4Duration    duration,
    MP4Duration    renderingOffset,
    bool           isSyncSample )
{
    ProtectWriteOperation(__FILE__, __LINE__, __FUNCTION__);
    m_pTracks[FindTrackIndex(trackId)]->WriteSample(
        pBytes, numBytes, duration, renderingOffset, isSyncSample );
    m_pModificationProperty->SetValue( MP4GetAbsTimestamp() );
}

void MP4File::WriteSampleDependency(
    MP4TrackId     trackId,
    const uint8_t* pBytes,
    uint32_t       numBytes,
    MP4Duration    duration,
    MP4Duration    renderingOffset,
    bool           isSyncSample,
    uint32_t       dependencyFlags )
{
    ProtectWriteOperation(__FILE__, __LINE__, __FUNCTION__);
    m_pTracks[FindTrackIndex(trackId)]->WriteSampleDependency(
        pBytes, numBytes, duration, renderingOffset, isSyncSample, dependencyFlags );
    m_pModificationProperty->SetValue( MP4GetAbsTimestamp() );
}

void MP4File::SetSampleRenderingOffset(MP4TrackId trackId,
                                       MP4SampleId sampleId, MP4Duration renderingOffset)
{
    ProtectWriteOperation(__FILE__, __LINE__, __FUNCTION__);
    m_pTracks[FindTrackIndex(trackId)]->
    SetSampleRenderingOffset(sampleId, renderingOffset);

    m_pModificationProperty->SetValue(MP4GetAbsTimestamp());
}

void MP4File::MakeFtypAtom(
    char*    majorBrand,
    uint32_t minorVersion,
    char**   compatibleBrands,
    uint32_t compatibleBrandsCount)
{
    MP4FtypAtom* ftyp = (MP4FtypAtom*)m_pRootAtom->FindAtom( "ftyp" );
    if (ftyp == NULL)
        ftyp = (MP4FtypAtom*)InsertChildAtom( m_pRootAtom, "ftyp", 0 );

    // bail if majorbrand is not specified; defaults suffice.
    if (majorBrand == NULL)
        return;

    ftyp->majorBrand.SetValue( majorBrand );
    ftyp->minorVersion.SetValue( minorVersion );

    ftyp->compatibleBrands.SetCount( compatibleBrandsCount );
    for( uint32_t i = 0; i < compatibleBrandsCount; i++ )
        ftyp->compatibleBrands.SetValue( compatibleBrands[i], i );
}

char* MP4File::MakeTrackName(MP4TrackId trackId, const char* name)
{
    uint16_t trakIndex = FindTrakAtomIndex(trackId);

    if (name == NULL || name[0] == '\0') {
        snprintf(m_trakName, sizeof(m_trakName),
                 "moov.trak[%u]", trakIndex);
    } else {
        snprintf(m_trakName, sizeof(m_trakName),
                 "moov.trak[%u].%s", trakIndex, name);
    }
    return m_trakName;
}

MP4Atom *MP4File::FindTrackAtom (MP4TrackId trackId, const char *name)
{
    return FindAtom(MakeTrackName(trackId, name));
}

uint64_t MP4File::GetTrackIntegerProperty(MP4TrackId trackId, const char* name)
{
    return GetIntegerProperty(MakeTrackName(trackId, name));
}

void MP4File::SetTrackIntegerProperty(MP4TrackId trackId, const char* name,
                                      int64_t value)
{
    SetIntegerProperty(MakeTrackName(trackId, name), value);
}

float MP4File::GetTrackFloatProperty(MP4TrackId trackId, const char* name)
{
    return GetFloatProperty(MakeTrackName(trackId, name));
}

void MP4File::SetTrackFloatProperty(MP4TrackId trackId, const char* name,
                                    float value)
{
    SetFloatProperty(MakeTrackName(trackId, name), value);
}

const char* MP4File::GetTrackStringProperty(MP4TrackId trackId, const char* name)
{
    return GetStringProperty(MakeTrackName(trackId, name));
}

void MP4File::SetTrackStringProperty(MP4TrackId trackId, const char* name,
                                     const char* value)
{
    SetStringProperty(MakeTrackName(trackId, name), value);
}

void MP4File::GetTrackBytesProperty(MP4TrackId trackId, const char* name,
                                    uint8_t** ppValue, uint32_t* pValueSize)
{
    GetBytesProperty(MakeTrackName(trackId, name), ppValue, pValueSize);
}

void MP4File::SetTrackBytesProperty(MP4TrackId trackId, const char* name,
                                    const uint8_t* pValue, uint32_t valueSize)
{
    SetBytesProperty(MakeTrackName(trackId, name), pValue, valueSize);
}

bool MP4File::GetTrackLanguage( MP4TrackId trackId, char* code )
{
    ostringstream oss;
    oss << "moov.trak[" << FindTrakAtomIndex(trackId) << "].mdia.mdhd.language";

    MP4Property* prop;
    if( !m_pRootAtom->FindProperty( oss.str().c_str(), &prop ))
        return false;

    if( prop->GetType() != LanguageCodeProperty )
        return false;

    MP4LanguageCodeProperty& lang = *static_cast<MP4LanguageCodeProperty*>(prop);
    string slang;
    bmff::enumLanguageCode.toString( lang.GetValue(), slang );
    if( slang.length() != 3 ) {
        memset( code, '\0', 4 );
    }
    else {
        memcpy( code, slang.c_str(), 3 );
        code[3] = '\0';
    }

    return true;
}

bool MP4File::SetTrackLanguage( MP4TrackId trackId, const char* code )
{
    ProtectWriteOperation(__FILE__, __LINE__, __FUNCTION__);

    ostringstream oss;
    oss << "moov.trak[" << FindTrakAtomIndex(trackId) << "].mdia.mdhd.language";

    MP4Property* prop;
    if( !m_pRootAtom->FindProperty( oss.str().c_str(), &prop ))
        return false;

    if( prop->GetType() != LanguageCodeProperty )
        return false;

    MP4LanguageCodeProperty& lang = *static_cast<MP4LanguageCodeProperty*>(prop);
    lang.SetValue( bmff::enumLanguageCode.toType( code ));

    return true;
}


bool MP4File::GetTrackName( MP4TrackId trackId, char** name )
{
    unsigned char *val = NULL;
    uint32_t valSize = 0;
    MP4Atom *pMetaAtom;

    pMetaAtom = m_pRootAtom->FindAtom(MakeTrackName(trackId,"udta.name"));

    if (pMetaAtom)
    {
        GetBytesProperty(MakeTrackName(trackId,"udta.name.value"), (uint8_t**)&val, &valSize);
    }
    if (valSize > 0)
    {
        *name = (char*)malloc((valSize+1)*sizeof(char));
        if (*name == NULL) {
            free(val);
            return false;
        }
        memcpy(*name, val, valSize*sizeof(unsigned char));
        free(val);
        (*name)[valSize] = '\0';
        return true;
    }

    return false;
}

bool MP4File::SetTrackName( MP4TrackId trackId, const char* name )
{
    ProtectWriteOperation(__FILE__, __LINE__, __FUNCTION__);
    char atomstring[40];
    MP4Atom *pMetaAtom;
    MP4BytesProperty *pMetadataProperty = NULL;
    snprintf(atomstring, 40, "%s", MakeTrackName(trackId,"udta.name"));

    pMetaAtom = m_pRootAtom->FindAtom(atomstring);

    if (!pMetaAtom)
    {
        if (!AddDescendantAtoms(MakeTrackName(trackId, NULL), "udta.name"))
            return false;

        pMetaAtom = m_pRootAtom->FindAtom(atomstring);
        if (pMetaAtom == NULL) return false;
    }

    ASSERT(pMetaAtom->FindProperty("name.value",
                                   (MP4Property**)&pMetadataProperty));
    ASSERT(pMetadataProperty);

    pMetadataProperty->SetValue((uint8_t*)name, (uint32_t)strlen(name));

    return true;
}

// file level convenience functions

MP4Duration MP4File::GetDuration()
{
    return m_pDurationProperty->GetValue();
}

void MP4File::SetDuration(MP4Duration value)
{
    m_pDurationProperty->SetValue(value);
}

uint32_t MP4File::GetTimeScale()
{
    return m_pTimeScaleProperty->GetValue();
}

void MP4File::SetTimeScale(uint32_t value)
{
    if (value == 0) {
        throw new Exception("invalid value", __FILE__, __LINE__, __FUNCTION__);
    }
    m_pTimeScaleProperty->SetValue(value);
}

uint8_t MP4File::GetODProfileLevel()
{
    return GetIntegerProperty("moov.iods.ODProfileLevelId");
}

void MP4File::SetODProfileLevel(uint8_t value)
{
    SetIntegerProperty("moov.iods.ODProfileLevelId", value);
}

uint8_t MP4File::GetSceneProfileLevel()
{
    return GetIntegerProperty("moov.iods.sceneProfileLevelId");
}

void MP4File::SetSceneProfileLevel(uint8_t value)
{
    SetIntegerProperty("moov.iods.sceneProfileLevelId", value);
}

uint8_t MP4File::GetVideoProfileLevel()
{
    return GetIntegerProperty("moov.iods.visualProfileLevelId");
}

void MP4File::SetVideoProfileLevel(uint8_t value)
{
    SetIntegerProperty("moov.iods.visualProfileLevelId", value);
}

uint8_t MP4File::GetAudioProfileLevel()
{
    return GetIntegerProperty("moov.iods.audioProfileLevelId");
}

void MP4File::SetAudioProfileLevel(uint8_t value)
{
    SetIntegerProperty("moov.iods.audioProfileLevelId", value);
}

uint8_t MP4File::GetGraphicsProfileLevel()
{
    return GetIntegerProperty("moov.iods.graphicsProfileLevelId");
}

void MP4File::SetGraphicsProfileLevel(uint8_t value)
{
    SetIntegerProperty("moov.iods.graphicsProfileLevelId", value);
}

const char* MP4File::GetSessionSdp()
{
    return GetStringProperty("moov.udta.hnti.rtp .sdpText");
}

void MP4File::SetSessionSdp(const char* sdpString)
{
    (void)AddDescendantAtoms("moov", "udta.hnti.rtp ");

    SetStringProperty("moov.udta.hnti.rtp .sdpText", sdpString);
}

void MP4File::AppendSessionSdp(const char* sdpFragment)
{
    const char* oldSdpString = NULL;
    try {
        oldSdpString = GetSessionSdp();
    }
    catch (Exception* x) {
        delete x;
        SetSessionSdp(sdpFragment);
        return;
    }

    char* newSdpString =
        (char*)MP4Malloc(strlen(oldSdpString) + strlen(sdpFragment) + 1);
    strcpy(newSdpString, oldSdpString);
    strcat(newSdpString, sdpFragment);
    SetSessionSdp(newSdpString);
    MP4Free(newSdpString);
}

//
// ismacrypt API - retrieve OriginalFormatBox
//
// parameters are assumed to have been sanity tested in mp4.cpp
// don't call this unless media data name is 'encv',
// results may otherwise be unpredictable.
//
// input:
// trackID - valid encv track ID for this file
// buflen  - length of oFormat, minimum is 5 (4cc plus null terminator)
//
// output:
// oFormat - buffer to return null terminated string containing
//           track original format
// return:
// 0       - original format returned OK
// 1       - buffer length error or problem retrieving track property
//
//
bool MP4File::GetTrackMediaDataOriginalFormat(MP4TrackId trackId,
        char *originalFormat, uint32_t buflen)
{
    uint32_t format;

    if (buflen < 5)
        return false;

    format = GetTrackIntegerProperty(trackId,
                                     "mdia.minf.stbl.stsd.*.sinf.frma.data-format");

    IDATOM(format, originalFormat);
    return true;

}


// track level convenience functions

MP4SampleId MP4File::GetTrackNumberOfSamples(MP4TrackId trackId)
{
    return m_pTracks[FindTrackIndex(trackId)]->GetNumberOfSamples();
}

const char* MP4File::GetTrackType(MP4TrackId trackId)
{
    return m_pTracks[FindTrackIndex(trackId)]->GetType();
}

const char *MP4File::GetTrackMediaDataName (MP4TrackId trackId)
{
    MP4Atom *pChild;
    MP4Atom *pAtom =
        FindAtom(MakeTrackName(trackId,
                               "mdia.minf.stbl.stsd"));
    if (pAtom->GetNumberOfChildAtoms() != 1) {
        log.errorf("%s: \"%s\": track %d has more than 1 child atoms in stsd",
                   __FUNCTION__, GetFilename().c_str(), trackId);
        return NULL;
    }
    pChild = pAtom->GetChildAtom(0);
    return pChild->GetType();
}


uint32_t MP4File::GetTrackTimeScale(MP4TrackId trackId)
{
    return m_pTracks[FindTrackIndex(trackId)]->GetTimeScale();
}

void MP4File::SetTrackTimeScale(MP4TrackId trackId, uint32_t value)
{
    if (value == 0) {
        throw new Exception("invalid value", __FILE__, __LINE__, __FUNCTION__);
    }
    SetTrackIntegerProperty(trackId, "mdia.mdhd.timeScale", value);
}

MP4Duration MP4File::GetTrackDuration(MP4TrackId trackId)
{
    return GetTrackIntegerProperty(trackId, "mdia.mdhd.duration");
}

uint8_t MP4File::GetTrackEsdsObjectTypeId(MP4TrackId trackId)
{
    // changed mp4a to * to handle enca case
    try {
        return GetTrackIntegerProperty(trackId,
                                       "mdia.minf.stbl.stsd.*.esds.decConfigDescr.objectTypeId");
    } catch (Exception *x) {
        delete x;
        return GetTrackIntegerProperty(trackId,
                                       "mdia.minf.stbl.stsd.*.*.esds.decConfigDescr.objectTypeId");
    }
}

uint8_t MP4File::GetTrackAudioMpeg4Type(MP4TrackId trackId)
{
    // verify that track is an MPEG-4 audio track
    if (GetTrackEsdsObjectTypeId(trackId) != MP4_MPEG4_AUDIO_TYPE) {
        return MP4_MPEG4_INVALID_AUDIO_TYPE;
    }

    uint8_t* pEsConfig = NULL;
    uint32_t esConfigSize;

    // The Mpeg4 audio type (AAC, CELP, HXVC, ...)
    // is the first 5 bits of the ES configuration

    GetTrackESConfiguration(trackId, &pEsConfig, &esConfigSize);

    if (esConfigSize < 1) {
        free(pEsConfig);
        return MP4_MPEG4_INVALID_AUDIO_TYPE;
    }

    uint8_t mpeg4Type = ((pEsConfig[0] >> 3) & 0x1f);
    // TTTT TXXX XXX  potentially 6 bits of extension.
    if (mpeg4Type == 0x1f) {
        if (esConfigSize < 2) {
            free(pEsConfig);
            return MP4_MPEG4_INVALID_AUDIO_TYPE;
        }
        mpeg4Type = 32 +
                    (((pEsConfig[0] & 0x7) << 3) | ((pEsConfig[1] >> 5) & 0x7));
    }

    free(pEsConfig);

    return mpeg4Type;
}


MP4Duration MP4File::GetTrackFixedSampleDuration(MP4TrackId trackId)
{
    return m_pTracks[FindTrackIndex(trackId)]->GetFixedSampleDuration();
}

double MP4File::GetTrackVideoFrameRate(MP4TrackId trackId)
{
    MP4SampleId numSamples =
        GetTrackNumberOfSamples(trackId);
    uint64_t
    msDuration =
        ConvertFromTrackDuration(trackId,
                                 GetTrackDuration(trackId), MP4_MSECS_TIME_SCALE);

    if (msDuration == 0) {
        return 0.0;
    }

    return ((double)numSamples / double(msDuration)) * MP4_MSECS_TIME_SCALE;
}

int MP4File::GetTrackAudioChannels (MP4TrackId trackId)
{
    return GetTrackIntegerProperty(trackId,
                                   "mdia.minf.stbl.stsd.*[0].channels");
}

// true if media track encrypted according to ismacryp
bool MP4File::IsIsmaCrypMediaTrack(MP4TrackId trackId)
{
    if (GetTrackIntegerProperty(trackId,
                                "mdia.minf.stbl.stsd.*.sinf.frma.data-format")
            != (uint64_t)-1) {
        return true;
    }
    return false;
}

bool MP4File::IsWriteMode()
{
    if( !m_file )
        return false;

    switch( m_file->mode ) {
        case File::MODE_READ:
            return false;

        case File::MODE_MODIFY:
        case File::MODE_CREATE:
        default:
            break;
    }

    return true;
}

void MP4File::GetTrackESConfiguration(MP4TrackId trackId,
                                      uint8_t** ppConfig, uint32_t* pConfigSize)
{
    try {
        GetTrackBytesProperty(trackId,
                              "mdia.minf.stbl.stsd.*[0].esds.decConfigDescr.decSpecificInfo[0].info",
                              ppConfig, pConfigSize);
    } catch (Exception *x) {
        delete x;
        GetTrackBytesProperty(trackId,
                              "mdia.minf.stbl.stsd.*[0].*.esds.decConfigDescr.decSpecificInfo[0].info",
                              ppConfig, pConfigSize);
    }
}

void MP4File::GetTrackVideoMetadata(MP4TrackId trackId,
                                    uint8_t** ppConfig, uint32_t* pConfigSize)
{
    GetTrackBytesProperty(trackId,
                          "mdia.minf.stbl.stsd.*[0].*.metadata",
                          ppConfig, pConfigSize);
}

void MP4File::SetTrackESConfiguration(MP4TrackId trackId,
                                      const uint8_t* pConfig, uint32_t configSize)
{
    // get a handle on the track decoder config descriptor
    MP4DescriptorProperty* pConfigDescrProperty = NULL;
    if (FindProperty(MakeTrackName(trackId,
                                   "mdia.minf.stbl.stsd.*[0].esds.decConfigDescr.decSpecificInfo"),
                     (MP4Property**)&pConfigDescrProperty) == false ||
            pConfigDescrProperty == NULL) {
        // probably trackId refers to a hint track
        throw new Exception("no such property", __FILE__, __LINE__, __FUNCTION__);
    }

    // lookup the property to store the configuration
    MP4BytesProperty* pInfoProperty = NULL;
    (void)pConfigDescrProperty->FindProperty("decSpecificInfo[0].info",
            (MP4Property**)&pInfoProperty);

    // configuration being set for the first time
    if (pInfoProperty == NULL) {
        // need to create a new descriptor to hold it
        MP4Descriptor* pConfigDescr =
            pConfigDescrProperty->AddDescriptor(MP4DecSpecificDescrTag);
        pConfigDescr->Generate();

        (void)pConfigDescrProperty->FindProperty(
            "decSpecificInfo[0].info",
            (MP4Property**)&pInfoProperty);
        ASSERT(pInfoProperty);
    }

    // set the value
    pInfoProperty->SetValue(pConfig, configSize);
}


void MP4File::GetTrackH264SeqPictHeaders (MP4TrackId trackId,
        uint8_t ***pppSeqHeader,
        uint32_t **ppSeqHeaderSize,
        uint8_t ***pppPictHeader,
        uint32_t **ppPictHeaderSize)
{
    uint32_t count;
    const char *format;
    MP4Atom *avcCAtom;

    *pppSeqHeader = NULL;
    *pppPictHeader = NULL;
    *ppSeqHeaderSize = NULL;
    *ppPictHeaderSize = NULL;

    // get 4cc media format - can be avc1 or encv for ismacrypted track
    format = GetTrackMediaDataName (trackId);

    if (!strcasecmp(format, "avc1"))
        avcCAtom = FindAtom(MakeTrackName(trackId, "mdia.minf.stbl.stsd.avc1.avcC"));
    else if (!strcasecmp(format, "encv"))
        avcCAtom = FindAtom(MakeTrackName(trackId, "mdia.minf.stbl.stsd.encv.avcC"));
    else
        // huh?  unknown track format
        return;

    MP4BitfieldProperty *pSeqCount;
    MP4IntegerProperty *pSeqLen, *pPictCount, *pPictLen;
    MP4BytesProperty *pSeqVal, *pPictVal;

    if ((avcCAtom->FindProperty("avcC.numOfSequenceParameterSets",
                                (MP4Property **)&pSeqCount) == false) ||
            (avcCAtom->FindProperty("avcC.sequenceEntries.sequenceParameterSetLength",
                                    (MP4Property **)&pSeqLen) == false) ||
            (avcCAtom->FindProperty("avcC.sequenceEntries.sequenceParameterSetNALUnit",
                                    (MP4Property **)&pSeqVal) == false)) {
        log.errorf("%s: \"%s\": Could not find avcC properties", __FUNCTION__, GetFilename().c_str());
        return ;
    }
    uint8_t **ppSeqHeader =
        (uint8_t **)malloc((pSeqCount->GetValue() + 1) * sizeof(uint8_t *));
    if (ppSeqHeader == NULL) return;
    *pppSeqHeader = ppSeqHeader;

    uint32_t *pSeqHeaderSize =
        (uint32_t *)malloc((pSeqCount->GetValue() + 1) * sizeof(uint32_t *));

    if (pSeqHeaderSize == NULL) return;

    *ppSeqHeaderSize = pSeqHeaderSize;
    for (count = 0; count < pSeqCount->GetValue(); count++) {
        pSeqVal->GetValue(&(ppSeqHeader[count]), &(pSeqHeaderSize[count]),
                          count);
    }
    ppSeqHeader[count] = NULL;
    pSeqHeaderSize[count] = 0;

    if ((avcCAtom->FindProperty("avcC.numOfPictureParameterSets",
                                (MP4Property **)&pPictCount) == false) ||
            (avcCAtom->FindProperty("avcC.pictureEntries.pictureParameterSetLength",
                                    (MP4Property **)&pPictLen) == false) ||
            (avcCAtom->FindProperty("avcC.pictureEntries.pictureParameterSetNALUnit",
                                    (MP4Property **)&pPictVal) == false)) {
        log.errorf("%s: \"%s\": Could not find avcC picture table properties",
                   __FUNCTION__, GetFilename().c_str());
        return ;
    }
    uint8_t
    **ppPictHeader =
        (uint8_t **)malloc((pPictCount->GetValue() + 1) * sizeof(uint8_t *));
    if (ppPictHeader == NULL) return;
    uint32_t *pPictHeaderSize =
        (uint32_t *)malloc((pPictCount->GetValue() + 1)* sizeof(uint32_t *));
    if (pPictHeaderSize == NULL) {
        free(ppPictHeader);
        return;
    }
    *pppPictHeader = ppPictHeader;
    *ppPictHeaderSize = pPictHeaderSize;

    for (count = 0; count < pPictCount->GetValue(); count++) {
        pPictVal->GetValue(&(ppPictHeader[count]), &(pPictHeaderSize[count]),
                           count);
    }
    ppPictHeader[count] = NULL;
    pPictHeaderSize[count] = 0;
    return ;
}



const char* MP4File::GetHintTrackSdp(MP4TrackId hintTrackId)
{
    return GetTrackStringProperty(hintTrackId, "udta.hnti.sdp .sdpText");
}

void MP4File::SetHintTrackSdp(MP4TrackId hintTrackId, const char* sdpString)
{
    MP4Track* pTrack = m_pTracks[FindTrackIndex(hintTrackId)];

    if (strcmp(pTrack->GetType(), MP4_HINT_TRACK_TYPE)) {
        throw new Exception("track is not a hint track", __FILE__, __LINE__, __FUNCTION__);
    }

    (void)AddDescendantAtoms(
        MakeTrackName(hintTrackId, NULL), "udta.hnti.sdp ");

    SetTrackStringProperty(hintTrackId, "udta.hnti.sdp .sdpText", sdpString);
}

void MP4File::AppendHintTrackSdp(MP4TrackId hintTrackId,
                                 const char* sdpFragment)
{
    const char* oldSdpString = NULL;
    try {
        oldSdpString = GetHintTrackSdp(hintTrackId);
    }
    catch (Exception* x) {
        delete x;
        SetHintTrackSdp(hintTrackId, sdpFragment);
        return;
    }

    char* newSdpString =
        (char*)MP4Malloc(strlen(oldSdpString) + strlen(sdpFragment) + 1);
    strcpy(newSdpString, oldSdpString);
    strcat(newSdpString, sdpFragment);
    SetHintTrackSdp(hintTrackId, newSdpString);
    MP4Free(newSdpString);
}

void MP4File::GetHintTrackRtpPayload(
    MP4TrackId hintTrackId,
    char** ppPayloadName,
    uint8_t* pPayloadNumber,
    uint16_t* pMaxPayloadSize,
    char **ppEncodingParams)
{
    MP4Track* pTrack = m_pTracks[FindTrackIndex(hintTrackId)];

    if (strcmp(pTrack->GetType(), MP4_HINT_TRACK_TYPE)) {
        throw new Exception("track is not a hint track", __FILE__, __LINE__, __FUNCTION__);
    }

    ((MP4RtpHintTrack*)pTrack)->GetPayload(
        ppPayloadName, pPayloadNumber, pMaxPayloadSize, ppEncodingParams);
}

void MP4File::SetHintTrackRtpPayload(MP4TrackId hintTrackId,
                                     const char* payloadName, uint8_t* pPayloadNumber, uint16_t maxPayloadSize,
                                     const char *encoding_params,
                                     bool include_rtp_map,
                                     bool include_mpeg4_esid)
{
    MP4Track* pTrack = m_pTracks[FindTrackIndex(hintTrackId)];

    if (strcmp(pTrack->GetType(), MP4_HINT_TRACK_TYPE)) {
        throw new Exception("track is not a hint track", __FILE__, __LINE__, __FUNCTION__);
    }

    uint8_t payloadNumber;
    if (pPayloadNumber && *pPayloadNumber != MP4_SET_DYNAMIC_PAYLOAD) {
        payloadNumber = *pPayloadNumber;
    } else {
        payloadNumber = AllocRtpPayloadNumber();
        if (pPayloadNumber) {
            *pPayloadNumber = payloadNumber;
        }
    }

    ((MP4RtpHintTrack*)pTrack)->SetPayload(
        payloadName, payloadNumber, maxPayloadSize, encoding_params,
        include_rtp_map, include_mpeg4_esid);
}

uint8_t MP4File::AllocRtpPayloadNumber()
{
    MP4Integer32Array usedPayloads;
    uint32_t i;

    // collect rtp payload numbers in use by existing tracks
    for (i = 0; i < m_pTracks.Size(); i++) {
        MP4Atom& trakAtom = m_pTracks[i]->GetTrakAtom();

        MP4Integer32Property* pPayloadProperty = NULL;
        if (trakAtom.FindProperty("trak.udta.hinf.payt.payloadNumber",
                                    (MP4Property**)&pPayloadProperty) &&
                pPayloadProperty) {
            usedPayloads.Add(pPayloadProperty->GetValue());
        }
    }

    // search dynamic payload range for an available slot
    uint8_t payload;
    for (payload = 96; payload < 128; payload++) {
        for (i = 0; i < usedPayloads.Size(); i++) {
            if (payload == usedPayloads[i]) {
                break;
            }
        }
        if (i == usedPayloads.Size()) {
            break;
        }
    }

    if (payload >= 128) {
        throw new Exception("no more available rtp payload numbers",
                            __FILE__, __LINE__, __FUNCTION__);
    }

    return payload;
}

MP4TrackId MP4File::GetHintTrackReferenceTrackId(
    MP4TrackId hintTrackId)
{
    MP4Track* pTrack = m_pTracks[FindTrackIndex(hintTrackId)];

    if (strcmp(pTrack->GetType(), MP4_HINT_TRACK_TYPE)) {
        throw new Exception("track is not a hint track",
                            __FILE__, __LINE__, __FUNCTION__);
    }

    MP4Track* pRefTrack = ((MP4RtpHintTrack*)pTrack)->GetRefTrack();

    if (pRefTrack == NULL) {
        return MP4_INVALID_TRACK_ID;
    }
    return pRefTrack->GetId();
}

void MP4File::ReadRtpHint(
    MP4TrackId hintTrackId,
    MP4SampleId hintSampleId,
    uint16_t* pNumPackets)
{
    MP4Track* pTrack = m_pTracks[FindTrackIndex(hintTrackId)];

    if (strcmp(pTrack->GetType(), MP4_HINT_TRACK_TYPE)) {
        throw new Exception("track is not a hint track", __FILE__, __LINE__, __FUNCTION__);
    }
    ((MP4RtpHintTrack*)pTrack)->
    ReadHint(hintSampleId, pNumPackets);
}

uint16_t MP4File::GetRtpHintNumberOfPackets(
    MP4TrackId hintTrackId)
{
    MP4Track* pTrack = m_pTracks[FindTrackIndex(hintTrackId)];

    if (strcmp(pTrack->GetType(), MP4_HINT_TRACK_TYPE)) {
        throw new Exception("track is not a hint track",
                            __FILE__, __LINE__, __FUNCTION__);
    }
    return ((MP4RtpHintTrack*)pTrack)->GetHintNumberOfPackets();
}

int8_t MP4File::GetRtpPacketBFrame(
    MP4TrackId hintTrackId,
    uint16_t packetIndex)
{
    MP4Track* pTrack = m_pTracks[FindTrackIndex(hintTrackId)];

    if (strcmp(pTrack->GetType(), MP4_HINT_TRACK_TYPE)) {
        throw new Exception("track is not a hint track",
                            __FILE__, __LINE__, __FUNCTION__);
    }
    return ((MP4RtpHintTrack*)pTrack)->GetPacketBFrame(packetIndex);
}

int32_t MP4File::GetRtpPacketTransmitOffset(
    MP4TrackId hintTrackId,
    uint16_t packetIndex)
{
    MP4Track* pTrack = m_pTracks[FindTrackIndex(hintTrackId)];

    if (strcmp(pTrack->GetType(), MP4_HINT_TRACK_TYPE)) {
        throw new Exception("track is not a hint track",
                            __FILE__, __LINE__, __FUNCTION__);
    }
    return ((MP4RtpHintTrack*)pTrack)->GetPacketTransmitOffset(packetIndex);
}

void MP4File::ReadRtpPacket(
    MP4TrackId hintTrackId,
    uint16_t packetIndex,
    uint8_t** ppBytes,
    uint32_t* pNumBytes,
    uint32_t ssrc,
    bool includeHeader,
    bool includePayload)
{
    MP4Track* pTrack = m_pTracks[FindTrackIndex(hintTrackId)];

    if (strcmp(pTrack->GetType(), MP4_HINT_TRACK_TYPE)) {
        throw new Exception("track is not a hint track", __FILE__, __LINE__, __FUNCTION__);
    }
    ((MP4RtpHintTrack*)pTrack)->ReadPacket(
        packetIndex, ppBytes, pNumBytes,
        ssrc, includeHeader, includePayload);
}

MP4Timestamp MP4File::GetRtpTimestampStart(
    MP4TrackId hintTrackId)
{
    MP4Track* pTrack = m_pTracks[FindTrackIndex(hintTrackId)];

    if (strcmp(pTrack->GetType(), MP4_HINT_TRACK_TYPE)) {
        throw new Exception("track is not a hint track", __FILE__, __LINE__, __FUNCTION__);
    }
    return ((MP4RtpHintTrack*)pTrack)->GetRtpTimestampStart();
}

void MP4File::SetRtpTimestampStart(
    MP4TrackId hintTrackId,
    MP4Timestamp rtpStart)
{
    MP4Track* pTrack = m_pTracks[FindTrackIndex(hintTrackId)];

    if (strcmp(pTrack->GetType(), MP4_HINT_TRACK_TYPE)) {
        throw new Exception("track is not a hint track",
                            __FILE__, __LINE__, __FUNCTION__);
    }
    ((MP4RtpHintTrack*)pTrack)->SetRtpTimestampStart(rtpStart);
}

void MP4File::AddRtpHint(MP4TrackId hintTrackId,
                         bool isBframe, uint32_t timestampOffset)
{
    ProtectWriteOperation(__FILE__, __LINE__, __FUNCTION__);

    MP4Track* pTrack = m_pTracks[FindTrackIndex(hintTrackId)];

    if (strcmp(pTrack->GetType(), MP4_HINT_TRACK_TYPE)) {
        throw new Exception("track is not a hint track", __FILE__, __LINE__, __FUNCTION__);
    }
    ((MP4RtpHintTrack*)pTrack)->AddHint(isBframe, timestampOffset);
}

void MP4File::AddRtpPacket(
    MP4TrackId hintTrackId, bool setMbit, int32_t transmitOffset)
{
    ProtectWriteOperation(__FILE__, __LINE__, __FUNCTION__);

    MP4Track* pTrack = m_pTracks[FindTrackIndex(hintTrackId)];

    if (strcmp(pTrack->GetType(), MP4_HINT_TRACK_TYPE)) {
        throw new Exception("track is not a hint track", __FILE__, __LINE__, __FUNCTION__);
    }
    ((MP4RtpHintTrack*)pTrack)->AddPacket(setMbit, transmitOffset);
}

void MP4File::AddRtpImmediateData(MP4TrackId hintTrackId,
                                  const uint8_t* pBytes, uint32_t numBytes)
{
    ProtectWriteOperation(__FILE__, __LINE__, __FUNCTION__);

    MP4Track* pTrack = m_pTracks[FindTrackIndex(hintTrackId)];

    if (strcmp(pTrack->GetType(), MP4_HINT_TRACK_TYPE)) {
        throw new Exception("track is not a hint track",
                            __FILE__, __LINE__, __FUNCTION__);
    }
    ((MP4RtpHintTrack*)pTrack)->AddImmediateData(pBytes, numBytes);
}

void MP4File::AddRtpSampleData(MP4TrackId hintTrackId,
                               MP4SampleId sampleId, uint32_t dataOffset, uint32_t dataLength)
{
    ProtectWriteOperation(__FILE__, __LINE__, __FUNCTION__);

    MP4Track* pTrack = m_pTracks[FindTrackIndex(hintTrackId)];

    if (strcmp(pTrack->GetType(), MP4_HINT_TRACK_TYPE)) {
        throw new Exception("track is not a hint track",
                            __FILE__, __LINE__, __FUNCTION__);
    }
    ((MP4RtpHintTrack*)pTrack)->AddSampleData(
        sampleId, dataOffset, dataLength);
}

void MP4File::AddRtpESConfigurationPacket(MP4TrackId hintTrackId)
{
    ProtectWriteOperation(__FILE__, __LINE__, __FUNCTION__);

    MP4Track* pTrack = m_pTracks[FindTrackIndex(hintTrackId)];

    if (strcmp(pTrack->GetType(), MP4_HINT_TRACK_TYPE)) {
        throw new Exception("track is not a hint track",
                            __FILE__, __LINE__, __FUNCTION__);
    }
    ((MP4RtpHintTrack*)pTrack)->AddESConfigurationPacket();
}

void MP4File::WriteRtpHint(MP4TrackId hintTrackId,
                           MP4Duration duration, bool isSyncSample)
{
    ProtectWriteOperation(__FILE__, __LINE__, __FUNCTION__);

    MP4Track* pTrack = m_pTracks[FindTrackIndex(hintTrackId)];

    if (strcmp(pTrack->GetType(), MP4_HINT_TRACK_TYPE)) {
        throw new Exception("track is not a hint track",
                            __FILE__, __LINE__, __FUNCTION__);
    }
    ((MP4RtpHintTrack*)pTrack)->WriteHint(duration, isSyncSample);
}

uint64_t MP4File::ConvertFromMovieDuration(
    MP4Duration duration,
    uint32_t timeScale)
{
    return MP4ConvertTime((uint64_t)duration,
                          GetTimeScale(), timeScale);
}

uint64_t MP4File::ConvertFromTrackTimestamp(
    MP4TrackId trackId,
    MP4Timestamp timeStamp,
    uint32_t timeScale)
{
    return MP4ConvertTime(timeStamp,
                          GetTrackTimeScale(trackId), timeScale);
}

MP4Timestamp MP4File::ConvertToTrackTimestamp(
    MP4TrackId trackId,
    uint64_t timeStamp,
    uint32_t timeScale)
{
    return (MP4Timestamp)MP4ConvertTime(timeStamp,
                                        timeScale, GetTrackTimeScale(trackId));
}

uint64_t MP4File::ConvertFromTrackDuration(
    MP4TrackId trackId,
    MP4Duration duration,
    uint32_t timeScale)
{
    return MP4ConvertTime((uint64_t)duration,
                          GetTrackTimeScale(trackId), timeScale);
}

MP4Duration MP4File::ConvertToTrackDuration(
    MP4TrackId trackId,
    uint64_t duration,
    uint32_t timeScale)
{
    return (MP4Duration)MP4ConvertTime(duration,
                                       timeScale, GetTrackTimeScale(trackId));
}

uint8_t MP4File::ConvertTrackTypeToStreamType(const char* trackType)
{
    uint8_t streamType;

    if (!strcmp(trackType, MP4_OD_TRACK_TYPE)) {
        streamType = MP4ObjectDescriptionStreamType;
    } else if (!strcmp(trackType, MP4_SCENE_TRACK_TYPE)) {
        streamType = MP4SceneDescriptionStreamType;
    } else if (!strcmp(trackType, MP4_CLOCK_TRACK_TYPE)) {
        streamType = MP4ClockReferenceStreamType;
    } else if (!strcmp(trackType, MP4_MPEG7_TRACK_TYPE)) {
        streamType = MP4Mpeg7StreamType;
    } else if (!strcmp(trackType, MP4_OCI_TRACK_TYPE)) {
        streamType = MP4OCIStreamType;
    } else if (!strcmp(trackType, MP4_IPMP_TRACK_TYPE)) {
        streamType = MP4IPMPStreamType;
    } else if (!strcmp(trackType, MP4_MPEGJ_TRACK_TYPE)) {
        streamType = MP4MPEGJStreamType;
    } else {
        streamType = MP4UserPrivateStreamType;
    }

    return streamType;
}

// edit list

char* MP4File::MakeTrackEditName(
    MP4TrackId trackId,
    MP4EditId editId,
    const char* name)
{
    char* trakName = MakeTrackName(trackId, NULL);

    if (m_editName == NULL) {
        m_editName = (char *)malloc(1024);
        if (m_editName == NULL) return NULL;
    }
    snprintf(m_editName, 1024,
             "%s.edts.elst.entries[%u].%s",
             trakName, editId - 1, name);
    return m_editName;
}

MP4EditId MP4File::AddTrackEdit(
    MP4TrackId trackId,
    MP4EditId editId)
{
    ProtectWriteOperation(__FILE__, __LINE__, __FUNCTION__);
    return m_pTracks[FindTrackIndex(trackId)]->AddEdit(editId);
}

void MP4File::DeleteTrackEdit(
    MP4TrackId trackId,
    MP4EditId editId)
{
    ProtectWriteOperation(__FILE__, __LINE__, __FUNCTION__);
    m_pTracks[FindTrackIndex(trackId)]->DeleteEdit(editId);
}

uint32_t MP4File::GetTrackNumberOfEdits(
    MP4TrackId trackId)
{
    return GetTrackIntegerProperty(trackId, "edts.elst.entryCount");
}

MP4Duration MP4File::GetTrackEditTotalDuration(
    MP4TrackId trackId,
    MP4EditId editId)
{
    return m_pTracks[FindTrackIndex(trackId)]->GetEditTotalDuration(editId);
}

MP4Timestamp MP4File::GetTrackEditStart(
    MP4TrackId trackId,
    MP4EditId editId)
{
    return m_pTracks[FindTrackIndex(trackId)]->GetEditStart(editId);
}

MP4Timestamp MP4File::GetTrackEditMediaStart(
    MP4TrackId trackId,
    MP4EditId editId)
{
    return GetIntegerProperty(
               MakeTrackEditName(trackId, editId, "mediaTime"));
}

void MP4File::SetTrackEditMediaStart(
    MP4TrackId trackId,
    MP4EditId editId,
    MP4Timestamp startTime)
{
    SetIntegerProperty(
        MakeTrackEditName(trackId, editId, "mediaTime"),
        startTime);
}

MP4Duration MP4File::GetTrackEditDuration(
    MP4TrackId trackId,
    MP4EditId editId)
{
    return GetIntegerProperty(
               MakeTrackEditName(trackId, editId, "segmentDuration"));
}

void MP4File::SetTrackEditDuration(
    MP4TrackId trackId,
    MP4EditId editId,
    MP4Duration duration)
{
    SetIntegerProperty(
        MakeTrackEditName(trackId, editId, "segmentDuration"),
        duration);
}

bool MP4File::GetTrackEditDwell(
    MP4TrackId trackId,
    MP4EditId editId)
{
    return (GetIntegerProperty(
                MakeTrackEditName(trackId, editId, "mediaRate")) == 0);
}

void MP4File::SetTrackEditDwell(
    MP4TrackId trackId,
    MP4EditId editId,
    bool dwell)
{
    SetIntegerProperty(
        MakeTrackEditName(trackId, editId, "mediaRate"),
        (dwell ? 0 : 1));
}

MP4SampleId MP4File::GetSampleIdFromEditTime(
    MP4TrackId trackId,
    MP4Timestamp when,
    MP4Timestamp* pStartTime,
    MP4Duration* pDuration)
{
    return m_pTracks[FindTrackIndex(trackId)]->GetSampleIdFromEditTime(
               when, pStartTime, pDuration);
}

MP4Duration MP4File::GetTrackDurationPerChunk( MP4TrackId trackId )
{
    return m_pTracks[FindTrackIndex(trackId)]->GetDurationPerChunk();
}

void MP4File::SetTrackDurationPerChunk( MP4TrackId trackId, MP4Duration duration )
{
    m_pTracks[FindTrackIndex(trackId)]->SetDurationPerChunk( duration );
}

void MP4File::CopySample(
    MP4File*    srcFile,
    MP4TrackId  srcTrackId,
    MP4SampleId srcSampleId,
    MP4File*    dstFile,
    MP4TrackId  dstTrackId,
    MP4Duration dstSampleDuration )
{
    // Note: we leave it up to the caller to ensure that the
    // source and destination tracks are compatible.
    // i.e. copying audio samples into a video track
    // is unlikely to do anything useful

    uint8_t* pBytes = NULL;
    uint32_t numBytes = 0;
    MP4Duration sampleDuration;
    MP4Duration renderingOffset;
    bool isSyncSample;
    bool hasDependencyFlags;
    uint32_t dependencyFlags;

    srcFile->ReadSample(
         srcTrackId,
         srcSampleId,
         &pBytes,
         &numBytes,
         NULL,
         &sampleDuration,
         &renderingOffset,
         &isSyncSample,
         &hasDependencyFlags,
         &dependencyFlags );

    if( !dstFile )
        dstFile = srcFile;

    if( dstTrackId == MP4_INVALID_TRACK_ID )
        dstTrackId = srcTrackId;

    if( dstSampleDuration != MP4_INVALID_DURATION )
        sampleDuration = dstSampleDuration;

    if( hasDependencyFlags ) {
        dstFile->WriteSampleDependency(
            dstTrackId,
            pBytes,
            numBytes,
            sampleDuration,
            renderingOffset,
            isSyncSample,
            dependencyFlags );
    }
    else {
        dstFile->WriteSample(
            dstTrackId,
            pBytes,
            numBytes,
            sampleDuration,
            renderingOffset,
            isSyncSample );
    }

    free( pBytes );
}

void MP4File::EncAndCopySample(
    MP4File*      srcFile,
    MP4TrackId    srcTrackId,
    MP4SampleId   srcSampleId,
    encryptFunc_t encfcnp,
    uint32_t      encfcnparam1,
    MP4File*      dstFile,
    MP4TrackId    dstTrackId,
    MP4Duration   dstSampleDuration )
{
    // Note: we leave it up to the caller to ensure that the
    // source and destination tracks are compatible.
    // i.e. copying audio samples into a video track
    // is unlikely to do anything useful

    uint8_t* pBytes = NULL;
    uint32_t numBytes = 0;
    uint8_t* encSampleData = NULL;
    uint32_t encSampleLength = 0;
    MP4Duration sampleDuration;
    MP4Duration renderingOffset;
    bool isSyncSample;
    bool hasDependencyFlags;
    uint32_t dependencyFlags;

    ASSERT(srcFile);
    srcFile->ReadSample(
         srcTrackId,
         srcSampleId,
         &pBytes,
         &numBytes,
         NULL,
         &sampleDuration,
         &renderingOffset,
         &isSyncSample,
         &hasDependencyFlags,
         &dependencyFlags );

    if( !dstFile )
        dstFile = srcFile;

    ASSERT(dstFile);

    if( dstTrackId == MP4_INVALID_TRACK_ID )
        dstTrackId = srcTrackId;

    if( dstSampleDuration != MP4_INVALID_DURATION )
        sampleDuration = dstSampleDuration;

    //if( ismacrypEncryptSampleAddHeader( ismaCryptSId, numBytes, pBytes, &encSampleLength, &encSampleData ) != 0)
    if( encfcnp( encfcnparam1, numBytes, pBytes, &encSampleLength, &encSampleData ) != 0 )
        log.errorf("%s(%s,%s) Can't encrypt the sample and add its header %u",
                   __FUNCTION__, srcFile->GetFilename().c_str(), dstFile->GetFilename().c_str(), srcSampleId );

    if( hasDependencyFlags ) {
        dstFile->WriteSampleDependency(
            dstTrackId,
            pBytes,
            numBytes,
            sampleDuration,
            renderingOffset,
            isSyncSample,
            dependencyFlags );
    }
    else {
        dstFile->WriteSample(
            dstTrackId,
            encSampleData,
            encSampleLength,
            sampleDuration,
            renderingOffset,
            isSyncSample );
    }

    free( pBytes );

    if( encSampleData != NULL )
        free( encSampleData );
}

///////////////////////////////////////////////////////////////////////////////

}} // namespace mp4v2::impl
