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

📄 umc_mp4_mux_atoms.cpp

📁 audio-video-codecs.rar语音编解码器
💻 CPP
📖 第 1 页 / 共 3 页
字号:
            InitStss(nTrack);

            TM_stbl_data& stbl = m_headerMPEG4.trak[nTrack]->mdia.minf.stbl;

            for (i = 0; i < m_sTrack[nTrack].m_nSamplesCount; i++)
            {
                stbl.stsz.table[i].size     = m_sTrack[nTrack].m_pSamples[i].m_nSize;
                stbl.stco.table[i].offset   = (Ipp32u)m_sTrack[nTrack].m_pSamples[i].m_nPosition + (m_nHeaderSize + 24) + m_headerMVEX.size_atom;  // +offset = (moov size + file head (ftyp, isom ))
                stbl.stsc.table[i].chunk    =  m_sTrack[nTrack].m_pSamples[i].m_nFirstChunk;
                stbl.stsc.table[i].samples  =  m_sTrack[nTrack].m_pSamples[i].m_nSamplesPerChunk;
                stbl.stsc.table[i].id       = m_sTrack[nTrack].m_pSamples[i].m_nId;

                if (I_PICTURE == m_sTrack[nTrack].m_pSamples[i].m_frameTMype)
                {

                    stbl.stss.table[stbl.stss.total_entries].sample = i;
                    stbl.stss.total_entries++;
                }
            }

            // filling stts
            dur = m_sTrack[nTrack].m_pSamples[0].m_nDuration;
            stbl.stts.table[0].sample_count = 1;
            stbl.stts.table[0].sample_duration = dur;
            for (i = 1, j = 0; i < m_sTrack[nTrack].m_nSamplesCount - 1; i++)
            {
              if (dur != m_sTrack[nTrack].m_pSamples[i].m_nDuration)
              {
                j++;
                stbl.stts.table[j].sample_count = 1;
                dur = m_sTrack[nTrack].m_pSamples[i].m_nDuration;
                stbl.stts.table[j].sample_duration = dur;
              } else
              {
                stbl.stts.table[j].sample_count++;
              }
            }

            if (i > 1)
            {
              if ((m_sTrack[nTrack].m_pSamples[i].m_nDuration == 0) || // last sample
                  m_sTrack[nTrack].m_pSamples[i].m_nDuration == m_sTrack[nTrack].m_pSamples[i - 1].m_nDuration)
              {
                stbl.stts.table[j].sample_count++; // last sample
              } else
              {
                stbl.stts.table[j + 1].sample_count = 1;
                stbl.stts.table[j + 1].sample_duration = m_sTrack[nTrack].m_pSamples[i].m_nDuration;
              }
            }

            // filling 駎ts if needed
            if (m_sTrack[nTrack].m_nCttsEntries) {
              Ipp32s mDTS, curoff, off;
              sMuxSample *pSamples = m_sTrack[nTrack].m_pSamples;
              Ipp32u  nSamples = m_sTrack[nTrack].m_nSamplesCount;

              stbl.ctts.table[0].sample_count = 1;
              stbl.ctts.table[0].sample_offset = -m_sTrack[nTrack].m_ctts_delta;
              mDTS = pSamples[0].m_nTimeStamp + pSamples[0].m_nDuration;
              curoff = -m_sTrack[nTrack].m_ctts_delta;

              for (i = 1, j = 0; i < nSamples; i++) {
                off = pSamples[i].m_nTimeStamp - mDTS - m_sTrack[nTrack].m_ctts_delta;
                if (curoff != off) {
                  j++;
                  stbl.ctts.table[j].sample_count = 1;
                  stbl.ctts.table[j].sample_offset = off;
                  curoff = off;
                } else {
                  stbl.ctts.table[j].sample_count++;
                }
                mDTS += pSamples[i].m_nDuration;
              }
           }

        }

        return UMC_OK;
    }

    static Ipp32s FindStartCode(Ipp8u * (&pb), size_t& nSize)
    {
        // there is no data
        if ((Ipp32s) nSize < 4)
            return 0;

        // find start code
        while ((4 <= nSize) && ((0 != pb[0]) || (0 != pb[1]) || (1 != pb[2])))
        {
            pb += 1;
            nSize -= 1;
        }

        if (4 <= nSize)
            return ((pb[0] << 24) | (pb[1] << 16) | (pb[2] << 8) | (pb[3]));

        return 0;
    } // Ipp32s FindStartCode(Ipp8u * (&pb), size_t &nSize)

    Status MP4Muxer::CheckStartCode(Ipp32s nNAL, Ipp8s* pData, Ipp32u nPos, MediaData* mH264Data, bool bLast)
    {
        Ipp32s length = 0;

        if (bLast)
        {
            length = mH264Data->GetDataSize() - nPos;
        }
        else
        {
            length = (Ipp8s*)pData - (Ipp8s*)mH264Data->GetBufferPointer() - nPos;
        }

        if (NAL_UT_SPS == nNAL || NAL_UT_SPS_EX == nNAL)
        {
            m_pH264Header->m_pNal_ut_sps[m_pH264Header->m_nSps_num].m_pNal_ut_sps = _NEW_n(Ipp8s, length);
            m_pH264Header->m_pNal_ut_sps[m_pH264Header->m_nSps_num].m_nLength = length;
            memcpy(m_pH264Header->m_pNal_ut_sps[m_pH264Header->m_nSps_num].m_pNal_ut_sps,
                        (Ipp8s*)mH264Data->GetBufferPointer() + nPos, length);
            m_pH264Header->m_nSps_num++;

            return UMC_HEADER;
        }

        if (NAL_UT_PPS == nNAL)
        {
            m_pH264Header->m_pNal_ut_pps[m_pH264Header->m_nPps_num].m_pNal_ut_pps = _NEW_n(Ipp8s, length);
            m_pH264Header->m_pNal_ut_pps[m_pH264Header->m_nPps_num].m_nLength = length;
            memcpy(m_pH264Header->m_pNal_ut_pps[m_pH264Header->m_nPps_num].m_pNal_ut_pps,
                (Ipp8s*)mH264Data->GetBufferPointer() + nPos, length);
            m_pH264Header->m_nPps_num++;

            return UMC_HEADER;
        }

        if (NAL_UT_SLICE == nNAL || NAL_UT_IDR_SLICE == nNAL || NAL_UT_AUXILIARY == nNAL)
        {
            Ipp32u s_length = BSWAP32(length);
            memcpy(m_pH264Data + m_nH264DataOffset, (Ipp8s*)&s_length, 4);
            m_nH264DataOffset +=4;
            memcpy(m_pH264Data + m_nH264DataOffset, (Ipp8s*)mH264Data->GetBufferPointer() + nPos, length);
            m_nH264DataOffset +=length;
            return UMC_DATA;
        }

        return UMC_NO_SUCH_CODE;
    };

    MediaData* MP4Muxer::TransformH264Frame(MediaData* mH264Data, Ipp32u nTrack)
    {
        Ipp8u *pData = (Ipp8u *) mH264Data->GetBufferPointer();
        size_t nLen = mH264Data->GetDataSize();

        bool bStop = false;
        Ipp32s pos = 0;
        Ipp32s nNAL = 0;

        bool bIsData = false;
        Status umcRes = 0;

        //FILE* f2;
        //f2 = fopen("1.h264", "ab+");
        //fwrite(mH264Data->GetDataPointer(), 1, mH264Data->GetDataSize(), f2);
        //fclose(f2);

        if( m_iH264DataCurSize < nLen+10000 ){
            _SAFE_DELETE_ARRAY(m_pH264Data);
            m_iH264DataCurSize = nLen+10000; //Added ~10K, because cut of NAL unit takes 3 bytes away, but muxer adds size of NAL unit that is 4 bytest ( 1 byte difference )
            _SAFE_NEW_n(m_pH264Data, Ipp8s, m_iH264DataCurSize);
            m_mH264DataOut->SetBufferPointer((Ipp8u*)m_pH264Data, m_iH264DataCurSize);
        }
       // memset(m_pH264Data, 0, m_iH264DataCurSize);

        _SAFE_NEW_n(m_pH264Header->m_pNal_ut_sps, sNal_ut_sps, 32);
        _SAFE_NEW_n(m_pH264Header->m_pNal_ut_pps, sNal_ut_pps, 256);

        while ((Ipp8s*)pData < ((Ipp8s*)mH264Data->GetBufferPointer() + mH264Data->GetDataSize()))
        {
            Ipp32s iCode = FindStartCode(pData, nLen);

            // check start codes
            if (NAL_UT_SPS == (iCode & NAL_UNITTYPE_BITS)     ||
                NAL_UT_SPS_EX == (iCode & NAL_UNITTYPE_BITS)  ||
                NAL_UT_PPS == (iCode & NAL_UNITTYPE_BITS)     ||
                NAL_UT_SLICE == (iCode & NAL_UNITTYPE_BITS)   ||
                NAL_UT_IDR_SLICE == (iCode & NAL_UNITTYPE_BITS) ||
                NAL_UT_AUXILIARY == (iCode & NAL_UNITTYPE_BITS))
            {
                if (bStop)
                {
                    umcRes = CheckStartCode(nNAL, (Ipp8s*)pData, pos, mH264Data, 0);
                }

                bStop = true;
            }
            else
            {
                if (bStop)
                {
                    umcRes = CheckStartCode(nNAL, (Ipp8s*)pData, pos, mH264Data, 1);
                }
                bStop = false;
            }

            nNAL = iCode & NAL_UNITTYPE_BITS;
            pos = (Ipp8s*)pData - (Ipp8s*)mH264Data->GetBufferPointer() + 3;
            pData +=3;
            nLen -= 3;

            if (UMC_DATA == umcRes)
            {
                bIsData = true;
            }
        }

        if (bIsData)
        {
            m_mH264DataOut->SetDataSize(m_nH264DataOffset);
            m_mH264DataOut->SetTime(mH264Data->GetTime());
            m_mH264DataOut->SetFrameType(mH264Data->GetFrameType());
            Ipp64f dPTS, dDTS;
            mH264Data->GetTime(dPTS, dDTS);
            m_mH264DataOut->SetTime(dPTS, dDTS);
        } else
            return NULL;

        m_nH264DataOffset = 0;


        return m_mH264DataOut;
    }

    Status MP4Muxer::InitEsds(MuxerParams* params)
    {
        for (Ipp32u i = 0; i < m_headerMPEG4.total_tracks; i++)
        {
            Ipp32s nIndex = m_headerMPEG4.trak[i]->mdia.minf.stbl.stsd.total_entries - 1; // now total_entries = 1, so nIndex = 0;

            TM_esds_data& esds = m_headerMPEG4.trak[i]->mdia.minf.stbl.stsd.table[nIndex].esds;

            if (UMC::H264_VIDEO == m_pTrackParams[i].info.video->stream_type) {
              if (!m_mH264DataOut)
                  m_mH264DataOut = new MediaData;

              if (!m_pH264Header) {
                  m_pH264Header = new sH246_Header;
                  memset(m_pH264Header, 0, sizeof(sH246_Header));
              }
            }

            esds.objectTypeID = 0;
            esds.streamType = 0;
            esds.decoderConfigLen = 0;
            esds.decoderConfig = NULL;


            esds.version = 0;
            esds.flags = 0;
        }

        return UMC_OK;
    };

    Status MP4Muxer::InitMoof()
    {
        Ipp32u nTrack = 0;
        Ipp32u i = 0;

        m_headerMoof.sequence_number++;

        m_headerMoof.size_atom = m_nHeaderSize;

        if (m_headerMoof.trun)
        {
            for (nTrack = 0; nTrack < m_headerMPEG4.total_tracks; nTrack++)
            {
                _SAFE_DELETE_ARRAY(m_headerMoof.trun[nTrack].trun);
            }
        }
        else
        {
             m_headerMoof.trun = _NEW_n(TM_table_trun, m_headerMPEG4.total_tracks);
        }

        for ( nTrack = 0; nTrack < m_headerMPEG4.total_tracks; nTrack++)
        {
            TM_table_trun& trunTrack = m_headerMoof.trun[nTrack];

            trunTrack.entry_count = m_sTrack[nTrack].m_nSamplesCount;
            trunTrack.trun = _NEW_n(TM_trun_table_data, trunTrack.entry_count);

            for (i = 0; i < m_sTrack[nTrack].m_nSamplesCount; i++)
            {
                if (i != m_sTrack[nTrack].m_nSamplesCount - 1) {
                    trunTrack.trun[i].sample_duration = m_sTrack[nTrack].m_pSamples[i+1].m_nTimeStamp - m_sTrack[nTrack].m_pSamples[i].m_nTimeStamp;
                } else {
                  if (i != 0) {
                    trunTrack.trun[i].sample_duration = trunTrack.trun[i-1].sample_duration;  //last sample
                  }
                }
//                trunTrack.trun[i].sample_duration = m_sTrack[nTrack].m_pSamples[i].m_nTimeStamp;
                trunTrack.trun[i].sample_size = m_sTrack[nTrack].m_pSamples[i].m_nSize;
            }
        }

        return UMC_OK;
    };

}

⌨️ 快捷键说明

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