⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 umc_mp4_mux_atoms.cpp

📁 audio-video-codecs.rar语音编解码器
💻 CPP
📖 第 1 页 / 共 3 页
字号:
/*//////////////////////////////////////////////////////////////////////////////
//
//                  INTEL CORPORATION PROPRIETARY INFORMATION
//     This software is supplied under the terms of a license agreement or
//     nondisclosure agreement with Intel Corporation and may not be copied
//     or disclosed except in accordance with the terms of that agreement.
//          Copyright(c) 2003-2007 Intel Corporation. All Rights Reserved.
//
*/

#include <time.h>
#include <ipps.h>
#include "umc_mp4_mux_defs.h"
#include "umc_mp4_mux.h"
#include "vm_time.h"

#ifdef OSX32
#include <sys/malloc.h>
#else
#include <malloc.h>
#endif /* OSX32 */

namespace UMC
{

    Ipp64f MP4Muxer::GetMaxDuration()
    {
        Ipp32u i, j;
        Ipp64f temp = 0, temp1 = 0;
        for ( i = 0; i < m_headerMPEG4.total_tracks; i++ ) {
            sMuxSample *pSamples = m_sTrack[i].m_pSamples;
            temp = 0;
            for ( j = 0; j < m_sTrack[i].m_nSamplesCount; j++ ) {
                temp += pSamples[j].m_nDuration;
            }
            temp /= nTimeScale;
            if ( temp1 < temp ) {
                temp1 = temp;
            }
        }
        return temp1;
    }

    Ipp32s MP4Muxer::GetMP4VideoTypeID(VideoStreamType type)
    {
        Ipp32s tag;

        if (type == MPEG4_VIDEO) {
          tag = 0x20; // Visual ISO/IEC 14496-2
        } else {
          tag = type;
        }
        return tag;
    }

    Ipp32s MP4Muxer::GetMP4AudioTypeID(AudioStreamType type)
    {
        Ipp32s tag;

        if (type & AAC_AUDIO) {
          tag = 0x40;
        } else
        if ((type & MPEG1_AUDIO) ||
            (type & MPEG2_AUDIO)) {
          tag = 0x6b;
        } else {
          tag = type;
        }
        return tag;
    }

    Ipp32s MP4Muxer::GetMP4StreamType(Ipp32s type)
    {
        Ipp32s tag;

        if (type == MPEG4_VIDEO_QTIME) {
          tag = 0x04; // Visual Stream
        } else
        if (type == UNDEF_AUDIO_SUBTYPE) {
          tag = 0x05;
        } else {
          tag = type;
        }
        return tag;
    }

    Ipp64f MP4Muxer::GetTrakDuration(Ipp32s ntrak)
    {
        Ipp64f temp = 0;
        Ipp32u i;

        if (m_sTrack[ntrak].m_nSamplesCount == 0) {
          return 0.0;
        }

        for (i = 0; i < m_sTrack[ntrak].m_nSamplesCount; i++) {
            temp += (Ipp64f)m_sTrack[ntrak].m_pSamples[i].m_nDuration;
        }

        return temp / nTimeScale;
    }

    Ipp32s MP4Muxer::CalculateFragmentSize(TM_moof *moof)
    {
        moof->size_atom = 0;
        moof->size_atom += 8; //moof box
        moof->size_atom += (8 + 1 + 3 + 4); //mfhd

        for (Ipp32u i = 0; i < moof->total_tracks; i++)
        {
            moof->size_atom += 8;                                  //traf
            moof->size_atom += (8 + 1 + 3 + 4);                    //tfhd
            moof->size_atom += (8 + 1 + 3 + 4 + m_sTrack[i].m_nSamplesCount * 4 * 2);  //trun
        }
        return moof->size_atom;
    }

    Ipp32s MP4Muxer::CalculateMvexExtendedSize(TM_mvex* mvex)
    {
        mvex->total_tracks = m_headerMPEG4.total_tracks;

        mvex->size_atom = 0;
        mvex->size_atom += 8; //mvex box

        for (Ipp32u i = 0; i < mvex->total_tracks; i++)
        {
            mvex->size_atom += (8 + 1 + 3 + 4 + 4 + 4 + 4 + 4); //trex
        }

        m_headerMPEG4.size_atom += mvex->size_atom;

        return m_headerMPEG4.size_atom;
    }

