ESDescriptor.java revision dd9eb897ee7c7b507cbdcf80263bb4b5de6966bf
1/*
2 * Copyright 2011 castLabs, 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
17package com.googlecode.mp4parser.boxes.mp4.objectdescriptors;
18
19import com.coremedia.iso.IsoTypeReader;
20import com.coremedia.iso.IsoTypeWriter;
21
22import java.io.IOException;
23import java.nio.ByteBuffer;
24import java.util.ArrayList;
25import java.util.List;
26import java.util.logging.Logger;
27
28/*
29class ES_Descriptor extends BaseDescriptor : bit(8) tag=ES_DescrTag {
30bit(16) ES_ID;
31bit(1) streamDependenceFlag;
32bit(1) URL_Flag;
33bit(1) OCRstreamFlag;
34bit(5) streamPriority;
35if (streamDependenceFlag)
36bit(16) dependsOn_ES_ID;
37if (URL_Flag) {
38bit(8) URLlength;
39bit(8) URLstring[URLlength];
40}
41if (OCRstreamFlag)
42bit(16) OCR_ES_Id;
43DecoderConfigDescriptor decConfigDescr;
44if (ODProfileLevelIndication==0x01) //no SL extension.
45{
46SLConfigDescriptor slConfigDescr;
47}
48else // SL extension is possible.
49{
50SLConfigDescriptor slConfigDescr;
51}
52IPI_DescrPointer ipiPtr[0 .. 1];
53IP_IdentificationDataSet ipIDS[0 .. 255];
54IPMP_DescriptorPointer ipmpDescrPtr[0 .. 255];
55LanguageDescriptor langDescr[0 .. 255];
56QoS_Descriptor qosDescr[0 .. 1];
57RegistrationDescriptor regDescr[0 .. 1];
58ExtensionDescriptor extDescr[0 .. 255];
59}
60 */
61@Descriptor(tags = {0x03})
62public class ESDescriptor extends BaseDescriptor {
63    private static Logger log = Logger.getLogger(ESDescriptor.class.getName());
64
65    int esId;
66    int streamDependenceFlag;
67    int URLFlag;
68    int oCRstreamFlag;
69    int streamPriority;
70
71
72    int URLLength = 0;
73    String URLString;
74    int remoteODFlag;
75
76    int dependsOnEsId;
77    int oCREsId;
78
79    DecoderConfigDescriptor decoderConfigDescriptor;
80    SLConfigDescriptor slConfigDescriptor;
81    List<BaseDescriptor> otherDescriptors = new ArrayList<BaseDescriptor>();
82
83    @Override
84    public void parseDetail(ByteBuffer bb) throws IOException {
85        esId = IsoTypeReader.readUInt16(bb);
86
87        int data = IsoTypeReader.readUInt8(bb);
88        streamDependenceFlag = data >>> 7;
89        URLFlag = (data >>> 6) & 0x1;
90        oCRstreamFlag = (data >>> 5) & 0x1;
91        streamPriority = data & 0x1f;
92
93        if (streamDependenceFlag == 1) {
94            dependsOnEsId = IsoTypeReader.readUInt16(bb);
95        }
96        if (URLFlag == 1) {
97            URLLength = IsoTypeReader.readUInt8(bb);
98            URLString = IsoTypeReader.readString(bb, URLLength);
99        }
100        if (oCRstreamFlag == 1) {
101            oCREsId = IsoTypeReader.readUInt16(bb);
102        }
103
104        int baseSize = 1 /*tag*/ + getSizeBytes() + 2 + 1 + (streamDependenceFlag == 1 ? 2 : 0) + (URLFlag == 1 ? 1 + URLLength : 0) + (oCRstreamFlag == 1 ? 2 : 0);
105
106        int begin = bb.position();
107        if (getSize() > baseSize + 2) {
108            BaseDescriptor descriptor = ObjectDescriptorFactory.createFrom(-1, bb);
109            final long read = bb.position() - begin;
110            log.finer(descriptor + " - ESDescriptor1 read: " + read + ", size: " + (descriptor != null ? descriptor.getSize() : null));
111            if (descriptor != null) {
112                final int size = descriptor.getSize();
113                bb.position(begin + size);
114                baseSize += size;
115            } else {
116                baseSize += read;
117            }
118            if (descriptor instanceof DecoderConfigDescriptor) {
119                decoderConfigDescriptor = (DecoderConfigDescriptor) descriptor;
120            }
121        }
122
123        begin = bb.position();
124        if (getSize() > baseSize + 2) {
125            BaseDescriptor descriptor = ObjectDescriptorFactory.createFrom(-1, bb);
126            final long read = bb.position() - begin;
127            log.finer(descriptor + " - ESDescriptor2 read: " + read + ", size: " + (descriptor != null ? descriptor.getSize() : null));
128            if (descriptor != null) {
129                final int size = descriptor.getSize();
130                bb.position(begin + size);
131                baseSize += size;
132            } else {
133                baseSize += read;
134            }
135            if (descriptor instanceof SLConfigDescriptor) {
136                slConfigDescriptor = (SLConfigDescriptor) descriptor;
137            }
138        } else {
139            log.warning("SLConfigDescriptor is missing!");
140        }
141
142        while (getSize() - baseSize > 2) {
143            begin = bb.position();
144            BaseDescriptor descriptor = ObjectDescriptorFactory.createFrom(-1, bb);
145            final long read = bb.position() - begin;
146            log.finer(descriptor + " - ESDescriptor3 read: " + read + ", size: " + (descriptor != null ? descriptor.getSize() : null));
147            if (descriptor != null) {
148                final int size = descriptor.getSize();
149                bb.position(begin + size);
150                baseSize += size;
151            } else {
152                baseSize += read;
153            }
154            otherDescriptors.add(descriptor);
155        }
156    }
157    public int serializedSize() {
158        int out = 5;
159        if (streamDependenceFlag > 0) {
160            out += 2;
161        }
162        if (URLFlag > 0) {
163            out += 1 + URLLength;
164        }
165        if (oCRstreamFlag > 0) {
166            out += 2;
167        }
168
169        out += decoderConfigDescriptor.serializedSize();
170        out += slConfigDescriptor.serializedSize();
171
172        // Doesn't handle other descriptors yet
173
174        return out;
175    }
176
177    public ByteBuffer serialize() {
178        ByteBuffer out = ByteBuffer.allocate(serializedSize()); // Usually is around 30 bytes, so 200 should be enough...
179        IsoTypeWriter.writeUInt8(out, 3);
180        IsoTypeWriter.writeUInt8(out, serializedSize() - 2); // Not OK for longer sizes!
181        IsoTypeWriter.writeUInt16(out, esId);
182        int flags = (streamDependenceFlag << 7) | (URLFlag << 6) | (oCRstreamFlag << 5) | (streamPriority & 0x1f);
183        IsoTypeWriter.writeUInt8(out, flags);
184        if (streamDependenceFlag > 0) {
185            IsoTypeWriter.writeUInt16(out, dependsOnEsId);
186        }
187        if (URLFlag > 0) {
188            IsoTypeWriter.writeUInt8(out, URLLength);
189            IsoTypeWriter.writeUtf8String(out, URLString);
190        }
191        if (oCRstreamFlag > 0) {
192            IsoTypeWriter.writeUInt16(out, oCREsId);
193        }
194
195        ByteBuffer dec = decoderConfigDescriptor.serialize();
196        ByteBuffer sl = slConfigDescriptor.serialize();
197        out.put(dec.array());
198        out.put(sl.array());
199
200        // Doesn't handle other descriptors yet
201
202        return out;
203    }
204
205//  @Override
206//  public int getSize() {
207//    return 3 + (streamDependenceFlag == 1 ? 2 : 0) +
208//            (URLFlag == 1 ? 1 + 8 * URLLength : 0) +
209//            (oCRstreamFlag == 1 ? 2 : 0);
210//  }
211
212    public DecoderConfigDescriptor getDecoderConfigDescriptor() {
213        return decoderConfigDescriptor;
214    }
215
216    public SLConfigDescriptor getSlConfigDescriptor() {
217        return slConfigDescriptor;
218    }
219
220    public void setDecoderConfigDescriptor(DecoderConfigDescriptor decoderConfigDescriptor) {
221        this.decoderConfigDescriptor = decoderConfigDescriptor;
222    }
223
224    public void setSlConfigDescriptor(SLConfigDescriptor slConfigDescriptor) {
225        this.slConfigDescriptor = slConfigDescriptor;
226    }
227
228    public List<BaseDescriptor> getOtherDescriptors() {
229        return otherDescriptors;
230    }
231
232    public int getoCREsId() {
233        return oCREsId;
234    }
235
236    public void setoCREsId(int oCREsId) {
237        this.oCREsId = oCREsId;
238    }
239
240    public int getEsId() {
241        return esId;
242    }
243
244    public void setEsId(int esId) {
245        this.esId = esId;
246    }
247
248    public int getStreamDependenceFlag() {
249        return streamDependenceFlag;
250    }
251
252    public void setStreamDependenceFlag(int streamDependenceFlag) {
253        this.streamDependenceFlag = streamDependenceFlag;
254    }
255
256    public int getURLFlag() {
257        return URLFlag;
258    }
259
260    public void setURLFlag(int URLFlag) {
261        this.URLFlag = URLFlag;
262    }
263
264    public int getoCRstreamFlag() {
265        return oCRstreamFlag;
266    }
267
268    public void setoCRstreamFlag(int oCRstreamFlag) {
269        this.oCRstreamFlag = oCRstreamFlag;
270    }
271
272    public int getStreamPriority() {
273        return streamPriority;
274    }
275
276    public void setStreamPriority(int streamPriority) {
277        this.streamPriority = streamPriority;
278    }
279
280    public int getURLLength() {
281        return URLLength;
282    }
283
284    public void setURLLength(int URLLength) {
285        this.URLLength = URLLength;
286    }
287
288    public String getURLString() {
289        return URLString;
290    }
291
292    public void setURLString(String URLString) {
293        this.URLString = URLString;
294    }
295
296    public int getRemoteODFlag() {
297        return remoteODFlag;
298    }
299
300    public void setRemoteODFlag(int remoteODFlag) {
301        this.remoteODFlag = remoteODFlag;
302    }
303
304    public int getDependsOnEsId() {
305        return dependsOnEsId;
306    }
307
308    public void setDependsOnEsId(int dependsOnEsId) {
309        this.dependsOnEsId = dependsOnEsId;
310    }
311
312    @Override
313    public String toString() {
314        final StringBuilder sb = new StringBuilder();
315        sb.append("ESDescriptor");
316        sb.append("{esId=").append(esId);
317        sb.append(", streamDependenceFlag=").append(streamDependenceFlag);
318        sb.append(", URLFlag=").append(URLFlag);
319        sb.append(", oCRstreamFlag=").append(oCRstreamFlag);
320        sb.append(", streamPriority=").append(streamPriority);
321        sb.append(", URLLength=").append(URLLength);
322        sb.append(", URLString='").append(URLString).append('\'');
323        sb.append(", remoteODFlag=").append(remoteODFlag);
324        sb.append(", dependsOnEsId=").append(dependsOnEsId);
325        sb.append(", oCREsId=").append(oCREsId);
326        sb.append(", decoderConfigDescriptor=").append(decoderConfigDescriptor);
327        sb.append(", slConfigDescriptor=").append(slConfigDescriptor);
328        sb.append('}');
329        return sb.toString();
330    }
331
332    @Override
333    public boolean equals(Object o) {
334        if (this == o) return true;
335        if (o == null || getClass() != o.getClass()) return false;
336
337        ESDescriptor that = (ESDescriptor) o;
338
339        if (URLFlag != that.URLFlag) return false;
340        if (URLLength != that.URLLength) return false;
341        if (dependsOnEsId != that.dependsOnEsId) return false;
342        if (esId != that.esId) return false;
343        if (oCREsId != that.oCREsId) return false;
344        if (oCRstreamFlag != that.oCRstreamFlag) return false;
345        if (remoteODFlag != that.remoteODFlag) return false;
346        if (streamDependenceFlag != that.streamDependenceFlag) return false;
347        if (streamPriority != that.streamPriority) return false;
348        if (URLString != null ? !URLString.equals(that.URLString) : that.URLString != null) return false;
349        if (decoderConfigDescriptor != null ? !decoderConfigDescriptor.equals(that.decoderConfigDescriptor) : that.decoderConfigDescriptor != null)
350            return false;
351        if (otherDescriptors != null ? !otherDescriptors.equals(that.otherDescriptors) : that.otherDescriptors != null)
352            return false;
353        if (slConfigDescriptor != null ? !slConfigDescriptor.equals(that.slConfigDescriptor) : that.slConfigDescriptor != null)
354            return false;
355
356        return true;
357    }
358
359    @Override
360    public int hashCode() {
361        int result = esId;
362        result = 31 * result + streamDependenceFlag;
363        result = 31 * result + URLFlag;
364        result = 31 * result + oCRstreamFlag;
365        result = 31 * result + streamPriority;
366        result = 31 * result + URLLength;
367        result = 31 * result + (URLString != null ? URLString.hashCode() : 0);
368        result = 31 * result + remoteODFlag;
369        result = 31 * result + dependsOnEsId;
370        result = 31 * result + oCREsId;
371        result = 31 * result + (decoderConfigDescriptor != null ? decoderConfigDescriptor.hashCode() : 0);
372        result = 31 * result + (slConfigDescriptor != null ? slConfigDescriptor.hashCode() : 0);
373        result = 31 * result + (otherDescriptors != null ? otherDescriptors.hashCode() : 0);
374        return result;
375    }
376}
377