• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
TrackFragmentHeaderBox()48     public TrackFragmentHeaderBox() {
49         super(TYPE);
50     }
51 
getContentSize()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 
getContent(ByteBuffer byteBuffer)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
_parseDetails(ByteBuffer content)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 
hasBaseDataOffset()119     public boolean hasBaseDataOffset() {
120         return (getFlags() & 0x1) != 0;
121     }
122 
hasSampleDescriptionIndex()123     public boolean hasSampleDescriptionIndex() {
124         return (getFlags() & 0x2) != 0;
125     }
126 
hasDefaultSampleDuration()127     public boolean hasDefaultSampleDuration() {
128         return (getFlags() & 0x8) != 0;
129     }
130 
hasDefaultSampleSize()131     public boolean hasDefaultSampleSize() {
132         return (getFlags() & 0x10) != 0;
133     }
134 
hasDefaultSampleFlags()135     public boolean hasDefaultSampleFlags() {
136         return (getFlags() & 0x20) != 0;
137     }
138 
getTrackId()139     public long getTrackId() {
140         return trackId;
141     }
142 
getBaseDataOffset()143     public long getBaseDataOffset() {
144         return baseDataOffset;
145     }
146 
getSampleDescriptionIndex()147     public long getSampleDescriptionIndex() {
148         return sampleDescriptionIndex;
149     }
150 
getDefaultSampleDuration()151     public long getDefaultSampleDuration() {
152         return defaultSampleDuration;
153     }
154 
getDefaultSampleSize()155     public long getDefaultSampleSize() {
156         return defaultSampleSize;
157     }
158 
getDefaultSampleFlags()159     public SampleFlags getDefaultSampleFlags() {
160         return defaultSampleFlags;
161     }
162 
isDurationIsEmpty()163     public boolean isDurationIsEmpty() {
164         return durationIsEmpty;
165     }
166 
setTrackId(long trackId)167     public void setTrackId(long trackId) {
168         this.trackId = trackId;
169     }
170 
setBaseDataOffset(long baseDataOffset)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 
setSampleDescriptionIndex(long sampleDescriptionIndex)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 
setDefaultSampleDuration(long defaultSampleDuration)189     public void setDefaultSampleDuration(long defaultSampleDuration) {
190         setFlags(getFlags() | 0x8); // activate the field
191         this.defaultSampleDuration = defaultSampleDuration;
192     }
193 
setDefaultSampleSize(long defaultSampleSize)194     public void setDefaultSampleSize(long defaultSampleSize) {
195         setFlags(getFlags() | 0x10); // activate the field
196         this.defaultSampleSize = defaultSampleSize;
197     }
198 
setDefaultSampleFlags(SampleFlags defaultSampleFlags)199     public void setDefaultSampleFlags(SampleFlags defaultSampleFlags) {
200         setFlags(getFlags() | 0x20); // activate the field
201         this.defaultSampleFlags = defaultSampleFlags;
202     }
203 
setDurationIsEmpty(boolean durationIsEmpty)204     public void setDurationIsEmpty(boolean durationIsEmpty) {
205         setFlags(getFlags() | 0x10000); // activate the field
206         this.durationIsEmpty = durationIsEmpty;
207     }
208 
209     @Override
toString()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