    Ipp32s MP4Muxer::CalculateSizes()
    {
        Ipp32u               i, j;
        TM_stsz_data*        stsz;
        TM_stsd_table_data*  stsd_table;
        TM_stsd_data*        stsd;
        TM_stts_data*        stts;
        TM_ctts_data*        ctts;
        TM_stss_data*        stss;
        TM_stbl_data*        stbl;
        TM_stco_data*        stco;
        TM_dref_data*        dref;
        TM_dinf_data*        dinf;
        TM_minf_data*        minf;
        TM_mdhd_data*        mdhd;
        TM_hdlr_data*        hdlr;
        TM_mdia_data*        mdia;
        TM_tkhd_data*        tkhd;
        TM_trak_data*        trak;
        TM_iods_data*        iods;
        TM_mvhd_data*        mvhd;
        TM_vmhd_data*        vmhd;
        TM_smhd_data*        smhd;
        TM_stsc_data*        stsc;

        iods = &m_headerMPEG4.iods;
        iods->size_atom = 8 + 4*4;

        mvhd = &m_headerMPEG4.mvhd;
        mvhd->size_atom = 8 + 4*25;

        m_headerMPEG4.size_atom = 8 + mvhd->size_atom + iods->size_atom;

        if (!m_bMoov)
        {
            m_headerMPEG4.size_atom += m_headerMVEX.size_atom;
        }

        for ( i = 0; i < m_headerMPEG4.total_tracks; i++ )
        {
            stsz = &m_headerMPEG4.trak[i]->mdia.minf.stbl.stsz;

            stsz->size_atom = 8 + 4*3;
            if (!stsz->sample_size)
                stsz->size_atom += m_sTrack[i].m_nSamplesCount * 4;

            stsd = &m_headerMPEG4.trak[i]->mdia.minf.stbl.stsd;

            stsd->size_atom = 8 + 4*2;

            for ( j = 0; j < stsd->total_entries; j++ )
            {
                stsd_table = &stsd->table[j];

                stsd_table->esds.size_atom = 46 + stsd_table->esds.decoderConfigLen;

                if ( stsd_table->format[0] == 'm' && stsd_table->format[1] == 'p' && stsd_table->format[2] == '4' && stsd_table->format[3] == 'a' )
                    stsd_table->size_atom = 16 + stsd_table->esds.size_atom + 20;
                if ( stsd_table->format[0] == 'm' && stsd_table->format[1] == 'p' && stsd_table->format[2] == '4' && stsd_table->format[3] == 'v' )
                    stsd_table->size_atom = 16 + stsd_table->esds.size_atom + 70;
                if ( stsd_table->format[0] == 'a' && stsd_table->format[1] == 'v' && stsd_table->format[2] == 'c' && stsd_table->format[3] == '1' )
                    stsd_table->size_atom = 16 + stsd_table->esds.size_atom + 32;

                stsd->size_atom += stsd_table->size_atom;
            }

            stts = &m_headerMPEG4.trak[i]->mdia.minf.stbl.stts;
            stts->size_atom = 8 + 4*2 + stts->total_entries * 8;


            ctts = &m_headerMPEG4.trak[i]->mdia.minf.stbl.ctts;
/*            ctts->size_atom = 8 + 4*2 + ctts->total_entries * 8;
*/

            stss = &m_headerMPEG4.trak[i]->mdia.minf.stbl.stss;
            stss->size_atom = 8 + 4*2 + m_nIDRFrames[i] * 4;

            stco = &m_headerMPEG4.trak[i]->mdia.minf.stbl.stco;
            stco->size_atom = 8 + 4*2 + m_sTrack[i].m_nSamplesCount * 4;

            stsc = &m_headerMPEG4.trak[i]->mdia.minf.stbl.stsc;
            stsc->size_atom = 8 + 4*2 + m_sTrack[i].m_nSamplesCount * 4 * 3;

            stbl = &m_headerMPEG4.trak[i]->mdia.minf.stbl;
            stbl->size_atom = 8 + stts->size_atom + stsd->size_atom + stsz->size_atom + stco->size_atom + stsc->size_atom + stss->size_atom + ctts->size_atom;

            dref = &m_headerMPEG4.trak[i]->mdia.minf.dinf.dref;
            dref->size_atom = 0x1C; //8 + 4*2;

            dinf = &m_headerMPEG4.trak[i]->mdia.minf.dinf;
            dinf->size_atom = 8 + dref->size_atom;

            vmhd = &m_headerMPEG4.trak[i]->mdia.minf.vmhd;
            vmhd->size_atom = 8 + 12;

            smhd = &m_headerMPEG4.trak[i]->mdia.minf.smhd;
            smhd->size_atom = 8 + 8;

            minf = &m_headerMPEG4.trak[i]->mdia.minf;
            if ( minf->is_video )
                minf->size_atom = 8 + dinf->size_atom + stbl->size_atom + vmhd->size_atom;
            if ( minf->is_audio )
                minf->size_atom = 8 + dinf->size_atom + stbl->size_atom + smhd->size_atom;

            mdhd = &m_headerMPEG4.trak[i]->mdia.mdhd;
            mdhd->size_atom = 8 + 4*6;

            hdlr = &m_headerMPEG4.trak[i]->mdia.hdlr;
            hdlr->size_atom = 58;

            mdia = &m_headerMPEG4.trak[i]->mdia;
            mdia->size_atom = 8 + mdhd->size_atom + minf->size_atom + hdlr->size_atom;

            tkhd = &m_headerMPEG4.trak[i]->tkhd;
            tkhd->size_atom = 8 + 4*21;

            trak = m_headerMPEG4.trak[i];
            trak->size_atom = 8 + tkhd->size_atom + mdia->size_atom;
            m_headerMPEG4.size_atom += trak->size_atom;
        }

        return m_headerMPEG4.size_atom;
    }

    Status MP4Muxer::UpdateHeader()
    {
        Ipp32u i, j;
        vm_timeval val; //file creation time
        Ipp64u start = 0; //file creation time
        vm_status vmRes = VM_OK;

        vmRes = vm_time_gettimeofday(&val, NULL);
        if (vmRes != VM_OK)
          return UMC_ERR_FAILED;
        start = val.tv_sec;
        start += 2082844800; //sec since 104 till 1970

        // MVHD
        m_headerMPEG4.mvhd.creation_time = start;
        m_headerMPEG4.mvhd.modification_time = start;
        Ipp64f maxDur = GetMaxDuration();
        m_headerMPEG4.mvhd.duration = (Ipp64u)(m_headerMPEG4.mvhd.nTimeScale * maxDur);

        // trak`s
        for (i = 0; i < m_headerMPEG4.total_tracks; i++ )
        {
            // trak->tkhd
            m_headerMPEG4.trak[i]->tkhd.creation_time =
                m_headerMPEG4.trak[i]->tkhd.modification_time = start;
            m_headerMPEG4.trak[i]->tkhd.duration = (Ipp64u)(m_headerMPEG4.mvhd.nTimeScale * GetTrakDuration(i));

            // trak->mdia.mdhd
            m_headerMPEG4.trak[i]->mdia.mdhd.creation_time =
                m_headerMPEG4.trak[i]->mdia.mdhd.modification_time = start;
            m_headerMPEG4.trak[i]->mdia.mdhd.duration = (Ipp64u)(m_headerMPEG4.trak[i]->mdia.mdhd.nTimeScale * GetTrakDuration(i));

            if (m_bDataFromEncoder && IS_VIDEO(i) && UMC::H264_VIDEO == m_pTrackParams[i].info.video->stream_type)
            {
                if (m_pH264Header)
                {
                    Ipp8u* pDecInfo = _NEW_n(Ipp8u, 1024 * 1024);
                    memset(pDecInfo, 0, 1024 * 1024);

                    Ipp32s pos = 0;
                    pDecInfo[pos] = 1; //version
                    pos++;
                    pDecInfo[pos] = 0; //AVCProfileIndication
                    pos++;
                    pDecInfo[pos] = 0; //profile_compatibility
                    pos++;
                    pDecInfo[pos] = 0; //AVCLevelIndication
                    pos++;
                    pDecInfo[pos] = (Ipp8u)(0xFC | 3); //lengthSizeMinusOne
                    pos++;
                    pDecInfo[pos] = (Ipp8u)(0xE0 | m_pH264Header->m_nSps_num); //numOfSequenceParameterSets
                    pos++;
                    for    (j = 0; j < m_pH264Header->m_nSps_num; j++)

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -