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

📄 umc_mp4_mux.cpp

📁 audio-video-codecs.rar语音编解码器
💻 CPP
📖 第 1 页 / 共 2 页
字号:

    if (m_sTrack[ntrak].m_nSamplesCount + 1 >= m_sTrack[ntrak].m_nTrackSize)
    {
        m_sTrack[ntrak].m_pSamples = (sMuxSample*) realloc(m_sTrack[ntrak].m_pSamples, sizeof(sMuxSample) * (INITIAL_TRACK_SIZE + (size_t)m_sTrack[ntrak].m_nTrackSize));
        m_sTrack[ntrak].m_nTrackSize += INITIAL_TRACK_SIZE;
    }

    return UMC_OK;
}

Status MP4Muxer::AdjustVideoData(MediaData* &lpData, Ipp32s nStreamNumber)
{
    if (m_bDataFromEncoder && UMC::H264_VIDEO == m_pTrackParams[nStreamNumber].info.video->stream_type)
    {
      lpData = TransformH264Frame(lpData, nStreamNumber);
    } else {
      if (m_FirstFrame[nStreamNumber]) {
        m_FirstFrame[nStreamNumber] = 0;
        TM_esds_data *pEsds = &(m_headerMPEG4.trak[nStreamNumber]->mdia.minf.stbl.stsd.table[0].esds);
        if (UMC::MPEG4_VIDEO == m_pTrackParams[nStreamNumber].info.video->stream_type) {
          if (m_bDataFromEncoder) {
            // mp4v from encoder: fill esds and PutData
            int i, m_InfoLen = 0;
            int mFrameLen = lpData->GetDataSize();
            Ipp8u *pData = (Ipp8u *)lpData->GetDataPointer();
            for (i = 0; i < mFrameLen - 3; i++) {
              if (((pData[i]==0x00)&&(pData[i+1]==0x00)&&(pData[i+2]==0x01)&&(pData[i+3]==0xb6)) ||
                ((pData[i]==0x00)&&(pData[i+1]==0x00)&&(pData[i+2]==0x01)&&(pData[i+3]==0xb3))) {
                  m_InfoLen = i;
                  break;
              }
            }
            // m_InfoLen can't be equal to zero
            vm_trace_i(m_InfoLen);
            if (m_InfoLen) {
              pEsds->decoderConfigLen = m_InfoLen;
              pEsds->decoderConfig = (Ipp8u *)malloc(m_InfoLen);
              memcpy(pEsds->decoderConfig, pData, m_InfoLen);
              lpData->MoveDataPointer(m_InfoLen);  // cut off mp4v header
            }
          } else {
            // mp4v from splitter: first frame is esds
            pEsds->decoderConfigLen = lpData->GetDataSize();
            pEsds->decoderConfig = (Ipp8u *)malloc(pEsds->decoderConfigLen);
            memcpy(pEsds->decoderConfig, lpData->GetDataPointer(), lpData->GetDataSize());
            lpData->SetDataSize(0);
          }
        }
      }
    }
    return UMC_OK;
}

