📄 umc_mpeg2_muxer.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 "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 + -