Imported Upstream version 2.0.0
[platform/upstream/libmp4v2.git] / src / atom_avcC.cpp
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. 2004.  All Rights Reserved.
17  *
18  * Contributor(s):
19  *      Bill May wmay@cisco.com
20  */
21
22 #include "src/impl.h"
23
24 namespace mp4v2 {
25 namespace impl {
26
27 ///////////////////////////////////////////////////////////////////////////////
28
29 /*
30  * SizeTableProperty is a special version of the MP4TableProperty -
31  * the BytesProperty will need to set the value before it can read
32  * from the file
33  */
34 class SizeTableProperty : public MP4TableProperty
35 {
36 public:
37     SizeTableProperty(MP4Atom& parentAtom, const char *name, MP4IntegerProperty *pCountProperty) :
38             MP4TableProperty(parentAtom, name, pCountProperty) {};
39 protected:
40     void ReadEntry(MP4File& file, uint32_t index) {
41         // Each table has a size, followed by the length field
42         // first, read the length
43         m_pProperties[0]->Read(file, index);
44         MP4IntegerProperty *pIntProp = (MP4IntegerProperty *)m_pProperties[0];
45         // set the size in the bytes property
46         MP4BytesProperty *pBytesProp = (MP4BytesProperty *)m_pProperties[1];
47         pBytesProp->SetValueSize(pIntProp->GetValue(index), index);
48         // And read the bytes
49         m_pProperties[1]->Read(file, index);
50     };
51 private:
52     SizeTableProperty();
53     SizeTableProperty ( const SizeTableProperty &src );
54     SizeTableProperty &operator= ( const SizeTableProperty &src );
55 };
56
57 MP4AvcCAtom::MP4AvcCAtom(MP4File &file)
58         : MP4Atom(file, "avcC")
59 {
60     MP4BitfieldProperty *pCount;
61     MP4TableProperty *pTable;
62
63     AddProperty( new MP4Integer8Property(*this,"configurationVersion")); /* 0 */
64
65     AddProperty( new MP4Integer8Property(*this,"AVCProfileIndication")); /* 1 */
66
67     AddProperty( new MP4Integer8Property(*this,"profile_compatibility")); /* 2 */
68
69     AddProperty( new MP4Integer8Property(*this,"AVCLevelIndication")); /* 3 */
70
71     AddProperty( new MP4BitfieldProperty(*this,"reserved", 6)); /* 4 */
72     AddProperty( new MP4BitfieldProperty(*this,"lengthSizeMinusOne", 2)); /* 5 */
73     AddProperty( new MP4BitfieldProperty(*this,"reserved1", 3)); /* 6 */
74     pCount = new MP4BitfieldProperty(*this,"numOfSequenceParameterSets", 5);
75     AddProperty(pCount); /* 7 */
76
77     pTable = new SizeTableProperty(*this,"sequenceEntries", pCount);
78     AddProperty(pTable); /* 8 */
79     pTable->AddProperty(new MP4Integer16Property(pTable->GetParentAtom(),"sequenceParameterSetLength"));
80     pTable->AddProperty(new MP4BytesProperty(pTable->GetParentAtom(),"sequenceParameterSetNALUnit"));
81
82     MP4Integer8Property *pCount2 = new MP4Integer8Property(*this,"numOfPictureParameterSets");
83     AddProperty(pCount2); /* 9 */
84
85     pTable = new SizeTableProperty(*this,"pictureEntries", pCount2);
86     AddProperty(pTable); /* 10 */
87     pTable->AddProperty(new MP4Integer16Property(pTable->GetParentAtom(),"pictureParameterSetLength"));
88     pTable->AddProperty(new MP4BytesProperty(pTable->GetParentAtom(),"pictureParameterSetNALUnit"));
89 }
90
91 void MP4AvcCAtom::Generate()
92 {
93     MP4Atom::Generate();
94
95     ((MP4Integer8Property*)m_pProperties[0])->SetValue(1);
96
97     m_pProperties[4]->SetReadOnly(false);
98     ((MP4BitfieldProperty*)m_pProperties[4])->SetValue(0x3f);
99     m_pProperties[4]->SetReadOnly(true);
100
101     m_pProperties[6]->SetReadOnly(false);
102     ((MP4BitfieldProperty*)m_pProperties[6])->SetValue(0x7);
103     m_pProperties[6]->SetReadOnly(true);
104 #if 0
105     // property reserved4 has non-zero fixed values
106     static uint8_t reserved4[4] = {
107         0x00, 0x18, 0xFF, 0xFF,
108     };
109     m_pProperties[7]->SetReadOnly(false);
110     ((MP4BytesProperty*)m_pProperties[7])->
111     SetValue(reserved4, sizeof(reserved4));
112     m_pProperties[7]->SetReadOnly(true);
113 #endif
114 }
115
116 //
117 // Clone - clone my properties to destination atom
118 //
119 // this method simplifies duplicating avcC atom properties from
120 // source to destination file using a single API rather than
121 // having to copy each property.  This API encapsulates the object
122 // so the application layer need not concern with each property
123 // thereby isolating any future changes to atom properties.
124 //
125 // ----------------------------------------
126 // property   description
127 // ----------------------------------------
128 //
129 // 0    configurationVersion
130 // 1    AVCProfileIndication
131 // 2    profile_compatibility
132 // 3    AVCLevelIndication
133 // 4    reserved
134 // 5    lengthSizeMinusOne
135 // 6    reserved
136 // 7    number of SPS
137 // 8    SPS entries
138 // 9    number of PPS
139 // 10   PPS entries
140 //
141 //
142 void MP4AvcCAtom::Clone(MP4AvcCAtom *dstAtom)
143 {
144
145     MP4Property *dstProperty;
146     MP4TableProperty *pTable;
147     uint16_t i16;
148     uint64_t i32;
149     uint64_t i64;
150     uint8_t *tmp;
151
152     // source pointer Property I16
153     MP4Integer16Property *spPI16;
154     // source pointer Property Bytes
155     MP4BytesProperty *spPB;
156
157     // dest pointer Property I16
158     MP4Integer16Property *dpPI16;
159     // dest pointer Property Bytes
160     MP4BytesProperty *dpPB;
161
162
163     // start with defaults and reserved fields
164     dstAtom->Generate();
165
166     // 0, 4, 6 are now generated from defaults
167     // leaving 1, 2, 3, 5, 7, 8, 9, 10 to export
168
169     dstProperty=dstAtom->GetProperty(1);
170     ((MP4Integer8Property *)dstProperty)->SetValue(
171         ((MP4Integer8Property *)m_pProperties[1])->GetValue());
172
173     dstProperty=dstAtom->GetProperty(2);
174     ((MP4Integer8Property *)dstProperty)->SetValue(
175         ((MP4Integer8Property *)m_pProperties[2])->GetValue());
176
177     dstProperty=dstAtom->GetProperty(3);
178     ((MP4Integer8Property *)dstProperty)->SetValue(
179         ((MP4Integer8Property *)m_pProperties[3])->GetValue());
180
181     dstProperty=dstAtom->GetProperty(5);
182     ((MP4BitfieldProperty *)dstProperty)->SetValue(
183         ((MP4BitfieldProperty *)m_pProperties[5])->GetValue());
184
185     //
186     // 7 and 8 are related SPS (one set of sequence parameters)
187     //
188     // first the count bitfield
189     //
190     dstProperty=dstAtom->GetProperty(7);
191     dstProperty->SetReadOnly(false);
192     ((MP4BitfieldProperty *)dstProperty)->SetValue(
193         ((MP4BitfieldProperty *)m_pProperties[7])->GetValue());
194     dstProperty->SetReadOnly(true);
195
196     // next export SPS Length and NAL bytes */
197
198     // first source pointers
199     pTable = (MP4TableProperty *) m_pProperties[8];
200     spPI16 = (MP4Integer16Property *)pTable->GetProperty(0);
201     spPB = (MP4BytesProperty *)pTable->GetProperty(1);
202
203     // now dest pointers
204     dstProperty=dstAtom->GetProperty(8);
205     pTable = (MP4TableProperty *) dstProperty;
206     dpPI16 = (MP4Integer16Property *)pTable->GetProperty(0);
207     dpPB = (MP4BytesProperty *)pTable->GetProperty(1);
208
209     // sps length
210     i16 = spPI16->GetValue();
211     i64 = i16;
212     // FIXME - this leaves m_maxNumElements =2
213     // but src atom m_maxNumElements is 1
214     dpPI16->InsertValue(i64, 0);
215
216     // export byte array
217     i32 = i16;
218     // copy bytes to local buffer
219     tmp = (uint8_t *)MP4Malloc(i32);
220     ASSERT(tmp != NULL);
221     spPB->CopyValue(tmp, 0);
222     // set element count
223     dpPB->SetCount(1);
224     // copy bytes
225     dpPB->SetValue(tmp, i32, 0);
226     MP4Free((void *)tmp);
227
228     //
229     // 9 and 10 are related PPS (one set of picture parameters)
230     //
231     // first the integer8 count
232     //
233     dstProperty=dstAtom->GetProperty(9);
234     dstProperty->SetReadOnly(false);
235     ((MP4Integer8Property *)dstProperty)->SetValue(
236         ((MP4Integer8Property *)m_pProperties[9])->GetValue());
237     dstProperty->SetReadOnly(true);
238
239     // next export PPS Length and NAL bytes */
240
241     // first source pointers
242     pTable = (MP4TableProperty *) m_pProperties[10];
243     spPI16 = (MP4Integer16Property *)pTable->GetProperty(0);
244     spPB = (MP4BytesProperty *)pTable->GetProperty(1);
245
246     // now dest pointers
247     dstProperty=dstAtom->GetProperty(10);
248     pTable = (MP4TableProperty *) dstProperty;
249     dpPI16 = (MP4Integer16Property *)pTable->GetProperty(0);
250     dpPB = (MP4BytesProperty *)pTable->GetProperty(1);
251
252     // pps length
253     i16 = spPI16->GetValue();
254     i64 = i16;
255     dpPI16->InsertValue(i64, 0);
256
257     // export byte array
258     i32 = i16;
259     // copy bytes to local buffer
260     tmp = (uint8_t *)MP4Malloc(i32);
261     ASSERT(tmp != NULL);
262     spPB->CopyValue(tmp, 0);
263     // set element count
264     dpPB->SetCount(1);
265     // copy bytes
266     dpPB->SetValue(tmp, i32, 0);
267     MP4Free((void *)tmp);
268 }
269
270 ///////////////////////////////////////////////////////////////////////////////
271
272 }
273 } // namespace mp4v2::impl