1/*
2 * Copyright 2008 CoreMedia AG, Hamburg
3 *
4 * Licensed under the Apache License, Version 2.0 (the License);
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 *     http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an AS IS BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17package com.coremedia.iso.boxes;
18
19import com.coremedia.iso.IsoTypeReader;
20import com.coremedia.iso.IsoTypeWriter;
21import com.googlecode.mp4parser.AbstractFullBox;
22
23import java.nio.ByteBuffer;
24
25/**
26 * <code>
27 * Box Type: 'mvhd'<br>
28 * Container: {@link MovieBox} ('moov')<br>
29 * Mandatory: Yes<br>
30 * Quantity: Exactly one<br><br>
31 * </code>
32 * This box defines overall information which is media-independent, and relevant to the entire presentation
33 * considered as a whole.
34 */
35public class MovieHeaderBox extends AbstractFullBox {
36    private long creationTime;
37    private long modificationTime;
38    private long timescale;
39    private long duration;
40    private double rate = 1.0;
41    private float volume = 1.0f;
42    private long[] matrix = new long[]{0x00010000, 0, 0, 0, 0x00010000, 0, 0, 0, 0x40000000};
43    private long nextTrackId;
44
45    private int previewTime;
46    private int previewDuration;
47    private int posterTime;
48    private int selectionTime;
49    private int selectionDuration;
50    private int currentTime;
51
52
53    public static final String TYPE = "mvhd";
54
55    public MovieHeaderBox() {
56        super(TYPE);
57    }
58
59    public long getCreationTime() {
60        return creationTime;
61    }
62
63    public long getModificationTime() {
64        return modificationTime;
65    }
66
67    public long getTimescale() {
68        return timescale;
69    }
70
71    public long getDuration() {
72        return duration;
73    }
74
75    public double getRate() {
76        return rate;
77    }
78
79    public float getVolume() {
80        return volume;
81    }
82
83    public long[] getMatrix() {
84        return matrix;
85    }
86
87    public long getNextTrackId() {
88        return nextTrackId;
89    }
90
91    protected long getContentSize() {
92        long contentSize = 4;
93        if (getVersion() == 1) {
94            contentSize += 28;
95        } else {
96            contentSize += 16;
97        }
98        contentSize += 80;
99        return contentSize;
100    }
101
102    @Override
103    public void _parseDetails(ByteBuffer content) {
104        parseVersionAndFlags(content);
105        if (getVersion() == 1) {
106            creationTime = IsoTypeReader.readUInt64(content);
107            modificationTime = IsoTypeReader.readUInt64(content);
108            timescale = IsoTypeReader.readUInt32(content);
109            duration = IsoTypeReader.readUInt64(content);
110        } else {
111            creationTime = IsoTypeReader.readUInt32(content);
112            modificationTime = IsoTypeReader.readUInt32(content);
113            timescale = IsoTypeReader.readUInt32(content);
114            duration = IsoTypeReader.readUInt32(content);
115        }
116        rate = IsoTypeReader.readFixedPoint1616(content);
117        volume = IsoTypeReader.readFixedPoint88(content);
118        IsoTypeReader.readUInt16(content);
119        IsoTypeReader.readUInt32(content);
120        IsoTypeReader.readUInt32(content);
121        matrix = new long[9];
122        for (int i = 0; i < 9; i++) {
123            matrix[i] = IsoTypeReader.readUInt32(content);
124        }
125
126        previewTime = content.getInt();
127        previewDuration = content.getInt();
128        posterTime = content.getInt();
129        selectionTime = content.getInt();
130        selectionDuration = content.getInt();
131        currentTime = content.getInt();
132
133        nextTrackId = IsoTypeReader.readUInt32(content);
134
135    }
136
137    public String toString() {
138        StringBuilder result = new StringBuilder();
139        result.append("MovieHeaderBox[");
140        result.append("creationTime=").append(getCreationTime());
141        result.append(";");
142        result.append("modificationTime=").append(getModificationTime());
143        result.append(";");
144        result.append("timescale=").append(getTimescale());
145        result.append(";");
146        result.append("duration=").append(getDuration());
147        result.append(";");
148        result.append("rate=").append(getRate());
149        result.append(";");
150        result.append("volume=").append(getVolume());
151        for (int i = 0; i < matrix.length; i++) {
152            result.append(";");
153            result.append("matrix").append(i).append("=").append(matrix[i]);
154        }
155        result.append(";");
156        result.append("nextTrackId=").append(getNextTrackId());
157        result.append("]");
158        return result.toString();
159    }
160
161
162    @Override
163    protected void getContent(ByteBuffer byteBuffer) {
164        writeVersionAndFlags(byteBuffer);
165        if (getVersion() == 1) {
166            IsoTypeWriter.writeUInt64(byteBuffer, creationTime);
167            IsoTypeWriter.writeUInt64(byteBuffer, modificationTime);
168            IsoTypeWriter.writeUInt32(byteBuffer, timescale);
169            IsoTypeWriter.writeUInt64(byteBuffer, duration);
170        } else {
171            IsoTypeWriter.writeUInt32(byteBuffer, creationTime);
172            IsoTypeWriter.writeUInt32(byteBuffer, modificationTime);
173            IsoTypeWriter.writeUInt32(byteBuffer, timescale);
174            IsoTypeWriter.writeUInt32(byteBuffer, duration);
175        }
176        IsoTypeWriter.writeFixedPont1616(byteBuffer, rate);
177        IsoTypeWriter.writeFixedPont88(byteBuffer, volume);
178        IsoTypeWriter.writeUInt16(byteBuffer, 0);
179        IsoTypeWriter.writeUInt32(byteBuffer, 0);
180        IsoTypeWriter.writeUInt32(byteBuffer, 0);
181
182
183        for (int i = 0; i < 9; i++) {
184            IsoTypeWriter.writeUInt32(byteBuffer, matrix[i]);
185        }
186
187
188        byteBuffer.putInt(previewTime);
189        byteBuffer.putInt(previewDuration);
190        byteBuffer.putInt(posterTime);
191        byteBuffer.putInt(selectionTime);
192        byteBuffer.putInt(selectionDuration);
193        byteBuffer.putInt(currentTime);
194
195        IsoTypeWriter.writeUInt32(byteBuffer, nextTrackId);
196    }
197
198
199    public void setCreationTime(long creationTime) {
200        this.creationTime = creationTime;
201    }
202
203    public void setModificationTime(long modificationTime) {
204        this.modificationTime = modificationTime;
205    }
206
207    public void setTimescale(long timescale) {
208        this.timescale = timescale;
209    }
210
211    public void setDuration(long duration) {
212        this.duration = duration;
213    }
214
215    public void setRate(double rate) {
216        this.rate = rate;
217    }
218
219    public void setVolume(float volume) {
220        this.volume = volume;
221    }
222
223    public void setMatrix(long[] matrix) {
224        this.matrix = matrix;
225    }
226
227    public void setNextTrackId(long nextTrackId) {
228        this.nextTrackId = nextTrackId;
229    }
230
231    public int getPreviewTime() {
232        return previewTime;
233    }
234
235    public void setPreviewTime(int previewTime) {
236        this.previewTime = previewTime;
237    }
238
239    public int getPreviewDuration() {
240        return previewDuration;
241    }
242
243    public void setPreviewDuration(int previewDuration) {
244        this.previewDuration = previewDuration;
245    }
246
247    public int getPosterTime() {
248        return posterTime;
249    }
250
251    public void setPosterTime(int posterTime) {
252        this.posterTime = posterTime;
253    }
254
255    public int getSelectionTime() {
256        return selectionTime;
257    }
258
259    public void setSelectionTime(int selectionTime) {
260        this.selectionTime = selectionTime;
261    }
262
263    public int getSelectionDuration() {
264        return selectionDuration;
265    }
266
267    public void setSelectionDuration(int selectionDuration) {
268        this.selectionDuration = selectionDuration;
269    }
270
271    public int getCurrentTime() {
272        return currentTime;
273    }
274
275    public void setCurrentTime(int currentTime) {
276        this.currentTime = currentTime;
277    }
278}
279