📄 umc_mp4_mux_atoms.cpp
字号:
{
pDecInfo[pos] = (Ipp8u)((m_pH264Header->m_pNal_ut_sps[j].m_nLength & 0xff00) >> 8);
pos++;
pDecInfo[pos] = (Ipp8u)(m_pH264Header->m_pNal_ut_sps[j].m_nLength & 0xff);
pos++;
memcpy(&pDecInfo[pos], m_pH264Header->m_pNal_ut_sps[j].m_pNal_ut_sps,
m_pH264Header->m_pNal_ut_sps[j].m_nLength);
pos += m_pH264Header->m_pNal_ut_sps[j].m_nLength;
}
pDecInfo[pos] = (Ipp8u)(m_pH264Header->m_nPps_num); //numOfSequenceParameterSets
pos++;
for (j = 0; j < m_pH264Header->m_nPps_num; j++)
{
pDecInfo[pos] = (Ipp8u)((m_pH264Header->m_pNal_ut_pps[j].m_nLength & 0xff00) >> 8);
pos++;
pDecInfo[pos] = (Ipp8u)(m_pH264Header->m_pNal_ut_pps[j].m_nLength & 0xff);
pos++;
memcpy(&pDecInfo[pos], m_pH264Header->m_pNal_ut_pps[j].m_pNal_ut_pps,
m_pH264Header->m_pNal_ut_pps[j].m_nLength);
pos += m_pH264Header->m_pNal_ut_pps[j].m_nLength;
}
m_headerMPEG4.trak[i]->mdia.minf.stbl.stsd.table[0].esds.decoderConfig = _NEW_n(Ipp8u, pos);
memcpy(m_headerMPEG4.trak[i]->mdia.minf.stbl.stsd.table[0].esds.decoderConfig, pDecInfo, pos);
m_headerMPEG4.trak[i]->mdia.minf.stbl.stsd.table[0].esds.decoderConfigLen = pos;
_SAFE_DELETE_ARRAY(pDecInfo);
m_nHeaderSize += (pos);
}
} else { // if decSpecificInfo is present offsets should be incremented accordingly
m_nHeaderSize += m_headerMPEG4.trak[i]->mdia.minf.stbl.stsd.table[0].esds.decoderConfigLen;
}
// increase header size depending from stts
m_nHeaderSize += m_sTrack[i].m_nSttsEntries * 8;
// count ctts_delta entries if needed
if (m_sTrack[i].m_nCttsEntries) {
TM_ctts_data *ctts = &m_headerMPEG4.trak[i]->mdia.minf.stbl.ctts;
Ipp32s k, off, curoff, mDTS;
sMuxSample *pSamples = m_sTrack[i].m_pSamples;
Ipp32s nSamples = m_sTrack[i].m_nSamplesCount;
m_sTrack[i].m_ctts_delta = 0;
curoff = 0;
mDTS = pSamples[0].m_nTimeStamp + pSamples[0].m_nDuration;
for (k = 1; k < nSamples; k++) {
off = pSamples[k].m_nTimeStamp - mDTS;
if (off != curoff) {
m_sTrack[i].m_nCttsEntries++;
curoff = off;
if (off < m_sTrack[i].m_ctts_delta) {
m_sTrack[i].m_ctts_delta = off;
}
}
mDTS += pSamples[k].m_nDuration;
}
ctts->size_atom = 8 + 4*2 + m_sTrack[i].m_nCttsEntries * 8;
m_nHeaderSize += ctts->size_atom;
}
}
return UMC_OK;
}
Status MP4Muxer::InitHeader()
{
Ipp32u i, j;
// MVHD
m_headerMPEG4.mvhd.version = 0;
m_headerMPEG4.mvhd.flags = 0;
m_headerMPEG4.mvhd.nTimeScale = nTimeScale;
m_headerMPEG4.mvhd.next_track_id = m_headerMPEG4.total_tracks + 1;
// IODS
m_headerMPEG4.iods.version = 0;
m_headerMPEG4.iods.flags = 0;
m_headerMPEG4.iods.audioProfileId = 0;
m_headerMPEG4.iods.videoProfileId = 0;
// trak`s
for ( i = 0; i < m_headerMPEG4.total_tracks; i++ )
{
// trak->tkhd
m_headerMPEG4.trak[i]->tkhd.version = 0;
m_headerMPEG4.trak[i]->tkhd.flags = 0;
if (IS_VIDEO(i))
{
m_headerMPEG4.trak[i]->tkhd.is_audio = 0;
m_headerMPEG4.trak[i]->tkhd.is_video = 1;
m_headerMPEG4.trak[i]->tkhd.track_width = (Ipp32f)(m_pTrackParams[i].info.video->clip_info.width << 16);
m_headerMPEG4.trak[i]->tkhd.track_height = (Ipp32f)(m_pTrackParams[i].info.video->clip_info.height << 16);
vm_string_strcpy(m_headerMPEG4.trak[i]->mdia.hdlr.component_type, VM_STRING("vide"));
vm_string_strcpy(m_headerMPEG4.trak[i]->mdia.hdlr.component_name, VM_STRING("Intel Video Media Handler"));
}
else
{
m_headerMPEG4.trak[i]->tkhd.is_audio = 1;
m_headerMPEG4.trak[i]->tkhd.is_video = 0;
m_headerMPEG4.trak[i]->tkhd.track_width = 0;
m_headerMPEG4.trak[i]->tkhd.track_height = 0;
vm_string_strcpy(m_headerMPEG4.trak[i]->mdia.hdlr.component_type, VM_STRING("soun"));
vm_string_strcpy(m_headerMPEG4.trak[i]->mdia.hdlr.component_name, VM_STRING("Intel Sound Media Handler"));
}
// trak->mdia
// trak->mdia.mdhd
m_headerMPEG4.trak[i]->mdia.mdhd.version = 0;
m_headerMPEG4.trak[i]->mdia.mdhd.flags = 0;
m_headerMPEG4.trak[i]->mdia.mdhd.nTimeScale = nTimeScale;
m_headerMPEG4.trak[i]->mdia.mdhd.language = 0;
// trak->mdia.hdlf
m_headerMPEG4.trak[i]->mdia.hdlr.version = 0;
m_headerMPEG4.trak[i]->mdia.hdlr.flags = 0;
// trak->mdia.minf
m_headerMPEG4.trak[i]->mdia.minf.is_video = 0;
m_headerMPEG4.trak[i]->mdia.minf.is_hint = 0;
m_headerMPEG4.trak[i]->mdia.minf.is_audio = 0;
// trak->mdia.minf.vmhd
m_headerMPEG4.trak[i]->mdia.minf.vmhd.version = 0;
m_headerMPEG4.trak[i]->mdia.minf.vmhd.flags = 0;
// trak->mdia.minf.smhd
m_headerMPEG4.trak[i]->mdia.minf.smhd.version = 0;
m_headerMPEG4.trak[i]->mdia.minf.smhd.flags = 0;
// trak->mdia.minf.dinf
// trak->mdia.minf.dinf.dref
m_headerMPEG4.trak[i]->mdia.minf.dinf.dref.version = 0;
m_headerMPEG4.trak[i]->mdia.minf.dinf.dref.flags = 0;
m_headerMPEG4.trak[i]->mdia.minf.dinf.dref.total_entries = 1;
// trak->mdia.minf.stbl.stsd
m_headerMPEG4.trak[i]->mdia.minf.stbl.stsd.version = 0;
m_headerMPEG4.trak[i]->mdia.minf.stbl.stsd.flags = 0;
m_headerMPEG4.trak[i]->mdia.minf.stbl.stsd.total_entries = 1;
m_headerMPEG4.trak[i]->mdia.minf.stbl.stsz.sample_size = 0;
m_headerMPEG4.trak[i]->mdia.minf.stbl.ctts.size_atom = 0;
for ( j = 0; j < m_headerMPEG4.trak[i]->mdia.minf.stbl.stsd.total_entries; j++ )
{
TM_stsd_table_data& table = m_headerMPEG4.trak[i]->mdia.minf.stbl.stsd.table[j];
if (IS_VIDEO(i))
{
if (UMC::H264_VIDEO == m_pTrackParams[i].info.video->stream_type)
{
table.format[0] = 'a';
table.format[1] = 'v';
table.format[2] = 'c';
table.format[3] = '1';
}
else
{
table.format[0] = 'm';
table.format[1] = 'p';
table.format[2] = '4';
table.format[3] = 'v';
}
m_headerMPEG4.trak[i]->mdia.minf.is_video = 1;
table.width = (Ipp16u)m_pTrackParams[i].info.video->clip_info.width;
table.height = (Ipp16u)m_pTrackParams[i].info.video->clip_info.height;
table.esds.maxBitrate = m_pTrackParams[i].info.video->bitrate;
table.esds.avgBitrate = m_pTrackParams[i].info.video->bitrate;
table.esds.objectTypeID = GetMP4VideoTypeID(m_pTrackParams[i].info.video->stream_type);
table.esds.streamType = GetMP4StreamType(m_pTrackParams[i].info.video->stream_subtype);
table.esds.streamType = (table.esds.streamType << 2) | 0x1; // 6 bits of type + 01
}
else
{
m_headerMPEG4.trak[i]->mdia.minf.is_audio = 1;
table.format[0] = 'm';
table.format[1] = 'p';
table.format[2] = '4';
table.format[3] = 'a';
table.channels = (Ipp16u)(m_pTrackParams[i].info.audio->channels);
table.sample_size = (Ipp16u)(m_pTrackParams[i].info.audio->bitPerSample);
table.sample_rate = m_pTrackParams[i].info.audio->sample_frequency;
table.esds.maxBitrate = m_pTrackParams[i].info.audio->bitrate;
table.esds.avgBitrate = m_pTrackParams[i].info.audio->bitrate;
table.esds.objectTypeID = GetMP4AudioTypeID(m_pTrackParams[i].info.audio->stream_type);
table.esds.streamType = GetMP4StreamType(m_pTrackParams[i].info.audio->stream_subtype);
table.esds.streamType = (table.esds.streamType << 2) | 0x1; // 6 bits of type + 01
}
m_headerMPEG4.trak[i]->mdia.minf.stbl.stsd.table[j].data_reference = 1;
}
m_headerMPEG4.trak[i]->tkhd.flags = 1;
m_headerMPEG4.trak[i]->tkhd.track_id = i + 1;
}
return UMC_OK;
};
Status MP4Muxer::InitStsz(Ipp32s nTrack)
{
TM_stsz_data& stsz = m_headerMPEG4.trak[nTrack]->mdia.minf.stbl.stsz;
stsz.sample_size = 0;
stsz.version = 0;
stsz.flags = 0;
stsz.total_entries = m_sTrack[nTrack].m_nSamplesCount;
stsz.table = _NEW_n(TM_stsz_table_data, m_sTrack[nTrack].m_nSamplesCount);
return UMC_OK;
}
Status MP4Muxer::InitStco(Ipp32s nTrack)
{
TM_stco_data& stco = m_headerMPEG4.trak[nTrack]->mdia.minf.stbl.stco;
stco.version = 0;
stco.flags = 0;
stco.total_entries = m_sTrack[nTrack].m_nSamplesCount;
stco.table = _NEW_n(TM_stco_table_data, m_sTrack[nTrack].m_nSamplesCount);
return UMC_OK;
}
Status MP4Muxer::InitStts(Ipp32s nTrack)
{
TM_stts_data& stts = m_headerMPEG4.trak[nTrack]->mdia.minf.stbl.stts;
stts.version = 0;
stts.flags = 0;
stts.total_entries = m_sTrack[nTrack].m_nSttsEntries;
stts.table = _NEW_n(TM_stts_table_data, m_sTrack[nTrack].m_nSttsEntries);
return UMC_OK;
}
Status MP4Muxer::InitCtts(Ipp32s nTrack)
{
TM_ctts_data& ctts = m_headerMPEG4.trak[nTrack]->mdia.minf.stbl.ctts;
ctts.version = 0;
ctts.flags = 0;
ctts.total_entries = m_sTrack[nTrack].m_nCttsEntries;
ctts.table = _NEW_n(TM_ctts_table_data, m_sTrack[nTrack].m_nCttsEntries);
return UMC_OK;
}
Status MP4Muxer::InitStss(Ipp32s nTrack)
{
TM_stss_data& stss = m_headerMPEG4.trak[nTrack]->mdia.minf.stbl.stss;
stss.version = 0;
stss.flags = 0;
stss.total_entries = 0;
stss.table = _NEW_n(TM_stss_table_data, m_nIDRFrames[nTrack]);
return UMC_OK;
}
Status MP4Muxer::InitStsc(Ipp32s nTrack)
{
TM_stsc_data& stsc = m_headerMPEG4.trak[nTrack]->mdia.minf.stbl.stsc;
stsc.version = 0;
stsc.flags = 0;
stsc.total_entries = m_sTrack[nTrack].m_nSamplesCount;
stsc.table = _NEW_n(TM_stsc_table_data, m_sTrack[nTrack].m_nSamplesCount);
return UMC_OK;
}
Status MP4Muxer::InitAtoms()
{
Ipp32u nTrack = 0;
Ipp32u i = 0;
Ipp32u j = 0, dur;
/*
for (nTrack = 0; nTrack < m_headerMPEG4.total_tracks; nTrack++)
{
TM_stbl_data& stbl = m_headerMPEG4.trak[nTrack]->mdia.minf.stbl;
if (!m_sTrack[nTrack].m_nCttsEntries) { // throw away ctts header
m_nHeaderSize -= stbl.ctts.size_atom;
}
}
*/
for (nTrack = 0; nTrack < m_headerMPEG4.total_tracks; nTrack++)
{
InitStsz(nTrack);
InitStco(nTrack);
InitStts(nTrack);
if (m_sTrack[nTrack].m_nCttsEntries) {
InitCtts(nTrack);
}
InitStsc(nTrack);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -