📄 umc_mp4_parser.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) 2004-2007 Intel Corporation. All Rights Reserved.
//
*/
#include "umc_mp4_spl.h"
#include "umc_mp4_parser.h"
namespace UMC
{
Status MP4Splitter::Read_traf(DataReader *dr, T_traf *traf, T_atom_mp4 *atom)
{
Status ret;
T_atom_mp4 current_atom;
traf->entry_count = 0;
do
{
ret = Read_Atom(dr, ¤t_atom);
UMC_CHECK_STATUS(ret)
if (Compare_Atom(¤t_atom, "tfhd"))
{
ret = Read_tfhd(dr, &traf->tfhd);
UMC_CHECK_STATUS(ret)
ret = Atom_Skip(dr, ¤t_atom);
UMC_CHECK_STATUS(ret)
}
if (Compare_Atom(¤t_atom, "trun"))
{
if (!traf->trun[traf->entry_count])
{
traf->trun[traf->entry_count] = (T_trun*) (ippsMalloc_8u(sizeof(T_trun)));
memset(traf->trun[traf->entry_count], 0, sizeof(T_trun));
}
ret = Read_trun(dr, traf->trun[traf->entry_count]);
UMC_CHECK_STATUS(ret)
traf->entry_count++;
ret = Atom_Skip(dr, ¤t_atom);
}
} while((dr->GetPosition() < atom->end) && (dr->GetPosition() != 0) && (ret == UMC_OK));
if (traf->entry_count > traf->max_truns)
traf->max_truns = traf->entry_count;
return ret;
}
/*****
Status Read_traf(DataReader *dr, T_traf *traf, T_atom_mp4 *atom)
{
Status ret;
T_atom_mp4 current_atom;
traf->entry_count = 0;
do
{
ret = Read_Atom(m_pDataReader, ¤t_atom);
UMC_CHECK_STATUS(ret)
if (Compare_Atom(¤t_atom, "tfhd"))
{
ret = Read_tfhd(m_pDataReader, &traf->tfhd);
UMC_CHECK_STATUS(ret)
ret = Atom_Skip(m_pDataReader, ¤t_atom);
UMC_CHECK_STATUS(ret)
}
if (Compare_Atom(¤t_atom, "trun"))
{
if (!traf->trun[traf->entry_count])
{
traf->trun[traf->entry_count] = (T_trun*) (ippsMalloc_8u(sizeof(T_trun)));
memset(traf->trun[traf->entry_count], 0, sizeof(T_trun));
}
ret = Read_trun(m_pDataReader, traf->trun[traf->entry_count]);
UMC_CHECK_STATUS(ret)
traf->entry_count++;
ret = Atom_Skip(m_pDataReader, ¤t_atom);
}
} while((dr->GetPosition() < atom->end) && (dr->GetPosition() != 0) && (ret == UMC_OK));
if (traf->entry_count > traf->max_truns)
traf->max_truns = traf->entry_count;
return ret;
}
*/
Status MP4Splitter::Read_tfhd(DataReader *dr, T_tfhd *tfhd)
{
dr->Get8u(&tfhd->version);
tfhd->flags = Get_24(dr);
dr->Get32uSwap(&tfhd->track_ID);
if (tfhd->flags & 0x000001)
{
dr->Get64uSwap((Ipp64u*)&tfhd->base_data_offset);
}
else
{
tfhd->base_data_offset = 0;
}
if (tfhd->flags & 0x000002)
{
dr->Get32uSwap((Ipp32u*)&tfhd->sample_description_index);
}
else
{
tfhd->sample_description_index = 0;
}
if (tfhd->flags & 0x000008)
{
dr->Get32uSwap((Ipp32u*)&tfhd->default_sample_duration);
}
else
{
tfhd->default_sample_duration = 0;
}
if (tfhd->flags & 0x000010)
{
dr->Get32uSwap((Ipp32u*)&tfhd->default_sample_size);
}
else
{
tfhd->default_sample_size = 0;
}
if (tfhd->flags & 0x000020)
{
dr->Get32uSwap((Ipp32u*)&tfhd->default_sample_flags);
}
else
{
tfhd->default_sample_flags = 0;
}
return UMC_OK;
}
Status MP4Splitter::Read_trun(DataReader *dr, T_trun *trun)
{
dr->Get8u(&trun->version);
trun->flags = Get_24(dr);
dr->Get32uSwap(&trun->sample_count);
if (trun->flags & 0x000001)
{
dr->Get32uSwap((Ipp32u*)&trun->data_offset);
}
else
{
trun->data_offset = 0;
}
if (trun->flags & 0x000004)
{
dr->Get32uSwap((Ipp32u*)&trun->first_sample_flags);
}
else
{
trun->first_sample_flags = 0;
}
if (!trun->table_trun)
{
trun->table_trun = (T_trun_table_data*) (ippsMalloc_8u(sizeof(T_trun_table_data) * /*trun->sample_count*/40000)); // 40000 ~= number of entries in standard moof box
}
memset(trun->table_trun, 0, sizeof(T_trun_table_data) * /*trun->sample_count*/40000);
return Read_trun_table(dr, trun, trun->table_trun);
//return 0;
}
Status MP4Splitter::Read_trun_table(DataReader *dr, T_trun* trun, T_trun_table_data* table)
{
for (unsigned int i = 0; i < trun->sample_count; i++)
{
if (trun->flags & 0x000100)
{
dr->Get32uSwap((Ipp32u*)&table[i].sample_duration);
}
if (trun->flags & 0x000200)
{
dr->Get32uSwap((Ipp32u*)&table[i].sample_size);
}
if (trun->flags & 0x000400)
{
dr->Get32uSwap((Ipp32u*)&table[i].sample_flags);
}
if (trun->flags & 0x000800)
{
dr->Get32uSwap((Ipp32u*)&table[i].sample_composition_time_offset);
}
}
return 0;
}
Status MP4Splitter::Clear_moof(T_moof &moof)
{
Ipp32u i, j;
for (i = 0; i < moof.total_tracks; i++) {
for (j = 0; j < moof.traf[i]->entry_count; j++) {
UMC_FREE(moof.traf[i]->trun[j]->table_trun)
UMC_FREE(moof.traf[i]->trun[j])
}
UMC_FREE(moof.traf[i])
}
return UMC_OK;
}
Status MP4Splitter::Read_moof(DataReader *dr, T_moof *moof, T_atom_mp4 *atom)
{
Status umcRes;
T_atom_mp4 current_atom;
moof->end = atom->end;
moof->total_tracks = 0;
do
{
umcRes = Read_Atom(dr, ¤t_atom);
UMC_CHECK_STATUS(umcRes)
if (Compare_Atom(¤t_atom, "mfhd")) {
umcRes = Read_mfhd(dr, &moof->mfhd);
UMC_CHECK_STATUS(umcRes)
umcRes = Atom_Skip(dr, ¤t_atom);
} else if (Compare_Atom(¤t_atom, "traf")) {
if (!moof->traf[moof->total_tracks]) {
moof->traf[moof->total_tracks] = (T_traf*)(ippsMalloc_8u(sizeof(T_traf)));
memset(moof->traf[moof->total_tracks], 0, sizeof(T_traf));
}
umcRes = Read_traf(dr, moof->traf[moof->total_tracks], ¤t_atom);
UMC_CHECK_STATUS(umcRes)
umcRes = Atom_Skip(dr, ¤t_atom);
UMC_CHECK_STATUS(umcRes)
moof->total_tracks++;
} else {
return UMC_ERR_INVALID_STREAM;
}
} while((dr->GetPosition() < atom->end) && (dr->GetPosition() != 0) && (umcRes == UMC_OK));
return umcRes;
}
/*****
Status Read_moof(DataReader *dr, T_moof *moof, T_atom_mp4 *atom)
{
Status ret;
T_atom_mp4 current_atom;
moof->end = atom->end;
moof->total_tracks = 0;
do
{
ret = Read_Atom(m_pDataReader, ¤t_atom);
UMC_CHECK_STATUS(ret)
if (Compare_Atom(¤t_atom, "mfhd"))
{
ret = Read_mfhd(m_pDataReader, &moof->mfhd);
UMC_CHECK_STATUS(ret)
ret = Atom_Skip(m_pDataReader, ¤t_atom);
}
else if (Compare_Atom(¤t_atom, "traf"))
{
if (!moof->traf[moof->total_tracks])
{
moof->traf[moof->total_tracks] = (T_traf*) (ippsMalloc_8u(sizeof(T_traf)));
memset(moof->traf[moof->total_tracks], 0, sizeof(T_traf));
}
ret = Read_traf(m_pDataReader, moof->traf[moof->total_tracks], ¤t_atom);
UMC_CHECK_STATUS(ret)
ret = Atom_Skip(m_pDataReader, ¤t_atom);
UMC_CHECK_STATUS(ret)
moof->total_tracks++;
}
else
{
return UMC_ERR_INVALID_STREAM;
}
}while((dr->GetPosition() < atom->end) && (dr->GetPosition() != 0) && (ret == UMC_OK));
return ret;
}
*/
long MP4Splitter::Get_24(DataReader *dr)
{
unsigned int result = 0;
unsigned int a, b, c;
unsigned int len;
char data[3];
len = 3;
dr->GetData(data, (Ipp32u*) &len);
a = (unsigned char)data[0];
b = (unsigned char)data[1];
c = (unsigned char)data[2];
result = (a<<16) + (b<<8) + c;
return (long)result;
}
Ipp32s MP4Splitter::Read_mp4_descr_length(DataReader *dr)
{
unsigned char b;
Ipp8u numBytes = 0;
Ipp32s length = 0;
do
{
dr->Get8u(&b);
numBytes++;
length = (length << 7) | (b & 0x7F);
} while ((b & 0x80) && numBytes < 4);
return length;
}
/*****
Ipp32s Get_mp4_descr_length(DataReader *dr)
{
unsigned char b;
Ipp8u numBytes = 0;
Ipp32s length = 0;
do
{
dr->Get8u(&b);
numBytes++;
length = (length << 7) | (b & 0x7F);
} while ((b & 0x80) && numBytes < 4);
return length;
}
*/
Status MP4Splitter::Atom_Skip(DataReader *dr, T_atom_mp4 *atom)
{
#ifndef UMC_MF
dr->SetPosition((Ipp64u)0);
dr->StartReadingAfterReposition();
return dr->MovePosition((int)atom->end);
#else
return dr->SetPosition(atom->end);
#endif
}
Status MP4Splitter::Compare_Atom(T_atom_mp4 *atom, char *type)
{
if ( atom->type[0] == type[0] &&
atom->type[1] == type[1] &&
atom->type[2] == type[2] &&
atom->type[3] == type[3] )
{
return 1;
}
else
{
return 0;
}
}
Status MP4Splitter::Read_Atom(DataReader *dr, T_atom_mp4 *atom)
{
Status ret;
unsigned int len;
unsigned int size = 0;
atom->start = dr->GetPosition();
dr->Get32uSwap(&size);
atom->is_large_size = (size == 1);
len = 4;
ret = dr->GetData(&atom->type, (Ipp32u*) &len);
if (ret != UMC_OK)
{
return UMC_ERR_FAILED;
}
if (size == 1)
{
ret = dr->Get64uSwap(&atom->size);
if (ret != UMC_OK)
{
return UMC_ERR_FAILED;
}
}
else
{
atom->size = size;
}
atom->end = atom->start + atom->size;
if (atom->type[0] == 'u' &&
atom->type[1] == 'u' &&
atom->type[2] == 'i' &&
atom->type[3] == 'd')
{
char userType[128];
len = 128;
ret = dr->GetData(userType, (Ipp32u*)&len);
}
return ret;
}
T_trak_data* MP4Splitter::Add_trak(T_moov *moov)
{
if ( moov->total_tracks < MAXTRACKS )
{
moov->trak[moov->total_tracks] = (T_trak_data*) (ippsMalloc_8u(sizeof(T_trak_data)));
if (moov->trak[moov->total_tracks]) {
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -