Home | History | Annotate | Download | only in boxes
      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 
     17 package com.coremedia.iso.boxes;
     18 
     19 
     20 import com.coremedia.iso.IsoTypeReader;
     21 import com.coremedia.iso.IsoTypeWriter;
     22 import com.googlecode.mp4parser.AbstractFullBox;
     23 
     24 import java.nio.ByteBuffer;
     25 
     26 /**
     27  * This box specifies the characteristics of a single track. Exactly one Track Header Box is contained in a track.<br>
     28  * In the absence of an edit list, the presentation of a track starts at the beginning of the overall presentation. An
     29  * empty edit is used to offset the start time of a track. <br>
     30  * The default value of the track header flags for media tracks is 7 (track_enabled, track_in_movie,
     31  * track_in_preview). If in a presentation all tracks have neither track_in_movie nor track_in_preview set, then all
     32  * tracks shall be treated as if both flags were set on all tracks. Hint tracks should have the track header flags set
     33  * to 0, so that they are ignored for local playback and preview.
     34  */
     35 public class TrackHeaderBox extends AbstractFullBox {
     36 
     37     public static final String TYPE = "tkhd";
     38 
     39     private long creationTime;
     40     private long modificationTime;
     41     private long trackId;
     42     private long duration;
     43     private int layer;
     44     private int alternateGroup;
     45     private float volume;
     46     private long[] matrix = new long[]{0x00010000, 0, 0, 0, 0x00010000, 0, 0, 0, 0x40000000};
     47     private double width;
     48     private double height;
     49 
     50 
     51     public TrackHeaderBox() {
     52         super(TYPE);
     53 
     54     }
     55 
     56     public long getCreationTime() {
     57         return creationTime;
     58     }
     59 
     60     public long getModificationTime() {
     61         return modificationTime;
     62     }
     63 
     64     public long getTrackId() {
     65         return trackId;
     66     }
     67 
     68     public long getDuration() {
     69         return duration;
     70     }
     71 
     72     public int getLayer() {
     73         return layer;
     74     }
     75 
     76     public int getAlternateGroup() {
     77         return alternateGroup;
     78     }
     79 
     80     public float getVolume() {
     81         return volume;
     82     }
     83 
     84     public long[] getMatrix() {
     85         return matrix;
     86     }
     87 
     88     public double getWidth() {
     89         return width;
     90     }
     91 
     92     public double getHeight() {
     93         return height;
     94     }
     95 
     96     protected long getContentSize() {
     97         long contentSize = 4;
     98         if (getVersion() == 1) {
     99             contentSize += 32;
    100         } else {
    101             contentSize += 20;
    102         }
    103         contentSize += 60;
    104         return contentSize;
    105     }
    106 
    107     @Override
    108     public void _parseDetails(ByteBuffer content) {
    109         parseVersionAndFlags(content);
    110         if (getVersion() == 1) {
    111             creationTime = IsoTypeReader.readUInt64(content);
    112             modificationTime = IsoTypeReader.readUInt64(content);
    113             trackId = IsoTypeReader.readUInt32(content);
    114             IsoTypeReader.readUInt32(content);
    115             duration = IsoTypeReader.readUInt64(content);
    116         } else {
    117             creationTime = IsoTypeReader.readUInt32(content);
    118             modificationTime = IsoTypeReader.readUInt32(content);
    119             trackId = IsoTypeReader.readUInt32(content);
    120             IsoTypeReader.readUInt32(content);
    121             duration = IsoTypeReader.readUInt32(content);
    122         } // 196
    123         IsoTypeReader.readUInt32(content);
    124         IsoTypeReader.readUInt32(content);
    125         layer = IsoTypeReader.readUInt16(content);    // 204
    126         alternateGroup = IsoTypeReader.readUInt16(content);
    127         volume = IsoTypeReader.readFixedPoint88(content);
    128         IsoTypeReader.readUInt16(content);     // 212
    129         matrix = new long[9];
    130         for (int i = 0; i < 9; i++) {
    131             matrix[i] = IsoTypeReader.readUInt32(content);
    132         }
    133         width = IsoTypeReader.readFixedPoint1616(content);    // 248
    134         height = IsoTypeReader.readFixedPoint1616(content);
    135     }
    136 
    137     public void getContent(ByteBuffer byteBuffer) {
    138         writeVersionAndFlags(byteBuffer);
    139         if (getVersion() == 1) {
    140             IsoTypeWriter.writeUInt64(byteBuffer, creationTime);
    141             IsoTypeWriter.writeUInt64(byteBuffer, modificationTime);
    142             IsoTypeWriter.writeUInt32(byteBuffer, trackId);
    143             IsoTypeWriter.writeUInt32(byteBuffer, 0);
    144             IsoTypeWriter.writeUInt64(byteBuffer, duration);
    145         } else {
    146             IsoTypeWriter.writeUInt32(byteBuffer, creationTime);
    147             IsoTypeWriter.writeUInt32(byteBuffer, modificationTime);
    148             IsoTypeWriter.writeUInt32(byteBuffer, trackId);
    149             IsoTypeWriter.writeUInt32(byteBuffer, 0);
    150             IsoTypeWriter.writeUInt32(byteBuffer, duration);
    151         } // 196
    152         IsoTypeWriter.writeUInt32(byteBuffer, 0);
    153         IsoTypeWriter.writeUInt32(byteBuffer, 0);
    154         IsoTypeWriter.writeUInt16(byteBuffer, layer);
    155         IsoTypeWriter.writeUInt16(byteBuffer, alternateGroup);
    156         IsoTypeWriter.writeFixedPont88(byteBuffer, volume);
    157         IsoTypeWriter.writeUInt16(byteBuffer, 0);
    158         for (int i = 0; i < 9; i++) {
    159             IsoTypeWriter.writeUInt32(byteBuffer, matrix[i]);
    160         }
    161         IsoTypeWriter.writeFixedPont1616(byteBuffer, width);
    162         IsoTypeWriter.writeFixedPont1616(byteBuffer, height);
    163     }
    164 
    165     public String toString() {
    166         StringBuilder result = new StringBuilder();
    167         result.append("TrackHeaderBox[");
    168         result.append("creationTime=").append(getCreationTime());
    169         result.append(";");
    170         result.append("modificationTime=").append(getModificationTime());
    171         result.append(";");
    172         result.append("trackId=").append(getTrackId());
    173         result.append(";");
    174         result.append("duration=").append(getDuration());
    175         result.append(";");
    176         result.append("layer=").append(getLayer());
    177         result.append(";");
    178         result.append("alternateGroup=").append(getAlternateGroup());
    179         result.append(";");
    180         result.append("volume=").append(getVolume());
    181         for (int i = 0; i < matrix.length; i++) {
    182             result.append(";");
    183             result.append("matrix").append(i).append("=").append(matrix[i]);
    184         }
    185         result.append(";");
    186         result.append("width=").append(getWidth());
    187         result.append(";");
    188         result.append("height=").append(getHeight());
    189         result.append("]");
    190         return result.toString();
    191     }
    192 
    193     public void setCreationTime(long creationTime) {
    194         this.creationTime = creationTime;
    195     }
    196 
    197     public void setModificationTime(long modificationTime) {
    198         this.modificationTime = modificationTime;
    199     }
    200 
    201     public void setTrackId(long trackId) {
    202         this.trackId = trackId;
    203     }
    204 
    205     public void setDuration(long duration) {
    206         this.duration = duration;
    207     }
    208 
    209     public void setLayer(int layer) {
    210         this.layer = layer;
    211     }
    212 
    213     public void setAlternateGroup(int alternateGroup) {
    214         this.alternateGroup = alternateGroup;
    215     }
    216 
    217     public void setVolume(float volume) {
    218         this.volume = volume;
    219     }
    220 
    221     public void setMatrix(long[] matrix) {
    222         this.matrix = matrix;
    223     }
    224 
    225     public void setWidth(double width) {
    226         this.width = width;
    227     }
    228 
    229     public void setHeight(double height) {
    230         this.height = height;
    231     }
    232 
    233 
    234     public boolean isEnabled() {
    235         return (getFlags() & 1) > 0;
    236     }
    237 
    238     public boolean isInMovie() {
    239         return (getFlags() & 2) > 0;
    240     }
    241 
    242     public boolean isInPreview() {
    243         return (getFlags() & 4) > 0;
    244     }
    245 
    246     public boolean isInPoster() {
    247         return (getFlags() & 8) > 0;
    248     }
    249 }
    250