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

📄 umc_mpeg2_muxer.cpp

📁 audio-video-codecs.rar语音编解码器
💻 CPP
📖 第 1 页 / 共 2 页
字号:
            pChunkWriterParams->uiBufferSize = pChunkWriterParams->uiInputSize *
                m_pParams->pTrackParams[nNum].bufferParams.m_numberOfFrames;

            if (CHECK_TRACK_TYPE(nNum, AUDIO_TRACK))
            { // audio
                vm_debug_trace2(VM_DEBUG_INFO, VM_STRING("Stream #%d: audio (type %d)"), nNum, m_pParams->pTrackParams[nNum].info.audio->stream_type);
                pPSChunkWriterParams->esType = ConvertAudioType(m_pParams->m_SystemType, m_pParams->pTrackParams[nNum].info.audio->stream_type);
                if (MPEG2MUX_ES_UNKNOWN == pPSChunkWriterParams->esType)
                {
                    vm_debug_trace2(VM_DEBUG_ERROR, VM_STRING("Unsupported audio format (%d) for track #%d is specified"), m_pParams->pTrackParams[nNum].info.audio->stream_type, nNum);
                    return UMC_ERR_UNSUPPORTED;
                }

                pPSChunkWriterParams->dFrameRate = 0.0;
                pPSChunkWriterParams->uiBitRate = m_pParams->pTrackParams[nNum].info.audio->bitrate;
                if (pPSChunkWriterParams->uiBitRate == 0)
                {
                    pPSChunkWriterParams->uiBitRate = 100000;
                    vm_debug_trace2(VM_DEBUG_INFO, VM_STRING("Bitrate for track #%d is unspecified, default value is %d bps"), nNum, pPSChunkWriterParams->uiBitRate);
                }

                if (MPEG2MUX_ES_AC3_AUDIO == pPSChunkWriterParams->esType)
                {
                    if (IsPSOrPES(m_pParams->m_SystemType) && uiNOfAC3AudioTracks >= MAX_AC3_AUDIO_TRACK_FOR_MPEG2PS)
                    {
                        vm_debug_trace1(VM_DEBUG_ERROR, VM_STRING("Too much AC3 tracks was specified. Only %d are supported for MPEG2PS"), MAX_AC3_AUDIO_TRACK_FOR_MPEG2PS);
                        return UMC_ERR_INVALID_PARAMS;
                    }

                    pPSChunkWriterParams->uiStreamID = MPEG2MUX_PES_ID_PRIVATE_1;
                    pPSChunkWriterParams->uiSubStreamID = MPEG2MUX_AC3_SUB_ID + uiNOfAC3AudioTracks;

                    uiNOfAC3AudioTracks++;
                    uiNOfPrivateAudioTracks++;
                    uiRateOfPrivateTracks += pPSChunkWriterParams->uiBitRate;
                }
                else if (MPEG2MUX_ES_LPCM_AUDIO == pChunkWriterParams->esType)
                {
                    if (IsPSOrPES(m_pParams->m_SystemType) && uiNOfLPCMAudioTracks >= MAX_LPCM_AUDIO_TRACK_FOR_MPEG2PS)
                    {
                        vm_debug_trace1(VM_DEBUG_ERROR, VM_STRING("Too much LPCM tracks was specified. Only %d are supported for MPEG2PS"), MAX_LPCM_AUDIO_TRACK_FOR_MPEG2PS);
                        return UMC_ERR_INVALID_PARAMS;
                    }

                    pPSChunkWriterParams->uiBitRate =
                        m_pParams->pTrackParams[nNum].info.audio->sample_frequency *
                        m_pParams->pTrackParams[nNum].info.audio->bitPerSample *
                        m_pParams->pTrackParams[nNum].info.audio->channels;

                    if (pPSChunkWriterParams->uiBitRate == 0)
                    {
                        pPSChunkWriterParams->uiBitRate = 100000;
                        vm_debug_trace2(VM_DEBUG_INFO, VM_STRING("Bitrate for track #%d is unspecified, default value is %d bps"), nNum, pPSChunkWriterParams->uiBitRate);
                    }

                    pPSChunkWriterParams->uiStreamID = MPEG2MUX_PES_ID_PRIVATE_1;
                    pPSChunkWriterParams->uiSubStreamID = MPEG2MUX_LPCM_SUB_ID + uiNOfLPCMAudioTracks;

                    uiNOfLPCMAudioTracks++;
                    uiNOfPrivateAudioTracks++;
                    uiRateOfPrivateTracks += pPSChunkWriterParams->uiBitRate;
                }
                else // MPEG audio
                {
                    if (IsPSOrPES(m_pParams->m_SystemType) && uiNOfMPEGAudioTracks >= MAX_MPEG_AUDIO_TRACK_FOR_MPEG2PS)
                    {
                        vm_debug_trace1(VM_DEBUG_ERROR, VM_STRING("Too much MPEGAudio tracks was specified. Only %d are supported for MPEG2PS"), MAX_MPEG_AUDIO_TRACK_FOR_MPEG2PS);
                        return UMC_ERR_INVALID_PARAMS;
                    }

                    pPSChunkWriterParams->uiStreamID = MPEG2MUX_PES_ID_AUDIO;

                    if (MPEG2_PROGRAMM_STREAM == m_pParams->m_SystemType)
                        pPSChunkWriterParams->uiStreamID += uiNOfMPEGAudioTracks;

                    uiNOfMPEGAudioTracks++;

                    if (MPEG2_PROGRAMM_STREAM == m_pParams->m_SystemType)
                    {
                        sysHeaderParams.pSystemStreamID[sysHeaderParams.uiSystemNumberOfStreams] = pPSChunkWriterParams->uiStreamID;
                        sysHeaderParams.pSystemSizeBound[sysHeaderParams.uiSystemNumberOfStreams] = pPSChunkWriterParams->uiBitRate / 8;
                        sysHeaderParams.uiSystemNumberOfStreams++;
                    }
                }

                if (IsTS(m_pParams->m_SystemType))
                {
                    pTSChunkWriterParams->uiPID = uiPID;
                    vm_debug_trace2(VM_DEBUG_INFO, VM_STRING("PID = %d is assinged for track #%d "), pTSChunkWriterParams->uiPID, nNum);
                    m_pPMTTableWriterParams[0].pStreamType[nNum] = pPSChunkWriterParams->esType;
                    m_pPMTTableWriterParams[0].pPID[nNum] = pTSChunkWriterParams->uiPID;
                    uiPID++;
                }

                uiNOfAudioTracks++;
            }
            else if (CHECK_TRACK_TYPE(nNum, VIDEO_TRACK))
            { // video
                if (IsPSOrPES(m_pParams->m_SystemType) && uiNOfVideoTracks >= MAX_VIDEO_TRACK_FOR_MPEG2PS)
                {
                    vm_debug_trace1(VM_DEBUG_ERROR, VM_STRING("Too much video tracks was specified. Only %d are supported for MPEG2PS"), MAX_VIDEO_TRACK_FOR_MPEG2PS);
                    return UMC_ERR_INVALID_PARAMS;
                }

                vm_debug_trace2(VM_DEBUG_INFO, VM_STRING("Stream #%d: video (type %d)"), nNum, m_pParams->pTrackParams[nNum].info.video->stream_type);
                pPSChunkWriterParams->esType = ConvertVideoType(m_pParams->m_SystemType, m_pParams->pTrackParams[nNum].info.video->stream_type);
                if (MPEG2MUX_ES_UNKNOWN == pPSChunkWriterParams->esType)
                {
                    vm_debug_trace2(VM_DEBUG_ERROR, VM_STRING("Unsupported video format (%d) for track #%d is specified"), m_pParams->pTrackParams[nNum].info.video->stream_type, nNum);
                    return UMC_ERR_UNSUPPORTED;
                }

                pPSChunkWriterParams->dFrameRate = m_pParams->pTrackParams[nNum].info.video->framerate;
                if (pPSChunkWriterParams->dFrameRate <= 0.0)
                {
                    pPSChunkWriterParams->dFrameRate = 30.0;
                    vm_debug_trace2(VM_DEBUG_INFO, VM_STRING("Framerate for track #%d is unspecified, default value is %d bps"), nNum, pPSChunkWriterParams->dFrameRate);
                }

                pPSChunkWriterParams->uiBitRate = m_pParams->pTrackParams[nNum].info.video->bitrate;
                if (pPSChunkWriterParams->uiBitRate == 0)
                {
                    pPSChunkWriterParams->uiBitRate = 1000000;
                    vm_debug_trace2(VM_DEBUG_INFO, VM_STRING("Bitrate for track #%d is unspecified, default value is %d bps"), nNum, pPSChunkWriterParams->uiBitRate);
                }

                pPSChunkWriterParams->uiStreamID = MPEG2MUX_PES_ID_VIDEO;
                if (MPEG2_PROGRAMM_STREAM == m_pParams->m_SystemType)
                    pPSChunkWriterParams->uiStreamID += uiNOfVideoTracks;

                if (MPEG2_PROGRAMM_STREAM == m_pParams->m_SystemType)
                {
                    sysHeaderParams.pSystemStreamID[sysHeaderParams.uiSystemNumberOfStreams] = pPSChunkWriterParams->uiStreamID;
                    sysHeaderParams.pSystemSizeBound[sysHeaderParams.uiSystemNumberOfStreams] = pPSChunkWriterParams->uiBitRate / 8;
                    sysHeaderParams.uiSystemNumberOfStreams++;
                }
                else if (IsTS(m_pParams->m_SystemType))
                {
                    pTSChunkWriterParams->uiPID = uiPID;
                    vm_debug_trace2(VM_DEBUG_INFO, VM_STRING("PID = %d is assinged for track #%d "), pTSChunkWriterParams->uiPID, nNum);
                    m_pPMTTableWriterParams[0].pStreamType[nNum] = pPSChunkWriterParams->esType;
                    m_pPMTTableWriterParams[0].pPID[nNum] = pTSChunkWriterParams->uiPID;
                    uiPID++;
                }

                uiNOfVideoTracks++;
                if (MPEG2MUX_ES_MPEG1_VIDEO == pChunkWriterParams->esType ||
                    MPEG2MUX_ES_MPEG2_VIDEO == pChunkWriterParams->esType)
                    uiNOfMPEGVideoTracks++;
            }
            else if (VBI_TRACK == m_pParams->pTrackParams[nNum].type)
            { // VBI
                vm_debug_trace2(VM_DEBUG_INFO, VM_STRING("Stream #%d: VBI (type %d)"), nNum, MPEG2MUX_ES_VBI_DATA);
                pPSChunkWriterParams->esType = MPEG2MUX_ES_VBI_DATA;
                pPSChunkWriterParams->uiStreamID = MPEG2MUX_PES_ID_PRIVATE_1;
                pTSChunkWriterParams->uiPID = uiPID;
                vm_debug_trace2(VM_DEBUG_INFO, VM_STRING("PID = %d is assinged for stream #%d "), pTSChunkWriterParams->uiPID, nNum);
                m_pPMTTableWriterParams[0].pStreamType[nNum] = pPSChunkWriterParams->esType;
                m_pPMTTableWriterParams[0].pPID[nNum] = pTSChunkWriterParams->uiPID;
                uiPID++;
            }

            if (IsTS(m_pParams->m_SystemType))
            {
                pTSChunkWriterParams->bIsPCRPID = false;
                if (nNum == uiPCRTrackNum)
                {
                    vm_debug_trace1(VM_DEBUG_INFO, VM_STRING("PCRPID = %d"), pTSChunkWriterParams->uiPID);
                    pTSChunkWriterParams->bIsPCRPID = true;
                    m_pPMTTableWriterParams[0].uiPCRPID = pTSChunkWriterParams->uiPID;
                }
            }

            m_uiTotalRate += pChunkWriterParams->uiBitRate / 8;
            UMC_CALL(m_ppBuffers[nNum]->Init(pChunkWriterParams));
        }

        // create chunk writers
        if (MPEG2_PROGRAMM_STREAM == m_pParams->m_SystemType)
        {
            if (uiNOfPrivateAudioTracks > 0)
            {
                sysHeaderParams.pSystemStreamID[sysHeaderParams.uiSystemNumberOfStreams] = MPEG2MUX_PES_ID_PRIVATE_1;
                sysHeaderParams.pSystemSizeBound[sysHeaderParams.uiSystemNumberOfStreams] = uiRateOfPrivateTracks / 8;
            }

            sysHeaderParams.uiSystemRateBound = m_uiTotalRate;
            sysHeaderParams.uiSystemAudioBound = uiNOfMPEGAudioTracks;
            sysHeaderParams.uiSystemVideoBound = uiNOfMPEGVideoTracks;

            for (nNum = 0; nNum < (Ipp32s)m_uiTotalNumStreams; nNum++)
            {
                MPEG2PSChunkWriter *pPSChunkWriter = (MPEG2PSChunkWriter *)(m_ppBuffers[nNum]);
                UMC_CALL(pPSChunkWriter->SetSystemHeaderParams(&sysHeaderParams));
            }

            UMC_FREE(sysHeaderParams.pSystemStreamID);
            UMC_FREE(sysHeaderParams.pSystemSizeBound);
        }
        else if (IsTS(m_pParams->m_SystemType))
        {
            UMC_CALL(m_ppPMTTableWriter[0]->Init(&m_pPMTTableWriterParams[0]));
        }
    }
    else
    {
        vm_debug_trace1(VM_DEBUG_ERROR, VM_STRING("Unsupported format system type (%d) is specified"), m_pParams->m_SystemType);
        return UMC_ERR_INVALID_PARAMS;
    }

    // init mutex
    if (0 == vm_mutex_is_valid(&m_synchro))
        if (VM_OK != vm_mutex_init(&m_synchro))
            return UMC_ERR_INIT;

    return UMC_OK;
} //Status MPEG2Muxer::Init(MuxerParams* lpInit)

