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

📄 umc_mp4_mux.cpp

📁 audio-video-codecs.rar语音编解码器
💻 CPP
📖 第 1 页 / 共 2 页
字号:
/*//////////////////////////////////////////////////////////////////////////////
//
//                  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 <ippi.h>
#include <math.h>
#include "bstream.h"
#include "aaccmn_adts.h"
#include "mp4cmn_config.h"
#include "umc_mp4_mux_defs.h"
#include "umc_mp4_mux.h"
#include "umc_automatic_mutex.h"

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

namespace UMC {

Muxer *CreateMPEG4Muxer()
{
  return (new MP4Muxer);
}

MP4Muxer::MP4Muxer():
m_nHeaderSize(0),
m_nMdatSize(0),
nTimeScale(48000),
bMuxerInitialized(false),
m_bMoov(true),
m_fTempOutput1(NULL),
m_fTempOutput2(NULL),
m_nMoovSize(MAX_MOOV_SIZE),
m_nMoofSize(MAX_MOOF_SIZE),
m_pH264Data(NULL),
m_iH264DataCurSize(0),
m_nH264DataOffset(0),
m_mH264DataOut(NULL),
m_pH264Header(NULL),
m_bDataFromEncoder(false),
m_nIDRFrames(0),
m_FirstFrame(0)
{
    m_headerMoof.sequence_number = 0;
    memset(&m_headerMoof,  0, sizeof(TM_moof));
    memset(&m_headerMPEG4, 0, sizeof(TM_moov));
    memset(&m_headerMVEX,  0, sizeof(TM_mvex));
    vm_mutex_set_invalid(&m_PutDataMutex);
}

MP4Muxer::~MP4Muxer()
{
    Close();
    vm_mutex_destroy(&m_PutDataMutex);
}

Status MP4Muxer::Init(MuxerParams *lpInit)
{
    Ipp32u i;

    UMC_CALL(CopyMuxerParams(lpInit));

    UMC_CHECK_PTR(m_pParams->m_lpDataWriter);

    m_bDataFromEncoder = ((m_pParams->m_lFlags & FLAG_DATA_FROM_SPLITTER) == 0);

    m_headerMoof.total_tracks = m_uiTotalNumStreams;
    m_headerMPEG4.total_tracks = m_uiTotalNumStreams;

    for (i = 0; i < m_uiTotalNumStreams; i++) {
      UMC_NEW(m_ppBuffers[i], SampleBuffer);
      UMC_CALL(m_ppBuffers[i]->Init(&m_pTrackParams[i].bufferParams));
    }

    for (i = 0; i < m_headerMPEG4.total_tracks; i++ )
    {
        m_headerMPEG4.trak[i] = _NEW(TM_trak_data);
        m_headerMPEG4.trak[i]->mdia.minf.stbl.stsd.total_entries = 1;
        m_headerMPEG4.trak[i]->mdia.minf.stbl.stsd.table = _NEW(TM_stsd_table_data);
        m_headerMPEG4.trak[i]->mdia.minf.stbl.stts.total_entries = 0;
        m_headerMPEG4.trak[i]->mdia.minf.stbl.ctts.total_entries = 0;
    }

    m_nIDRFrames = _NEW_n(Ipp32s, m_headerMPEG4.total_tracks);
    memset(m_nIDRFrames, 0, m_headerMPEG4.total_tracks * sizeof(Ipp32s));
    m_FirstFrame = _NEW_n(Ipp32s, m_headerMPEG4.total_tracks);
    for (i = 0; i < m_headerMPEG4.total_tracks; i++ )
    {
      m_FirstFrame[i] = 1;
    }

    //open file for data buffering
    InitTemporaryOutputFile1();

    InitTracks(m_headerMPEG4.total_tracks);
    InitEsds(m_pParams);
    InitHeader();

    //initial header and atoms sizes
    m_nHeaderSize = CalculateSizes();

    //all OK, muxer is initialized
    bMuxerInitialized = true;
    vm_mutex_init(&m_PutDataMutex);

    return UMC_OK;
}

Status MP4Muxer::Close(void)
{
    Status res = UMC_OK;
    Ipp32u i;
    MediaData cData;

    vm_trace_s("Close()");

    if ( bMuxerInitialized )
    {
        //dump buffers
        MuxData(true);

        if (m_bMoov)
        {
            if ( WriteHeader() != UMC_OK )
            {
                res = UMC_ERR_FAILED;
            }
        }
        else
        {
            m_headerMoof.sequence_number++;
            if ( WriteHeaderFragment() != UMC_OK )
            {
                res = UMC_ERR_FAILED;
            }
        }

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

            _SAFE_DELETE_ARRAY(stbl.stsc.table);
            _SAFE_DELETE_ARRAY(stbl.stts.table);
            if (m_sTrack[i].m_nCttsEntries)
              _SAFE_DELETE_ARRAY(stbl.ctts.table);
            _SAFE_DELETE_ARRAY(stbl.stco.table);
            _SAFE_DELETE_ARRAY(stbl.stsz.table);
            _SAFE_DELETE_ARRAY(stbl.stss.table);

            Ipp32s nIndex = stbl.stsd.total_entries - 1; // now total_entries = 1, so nIndex = 0;
            _SAFE_DELETE_ARRAY(stbl.stsd.table[nIndex].esds.decoderConfig);

            _SAFE_DELETE_ARRAY(m_sTrack[i].m_pSamples);

            _SAFE_DELETE_ARRAY(m_headerMPEG4.trak[i]->mdia.minf.stbl.stsd.table);
            _SAFE_DELETE_ARRAY(m_headerMPEG4.trak[i]);
        }

        _SAFE_DELETE_ARRAY(m_sTrack);

        if (m_headerMoof.trun)
        {
             for (i = 0; i < m_headerMPEG4.total_tracks; i++)
            {
                _SAFE_DELETE_ARRAY(m_headerMoof.trun[i].trun);
            }
            _SAFE_DELETE_ARRAY(m_headerMoof.trun);
        }

        _SAFE_DELETE_CPP(m_mH264DataOut);

        if (m_pH264Header)
        {
            if (m_pH264Header->m_pNal_ut_sps)
            {
                for (i = 0; i < m_pH264Header->m_nSps_num; i++)
                {
                    _SAFE_DELETE_ARRAY(m_pH264Header->m_pNal_ut_sps[i].m_pNal_ut_sps);
                };
            }
            _SAFE_DELETE_ARRAY(m_pH264Header->m_pNal_ut_sps);

            if (m_pH264Header->m_pNal_ut_pps)
            {
                for (i = 0; i < m_pH264Header->m_nPps_num; i++)
                {
                    _SAFE_DELETE_ARRAY(m_pH264Header->m_pNal_ut_pps[i].m_pNal_ut_pps);
                };
            }
            _SAFE_DELETE_ARRAY(m_pH264Header->m_pNal_ut_pps);
        }
        _SAFE_DELETE_CPP(m_pH264Header);

        _SAFE_DELETE_ARRAY(m_pH264Data);
        m_iH264DataCurSize=0;

        bMuxerInitialized = false;
    }

    _SAFE_DELETE_ARRAY( m_nIDRFrames );
    _SAFE_DELETE_ARRAY( m_FirstFrame );

    // Close base muxer
    UMC_CALL(Muxer::Close());

    return res;
}

Status MP4Muxer::SampleInfo(MediaData *lpData, Ipp32s ntrak)
{
    Ipp64f nStart = 0, nEnd = 0;  /* nEnd is not used really */
    Ipp32s nSize = 0;

    nSize = lpData->GetDataSize();
    lpData->GetTime(nStart, nEnd);

    sMuxSample& curSample       = m_sTrack[ntrak].m_pSamples[m_sTrack[ntrak].m_nSamplesCount];

    curSample.m_nSize           = nSize;
    curSample.m_nPosition       = vm_file_ftell(m_fTempOutput1) - nSize;

    // check start codes
    if (m_headerMPEG4.trak[ntrak]->tkhd.is_video) {
      curSample.m_frameTMype = GetPictureType(lpData, ntrak);
      if (I_PICTURE == curSample.m_frameTMype)
      {
          curSample.m_frameTMype = I_PICTURE;
          m_nHeaderSize += m_bMoov ? 4 : 0;
          m_nIDRFrames[ntrak]++;
      } else
      if (B_PICTURE == curSample.m_frameTMype) {
        m_sTrack[ntrak].m_nCttsEntries = 1;
      }
    }

    curSample.m_nTimeStamp    = (Ipp32s)(nStart * nTimeScale + 0.5);
    if (nStart > m_sTrack[ntrak].m_nTrackEnd) // to exclude B frames
      m_sTrack[ntrak].m_nTrackEnd = nStart;

    curSample.m_nSamplesPerChunk  = 1;
    curSample.m_nId               = 1;
    curSample.m_nFirstChunk       = m_sTrack[ntrak].m_nSamplesCount + 1;

    vm_debug_trace2(VM_DEBUG_PROGRESS, VM_STRING("*************** trak = %i m_nSamplesCount = %i "), ntrak, m_sTrack[ntrak].m_nSamplesCount);
    vm_debug_trace2(VM_DEBUG_PROGRESS, VM_STRING("*************** size = %i TrackEnd = %f\n"), nSize, m_sTrack[ntrak].m_nTrackEnd);


    // set duration
    curSample.m_nDuration = 0;
    if (m_sTrack[ntrak].m_nSamplesCount != 0) { // not the first sample in track
      sMuxSample& prevSample = m_sTrack[ntrak].m_pSamples[m_sTrack[ntrak].m_nSamplesCount - 1];
      prevSample.m_nDuration = curSample.m_nTimeStamp - prevSample.m_nTimeStamp;
      if (prevSample.m_nDuration < 0) {
        if (m_headerMPEG4.trak[ntrak]->tkhd.is_video) {
          /*** calculate duration from framerate ***/
          Ipp64f frate = m_pTrackParams[ntrak].info.video->framerate;
          if (frate <= 0) frate = 30;
          prevSample.m_nDuration = (Ipp32s)((1 / frate) * nTimeScale);
        } /*** behavior for audio is undefined yet ***/
      }
      if (m_sTrack[ntrak].m_nSamplesCount > 1) {
        sMuxSample& prevprevSample = m_sTrack[ntrak].m_pSamples[m_sTrack[ntrak].m_nSamplesCount - 2];
        if (prevSample.m_nDuration != prevprevSample.m_nDuration) {
          m_sTrack[ntrak].m_nSttsEntries++;
        }
      }
    }

    m_nHeaderSize += m_bMoov ? 20 : 8;  /* 12 stsc; 4 stco; 4 stsz  */

    m_sTrack[ntrak].m_nSamplesCount++;

⌨️ 快捷键说明

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