📄 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-2005 Intel Corporation. All Rights Reserved.//*/#include "umc_mp4_spl.h"#include "umc_mp4_spl_int.h"#include "umc_mp4_parser.h"#include <ipps.h>namespace UMC{Status SplitterMP4::ParceMP4Header(){ T_atom_mp4 current_atom; int result; bool flag_moov = false; do { result = Read_Atom(m_pDataReader, ¤t_atom); if ( result == 0 ) { if ( Compare_Atom(¤t_atom, "mdat") ) { headerMPEG4.data = current_atom; Atom_Skip(m_pDataReader, ¤t_atom); } else if ( Compare_Atom(¤t_atom, "ftyp") ) { Atom_Skip(m_pDataReader, ¤t_atom); } else if ( Compare_Atom(¤t_atom, "moof") ) Atom_Skip(m_pDataReader, ¤t_atom); else if ( Compare_Atom(¤t_atom, "mfra") ) Atom_Skip(m_pDataReader, ¤t_atom); else if ( Compare_Atom(¤t_atom, "free") ) Atom_Skip(m_pDataReader, ¤t_atom); else if ( Compare_Atom(¤t_atom, "skip") ) Atom_Skip(m_pDataReader, ¤t_atom); else if ( Compare_Atom(¤t_atom, "uuid") ) Atom_Skip(m_pDataReader, ¤t_atom); else if ( Compare_Atom(¤t_atom, "moov") ) { Read_moov(m_pDataReader, &(headerMPEG4.moov), ¤t_atom); flag_moov = true; return UMC_OK; } else { return UMC_BAD_STREAM; } } // if ( result == 0 ) } while ( !result ); if ( flag_moov ) { return UMC_OK; } else { return UMC_BAD_STREAM; }}long SplitterMP4::Get_24(DataReader *dr){ unsigned int result = 0; unsigned int a, b, c; unsigned int len; char data[3]; len = 3; dr->GetData(data, (vm_var32*) &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;}int SplitterMP4::Read_mp4_descr_length(DataReader *dr){ unsigned char b; vm_byte numBytes = 0; vm_var32 length = 0; do { dr->GetByte(&b); numBytes++; length = (length << 7) | (b & 0x7F); } while ((b & 0x80) && numBytes < 4); return length;}int SplitterMP4::Get_mp4_descr_length(DataReader *dr){ unsigned char b; vm_byte numBytes = 0; vm_var32 length = 0; do { dr->GetByte(&b); numBytes++; length = (length << 7) | (b & 0x7F); } while ((b & 0x80) && numBytes < 4); return length;}int SplitterMP4::Atom_Skip(DataReader *dr, T_atom_mp4 *atom){ dr->SetPosition(0.); dr->StartReadingAfterReposition(); return dr->MovePosition((int)atom->end); //return dr->SetPos(atom->end);}int SplitterMP4::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; }}int SplitterMP4::Read_Atom(DataReader *dr, T_atom_mp4 *atom){ int result; unsigned int len; atom->start = dr->GetPosition(); dr->GetUInt(&atom->size); len = 4; result = dr->GetData(&atom->type, (vm_var32*) &len); atom->end = atom->start + atom->size; if ( !result ) { return 0; } else { return 1; }}T_trak_data* SplitterMP4::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]) { memset(moov->trak[moov->total_tracks], 0, sizeof(T_trak_data)); moov->total_tracks++; } else { return 0; } } else { return 0; } return moov->trak[moov->total_tracks - 1];}// MOOV Box// The metadata for a presentation is stored in the single Movie Box which occurs at the top-level of a file.//int SplitterMP4::Read_moov(DataReader *dr, T_moov *moov, T_atom_mp4 *atom){ T_atom_mp4 current_atom; moov->total_tracks = 0; do { if ( Read_Atom(dr, ¤t_atom) != 0 ) { return 1; } if ( Compare_Atom(¤t_atom, "mvhd") ) { if(Read_mvhd(dr, &(moov->mvhd)) != 0) { return 1; } } else if ( Compare_Atom(¤t_atom, "iods") ) { if ( Read_iods(dr, &(moov->iods)) != 0 ) { return 1; } Atom_Skip(dr, ¤t_atom); } /*else if ( Compare_Atom(¤t_atom, "clip") ) { Atom_Skip(dr, ¤t_atom); }*/ else if ( Compare_Atom(¤t_atom, "trak") ) { T_trak_data *trak = Add_trak(moov); if ( trak == 0 ) { return 1; } if ( Read_trak(dr, trak, ¤t_atom) != 0 ) { return 1; } } else { Atom_Skip(dr, ¤t_atom); } } while ( (dr->GetPosition() < atom->end) && (dr->GetPosition() != 0) ); return 0;}// MVHD Box// This box defines overall information which is media-independent, and relevant to the entire presentation// considered as a whole.//int SplitterMP4::Read_mvhd(DataReader *dr, T_mvhd_data *mvhd){ unsigned int temp; dr->GetByte(&mvhd->version); mvhd->flags = Get_24(dr); if ( mvhd->version ) { dr->GetVar64(&mvhd->creation_time); dr->GetVar64(&mvhd->modification_time); dr->GetUInt(&mvhd->time_scale); dr->GetVar64(&mvhd->duration); } else { dr->GetUInt(&temp); mvhd->creation_time = temp; dr->GetUInt(&temp); mvhd->modification_time = temp; dr->GetUInt(&mvhd->time_scale); dr->GetUInt(&temp); mvhd->duration = temp; } dr->MovePosition((9 + 6) * 4 + 10 + 2 + 4); // RESERVED dr->GetUInt(&mvhd->next_track_id); return 0;}int SplitterMP4::Read_iods(DataReader *dr, T_iods_data *iods){ unsigned char tag; dr->GetByte(&iods->version); iods->flags = Get_24(dr ); dr->GetByte(&tag); Get_mp4_descr_length(dr); // skip length // skip ODID, ODProfile, sceneProfile dr->GetShort(&iods->objectDescriptorID); // ODID (16 bit ?) dr->GetByte(&iods->OD_profileAndLevel); // ODProfile dr->GetByte(&iods->scene_profileAndLevel); // sceneProfile dr->GetByte(&iods->audioProfileId); dr->GetByte(&iods->videoProfileId); dr->GetByte(&iods->graphics_profileAndLevel); return 0;}// TRAK Box// This is a container box for a single track of a presentation. A presentation consists of one or more tracks.// Each track is independent of the other tracks in the presentation and carries its own temporal and spatial// information. Each track will contain its associated Media Box.//int SplitterMP4::Read_trak(DataReader *dr, T_trak_data *trak, T_atom_mp4 *trak_atom){ T_atom_mp4 leaf_atom; trak->tref.dpnd.idTrak = 0; do { if ( Read_Atom(dr, &leaf_atom) != 0 ) { return 1; } if ( Compare_Atom(&leaf_atom, "tkhd") ) { if ( Read_tkhd(dr, &(trak->tkhd)) != 0 ) { return 1; } } else if ( Compare_Atom(&leaf_atom, "mdia") ) { if ( Read_mdia(dr, &(trak->mdia), &leaf_atom) != 0 ) { return 1; } } else if ( Compare_Atom(&leaf_atom, "tref") ) { Read_tref(dr, &(trak->tref), &leaf_atom); } else { Atom_Skip(dr, &leaf_atom); } } while ( (dr->GetPosition() < trak_atom->end) && (dr->GetPosition() != 0) ); return 0;}// TREF Box// This box provides a reference from the containing track to another track in the presentation. These references// are typed.//int SplitterMP4::Read_tref(DataReader *dr, T_tref_data *tref, T_atom_mp4 *atom){ T_atom_mp4 leaf_atom; do { if ( Read_Atom(dr, &leaf_atom) != 0 ) { return 1; } if ( Compare_Atom(&leaf_atom, "dpnd") ) { Read_dpnd(dr, &(tref->dpnd)); } else { Atom_Skip(dr, &leaf_atom); } } while ( (dr->GetPosition() < atom->end) && (dr->GetPosition() != 0) ); return 0;}int SplitterMP4::Read_dpnd(DataReader *dr, T_dpnd_data *dpnd){ dr->GetUInt(&dpnd->idTrak); return 0;}// TKHD Box// This box specifies the characteristics of a single track.//int SplitterMP4::Read_tkhd(DataReader *dr, T_tkhd_data *tkhd){ unsigned int temp; dr->GetByte(&tkhd->version); tkhd->flags = Get_24(dr); if ( tkhd->version ) { dr->GetVar64(&tkhd->creation_time); dr->GetVar64(&tkhd->modification_time); dr->GetUInt(&tkhd->track_id); dr->MovePosition(4); //RESERVED dr->GetVar64(&tkhd->duration); }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -