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 "src/impl.h"
23 
24 namespace mp4v2 {
25 namespace impl {
26 
27 ///////////////////////////////////////////////////////////////////////////////
28 
MP4TkhdAtom(MP4File & file)29 MP4TkhdAtom::MP4TkhdAtom(MP4File &file)
30         : MP4Atom(file, "tkhd")
31 {
32     AddVersionAndFlags();
33 }
34 
AddProperties(uint8_t version)35 void MP4TkhdAtom::AddProperties(uint8_t version)
36 {
37     if (version == 1) {
38         AddProperty( /* 2 */
39             new MP4Integer64Property(*this, "creationTime"));
40         AddProperty( /* 3 */
41             new MP4Integer64Property(*this, "modificationTime"));
42     } else { // version == 0
43         AddProperty( /* 2 */
44             new MP4Integer32Property(*this, "creationTime"));
45         AddProperty( /* 3 */
46             new MP4Integer32Property(*this, "modificationTime"));
47     }
48 
49     AddProperty( /* 4 */
50         new MP4Integer32Property(*this, "trackId"));
51     AddReserved(*this, "reserved1", 4); /* 5 */
52 
53     if (version == 1) {
54         AddProperty( /* 6 */
55             new MP4Integer64Property(*this, "duration"));
56     } else {
57         AddProperty( /* 6 */
58             new MP4Integer32Property(*this, "duration"));
59     }
60 
61     AddReserved(*this, "reserved2", 8); /* 7 */
62 
63     AddProperty( /* 8 */
64         new MP4Integer16Property(*this, "layer"));
65     AddProperty( /* 9 */
66         new MP4Integer16Property(*this, "alternate_group"));
67 
68     MP4Float32Property* pProp;
69 
70     pProp = new MP4Float32Property(*this, "volume");
71     pProp->SetFixed16Format();
72     AddProperty(pProp); /* 10 */
73 
74     AddReserved(*this, "reserved3", 2); /* 11 */
75 
76     AddProperty(new MP4BytesProperty(*this, "matrix", 36)); /* 12 */
77 
78     pProp = new MP4Float32Property(*this, "width");
79     pProp->SetFixed32Format();
80     AddProperty(pProp); /* 13 */
81 
82     pProp = new MP4Float32Property(*this, "height");
83     pProp->SetFixed32Format();
84     AddProperty(pProp); /* 14 */
85 }
86 
Generate()87 void MP4TkhdAtom::Generate()
88 {
89     uint8_t version = m_File.Use64Bits(GetType()) ? 1 : 0;
90     SetVersion(version);
91     AddProperties(version);
92 
93     MP4Atom::Generate();
94 
95     // set creation and modification times
96     MP4Timestamp now = MP4GetAbsTimestamp();
97     if (version == 1) {
98         ((MP4Integer64Property*)m_pProperties[2])->SetValue(now);
99         ((MP4Integer64Property*)m_pProperties[3])->SetValue(now);
100     } else {
101         ((MP4Integer32Property*)m_pProperties[2])->SetValue(now);
102         ((MP4Integer32Property*)m_pProperties[3])->SetValue(now);
103     }
104 
105     // property "matrix" has non-zero fixed values
106     // this default identity matrix indicates no transformation, i.e.
107     // 1, 0, 0
108     // 0, 1, 0
109     // 0, 0, 1
110     // see http://developer.apple.com/documentation/QuickTime/QTFF/QTFFChap4/chapter_5_section_4.html
111 
112     static uint8_t matrix[36] = {
113         0x00, 0x01, 0x00, 0x00,
114         0x00, 0x00, 0x00, 0x00,
115         0x00, 0x00, 0x00, 0x00,
116         0x00, 0x00, 0x00, 0x00,
117         0x00, 0x01, 0x00, 0x00,
118         0x00, 0x00, 0x00, 0x00,
119         0x00, 0x00, 0x00, 0x00,
120         0x00, 0x00, 0x00, 0x00,
121         0x40, 0x00, 0x00, 0x00,
122     };
123 
124     ((MP4BytesProperty*)m_pProperties[12])->
125     SetValue(matrix, sizeof(matrix));
126 }
127 
Read()128 void MP4TkhdAtom::Read()
129 {
130     /* read atom version */
131     ReadProperties(0, 1);
132 
133     /* need to create the properties based on the atom version */
134     AddProperties(GetVersion());
135 
136     /* now we can read the remaining properties */
137     ReadProperties(1);
138 
139     Skip(); // to end of atom
140 }
141 
142 ///////////////////////////////////////////////////////////////////////////////
143 
144 }
145 } // namespace mp4v2::impl
146