Home | History | Annotate | Download | only in fragment
      1 /*
      2  * Copyright 2009 castLabs GmbH, Berlin
      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.fragment;
     18 
     19 import com.coremedia.iso.IsoTypeReader;
     20 import com.coremedia.iso.IsoTypeWriter;
     21 import com.googlecode.mp4parser.AbstractFullBox;
     22 
     23 import java.nio.ByteBuffer;
     24 
     25 /**
     26  * aligned(8) class TrackFragmentHeaderBox
     27  * extends FullBox('tfhd', 0, tf_flags){
     28  * unsigned int(32) track_ID;
     29  * // all the following are optional fields
     30  * unsigned int(64) base_data_offset;
     31  * unsigned int(32) sample_description_index;
     32  * unsigned int(32) default_sample_duration;
     33  * unsigned int(32) default_sample_size;
     34  * unsigned int(32) default_sample_flags
     35  * }
     36  */
     37 public class TrackFragmentHeaderBox extends AbstractFullBox {
     38     public static final String TYPE = "tfhd";
     39 
     40     private long trackId;
     41     private long baseDataOffset = -1;
     42     private long sampleDescriptionIndex;
     43     private long defaultSampleDuration = -1;
     44     private long defaultSampleSize = -1;
     45     private SampleFlags defaultSampleFlags;
     46     private boolean durationIsEmpty;
     47 
     48     public TrackFragmentHeaderBox() {
     49         super(TYPE);
     50     }
     51 
     52     protected long getContentSize() {
     53         long size = 8;
     54         int flags = getFlags();
     55         if ((flags & 0x1) == 1) { //baseDataOffsetPresent
     56             size += 8;
     57         }
     58         if ((flags & 0x2) == 0x2) { //sampleDescriptionIndexPresent
     59             size += 4;
     60         }
     61         if ((flags & 0x8) == 0x8) { //defaultSampleDurationPresent
     62             size += 4;
     63         }
     64         if ((flags & 0x10) == 0x10) { //defaultSampleSizePresent
     65             size += 4;
     66         }
     67         if ((flags & 0x20) == 0x20) { //defaultSampleFlagsPresent
     68             size += 4;
     69         }
     70         return size;
     71     }
     72 
     73 
     74     protected void getContent(ByteBuffer byteBuffer) {
     75         writeVersionAndFlags(byteBuffer);
     76         IsoTypeWriter.writeUInt32(byteBuffer, trackId);
     77 
     78         if ((getFlags() & 0x1) == 1) { //baseDataOffsetPresent
     79             IsoTypeWriter.writeUInt64(byteBuffer, getBaseDataOffset());
     80         }
     81         if ((getFlags() & 0x2) == 0x2) { //sampleDescriptionIndexPresent
     82             IsoTypeWriter.writeUInt32(byteBuffer, getSampleDescriptionIndex());
     83         }
     84         if ((getFlags() & 0x8) == 0x8) { //defaultSampleDurationPresent
     85             IsoTypeWriter.writeUInt32(byteBuffer, getDefaultSampleDuration());
     86         }
     87         if ((getFlags() & 0x10) == 0x10) { //defaultSampleSizePresent
     88             IsoTypeWriter.writeUInt32(byteBuffer, getDefaultSampleSize());
     89         }
     90         if ((getFlags() & 0x20) == 0x20) { //defaultSampleFlagsPresent
     91             defaultSampleFlags.getContent(byteBuffer);
     92         }
     93     }
     94 
     95     @Override
     96     public void _parseDetails(ByteBuffer content) {
     97         parseVersionAndFlags(content);
     98         trackId = IsoTypeReader.readUInt32(content);
     99         if ((getFlags() & 0x1) == 1) { //baseDataOffsetPresent
    100             baseDataOffset = IsoTypeReader.readUInt64(content);
    101         }
    102         if ((getFlags() & 0x2) == 0x2) { //sampleDescriptionIndexPresent
    103             sampleDescriptionIndex = IsoTypeReader.readUInt32(content);
    104         }
    105         if ((getFlags() & 0x8) == 0x8) { //defaultSampleDurationPresent
    106             defaultSampleDuration = IsoTypeReader.readUInt32(content);
    107         }
    108         if ((getFlags() & 0x10) == 0x10) { //defaultSampleSizePresent
    109             defaultSampleSize = IsoTypeReader.readUInt32(content);
    110         }
    111         if ((getFlags() & 0x20) == 0x20) { //defaultSampleFlagsPresent
    112             defaultSampleFlags = new SampleFlags(content);
    113         }
    114         if ((getFlags() & 0x10000) == 0x10000) { //durationIsEmpty
    115             durationIsEmpty = true;
    116         }
    117     }
    118 
    119     public boolean hasBaseDataOffset() {
    120         return (getFlags() & 0x1) != 0;
    121     }
    122 
    123     public boolean hasSampleDescriptionIndex() {
    124         return (getFlags() & 0x2) != 0;
    125     }
    126 
    127     public boolean hasDefaultSampleDuration() {
    128         return (getFlags() & 0x8) != 0;
    129     }
    130 
    131     public boolean hasDefaultSampleSize() {
    132         return (getFlags() & 0x10) != 0;
    133     }
    134 
    135     public boolean hasDefaultSampleFlags() {
    136         return (getFlags() & 0x20) != 0;
    137     }
    138 
    139     public long getTrackId() {
    140         return trackId;
    141     }
    142 
    143     public long getBaseDataOffset() {
    144         return baseDataOffset;
    145     }
    146 
    147     public long getSampleDescriptionIndex() {
    148         return sampleDescriptionIndex;
    149     }
    150 
    151     public long getDefaultSampleDuration() {
    152         return defaultSampleDuration;
    153     }
    154 
    155     public long getDefaultSampleSize() {
    156         return defaultSampleSize;
    157     }
    158 
    159     public SampleFlags getDefaultSampleFlags() {
    160         return defaultSampleFlags;
    161     }
    162 
    163     public boolean isDurationIsEmpty() {
    164         return durationIsEmpty;
    165     }
    166 
    167     public void setTrackId(long trackId) {
    168         this.trackId = trackId;
    169     }
    170 
    171     public void setBaseDataOffset(long baseDataOffset) {
    172         if (baseDataOffset == -1) {
    173             setFlags(getFlags() & (Integer.MAX_VALUE ^ 0x1));
    174         } else {
    175             setFlags(getFlags() | 0x1); // activate the field
    176         }
    177         this.baseDataOffset = baseDataOffset;
    178     }
    179 
    180     public void setSampleDescriptionIndex(long sampleDescriptionIndex) {
    181         if (sampleDescriptionIndex == -1) {
    182             setFlags(getFlags() & (Integer.MAX_VALUE ^ 0x2));
    183         } else {
    184             setFlags(getFlags() | 0x2); // activate the field
    185         }
    186         this.sampleDescriptionIndex = sampleDescriptionIndex;
    187     }
    188 
    189     public void setDefaultSampleDuration(long defaultSampleDuration) {
    190         setFlags(getFlags() | 0x8); // activate the field
    191         this.defaultSampleDuration = defaultSampleDuration;
    192     }
    193 
    194     public void setDefaultSampleSize(long defaultSampleSize) {
    195         setFlags(getFlags() | 0x10); // activate the field
    196         this.defaultSampleSize = defaultSampleSize;
    197     }
    198 
    199     public void setDefaultSampleFlags(SampleFlags defaultSampleFlags) {
    200         setFlags(getFlags() | 0x20); // activate the field
    201         this.defaultSampleFlags = defaultSampleFlags;
    202     }
    203 
    204     public void setDurationIsEmpty(boolean durationIsEmpty) {
    205         setFlags(getFlags() | 0x10000); // activate the field
    206         this.durationIsEmpty = durationIsEmpty;
    207     }
    208 
    209     @Override
    210     public String toString() {
    211         final StringBuilder sb = new StringBuilder();
    212         sb.append("TrackFragmentHeaderBox");
    213         sb.append("{trackId=").append(trackId);
    214         sb.append(", baseDataOffset=").append(baseDataOffset);
    215         sb.append(", sampleDescriptionIndex=").append(sampleDescriptionIndex);
    216         sb.append(", defaultSampleDuration=").append(defaultSampleDuration);
    217         sb.append(", defaultSampleSize=").append(defaultSampleSize);
    218         sb.append(", defaultSampleFlags=").append(defaultSampleFlags);
    219         sb.append(", durationIsEmpty=").append(durationIsEmpty);
    220         sb.append('}');
    221         return sb.toString();
    222     }
    223 
    224 }
    225