📄 umc_mp4_parser.cpp
字号:
if (ret == UMC_OK) {
ret = Atom_Skip(dr, &leaf_atom);
}
}
else if ( Compare_Atom(&leaf_atom, "stts") )
{
ret = Read_stts(dr, &(stbl->stts));
}
else if ( Compare_Atom(&leaf_atom, "stss") )
{
ret = Read_stss(dr, &(stbl->stss));
}
else if ( Compare_Atom(&leaf_atom, "stsc") )
{
ret = Read_stsc(dr, &(stbl->stsc));
}
else if ( Compare_Atom(&leaf_atom, "stsz") )
{
ret = Read_stsz(dr, &(stbl->stsz));
}
else if ( Compare_Atom(&leaf_atom, "stco") )
{
ret = Read_stco(dr, &(stbl->stco));
}
else if ( Compare_Atom(&leaf_atom, "co64") )
{
ret = Read_co64(dr, &(stbl->co64));
}
else if ( Compare_Atom(&leaf_atom, "ctts") )
{
ret = Read_ctts(dr, &(stbl->ctts));
}
else
{
ret = Atom_Skip(dr, &leaf_atom);
}
} while ( (dr->GetPosition() < parent_atom->end) && (dr->GetPosition() != 0) && (ret == UMC_OK));
return ret;
}
// CO64 Box
// The chunk offset table gives the index of each chunk into the containing file. Use of 64-bit offsets.
//
Status MP4Splitter::Read_co64(DataReader *dr, T_co64_data *co64)
{
Status ret = UMC_OK;
unsigned int i;
dr->Get8u(&co64->version);
co64->flags = Get_24(dr);
dr->Get32uSwap(&co64->total_entries);
co64->table = (T_co64_table_data*)ippsMalloc_8u(sizeof(T_co64_table_data) * co64->total_entries);
// Check memory allocation
if (NULL == co64->table) {
return ret;
}
// Zeroed allocated table
memset(co64->table, 0, sizeof(T_co64_table_data) * co64->total_entries);
for ( i = 0; i < co64->total_entries; i++ )
{
dr->Get64uSwap(&co64->table[i].offset);
}
return ret;
}
// CTTS Box
// This box provides the offset between decoding time and composition time.
//
Status MP4Splitter::Read_ctts(DataReader *dr, T_ctts_data *ctts)
{
Status ret = UMC_OK;
unsigned int i;
dr->Get8u(&ctts->version);
ctts->flags = Get_24(dr);
dr->Get32uSwap(&ctts->total_entries);
ctts->table = (T_ctts_table_data*)ippsMalloc_8u(sizeof(T_ctts_table_data) * ctts->total_entries);
// Check memory allocation
if (NULL == ctts->table) {
return ret;
}
// Zeroed allocated table
memset(ctts->table, 0, sizeof(T_ctts_table_data) * ctts->total_entries);
for ( i = 0; i < ctts->total_entries; i++ )
{
dr->Get32uSwap(&ctts->table[i].sample_count);
dr->Get32uSwap(&ctts->table[i].sample_offset);
}
return ret;
}
// STCO Box
// The chunk offset table gives the index of each chunk into the containing file. Use of 32-bit offsets.
//
Status MP4Splitter::Read_stco(DataReader *dr, T_stco_data *stco)
{
Status ret = UMC_OK;
unsigned int i;
dr->Get8u(&stco->version);
stco->flags = Get_24(dr);
dr->Get32uSwap(&stco->total_entries);
stco->table = (T_stco_table_data*)ippsMalloc_8u(sizeof(T_stco_table_data) * stco->total_entries);
// Check memory allocation
if (NULL == stco->table) {
return ret;
}
// Zeroed allocated table
memset(stco->table, 0, sizeof(T_stco_table_data) * stco->total_entries);
for ( i = 0; i < stco->total_entries; i++ )
{
dr->Get32uSwap(&stco->table[i].offset);
}
return ret;
}
// STSZ Box
// This box contains the sample count and a table giving the size in bytes of each sample. This allows the media
// data itself to be unframed. The total number of samples in the media is always indicated in the sample count.
//
Status MP4Splitter::Read_stsz(DataReader *dr, T_stsz_data *stsz)
{
Status ret = UMC_OK;
unsigned int i;
dr->Get8u(&stsz->version);
stsz->flags = Get_24(dr);
dr->Get32uSwap(&stsz->sample_size);
dr->Get32uSwap(&stsz->total_entries);
stsz->max_sample_size = stsz->sample_size; // to calculate buffer size
if (!stsz->sample_size) {
stsz->table = (T_stsz_table_data*)ippsMalloc_8u(sizeof(T_stsz_table_data) * stsz->total_entries);
// Check memory allocation
if (NULL == stsz->table) {
return ret;
}
// Zeroed allocated table
memset(stsz->table, 0, sizeof(T_stsz_table_data) * stsz->total_entries);
for (i = 0; i < stsz->total_entries; i++) {
dr->Get32uSwap(&stsz->table[i].size);
if (stsz->table[i].size > stsz->max_sample_size) {
stsz->max_sample_size = stsz->table[i].size;
}
}
}
return ret;
}
// STSC Box
// Samples within the media data are grouped into chunks. Chunks can be of different sizes, and the samples
// within a chunk can have different sizes. This table can be used to find the chunk that contains a sample, its
// position, and the associated sample description.
//
Status MP4Splitter::Read_stsc(DataReader *dr, T_stsc_data *stsc)
{
Status ret = UMC_OK;
unsigned int i;
unsigned int sample = 0;
dr->Get8u(&stsc->version);
stsc->flags = Get_24(dr);
dr->Get32uSwap(&stsc->total_entries);
///// stsc->entries_allocated = stsc->total_entries;
stsc->table = (T_stsc_table_data*)ippsMalloc_8u(sizeof(T_stsc_table_data) * stsc->total_entries);
// Check memory allocation
if (NULL == stsc->table) {
return ret;
}
// Zeroed allocated table
memset(stsc->table, 0, sizeof(T_stsc_table_data) * stsc->total_entries);
for ( i = 0; i < stsc->total_entries; i++ )
{
dr->Get32uSwap(&stsc->table[i].chunk);
dr->Get32uSwap(&stsc->table[i].samples);
dr->Get32uSwap(&stsc->table[i].id);
}
for ( i = 0; i < stsc->total_entries; i++ )
{
stsc->table[i].first_sample = sample;
if ( i < stsc->total_entries - 1 )
{
sample += (stsc->table[i+1].chunk - stsc->table[i].chunk) * stsc->table[i].samples;
}
}
return ret;
}
// STTS Box
// This box contains a compact version of a table that allows indexing from decoding time to sample number.
//
Status MP4Splitter::Read_stts(DataReader *dr, T_stts_data *stts)
{
Status ret = UMC_OK;
unsigned int i;
dr->Get8u(&stts->version);
stts->flags = Get_24(dr);
dr->Get32uSwap(&stts->total_entries);
stts->table = (T_stts_table_data*)ippsMalloc_8u(sizeof(T_stts_table_data) * stts->total_entries);
// Check memory allocation
if (NULL == stts->table) {
return ret;
}
// Zeroed allocated table
memset(stts->table, 0, sizeof(T_stts_table_data) * stts->total_entries);
for( i = 0; i < stts->total_entries; i++ )
{
dr->Get32uSwap(&stts->table[i].sample_count);
dr->Get32uSwap(&stts->table[i].sample_duration);
}
return ret;
}
// STSS Box
// This box contains a sync (key, I-frame) sample map.
//
Ipp32s MP4Splitter::Read_stss(DataReader *dr, T_stss_data *stss)
{
Status ret = UMC_OK;
Ipp32u i;
dr->Get8u(&stss->version);
stss->flags = Get_24(dr);
dr->Get32uSwap(&stss->total_entries);
stss->table = (T_stss_table_data*)ippsMalloc_8u(sizeof(T_stss_table_data) * stss->total_entries);
// Check memory allocation
if (NULL == stss->table) {
return ret;
}
// Zeroed allocated table
memset(stss->table, 0, sizeof(T_stss_table_data) * stss->total_entries);
for( i = 0; i < stss->total_entries; i++ )
{
dr->Get32uSwap(&stss->table[i].sample_number);
UMC_CHECK_STATUS(ret)
}
return ret;
}
// STSD Box
// The sample description table gives detailed information about the coding type used, and any initialization
// information needed for that coding.
//
Status MP4Splitter::Read_stsd(DataReader *dr, T_minf_data *minf, T_stsd_data *stsd)
{
Status ret = UMC_OK;
unsigned int i;
dr->Get8u(&stsd->version);
stsd->flags = Get_24(dr);
dr->Get32uSwap(&stsd->total_entries);
stsd->table = (T_stsd_table_data*)ippsMalloc_8u(sizeof(T_stsd_table_data) * stsd->total_entries);
// Check memory allocation
if (NULL == stsd->table)
{
return ret;
}
// Zeroed allocated table
memset(stsd->table, 0, sizeof(T_stsd_table_data) * stsd->total_entries);
for ( i = 0; i < stsd->total_entries; i++ )
{
ret = Read_stsd_table(dr, minf, &(stsd->table[i]));
UMC_CHECK_STATUS(ret)
}
return ret;
}
Status MP4Splitter::Read_samr_audio(DataReader *dr,
T_stsd_table_data *table,
T_atom_mp4 *parent_atom)
{
Status ret;
T_atom_mp4 leaf_atom;
Ipp16u i;
dr->MovePosition(16); // reserved
dr->Get16uSwap(&i);
dr->MovePosition(2); // reserved
ret = Read_Atom(dr, &leaf_atom);
UMC_CHECK_STATUS(ret)
if (leaf_atom.type[0] == 'd' && leaf_atom.type[1] == 'a' &&
leaf_atom.type[2] == 'm' && leaf_atom.type[3] =='r') {
return Read_damr_audio(dr, table, &leaf_atom);
}
return ret;
}
Status MP4Splitter::Read_damr_audio(DataReader *dr,
T_stsd_table_data *table,
T_atom_mp4 *parent_atom)
{
Ipp32u temp;
table->damr.decoderConfigLen = (Ipp32s)(parent_atom->size - 8);
table->damr.decoderConfig = (Ipp8u*)(ippsMalloc_8u(table->damr.decoderConfigLen));
// Check memory allocation
if (NULL == table->damr.decoderConfig) {
return UMC_OK;
}
// Zeroed allocated table
memset(table->damr.decoderConfig, 0, table->damr.decoderConfigLen);
temp = table->damr.decoderConfigLen;
dr->GetData(table->damr.decoderConfig, (Ipp32u*) &temp);
return UMC_OK;
}
Status MP4Splitter::Read_stsd_table(DataReader *dr, T_minf_data * /*minf*/, T_stsd_table_data *table)
{
Status ret;
T_atom_mp4 leaf_atom;
ret = Read_Atom(dr, &leaf_atom);
UMC_CHECK_STATUS(ret)
table->is_protected = 0;
table->format[0] = leaf_atom.type[0];
table->format[1] = leaf_atom.type[1];
table->format[2] = leaf_atom.type[2];
table->format[3] = leaf_atom.type[3];
dr->MovePosition(6); // RESERVED
dr->Get16uSwap(&table->data_reference);
if ( table->format[0]=='m'&& table->format[1]=='p'&& table->format[2]=='4'&& table->format[3]=='a' )
{
ret = Read_stsd_audio(dr, table, &leaf_atom);
}
if ( table->format[0]=='s'&& table->format[1]=='a'&& table->format[2]=='m'&& table->format[3]=='r' )
{
ret = Read_samr_audio(dr, table, &leaf_atom);
}
if ( table->format[0]=='m'&& table->format[1]=='p'&& table->format[2]=='4'&& table->format[3]=='v' )
{
ret = Read_stsd_video(dr, table, &leaf_atom);
}
if ( table->format[0]=='m'&& table->format[1]=='p'&& table->format[2]=='4'&& table->format[3]=='s' )
{
ret = Read_stsd_hint(dr, table, &leaf_atom);
}
if ( table->format[0]=='d' && table->format[1]=='r' && table->format[2]=='m' && table->format[3]=='s' )
{
ret = Read_stsd_drms(dr, table, &leaf_atom);
}
if ( table->format[0]=='s'&& table->format[1]=='2'&& table->format[2]=='6'&& table->format[3]=='3' )
{
ret = Read_h263_video(dr, table, &leaf_atom);
table->esds.objectTypeID = 0xf2;
}
if ( table->format[0]=='a'&& table->format[1]=='v'&& table->format[2]=='c'&& table->format[3]=='1' )
{
ret = Read_h264_video(dr, table, &leaf_atom);
table->esds.objectTypeID = 0xf1;
}
return ret;
}
Status MP4Splitter::Read_stsd_drms(UMC::DataReader *dr, T_stsd_table_data *table, T_atom_mp4 *parent_atom)
{
Status ret = UMC_OK;
unsigned short sample_rate;
table->is_protected = 1;
dr->MovePosition(8); // reserved
dr->Get16uSwap(&table->channels);
dr->Get16uSwap(&table->sample_size);
dr->MovePosition(4); // reserved
dr->Get16uSwap(&sample_rate);
table->sample_rate = sample_rate;
dr->MovePosition(2); // reserved
while ( (dr->GetPosition() < parent_atom->end) && (dr->GetPosition() != 0) && (ret == UMC_OK))
{
T_atom_mp4 leaf_atom;
ret = Read_Atom(dr, &leaf_atom);
UMC_CHECK_STATUS(ret)
if (Compare_Atom(&leaf_atom, "esds"))
{
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -