📄 umc_mp4_mux_atoms.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 <time.h>
#include <ipps.h>
#include "umc_mp4_mux_defs.h"
#include "umc_mp4_mux.h"
#include "vm_time.h"
#ifdef OSX32
#include <sys/malloc.h>
#else
#include <malloc.h>
#endif /* OSX32 */
namespace UMC
{
Ipp64f MP4Muxer::GetMaxDuration()
{
Ipp32u i, j;
Ipp64f temp = 0, temp1 = 0;
for ( i = 0; i < m_headerMPEG4.total_tracks; i++ ) {
sMuxSample *pSamples = m_sTrack[i].m_pSamples;
temp = 0;
for ( j = 0; j < m_sTrack[i].m_nSamplesCount; j++ ) {
temp += pSamples[j].m_nDuration;
}
temp /= nTimeScale;
if ( temp1 < temp ) {
temp1 = temp;
}
}
return temp1;
}
Ipp32s MP4Muxer::GetMP4VideoTypeID(VideoStreamType type)
{
Ipp32s tag;
if (type == MPEG4_VIDEO) {
tag = 0x20; // Visual ISO/IEC 14496-2
} else {
tag = type;
}
return tag;
}
Ipp32s MP4Muxer::GetMP4AudioTypeID(AudioStreamType type)
{
Ipp32s tag;
if (type & AAC_AUDIO) {
tag = 0x40;
} else
if ((type & MPEG1_AUDIO) ||
(type & MPEG2_AUDIO)) {
tag = 0x6b;
} else {
tag = type;
}
return tag;
}
Ipp32s MP4Muxer::GetMP4StreamType(Ipp32s type)
{
Ipp32s tag;
if (type == MPEG4_VIDEO_QTIME) {
tag = 0x04; // Visual Stream
} else
if (type == UNDEF_AUDIO_SUBTYPE) {
tag = 0x05;
} else {
tag = type;
}
return tag;
}
Ipp64f MP4Muxer::GetTrakDuration(Ipp32s ntrak)
{
Ipp64f temp = 0;
Ipp32u i;
if (m_sTrack[ntrak].m_nSamplesCount == 0) {
return 0.0;
}
for (i = 0; i < m_sTrack[ntrak].m_nSamplesCount; i++) {
temp += (Ipp64f)m_sTrack[ntrak].m_pSamples[i].m_nDuration;
}
return temp / nTimeScale;
}
Ipp32s MP4Muxer::CalculateFragmentSize(TM_moof *moof)
{
moof->size_atom = 0;
moof->size_atom += 8; //moof box
moof->size_atom += (8 + 1 + 3 + 4); //mfhd
for (Ipp32u i = 0; i < moof->total_tracks; i++)
{
moof->size_atom += 8; //traf
moof->size_atom += (8 + 1 + 3 + 4); //tfhd
moof->size_atom += (8 + 1 + 3 + 4 + m_sTrack[i].m_nSamplesCount * 4 * 2); //trun
}
return moof->size_atom;
}
Ipp32s MP4Muxer::CalculateMvexExtendedSize(TM_mvex* mvex)
{
mvex->total_tracks = m_headerMPEG4.total_tracks;
mvex->size_atom = 0;
mvex->size_atom += 8; //mvex box
for (Ipp32u i = 0; i < mvex->total_tracks; i++)
{
mvex->size_atom += (8 + 1 + 3 + 4 + 4 + 4 + 4 + 4); //trex
}
m_headerMPEG4.size_atom += mvex->size_atom;
return m_headerMPEG4.size_atom;
}
Ipp32s MP4Muxer::CalculateSizes()
{
Ipp32u i, j;
TM_stsz_data* stsz;
TM_stsd_table_data* stsd_table;
TM_stsd_data* stsd;
TM_stts_data* stts;
TM_ctts_data* ctts;
TM_stss_data* stss;
TM_stbl_data* stbl;
TM_stco_data* stco;
TM_dref_data* dref;
TM_dinf_data* dinf;
TM_minf_data* minf;
TM_mdhd_data* mdhd;
TM_hdlr_data* hdlr;
TM_mdia_data* mdia;
TM_tkhd_data* tkhd;
TM_trak_data* trak;
TM_iods_data* iods;
TM_mvhd_data* mvhd;
TM_vmhd_data* vmhd;
TM_smhd_data* smhd;
TM_stsc_data* stsc;
iods = &m_headerMPEG4.iods;
iods->size_atom = 8 + 4*4;
mvhd = &m_headerMPEG4.mvhd;
mvhd->size_atom = 8 + 4*25;
m_headerMPEG4.size_atom = 8 + mvhd->size_atom + iods->size_atom;
if (!m_bMoov)
{
m_headerMPEG4.size_atom += m_headerMVEX.size_atom;
}
for ( i = 0; i < m_headerMPEG4.total_tracks; i++ )
{
stsz = &m_headerMPEG4.trak[i]->mdia.minf.stbl.stsz;
stsz->size_atom = 8 + 4*3;
if (!stsz->sample_size)
stsz->size_atom += m_sTrack[i].m_nSamplesCount * 4;
stsd = &m_headerMPEG4.trak[i]->mdia.minf.stbl.stsd;
stsd->size_atom = 8 + 4*2;
for ( j = 0; j < stsd->total_entries; j++ )
{
stsd_table = &stsd->table[j];
stsd_table->esds.size_atom = 46 + stsd_table->esds.decoderConfigLen;
if ( stsd_table->format[0] == 'm' && stsd_table->format[1] == 'p' && stsd_table->format[2] == '4' && stsd_table->format[3] == 'a' )
stsd_table->size_atom = 16 + stsd_table->esds.size_atom + 20;
if ( stsd_table->format[0] == 'm' && stsd_table->format[1] == 'p' && stsd_table->format[2] == '4' && stsd_table->format[3] == 'v' )
stsd_table->size_atom = 16 + stsd_table->esds.size_atom + 70;
if ( stsd_table->format[0] == 'a' && stsd_table->format[1] == 'v' && stsd_table->format[2] == 'c' && stsd_table->format[3] == '1' )
stsd_table->size_atom = 16 + stsd_table->esds.size_atom + 32;
stsd->size_atom += stsd_table->size_atom;
}
stts = &m_headerMPEG4.trak[i]->mdia.minf.stbl.stts;
stts->size_atom = 8 + 4*2 + stts->total_entries * 8;
ctts = &m_headerMPEG4.trak[i]->mdia.minf.stbl.ctts;
/* ctts->size_atom = 8 + 4*2 + ctts->total_entries * 8;
*/
stss = &m_headerMPEG4.trak[i]->mdia.minf.stbl.stss;
stss->size_atom = 8 + 4*2 + m_nIDRFrames[i] * 4;
stco = &m_headerMPEG4.trak[i]->mdia.minf.stbl.stco;
stco->size_atom = 8 + 4*2 + m_sTrack[i].m_nSamplesCount * 4;
stsc = &m_headerMPEG4.trak[i]->mdia.minf.stbl.stsc;
stsc->size_atom = 8 + 4*2 + m_sTrack[i].m_nSamplesCount * 4 * 3;
stbl = &m_headerMPEG4.trak[i]->mdia.minf.stbl;
stbl->size_atom = 8 + stts->size_atom + stsd->size_atom + stsz->size_atom + stco->size_atom + stsc->size_atom + stss->size_atom + ctts->size_atom;
dref = &m_headerMPEG4.trak[i]->mdia.minf.dinf.dref;
dref->size_atom = 0x1C; //8 + 4*2;
dinf = &m_headerMPEG4.trak[i]->mdia.minf.dinf;
dinf->size_atom = 8 + dref->size_atom;
vmhd = &m_headerMPEG4.trak[i]->mdia.minf.vmhd;
vmhd->size_atom = 8 + 12;
smhd = &m_headerMPEG4.trak[i]->mdia.minf.smhd;
smhd->size_atom = 8 + 8;
minf = &m_headerMPEG4.trak[i]->mdia.minf;
if ( minf->is_video )
minf->size_atom = 8 + dinf->size_atom + stbl->size_atom + vmhd->size_atom;
if ( minf->is_audio )
minf->size_atom = 8 + dinf->size_atom + stbl->size_atom + smhd->size_atom;
mdhd = &m_headerMPEG4.trak[i]->mdia.mdhd;
mdhd->size_atom = 8 + 4*6;
hdlr = &m_headerMPEG4.trak[i]->mdia.hdlr;
hdlr->size_atom = 58;
mdia = &m_headerMPEG4.trak[i]->mdia;
mdia->size_atom = 8 + mdhd->size_atom + minf->size_atom + hdlr->size_atom;
tkhd = &m_headerMPEG4.trak[i]->tkhd;
tkhd->size_atom = 8 + 4*21;
trak = m_headerMPEG4.trak[i];
trak->size_atom = 8 + tkhd->size_atom + mdia->size_atom;
m_headerMPEG4.size_atom += trak->size_atom;
}
return m_headerMPEG4.size_atom;
}
Status MP4Muxer::UpdateHeader()
{
Ipp32u i, j;
vm_timeval val; //file creation time
Ipp64u start = 0; //file creation time
vm_status vmRes = VM_OK;
vmRes = vm_time_gettimeofday(&val, NULL);
if (vmRes != VM_OK)
return UMC_ERR_FAILED;
start = val.tv_sec;
start += 2082844800; //sec since 104 till 1970
// MVHD
m_headerMPEG4.mvhd.creation_time = start;
m_headerMPEG4.mvhd.modification_time = start;
Ipp64f maxDur = GetMaxDuration();
m_headerMPEG4.mvhd.duration = (Ipp64u)(m_headerMPEG4.mvhd.nTimeScale * maxDur);
// trak`s
for (i = 0; i < m_headerMPEG4.total_tracks; i++ )
{
// trak->tkhd
m_headerMPEG4.trak[i]->tkhd.creation_time =
m_headerMPEG4.trak[i]->tkhd.modification_time = start;
m_headerMPEG4.trak[i]->tkhd.duration = (Ipp64u)(m_headerMPEG4.mvhd.nTimeScale * GetTrakDuration(i));
// trak->mdia.mdhd
m_headerMPEG4.trak[i]->mdia.mdhd.creation_time =
m_headerMPEG4.trak[i]->mdia.mdhd.modification_time = start;
m_headerMPEG4.trak[i]->mdia.mdhd.duration = (Ipp64u)(m_headerMPEG4.trak[i]->mdia.mdhd.nTimeScale * GetTrakDuration(i));
if (m_bDataFromEncoder && IS_VIDEO(i) && UMC::H264_VIDEO == m_pTrackParams[i].info.video->stream_type)
{
if (m_pH264Header)
{
Ipp8u* pDecInfo = _NEW_n(Ipp8u, 1024 * 1024);
memset(pDecInfo, 0, 1024 * 1024);
Ipp32s pos = 0;
pDecInfo[pos] = 1; //version
pos++;
pDecInfo[pos] = 0; //AVCProfileIndication
pos++;
pDecInfo[pos] = 0; //profile_compatibility
pos++;
pDecInfo[pos] = 0; //AVCLevelIndication
pos++;
pDecInfo[pos] = (Ipp8u)(0xFC | 3); //lengthSizeMinusOne
pos++;
pDecInfo[pos] = (Ipp8u)(0xE0 | m_pH264Header->m_nSps_num); //numOfSequenceParameterSets
pos++;
for (j = 0; j < m_pH264Header->m_nSps_num; j++)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -