/*
* Copyright (C) 2011 in-somnia
*
* This file is part of JAAD.
*
* JAAD 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 3 of the
* License, or (at your option) any later version.
*
* JAAD 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 library.
* If not, see <http://www.gnu.org/licenses/>.
*/
package net.sourceforge.jaad.mp4.boxes.impl;
import net.sourceforge.jaad.mp4.MP4InputStream;
import java.io.IOException;
import net.sourceforge.jaad.mp4.boxes.FullBox;
import net.sourceforge.jaad.mp4.boxes.Utils;
/**
* This box specifies the characteristics of a single track. Exactly one Track
* Header Box is contained in a track. In the absence of an edit list, the
* presentation of a track starts at the beginning of the overall presentation.
* An empty edit is used to offset the start time of a track.
* If in a presentation all tracks have neither trackInMovie nor trackInPreview
* set, then all tracks shall be treated as if both flags were set on all
* tracks. Hint tracks should not have the track header flags set, so that they
* are ignored for local playback and preview.
* The width and height in the track header are measured on a notional 'square'
* (uniform) grid. Track video data is normalized to these dimensions
* (logically) before any transformation or placement caused by a layup or
* composition system. Track (and movie) matrices, if used, also operate in this
* uniformly-scaled space.
* @author in-somnia
*/
public class TrackHeaderBox extends FullBox {
private boolean enabled, inMovie, inPreview;
private long creationTime, modificationTime, duration;
private int trackID, layer, alternateGroup;
private double volume, width, height;
private double[] matrix;
public TrackHeaderBox() {
super("Track Header Box");
matrix = new double[9];
}
@Override
public void decode(MP4InputStream in) throws IOException {
super.decode(in);
enabled = (flags&1)==1;
inMovie = (flags&2)==2;
inPreview = (flags&4)==4;
final int len = (version==1) ? 8 : 4;
creationTime = in.readBytes(len);
modificationTime = in.readBytes(len);
trackID = (int) in.readBytes(4);
in.skipBytes(4); //reserved
duration = Utils.detectUndetermined(in.readBytes(len));
in.skipBytes(8); //reserved
layer = (int) in.readBytes(2);
alternateGroup = (int) in.readBytes(2);
volume = in.readFixedPoint(8, 8);
in.skipBytes(2); //reserved
for(int i = 0; i<9; i++) {
if(i<6) matrix[i] = in.readFixedPoint(16, 16);
else matrix[i] = in.readFixedPoint(2, 30);
}
width = in.readFixedPoint(16, 16);
height = in.readFixedPoint(16, 16);
}
/**
* A flag indicating that the track is enabled. A disabled track is treated
* as if it were not present.
* @return true if the track is enabled
*/
public boolean isTrackEnabled() {
return enabled;
}
/**
* A flag indicating that the track is used in the presentation.
* @return true if the track is used
*/
public boolean isTrackInMovie() {
return inMovie;
}
/**
* A flag indicating that the track is used when previewing the
* presentation.
* @return true if the track is used in previews
*/
public boolean isTrackInPreview() {
return inPreview;
}
/**
* The creation time is an integer that declares the creation time of the
* presentation in seconds since midnight, Jan. 1, 1904, in UTC time.
* @return the creation time
*/
public long getCreationTime() {
return creationTime;
}
/**
* The modification time is an integer that declares the most recent time
* the presentation was modified in seconds since midnight, Jan. 1, 1904,
* in UTC time.
*/
public long getModificationTime() {
return modificationTime;
}
/**
* The track ID is an integer that uniquely identifies this track over the
* entire life-time of this presentation. Track IDs are never re-used and
* cannot be zero.
* @return the track's ID
*/
public int getTrackID() {
return trackID;
}
/**
* The duration is an integer that indicates the duration of this track (in
* the timescale indicated in the Movie Header Box). The value of this field
* is equal to the sum of the durations of all of the track's edits. If
* there is no edit list, then the duration is the sum of the sample
* durations, converted into the timescale in the Movie Header Box. If the
* duration of this track cannot be determined then this value is -1.
* @return the duration this track
*/
public long getDuration() {
return duration;
}
/**
* The layer specifies the front-to-back ordering of video tracks; tracks
* with lower numbers are closer to the viewer. 0 is the normal value, and
* -1 would be in front of track 0, and so on.
* @return the layer
*/
public int getLayer() {
return layer;
}
/**
* The alternate group is an integer that specifies a group or collection
* of tracks. If this field is 0 there is no information on possible
* relations to other tracks. If this field is not 0, it should be the same
* for tracks that contain alternate data for one another and different for
* tracks belonging to different such groups. Only one track within an
* alternate group should be played or streamed at any one time, and must be
* distinguishable from other tracks in the group via attributes such as
* bitrate, codec, language, packet size etc. A group may have only one
* member.
* @return the alternate group
*/
public int getAlternateGroup() {
return alternateGroup;
}
/**
* The volume is a floating point number that indicates the preferred
* playback volume: 0.0 is mute, 1.0 is normal volume.
* @return the volume
*/
public double getVolume() {
return volume;
}
/**
* The width specifies the track's visual presentation width as a floating
* point values. This needs not be the same as the pixel width of the
* images, which is documented in the sample description(s); all images in
* the sequence are scaled to this width, before any overall transformation
* of the track represented by the matrix. The pixel dimensions of the
* images are the default values.
* @return the image width
*/
public double getWidth() {
return width;
}
/**
* The height specifies the track's visual presentation height as a floating
* point value. This needs not be the same as the pixel height of the
* images, which is documented in the sample description(s); all images in
* the sequence are scaled to this height, before any overall transformation
* of the track represented by the matrix. The pixel dimensions of the
* images are the default values.
* @return the image height
*/
public double getHeight() {
return height;
}
public double[] getMatrix() {
return matrix;
}
}