Status MPEG2Muxer::PutEndOfStream(Ipp32s iTrack)
{
    Status umcRes = Muxer::PutEndOfStream(iTrack);
    WriteInterleavedFramesIntoStream(false);
    return umcRes;
} //Status MPEG2Muxer::PutEndOfStream(Ipp32s iTrack)

Status MPEG2Muxer::UnlockBuffer(MediaData *pData, Ipp32s iTrack)
{
    Status umcRes = Muxer::UnlockBuffer(pData, iTrack);
    WriteInterleavedFramesIntoStream(false);
    return umcRes;
} //Status MPEG2Muxer::UnlockBuffer(MediaData *pData, Ipp32s iTrack)

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

Status MPEG2Muxer::WriteInterleavedFramesIntoStream(bool bFlushMode)
{
    AutomaticMutex guard(m_synchro);

    Status umcRes = UMC_OK;
    Ipp32s num;

    while (!m_bQuit)
    {
        if (IsPure(m_pParams->m_SystemType))
        {
            UMC_CALL(((MPEG2ChunkWriter *)m_ppBuffers[0])->WriteChunk());
            vm_debug_trace(VM_DEBUG_PROGRESS, VM_STRING("Portion of pure data was written"));
        }
        else
        {
            UMC_CALL(GetStreamToWrite(num, bFlushMode));

            Ipp64f dExactTime;
            GetOutputTime(num, dExactTime);

            Ipp64f dReferenceClock;
            if (dExactTime - m_pMPEG2MuxerParams->m_dSystemTimeDelay > m_dReferenceClock)
                dReferenceClock = dExactTime - m_pMPEG2MuxerParams->m_dSystemTimeDelay;
            else
                dReferenceClock = m_dReferenceClock + 1.0 / MPEG2MUX_SYS_CLOCK_FREQ;

            vm_debug_trace1(VM_DEBUG_PROGRESS, VM_STRING("Current reference clock is %.3f sec"), dReferenceClock);

            ((MPEG2ChunkWriter *)m_ppBuffers[num])->SetReferenceClock(IsTTS0(m_pParams->m_SystemType) ? 0.0 : dReferenceClock);
            ((MPEG2ChunkWriter *)m_ppBuffers[num])->SetMuxRate(m_uiTotalRate);

            if ((dReferenceClock - m_dReferenceClockOfPrevSI) > 4.9)
            {
                if (IsTS(m_pParams->m_SystemType))
                {
                    Ipp32s i;
                    m_pPATTableWriter->SetReferenceClock(dReferenceClock);
                    UMC_CALL(m_pPATTableWriter->WriteChunk());
                    dReferenceClock += 1.0 / MPEG2MUX_SYS_CLOCK_FREQ;

                    for (i = 0; i < m_pPATTableWriterParams->iNOfPrograms; i++)
                    {
                        m_ppPMTTableWriter[i]->SetReferenceClock(dReferenceClock);
                        UMC_CALL(m_ppPMTTableWriter[i]->WriteChunk());
                        dReferenceClock += 1.0 / MPEG2MUX_SYS_CLOCK_FREQ;
                    }

                    vm_debug_trace(VM_DEBUG_INFO, VM_STRING("PSI was written"));
                }
                else
                {
                    ((MPEG2PSChunkWriter *)m_ppBuffers[num])->ToggleSystemHeader();
                    vm_debug_trace(VM_DEBUG_INFO, VM_STRING("System header was written"));
                }

                m_dReferenceClockOfPrevSI = dReferenceClock;
            }

            umcRes = ((MPEG2ChunkWriter *)m_ppBuffers[num])->WriteChunk();
            if (UMC_OK != umcRes)
            {
                vm_debug_trace2(VM_DEBUG_PROGRESS, VM_STRING("Writing of chunk from stream #%d was failed (%d)"), num, umcRes);
                return umcRes;
            }

            m_dReferenceClock = dReferenceClock;
        }
    }

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

Status MPEG2Muxer::GetOutputTime(Ipp32s nStreamNumber, Ipp64f &dTime)
{
    return ((MPEG2ChunkWriter *)m_ppBuffers[nStreamNumber])->GetOutputTime(dTime);
} //Status MPEG2Muxer::GetOutputTime(Ipp32u nStreamNumber, Ipp64f &dTime)

⌨️ 快捷键说明

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