【VC开源代码栏目提醒】:网学会员,鉴于大家对VC开源代码十分关注,论文会员在此为大家搜集整理了“mp4file.cpp”一文,供大家参考学习!
/*
* The contents of this file are subject to the Mozilla Public
* License Version 1.1 (the "License"); you may not use this file
* except in compliance with the License. You may obtain a copy of
* the License at http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
* implied. See the License for the specific language governing
* rights and limitations under the License.
*
* The Original Code is MPEG4IP.
*
* The Initial Developer of the Original Code is Cisco Systems Inc.
* Portions created by Cisco Systems Inc. are
* Copyright (C) Cisco Systems Inc. 2001. All Rights Reserved.
*
* Contributor(s):
* Dave Mackie dmackie@cisco.com
*/
#include "mp4common.h"
MP4File::MP4File(u_int32_t verbosity)
{
m_fileName = NULL;
m_pFile = NULL;
m_orgFileSize = 0;
m_fileSize = 0;
m_pRootAtom = NULL;
m_odTrackId = MP4_INVALID_TRACK_ID;
m_verbosity = verbosity;
m_mode = 0;
m_use64bits = false;
m_useIsma = false;
m_pModificationProperty = NULL;
m_pTimeScaleProperty = NULL;
m_pDurationProperty = NULL;
m_memoryBuffer = NULL;
m_memoryBufferSize = 0;
m_memoryBufferPosition = 0;
m_numReadBits = 0;
m_bufReadBits = 0;
m_numWriteBits = 0;
m_bufWriteBits = 0;
}
MP4File::~MP4File()
{
MP4Free(m_fileName);
delete m_pRootAtom;
for (u_int32_t i = 0; i < m_pTracks.Size(); i++) {
delete m_pTracks[i];
}
MP4Free(m_memoryBuffer); // just in case
}
void MP4File::Read(const char* fileName)
{
m_fileName = MP4Stralloc(fileName);
m_mode = 'r';
Open("rb");
ReadFromFile();
CacheProperties();
}
void MP4File::Create(const char* fileName, bool use64bits)
{
m_fileName = MP4Stralloc(fileName);
m_mode = 'w';
m_use64bits = use64bits;
Open("wb+");
// generate a skeletal atom tree
m_pRootAtom = MP4Atom::CreateAtom(NULL);
m_pRootAtom->SetFile(this);
m_pRootAtom->Generate();
CacheProperties();
// create mdat, and insert it after ftyp, and before moov
InsertChildAtom(m_pRootAtom, "mdat", 1);
// start writing
m_pRootAtom->BeginWrite();
}
void MP4File::Modify(const char* fileName)
{
m_fileName = MP4Stralloc(fileName);
m_mode = 'r';
Open("rb+");
ReadFromFile();
m_mode = 'w';
// find the moov atom
MP4Atom* pMoovAtom = m_pRootAtom->FindAtom("moov");
u_int32_t numAtoms;
if (pMoovAtom == NULL) {
// there isn't one, odd but we can still proceed
pMoovAtom = AddChildAtom(m_pRootAtom, "moov");
} else {
numAtoms = m_pRootAtom->GetNumberOfChildAtoms();
// work backwards thru the top level atoms
int32_t i;
bool lastAtomIsMoov = true;
MP4Atom* pLastAtom = NULL;
for (i = numAtoms - 1; i >= 0; i--) {
MP4Atom* pAtom = m_pRootAtom->GetChildAtom(i);
const char* type = pAtom->GetType();
// get rid of any trailing free or skips
if (!strcmp(type, "free") || !strcmp(type, "skip")) {
m_pRootAtom->DeleteChildAtom(pAtom);
continue;
}
if (strcmp(type, "moov")) {
if (pLastAtom == NULL) {
pLastAtom = pAtom;
lastAtomIsMoov = false;
}
continue;
}
// now at moov atom
// multiple moov atoms?!?
if (pAtom != pMoovAtom) {
throw new MP4Error(
"Badly formed mp4 file, multiple moov atoms",
"MP4Modify");
}
if (lastAtomIsMoov) {
// position to start of moov atom,
// effectively truncating file
// prior to adding new mdat
SetPosition(pMoovAtom->GetStart());
} else { // last atom isn't moov
// need to place a free atom
MP4Atom* pFreeAtom = MP4Atom::CreateAtom("free");
// in existing position of the moov atom
m_pRootAtom->InsertChildAtom(pFreeAtom, i);
m_pRootAtom->DeleteChildAtom(pMoovAtom);
m_pRootAtom->AddChildAtom(pMoovAtom);
// write free atom to disk
SetPosition(pMoovAtom->GetStart());
pFreeAtom->SetSize(pMoovAtom->GetSize());
pFreeAtom->Write();
// finally set our file position to the end of the last atom
SetPosition(pLastAtom->GetEnd());
}
break;
}
ASSERT(i != -1);
}
CacheProperties(); // of moov atom
numAtoms = m_pRootAtom->GetNumberOfChildAtoms();
// insert another mdat prior to moov atom (the last atom)
MP4Atom* pMdatAtom = InsertChildAtom(m_pRootAtom, "mdat", numAtoms - 1);
// start writing new mdat
pMdatAtom->BeginWrite();
}
void MP4File::Optimize(const char* orgFileName, const char* newFileName)
{
m_fileName = MP4Stralloc(orgFileName);
m_mode = 'r';
// first load meta-info into memory
Open("rb");
ReadFromFile();
CacheProperties(); // of moov ato