Status MP4Muxer::AdjustAudioData(MediaData* &lpData, Ipp32s nStreamNumber)
{
    Ipp32s nbits, nbytes;
    sBitsreamBuffer BS;
    sAdts_fixed_header m_adts_fixed_header;
    sAdts_variable_header m_adts_variable_header;

    if (m_pTrackParams[nStreamNumber].info.audio->stream_type & AAC_AUDIO) {
      if (m_bDataFromEncoder) {
        GET_INIT_BITSTREAM(&BS, lpData->GetDataPointer());
        if ((0 == dec_adts_fixed_header(&m_adts_fixed_header, &BS)) &&
            (0 == dec_adts_variable_header(&m_adts_variable_header, &BS)))
        {
          Byte_alignment(&BS);
          GET_BITS_COUNT(&BS, nbits);
          nbytes = nbits >> 3;
          if (m_adts_fixed_header.protection_absent == 0) {
            nbytes += 2;
          }
          lpData->MoveDataPointer(nbytes);  // cut off adts headers
        }
      }

      if (m_FirstFrame[nStreamNumber]) {
        m_FirstFrame[nStreamNumber] = 0;
        if (m_bDataFromEncoder) {
          sAudio_specific_config decSpecConfig;
          MediaData p_SpecInfo(400);

          /// AudioSpecificConfig;
          decSpecConfig.sbrPresentFlag = 0;
          decSpecConfig.audioObjectType = get_audio_object_type_by_adts_header(&m_adts_fixed_header);
          decSpecConfig.samplingFrequencyIndex = m_adts_fixed_header.sampling_frequency_index;
          decSpecConfig.samplingFrequency = 0;
          decSpecConfig.channelConfiguration = m_adts_fixed_header.channel_configuration;
          decSpecConfig.extensionAudioObjectType = 0; // for SBR
          decSpecConfig.extensionSamplingFrequencyIndex = 0; // for SBR
          decSpecConfig.extensionSamplingFrequency = 0; // for SBR

          /// sGA_specific_config;
          decSpecConfig.GASpecificConfig.frameLengthFlag = 1; //1024
          decSpecConfig.GASpecificConfig.dependsOnCoreCoder = 0;
          decSpecConfig.GASpecificConfig.coreCoderDelay = 0;
          decSpecConfig.GASpecificConfig.extensionFlag = 0; // for SBR
          // decSpecConfig.GASpecificConfig.pce;

          INIT_BITSTREAM(&BS, p_SpecInfo.GetDataPointer());
          enc_audio_specific_config(&decSpecConfig, &BS);
          GET_BITS_COUNT(&BS, nbits);
          nbytes = nbits >> 3;
          p_SpecInfo.SetDataSize(nbytes);

          TM_esds_data *pEsds = &(m_headerMPEG4.trak[nStreamNumber]->mdia.minf.stbl.stsd.table[0].esds);
          pEsds->decoderConfigLen = nbytes;
          pEsds->decoderConfig = (Ipp8u *)malloc(pEsds->decoderConfigLen);
          memcpy(pEsds->decoderConfig, p_SpecInfo.GetDataPointer(), nbytes);
        } else { // AAC from splitter case
          TM_esds_data *pEsds = &(m_headerMPEG4.trak[nStreamNumber]->mdia.minf.stbl.stsd.table[0].esds);
          pEsds->decoderConfigLen = lpData->GetDataSize();
          pEsds->decoderConfig = (Ipp8u *)malloc(pEsds->decoderConfigLen);
          memcpy(pEsds->decoderConfig, lpData->GetDataPointer(), lpData->GetDataSize());
          lpData->SetDataSize(0);
        }
      } // m_bFirstAudioFrame
    }

    return UMC_OK;
}

Status MP4Muxer::UnlockBuffer(MediaData *lpData, Ipp32s iTrack)
{
    Status umcRes;

    UMC_CHECK(lpData, UMC_OK);
    UMC_CHECK(lpData->GetDataSize(), UMC_OK);

    umcRes = Muxer::UnlockBuffer(lpData, iTrack);
    if (umcRes != UMC::UMC_OK) {
      return umcRes;
    }
    return MuxData(false);
}

Status MP4Muxer::PutEndOfStream(Ipp32s iTrack)
{
  Status umcRes;

  umcRes = Muxer::PutEndOfStream(iTrack);
  if ((umcRes != UMC::UMC_OK) && (umcRes != UMC::UMC_ERR_NULL_PTR)) {
    return umcRes;
  }
  return MuxData(false);

} //Status Muxer::PutEndOfStream(Ipp32u iTrack)

Status MP4Muxer::Flush(void)
{
    return MuxData(true);
} //Status MPEG2Muxer::Flush(void)

Status MP4Muxer::MuxData(bool bFlushMode)
{
    AutomaticMutex guard(m_PutDataMutex);
    Ipp32s nEndIndex;
    MediaData cData, *pcData;
    Status umcRes;
    int nSize;

    for (;;) {
      //find shortest track, and add frame to it
      nEndIndex = FindMinTrackEnd(m_sTrack, m_uiTotalNumStreams);
      vm_debug_trace2(VM_DEBUG_PROGRESS, VM_STRING("nEndIndex = %i m_sTrack->m_nTrackEnd = %f\n"), nEndIndex, m_sTrack[nEndIndex].m_nTrackEnd);

      if (nEndIndex == -1) break; // EOS in all tracks

      umcRes = m_ppBuffers[nEndIndex]->LockOutputBuffer(&cData);
      if (umcRes == UMC_OK) {
        pcData = &cData;
        if (IS_VIDEO(nEndIndex)) {
          //maybe problem with video in one header, and audio in another
          if (needNewFragment(pcData, nEndIndex))
            DisposeDataToFile();

          vm_debug_trace1(VM_DEBUG_PROGRESS, VM_STRING("m_nHeaderSize = %d\n"), m_nHeaderSize);
          AdjustVideoData(pcData, nEndIndex);
        } else {
          vm_debug_trace(VM_DEBUG_PROGRESS, VM_STRING("audio buffer is chosen!!!\n"));
          AdjustAudioData(pcData, nEndIndex);
        }

        if (pcData->GetDataSize() != 0) { // don't mux if decSpecInfo
          vm_file *pFile = m_fTempOutput1;
          if (IS_AUDIO(nEndIndex) && !m_bMoov)
            pFile = m_fTempOutput2[nEndIndex];

          nSize = _FWRITE_P(pcData, pFile);
          vm_debug_trace2(VM_DEBUG_PROGRESS, VM_STRING("wrote from buffer %d to file %i bytes!!!\n"), nEndIndex, nSize);

          m_nMdatSize += nSize;
          SampleInfo(pcData, nEndIndex);
        }

        cData.SetDataSize(0);
        m_ppBuffers[nEndIndex]->UnLockOutputBuffer(&cData);
      } else if (umcRes == UMC_ERR_END_OF_STREAM) {
        m_sTrack[nEndIndex].m_nTrackStatus = 1;  // track is fully muxed
      } else if (umcRes == UMC_ERR_NOT_ENOUGH_DATA) { // no data
        if (bFlushMode == false) {
          break;  // break if not flush mode
        } else {
          m_sTrack[nEndIndex].m_nTrackStatus = 1;
        }
      } else {
        break; // probably error
      }
    }

    return UMC_OK;
}

Status MP4Muxer::WriteHeader()
{
    vm_trace_s("WriteHeader");

    //write the very head to file ("ftypisom-isom")
    Write_head(m_pParams->m_lpDataWriter);

    //update atoms in header (moov),
    UpdateHeader();

    //init atoms in header (moov)
    InitAtoms();

    //calculate sizes of all atoms in header (moov)
    CalculateSizes();

    //write main(single, if true == m_bMoov) "header" to file
    if (Write_moov(m_pParams->m_lpDataWriter, &m_headerMPEG4) != UMC_OK )
        return UMC_ERR_FAILED;

    //if header has extensions, then file structure will has moof atoms
    if (!m_bMoov)
    {
        if (Write_mvex(m_pParams->m_lpDataWriter, &m_headerMVEX) != UMC_OK)
            return UMC_ERR_FAILED;
    }

    //write "mdat" atom size to first 4 bytes in file
    WriteMdatSize();

    //transfer data from temporary file to output resulting file
    TransferDataFromTemporaryFile(m_fTempOutput1);

    return UMC_OK;
}

Status MP4Muxer::WriteHeaderFragment()
{
    vm_trace_s("WriteHeaderFragment");

    InitMoof();
    if (Write_moof(m_pParams->m_lpDataWriter, &m_headerMoof) != UMC_OK )
        return UMC_ERR_FAILED;
    WriteMdatSize();
    TransferDataFromTemporaryFile(m_fTempOutput1);
    for (Ipp32u i = 0; i < m_uiTotalNumStreams; i++)
    {
      if (IS_AUDIO(i)) {
        _SEEK_FILE_START(m_fTempOutput2[i]);
        TransferDataFromTemporaryFile(m_fTempOutput2[i]);
      }
    }
    return UMC_OK;
}

Status MP4Muxer::DumpState()
{
  Ipp32u i;
  UMC_CHECK_PTR(m_ppBuffers);
  for (i = 0; i < m_uiTotalNumStreams; i++) {
    vm_trace_i(m_pTrackParams[i].type);
    UMC_CHECK_PTR(m_ppBuffers[i]);
  }
  return UMC_OK;
}

} // namespace UMC

⌨️ 快捷键说明

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