/* * Mobicents, Communications Middleware * * Copyright (c) 2008, Red Hat Middleware LLC or third-party * contributors as * indicated by the @author tags or express copyright attribution * statements applied by the authors. All third-party contributions are * distributed under license by Red Hat Middleware LLC. * * This copyrighted material is made available to anyone wishing to use, modify, * copy, or redistribute it subject to the terms and conditions of the GNU * Lesser General Public License, as published by the Free Software Foundation. * * This program 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 distribution; if not, write to: * Free Software Foundation, Inc. * 51 Franklin Street, Fifth Floor * * Boston, MA 02110-1301 USA */ package org.mobicents.media.server.impl.resource.video; import java.io.DataInputStream; import java.io.IOException; import java.util.Calendar; import java.util.Date; /** * This box defines overall information which is media-independent, and relevant to the entire presentation considered * as a whole. * * Box Type: mvhd Container: Movie Box Mandatory: Yes Quantity: Exactly one * * @author kulikov */ 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 int 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 int 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 = read64(fin); this.modificationTime = read64(fin); this.timescale = fin.readInt(); this.duration = read64(fin); } else { this.creationTime = fin.readInt(); this.modificationTime = fin.readInt(); this.timescale = fin.readInt(); this.duration = fin.readInt(); } // 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(); } }