/*
 * 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()
{
    SetPosition(0);

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