• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 import com.coremedia.iso.IsoTypeReader;
20 import com.coremedia.iso.IsoTypeWriter;
21 import com.googlecode.mp4parser.AbstractFullBox;
22 
23 import java.nio.ByteBuffer;
24 import java.util.ArrayList;
25 import java.util.Collections;
26 import java.util.Iterator;
27 import java.util.LinkedList;
28 import java.util.List;
29 
30 import static com.googlecode.mp4parser.util.CastUtils.l2i;
31 
32 /**
33  * Samples within the media data are grouped into chunks. Chunks can be of different sizes, and the
34  * samples within a chunk can have different sizes. This table can be used to find the chunk that
35  * contains a sample, its position, and the associated sample description. Defined in ISO/IEC 14496-12.
36  */
37 public class SampleToChunkBox extends AbstractFullBox {
38     List<Entry> entries = Collections.emptyList();
39 
40     public static final String TYPE = "stsc";
41 
SampleToChunkBox()42     public SampleToChunkBox() {
43         super(TYPE);
44     }
45 
getEntries()46     public List<Entry> getEntries() {
47         return entries;
48     }
49 
setEntries(List<Entry> entries)50     public void setEntries(List<Entry> entries) {
51         this.entries = entries;
52     }
53 
getContentSize()54     protected long getContentSize() {
55         return entries.size() * 12 + 8;
56     }
57 
58     @Override
_parseDetails(ByteBuffer content)59     public void _parseDetails(ByteBuffer content) {
60         parseVersionAndFlags(content);
61 
62         int entryCount = l2i(IsoTypeReader.readUInt32(content));
63         entries = new ArrayList<Entry>(entryCount);
64         for (int i = 0; i < entryCount; i++) {
65             entries.add(new Entry(
66                     IsoTypeReader.readUInt32(content),
67                     IsoTypeReader.readUInt32(content),
68                     IsoTypeReader.readUInt32(content)));
69         }
70     }
71 
72     @Override
getContent(ByteBuffer byteBuffer)73     protected void getContent(ByteBuffer byteBuffer) {
74         writeVersionAndFlags(byteBuffer);
75         IsoTypeWriter.writeUInt32(byteBuffer, entries.size());
76         for (Entry entry : entries) {
77             IsoTypeWriter.writeUInt32(byteBuffer, entry.getFirstChunk());
78             IsoTypeWriter.writeUInt32(byteBuffer, entry.getSamplesPerChunk());
79             IsoTypeWriter.writeUInt32(byteBuffer, entry.getSampleDescriptionIndex());
80         }
81     }
82 
toString()83     public String toString() {
84         return "SampleToChunkBox[entryCount=" + entries.size() + "]";
85     }
86 
87     /**
88      * Decompresses the list of entries and returns the number of samples per chunk for
89      * every single chunk.
90      *
91      * @param chunkCount overall number of chunks
92      * @return number of samples per chunk
93      */
blowup(int chunkCount)94     public long[] blowup(int chunkCount) {
95         long[] numberOfSamples = new long[chunkCount];
96         int j = 0;
97         List<SampleToChunkBox.Entry> sampleToChunkEntries = new LinkedList<Entry>(entries);
98         Collections.reverse(sampleToChunkEntries);
99         Iterator<Entry> iterator = sampleToChunkEntries.iterator();
100         SampleToChunkBox.Entry currentEntry = iterator.next();
101 
102         for (int i = numberOfSamples.length; i > 1; i--) {
103             numberOfSamples[i - 1] = currentEntry.getSamplesPerChunk();
104             if (i == currentEntry.getFirstChunk()) {
105                 currentEntry = iterator.next();
106             }
107         }
108         numberOfSamples[0] = currentEntry.getSamplesPerChunk();
109         return numberOfSamples;
110     }
111 
112     public static class Entry {
113         long firstChunk;
114         long samplesPerChunk;
115         long sampleDescriptionIndex;
116 
Entry(long firstChunk, long samplesPerChunk, long sampleDescriptionIndex)117         public Entry(long firstChunk, long samplesPerChunk, long sampleDescriptionIndex) {
118             this.firstChunk = firstChunk;
119             this.samplesPerChunk = samplesPerChunk;
120             this.sampleDescriptionIndex = sampleDescriptionIndex;
121         }
122 
getFirstChunk()123         public long getFirstChunk() {
124             return firstChunk;
125         }
126 
setFirstChunk(long firstChunk)127         public void setFirstChunk(long firstChunk) {
128             this.firstChunk = firstChunk;
129         }
130 
getSamplesPerChunk()131         public long getSamplesPerChunk() {
132             return samplesPerChunk;
133         }
134 
setSamplesPerChunk(long samplesPerChunk)135         public void setSamplesPerChunk(long samplesPerChunk) {
136             this.samplesPerChunk = samplesPerChunk;
137         }
138 
getSampleDescriptionIndex()139         public long getSampleDescriptionIndex() {
140             return sampleDescriptionIndex;
141         }
142 
setSampleDescriptionIndex(long sampleDescriptionIndex)143         public void setSampleDescriptionIndex(long sampleDescriptionIndex) {
144             this.sampleDescriptionIndex = sampleDescriptionIndex;
145         }
146 
147         @Override
toString()148         public String toString() {
149             return "Entry{" +
150                     "firstChunk=" + firstChunk +
151                     ", samplesPerChunk=" + samplesPerChunk +
152                     ", sampleDescriptionIndex=" + sampleDescriptionIndex +
153                     '}';
154         }
155     }
156 }
157