/* * JBoss, Home of Professional Open Source * Copyright 2011, Red Hat, Inc. and individual contributors * by the @authors tag. See the copyright.txt in the distribution for a * full listing of individual contributors. * * This is free software; you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License as * published by the Free Software Foundation; either version 2.1 of * the License, or (at your option) any later version. * * This software is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this software; if not, write to the Free * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA * 02110-1301 USA, or see the FSF site: http://www.fsf.org. */ package org.restcomm.media.resource.player.video.mpeg; import java.io.DataInputStream; import java.io.IOException; import java.util.Calendar; import java.util.Date; /** * <b>8.2.2.1 Definition</b> * <ul> * <li>Box Type: �?mvhd’</li> * <li>Container: {@link MovieBox} (�?moov’)</li> * <li>Mandatory: Yes</li> * <li>Quantity: Exactly one</li> * </ul> * <p> * This box defines overall information which is media-independent, and relevant to the entire presentation considered * as a whole. * </p> * * @author kulikov * @author amit bhayani */ public class MovieHeaderBox extends FullBox { // File Type = moov static byte[] TYPE = new byte[] { AsciiTable.ALPHA_m, AsciiTable.ALPHA_v, AsciiTable.ALPHA_h, AsciiTable.ALPHA_d }; static String TYPE_S = "mvhd"; static { bytetoTypeMap.put(TYPE, TYPE_S); } /** * is an integer that declares the creation time of the presentation (in seconds since midnight, Jan. 1, 1904, in * UTC time */ private long creationTime; /** * is an integer that declares the most recent time the presentation was modified (inseconds since midnight, Jan. 1, * 1904, in UTC time) */ private long modificationTime; /** * is an integer that specifies the time-scale for the entire presentation; this is the number of time units that * pass in one second. For example, a time coordinate system that measures time in sixtieths of a second has a time * scale of 60. */ private long timescale; /** * is an integer that declares length of the presentation (in the indicated timescale). This property is derived * from the presentation�s tracks: the value of this field corresponds to the duration of the longest track in the * presentation */ private long duration; /** indicates the preferred rate to play the presentation */ private double rate; /** indicates the preferred playback volume */ private double volume; /** provides a transformation matrix for the video */ private int[] matrix = new int[9]; private int[] predefined = new int[6]; /** * is a non-zero integer that indicates a value to use for the track ID of the next track to be added to this * presentation. Zero is not a valid track ID value. The value of next_track_ID shall be larger than the largest * track-ID in use. If this value is equal to all 1s (32-bit maxint), and a new mediatrack is to be added, then a * search must be made in the file for an unused track identifier. */ private int nextTrackID; private Calendar calendar = Calendar.getInstance(); public MovieHeaderBox(long size) { super(size, TYPE_S); } /** * Gets the creation time of this presentation. * * @return creation time */ public Date getCreationTime() { calendar.set(Calendar.YEAR, 1904); calendar.set(Calendar.MONTH, Calendar.JANUARY); calendar.set(Calendar.DATE, 1); calendar.set(Calendar.HOUR_OF_DAY, 0); calendar.set(Calendar.MINUTE, 0); calendar.set(Calendar.SECOND, 0); calendar.roll(Calendar.SECOND, (int) creationTime); return calendar.getTime(); } /** * Gets the modification time of this presentation. * * @return creation time */ public Date getModificationTime() { return new Date(modificationTime); } /** * Gets the time scale of this presentation. * * @return the number of time units that pass in one second. For example, a time coordinate system that measures * time in sixtieths of a second has a time scale of 60. */ public long getTimeScale() { return timescale; } /** * Gets duration of this presentation. * * @return an integer that declares length of the presentation (in the indicated timescale). This property is * derived from the presentation�s tracks: the value of this field corresponds to the duration of the * longest track in the presentation */ public long getDuration() { return duration; } /** * Gets the preffered rate to play the presentation. * * @return the rate value, value 1.0 is normal forward playback */ public double getRate() { return rate; } /** * Gets the preffered volume to play the presentation. * * @return the rate value, value 1.0 is full volume */ public double getVolume() { return volume; } public int[] getMatrix() { return matrix; } /** * Gets identifier of next track to use. * * @return a non-zero integer that indicates a value to use for the track ID */ public int getNextTrackID() { return nextTrackID; } @Override protected int load(DataInputStream fin) throws IOException { super.load(fin); if (this.getVersion() == 1) { this.creationTime = readU64(fin); this.modificationTime = readU64(fin); this.timescale = readU32(fin); this.duration = readU64(fin); } else { this.creationTime = readU32(fin); this.modificationTime = readU32(fin); this.timescale = readU32(fin); this.duration = readU32(fin); } // reading rate. it is a fixed point 16.16 number that indicates the // preferred rate to play the presentation int a = fin.readInt(); rate = (a >> 16) + (a & 0xffff) / 10; // reading volume. it is a fixed 8.8 number volume = fin.readByte() + fin.readByte() / 10; // skip reserved 16bits fin.readByte(); fin.readByte(); fin.readInt(); fin.readInt(); for (int i = 0; i < matrix.length; i++) { matrix[i] = fin.readInt(); } for (int i = 0; i < predefined.length; i++) { predefined[i] = fin.readInt(); } this.nextTrackID = fin.readInt(); return (int) this.getSize(); } }