2
|
1 /*
|
|
2 * The contents of this file are subject to the Mozilla Public
|
|
3 * License Version 1.1 (the "License"); you may not use this file
|
|
4 * except in compliance with the License. You may obtain a copy of
|
|
5 * the License at http://www.mozilla.org/MPL/
|
|
6 *
|
|
7 * Software distributed under the License is distributed on an "AS
|
|
8 * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
|
|
9 * implied. See the License for the specific language governing
|
|
10 * rights and limitations under the License.
|
|
11 *
|
|
12 * The Original Code is MPEG4IP.
|
|
13 *
|
|
14 * The Initial Developer of the Original Code is Cisco Systems Inc.
|
|
15 * Portions created by Cisco Systems Inc. are
|
|
16 * Copyright (C) Cisco Systems Inc. 2001. All Rights Reserved.
|
|
17 *
|
|
18 * Contributor(s):
|
|
19 * Dave Mackie dmackie@cisco.com
|
|
20 */
|
|
21
|
|
22 #include "mp4common.h"
|
|
23
|
|
24 MP4RootAtom::MP4RootAtom()
|
|
25 : MP4Atom(NULL)
|
|
26 {
|
|
27 ExpectChildAtom("ftyp", Required, OnlyOne);
|
|
28 ExpectChildAtom("moov", Required, OnlyOne);
|
|
29 ExpectChildAtom("mdat", Optional, Many);
|
|
30 ExpectChildAtom("free", Optional, Many);
|
|
31 ExpectChildAtom("skip", Optional, Many);
|
|
32 ExpectChildAtom("udta", Optional, Many);
|
|
33 ExpectChildAtom("moof", Optional, Many);
|
|
34 }
|
|
35
|
|
36 void MP4RootAtom::BeginWrite(bool use64)
|
|
37 {
|
|
38 // only call under MP4Create() control
|
|
39 WriteAtomType("ftyp", OnlyOne);
|
|
40
|
|
41 m_pChildAtoms[GetLastMdatIndex()]->BeginWrite(m_pFile->Use64Bits());
|
|
42 }
|
|
43
|
|
44 void MP4RootAtom::Write()
|
|
45 {
|
|
46 // no-op
|
|
47 }
|
|
48
|
|
49 void MP4RootAtom::FinishWrite(bool use64)
|
|
50 {
|
|
51 // finish writing last mdat atom
|
|
52 u_int32_t mdatIndex = GetLastMdatIndex();
|
|
53 m_pChildAtoms[mdatIndex]->FinishWrite(m_pFile->Use64Bits());
|
|
54
|
|
55 // write all atoms after last mdat
|
|
56 u_int32_t size = m_pChildAtoms.Size();
|
|
57 for (u_int32_t i = mdatIndex + 1; i < size; i++) {
|
|
58 m_pChildAtoms[i]->Write();
|
|
59 }
|
|
60 }
|
|
61
|
|
62 void MP4RootAtom::BeginOptimalWrite()
|
|
63 {
|
|
64 WriteAtomType("ftyp", OnlyOne);
|
|
65 WriteAtomType("moov", OnlyOne);
|
|
66 WriteAtomType("udta", Many);
|
|
67
|
|
68 m_pChildAtoms[GetLastMdatIndex()]->BeginWrite(m_pFile->Use64Bits());
|
|
69 }
|
|
70
|
|
71 void MP4RootAtom::FinishOptimalWrite()
|
|
72 {
|
|
73 // finish writing mdat
|
|
74 m_pChildAtoms[GetLastMdatIndex()]->FinishWrite(m_pFile->Use64Bits());
|
|
75
|
|
76 // find moov atom
|
|
77 u_int32_t size = m_pChildAtoms.Size();
|
|
78 MP4Atom* pMoovAtom = NULL;
|
|
79
|
|
80 u_int32_t i;
|
|
81 for (i = 0; i < size; i++) {
|
|
82 if (!strcmp("moov", m_pChildAtoms[i]->GetType())) {
|
|
83 pMoovAtom = m_pChildAtoms[i];
|
|
84 break;
|
|
85 }
|
|
86 }
|
|
87 ASSERT(i < size);
|
|
88
|
|
89 // rewrite moov so that updated chunkOffsets are written to disk
|
|
90 m_pFile->SetPosition(pMoovAtom->GetStart());
|
|
91 u_int64_t oldSize = pMoovAtom->GetSize();
|
|
92
|
|
93 pMoovAtom->Write();
|
|
94
|
|
95 // sanity check
|
|
96 u_int64_t newSize = pMoovAtom->GetSize();
|
|
97 ASSERT(oldSize == newSize);
|
|
98 }
|
|
99
|
|
100 u_int32_t MP4RootAtom::GetLastMdatIndex()
|
|
101 {
|
|
102 for (int32_t i = m_pChildAtoms.Size() - 1; i >= 0; i--) {
|
|
103 if (!strcmp("mdat", m_pChildAtoms[i]->GetType())) {
|
|
104 return i;
|
|
105 }
|
|
106 }
|
|
107 ASSERT(false);
|
|
108 return (u_int32_t)-1;
|
|
109 }
|
|
110
|
|
111 void MP4RootAtom::WriteAtomType(const char* type, bool onlyOne)
|
|
112 {
|
|
113 u_int32_t size = m_pChildAtoms.Size();
|
|
114
|
|
115 for (u_int32_t i = 0; i < size; i++) {
|
|
116 if (!strcmp(type, m_pChildAtoms[i]->GetType())) {
|
|
117 m_pChildAtoms[i]->Write();
|
|
118 if (onlyOne) {
|
|
119 break;
|
|
120 }
|
|
121 }
|
|
122 }
|
|
123 }
|