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

📄 umc_mp4_mux_common.cpp

📁 audio-video-codecs.rar语音编解码器
💻 CPP
字号:
/*//////////////////////////////////////////////////////////////////////////////
//
//                  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 <stdio.h>
#include "ipps.h"
#include "umc_mp4_mux_defs.h"
#include "umc_mp4_mux.h"

namespace UMC
{
    /* return the index of the shortest track; -1 if all are muxed */
    Ipp32s MP4Muxer::FindMinTrackEnd(sMuxTMrack* sTrack, Ipp32s nTracksNum)
    {
      Ipp32s  nEndIndex = 0;
      Ipp64f  dEnd = MAX_TIME;
      Ipp32s  nMuxedTracks = 0;
      int i;

      for (i = 0; i < nTracksNum; i++) {
        if (sTrack[i].m_nTrackStatus == 1) {  // track is muxed
          nMuxedTracks++;
          if (nMuxedTracks == nTracksNum) {
            return -1;
          } else {
            continue;
          }
        }
        if (sTrack[i].m_nTrackEnd < dEnd) {
            dEnd = sTrack[i].m_nTrackEnd;
            nEndIndex = i;
        }
      }
      return nEndIndex;
    }

    Status MP4Muxer::Write_size(vm_file *dw, Ipp32u value)
    {
        Ipp8u    data_char[4];

        data_char[0] = (Ipp8u)((value & 0xff000000) >> 24);
        data_char[1] = (Ipp8u)((value & 0xff0000) >> 16);
        data_char[2] = (Ipp8u)((value & 0xff00) >> 8);
        data_char[3] = (Ipp8u) (value & 0xff);

        return vm_file_fwrite(data_char, 4, 1, dw) ? UMC_ERR_FAILED : UMC_OK;
    }

    Status MP4Muxer::InitTemporaryOutputFile1()
    {
        m_nMdatSize = 0;

        m_fTempOutput1 = vm_file_tmpfile();

        vm_file_fwrite("xxxxmdat", 8, 1, m_fTempOutput1);

        return UMC_OK;
    };

    Status MP4Muxer::InitAdditionalTemporaryOutputFiles()
    {
        m_fTempOutput2 = new vm_file*[m_uiTotalNumStreams];

        for (Ipp32u i = 0; i < m_uiTotalNumStreams; i++)
        {
          if (IS_AUDIO(i)) {
            m_fTempOutput2[i] = vm_file_tmpfile();
          } else {
            m_fTempOutput2[i] = NULL;
          }
        }

        return UMC_OK;
    };

    Status MP4Muxer::InitTracks(Ipp32s nTracks)
    {
        m_sTrack = _NEW_n(sMuxTMrack, nTracks);

        for (Ipp32s i = 0; i < nTracks; i++)
        {
            m_sTrack[i].m_pSamples      = _NEW_n(sMuxSample, INITIAL_TRACK_SIZE);
            m_sTrack[i].m_nSamplesCount = 0;
            m_sTrack[i].m_nTrackSize    = INITIAL_TRACK_SIZE;
            m_sTrack[i].m_nTrackEnd     = 0;
            m_sTrack[i].m_nTrackStatus  = 0;
            m_sTrack[i].m_nSttsEntries  = 1;  // at least 1 entry
            m_sTrack[i].m_nCttsEntries  = 0;  // is not needed
        }

        return UMC_OK;
    };

    Status MP4Muxer::DisposeDataToFile()
    {
        vm_debug_trace1(VM_DEBUG_PROGRESS, VM_STRING("DisposeDataToFile %d"), (int)m_bMoov);

        if (m_bMoov)
        {
            m_bMoov = false;

            CalculateMvexExtendedSize(&m_headerMVEX);

            WriteHeader();
        }
        else
        {
            WriteHeaderFragment();
        }

        //reopen file for data buffering
        InitTemporaryOutputFile1();
        InitAdditionalTemporaryOutputFiles();

        for (Ipp32u i = 0; i < m_headerMPEG4.total_tracks; i++)
        {
            m_sTrack[i].m_nSamplesCount = 0;
        }

        m_nHeaderSize = CalculateFragmentSize(&m_headerMoof);

        return UMC_OK;
    };

    Status MP4Muxer::GetBits(Ipp32s *data, Ipp32s nbits, Ipp32s *ptr, Ipp8u *buf)
    {
        Ipp32s   num, maxNum, curNum;
        Ipp32u   bits;

        num = 0;
        *data = 0;
        maxNum = BYTE_BIT - *ptr % BYTE_BIT;
        while (num < nbits)
        {
            curNum = IPP_MIN(nbits - num, maxNum);
            bits = (buf[*ptr / BYTE_BIT] >> (BYTE_BIT - *ptr % BYTE_BIT - curNum)) & ((1 << curNum) - 1);
            *data |= bits << (nbits - num - curNum);
            num += curNum;
            *ptr += curNum;
            maxNum = BYTE_BIT;
        }
        return UMC::UMC_OK;
    }

    FrameType MP4Muxer::GetPictureType(MediaData *lpData, Ipp32s nTrak)
    {
        if (!lpData) return NONE_PICTURE;
        FrameType frame_type = lpData->GetFrameType();
        if (frame_type != NONE_PICTURE) {
          if (I_PICTURE == frame_type) {
            vm_debug_trace_s(VM_DEBUG_PROGRESS, "GetPictureType: I_PICTURE _");
          }
          return frame_type;
        }
        if (UMC::H264_VIDEO == m_pTrackParams[nTrak].info.video->stream_type)
        {
            if (NAL_UT_IDR_SLICE == (((Ipp8s*)lpData->GetDataPointer())[4] & NAL_UNITTYPE_BITS))
            {
                vm_debug_trace_s(VM_DEBUG_PROGRESS, "GetPictureType: I_PICTURE");
                return I_PICTURE;
            } else {
                vm_debug_trace_s(VM_DEBUG_PROGRESS, "GetPictureType: Unknown PICTURE");
                return NONE_PICTURE;
            }
        }
        if (UMC::MPEG4_VIDEO == m_pTrackParams[nTrak].info.video->stream_type)
        {
//            Ipp32s nSizeToRead = 6;
            Ipp32s nCodingType = 0;

            Ipp32s nBitPos = 32; // start code

            GetBits(&nCodingType, 2/*two bits*/, &nBitPos, (Ipp8u*)lpData->GetBufferPointer());

            switch (nCodingType)
            {
              case 0: return I_PICTURE;
              case 1: return P_PICTURE;
              case 2: return B_PICTURE;
              case 3: return D_PICTURE; // SPRITE picture?
            }
        }
        return NONE_PICTURE;
    }

    bool MP4Muxer::needNewFragment(MediaData *lpData, Ipp32s nTrak)
    {
      if (m_pParams->m_lFlags & FLAG_FRAGMENTED_BY_HEADER_SIZE) {
        Ipp32u nHeaderSize = (m_bMoov ? m_nMoovSize : m_nMoofSize) - 28 * m_headerMPEG4.total_tracks;
        if (m_nHeaderSize >= nHeaderSize && I_PICTURE == GetPictureType(lpData, nTrak)) {
          vm_debug_trace_s(VM_DEBUG_PROGRESS, "needNewFragment");
          return true;
        }
      }
      /*if (m_pParams->m_lFlags & FLAG_FRAGMENTED_NUMBER_FRAMES) {
        if ((m_sTrack[nTrak].m_nSamplesCount & 15) == 15) {
          vm_debug_trace_s(VM_DEBUG_PROGRESS, "needNewFragment");
          return true;
        }
      }*/
      if (m_pParams->m_lFlags & FLAG_FRAGMENTED_AT_I_PICTURES) {
        if (m_sTrack[nTrak].m_nSamplesCount > 10 && I_PICTURE == GetPictureType(lpData, nTrak)) {
          vm_debug_trace_s(VM_DEBUG_PROGRESS, "needNewFragment");
          return true;
        }
      }
      return false;
    }

    Status MP4Muxer::TransferDataFromTemporaryFile(vm_file* fTemp)
    {
        DataWriter *m_lpDataWriter = m_pParams->m_lpDataWriter;
        Ipp32s nsize = 0;
        Ipp8s buffer[1024 + 16];

        vm_debug_trace_s(VM_DEBUG_PROGRESS, "TransferDataFromTemporaryFile");

        nsize = vm_file_fread(buffer, 1, 1024, fTemp);
        while(0 != nsize)
        {
            m_lpDataWriter->PutData(buffer, nsize);
            nsize = vm_file_fread(buffer, 1, 1024, fTemp);
        }
        vm_file_fclose(fTemp);

        vm_debug_trace_s(VM_DEBUG_PROGRESS, "TransferDataFromTemporaryFile OK");
        return UMC_OK;
    };

    Status MP4Muxer::WriteMdatSize()
    {
        _SEEK_FILE_START(m_fTempOutput1);
        Write_size(m_fTempOutput1, m_nMdatSize + 8);
        _SEEK_FILE_START(m_fTempOutput1);

        return UMC_OK;
    };

    Status MP4Muxer::SetHeaderSizes(Ipp32s nMoovSize, Ipp32s nMoofSize)
    {
        m_nMoovSize = nMoovSize;
        m_nMoofSize = nMoofSize;

        return UMC_OK;
    };
} // namespace UMC

⌨️ 快捷键说明

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