📄 umc_mpeg2_muxer.cpp
字号:
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 + -