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

📄 umc_mpeg2_muxer.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 "ipps.h"
#include "vm_debug.h"
#include "umc_defs.h"
#include "umc_automatic_mutex.h"
#include "umc_mpeg2_muxer.h"
#include "umc_mpeg2_muxer_linbuf.h"
#include "umc_mpeg2_muxer_chunk.h"

#define MAX_VIDEO_TRACK_FOR_MPEG2PS 16
#define MAX_MPEG_AUDIO_TRACK_FOR_MPEG2PS 32
#define MAX_AC3_AUDIO_TRACK_FOR_MPEG2PS 8
#define MAX_LPCM_AUDIO_TRACK_FOR_MPEG2PS 8

#define IS_PCR_PID(PROG, ES_NUM) (m_pPMTTableWriterParams[PROG].pPID[ES_NUM] == m_pPMTTableWriterParams[PROG].uiPCRPID)

using namespace UMC;

Muxer* UMC::CreateMPEG2Muxer() {
  return (new MPEG2Muxer);
}

MPEG2Muxer::MPEG2Muxer(void)
{
    //vm_debug_setlevel((vm_debug_level)(VM_DEBUG_ERROR | VM_DEBUG_WARNING /*| VM_DEBUG_INFO*/));

    m_pMPEG2MuxerParams = NULL;

    // reset variable(s)
    m_bQuit = false;
    m_uiTotalRate = 0;

    m_pPATTableWriterParams = NULL;
    m_pPATTableWriter = NULL;
    m_pPMTTableWriterParams = NULL;
    m_ppPMTTableWriter = NULL;

    // frame selection for system clock approximation
    m_dReferenceClock = 0.0;
    m_dReferenceClockOfPrevSI = -5.0;

    // reset mutex
    vm_mutex_set_invalid(&m_synchro);

    max_video_buff = 0;
    max_audio_buff = 0;
#ifdef MUX_STATISTICS
    max_video_size = 0;
    max_audio_size = 0;
    total_video_size = 0;
    total_audio_size = 0;
    num_video_frames = 0;
    num_audio_frames = 0;
#endif
} //MPEG2Muxer::MPEG2Muxer(void)

MPEG2Muxer::~MPEG2Muxer(void)
{
    Close();

    // destroy mutex
    if (vm_mutex_is_valid(&m_synchro)) {
        vm_mutex_destroy(&m_synchro);
    }

} //MPEG2Muxer::~MPEG2Muxer(void)

Status MPEG2Muxer::Close(void)
{
#if 0
    if (m_lpDataWriter) {
      Ipp32u total_size, size2;
      m_lpDataWriter->GetPosition(&total_size, &size2);

      Ipp32s audio_bitrate = m_pESState[0].bitrate;
      Ipp32s video_bitrate = m_pESState[1].bitrate;
      Ipp64f framerate = m_pESState[1].frameRate;
      Ipp64f ave_video_size = video_bitrate/(8.0*framerate);
      Ipp64f duration = num_video_frames/framerate;
      Ipp64f expected_video_size = video_bitrate*duration/8.0;
      Ipp64f expected_audio_size = audio_bitrate*duration/8.0;
      TmpLog("\n%.4f Video(%dKbit/s %.4f), Audio(%dKbit/s %.4f), Muxed(%.2fMb - %.2fMb - %.2fMb = %.2fMb (%.2f%%))\n",
        (Ipp64f)max_video_size/max_video_buff,
        video_bitrate/1000,
        total_video_size/expected_video_size,
        audio_bitrate/1000,
        total_audio_size/expected_audio_size,
        total_size*1e-6,
        total_video_size*1e-6,
        total_audio_size*1e-6,
        (total_size - total_video_size - total_audio_size)*1e-6,
        100.0*(total_size - total_video_size - total_audio_size)/total_size
        );
    }
#endif

    m_bQuit = false;
    m_uiTotalRate = 0;

    // frame selection for system clock approximation
    m_dReferenceClock = 0.0;
    m_dReferenceClockOfPrevSI = -5.0;

    if (m_pPMTTableWriterParams)
    {
        UMC_FREE(m_pPMTTableWriterParams->pPID);
        UMC_FREE(m_pPMTTableWriterParams->pStreamType);
        UMC_DELETE_ARR(m_pPMTTableWriterParams);
    }

    if (m_ppPMTTableWriter)
    {
        Ipp32s i;
        for (i = 0; i < m_pPATTableWriterParams->iNOfPrograms; i++)
            UMC_DELETE(m_ppPMTTableWriter[i]);

        UMC_FREE(m_ppPMTTableWriter);
    }

    if (m_pPATTableWriterParams)
    {
        UMC_FREE(m_pPATTableWriterParams->pProgramPID);
        UMC_DELETE(m_pPATTableWriterParams);
    }

    UMC_DELETE(m_pPATTableWriter);

    UMC_CALL(Muxer::Close());

    return UMC_OK;
} //Status MPEG2Muxer::Close(void)

Status MPEG2Muxer::Init(MuxerParams *lpInit)
{
    MPEG2ChunkWriterParams *pChunkWriterParams = NULL;
    SystemHeaderParams sysHeaderParams;
    Ipp16u uiPCRTrackNum = 0x1FFF;
    Ipp32s nNum;

    // release muxer before initialization
    Close();

    // allocate MPEG2MuxerParams
    UMC_NEW(m_pParams, MPEG2MuxerParams);
    m_pMPEG2MuxerParams = (MPEG2MuxerParams*)m_pParams;

    // Base muxer Init
    UMC_CALL(CopyMuxerParams(lpInit));

    MPEG2MuxerParams *pMPEG2MuxerParams = DynamicCast<MPEG2MuxerParams>(lpInit);
    if (pMPEG2MuxerParams)
    {
        vm_debug_trace(VM_DEBUG_INFO, VM_STRING("Initialization with MPEG2MuxerParams"));
        m_pMPEG2MuxerParams->m_uiAlignmentFlags = pMPEG2MuxerParams->m_uiAlignmentFlags;
        m_pMPEG2MuxerParams->m_dSystemTimeDelay = pMPEG2MuxerParams->m_dSystemTimeDelay;
        m_pMPEG2MuxerParams->m_uiChunkSizeLimit = IPP_MAX(pMPEG2MuxerParams->m_uiChunkSizeLimit, 0x100);
    }

    if (IsPure(m_pParams->m_SystemType))
    {
        UMC_NEW(pChunkWriterParams, MPEG2ChunkWriterParams);

        if (MPEG2_PURE_VIDEO_STREAM == m_pParams->m_SystemType ||
            MPEG4_PURE_VIDEO_STREAM == m_pParams->m_SystemType ||
            H264_PURE_VIDEO_STREAM  == m_pParams->m_SystemType ||
            MPEGx_PURE_VIDEO_STREAM == m_pParams->m_SystemType)
        {
            if (!CHECK_TRACK_TYPE(0, VIDEO_TRACK))
            {
                vm_debug_trace1(VM_DEBUG_ERROR, VM_STRING("Pure video stream (type %d) was demanded at output, but no video track was provided"), m_pParams->m_SystemType);
                return UMC_ERR_INVALID_PARAMS;
            }

            pChunkWriterParams->uiBitRate = m_pParams->pTrackParams[0].info.video->bitrate;
        }
        else if (MPEG2_PURE_AUDIO_STREAM == m_pParams->m_SystemType ||
                 MPEGx_PURE_AUDIO_STREAM == m_pParams->m_SystemType)
        {
            if (!CHECK_TRACK_TYPE(0, AUDIO_TRACK))
            {
                vm_debug_trace1(VM_DEBUG_ERROR, VM_STRING("Pure audio stream (type %d) was demanded at output, but no audio track was provided"), m_pParams->m_SystemType);
                return UMC_ERR_INVALID_PARAMS;
            }

            pChunkWriterParams->uiBitRate = m_pParams->pTrackParams[0].info.audio->bitrate;
        }

        pChunkWriterParams->pDataWriter = m_pParams->m_lpDataWriter;
        pChunkWriterParams->uiAlignmentFlags = 0;
        pChunkWriterParams->esType = MPEG2MUX_ES_UNKNOWN;

        pChunkWriterParams->uiOfFrames = 1;
        pChunkWriterParams->uiInputSize = m_pParams->pTrackParams[0].bufferParams.m_prefInputBufferSize;
        pChunkWriterParams->uiBufferSize = pChunkWriterParams->uiInputSize *
            m_pParams->pTrackParams[0].bufferParams.m_numberOfFrames;

        UMC_NEW(m_ppBuffers[0], MPEG2ChunkWriter);
        UMC_CALL(m_ppBuffers[0]->Init(pChunkWriterParams));
    }
    else if (IsPSOrPES(m_pParams->m_SystemType) || IsTS(m_pParams->m_SystemType))
    {
        if (IsPSOrPES(m_pParams->m_SystemType))
        {
            if (MPEG2_PES_PACKETS_STREAM == m_pParams->m_SystemType)
                m_uiTotalNumStreams = 1;

            UMC_NEW(pChunkWriterParams, MPEG2PSChunkWriterParams);

            for (nNum = 0; nNum < m_uiTotalNumStreams; nNum++)
                UMC_NEW(m_ppBuffers[nNum], MPEG2PSChunkWriter);

            UMC_ALLOC_ARR(sysHeaderParams.pSystemSizeBound, Ipp32u, m_uiTotalNumStreams);
            UMC_ALLOC_ARR(sysHeaderParams.pSystemStreamID, Ipp32u, m_uiTotalNumStreams);
        }
        else // TS, TTS or TTS0
        {
            // choose PCR_PID
            for (uiPCRTrackNum = 0; uiPCRTrackNum < m_uiTotalNumStreams; uiPCRTrackNum++)
                if (CHECK_TRACK_TYPE(uiPCRTrackNum, VIDEO_TRACK))
                    break;

            if (uiPCRTrackNum == m_uiTotalNumStreams)
                uiPCRTrackNum = 0;

            UMC_NEW(pChunkWriterParams, MPEG2TSChunkWriterParams);

            if (IsTTS(m_pParams->m_SystemType))
            {
                for (nNum = 0; nNum < m_uiTotalNumStreams; nNum++)
                    UMC_NEW(m_ppBuffers[nNum], MPEG2TTSChunkWriter);
            }
            else
            {
                for (nNum = 0; nNum < m_uiTotalNumStreams; nNum++)
                    UMC_NEW(m_ppBuffers[nNum], MPEG2TSChunkWriter);
            }



            UMC_NEW(m_pPATTableWriterParams, PATTableWriterParams);
            m_pPATTableWriterParams->pDataWriter = m_pParams->m_lpDataWriter;
            m_pPATTableWriterParams->iNOfPrograms = 1;

            UMC_ALLOC_ARR(m_pPATTableWriterParams->pProgramPID, Ipp16u, m_pPATTableWriterParams->iNOfPrograms);
            m_pPATTableWriterParams->pProgramPID[0] = MPEG2MUX_PROGRAM_MAP_PID;

            if (IsTTS(m_pParams->m_SystemType))
            {
                UMC_NEW(m_pPATTableWriter, TTSPATTableWriter);
            }
            else
            {
                UMC_NEW(m_pPATTableWriter, PATTableWriter);
            }

            UMC_CALL(m_pPATTableWriter->Init(m_pPATTableWriterParams));

            UMC_NEW_ARR(m_pPMTTableWriterParams, PMTTableWriterParams, m_pPATTableWriterParams->iNOfPrograms);
            UMC_ALLOC_ZERO_ARR(m_ppPMTTableWriter, PMTTableWriter*, m_pPATTableWriterParams->iNOfPrograms);

            for (nNum = 0; nNum < m_pPATTableWriterParams->iNOfPrograms; nNum++)
            {
                if (IsTTS(m_pParams->m_SystemType))
                {
                    UMC_NEW(m_ppPMTTableWriter[nNum], TTSPMTTableWriter);
                }
                else
                {
                    UMC_NEW(m_ppPMTTableWriter[nNum], PMTTableWriter);
                }

                m_pPMTTableWriterParams[nNum].pDataWriter = m_pParams->m_lpDataWriter;
                m_pPMTTableWriterParams[nNum].uiProgramNumber = nNum + 1;
                m_pPMTTableWriterParams[nNum].uiProgramPID = m_pPATTableWriterParams->pProgramPID[nNum];
            }

            // this suggests that only one program is currently supported
            m_pPMTTableWriterParams[0].uiNOfStreams = m_uiTotalNumStreams;
            UMC_ALLOC_ARR(m_pPMTTableWriterParams[0].pStreamType, MPEG2MuxerESType, m_uiTotalNumStreams);
            UMC_ALLOC_ARR(m_pPMTTableWriterParams[0].pPID, Ipp32u, m_uiTotalNumStreams);
        }

        m_uiTotalRate = 0;

        //initialize chunk writers
        MPEG2PSChunkWriterParams *pPSChunkWriterParams = (MPEG2PSChunkWriterParams *)pChunkWriterParams;
        MPEG2TSChunkWriterParams *pTSChunkWriterParams = (MPEG2TSChunkWriterParams *)pChunkWriterParams;
        pPSChunkWriterParams->uiAlignmentFlags = m_pMPEG2MuxerParams->m_uiAlignmentFlags;
        pPSChunkWriterParams->pDataWriter = m_pParams->m_lpDataWriter;
        pPSChunkWriterParams->uiOfFrames = 30;
        pPSChunkWriterParams->bPackHeaderPresent = true;
        pPSChunkWriterParams->uiPacketSize = m_pMPEG2MuxerParams->m_uiChunkSizeLimit;

        // track statistic
        Ipp32u uiPID = MPEG2MUX_INITIAL_ES_PID;
        Ipp32u uiNOfVideoTracks = 0;
        Ipp32u uiNOfMPEGVideoTracks = 0;
        Ipp32u uiNOfAudioTracks = 0;
        Ipp32u uiNOfMPEGAudioTracks = 0;
        Ipp32u uiNOfPrivateAudioTracks = 0;
        Ipp32u uiNOfAC3AudioTracks = 0;
        Ipp32u uiNOfLPCMAudioTracks = 0;
        Ipp32u uiRateOfPrivateTracks = 0;
        for(nNum = 0; nNum < (Ipp32s)m_uiTotalNumStreams; nNum++)
        {
            pChunkWriterParams->uiInputSize = m_pParams->pTrackParams[nNum].bufferParams.m_prefInputBufferSize;

⌨️ 快捷键说明

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