summaryrefslogtreecommitdiff
path: root/isoparser/src/main/java/com/googlecode/mp4parser/boxes/mp4/objectdescriptors/.svn/text-base/DecoderConfigDescriptor.java.svn-base
blob: 69d603ae28e1e3419b0a16c1899d36ea6954f34f (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
/*
 * Copyright 2011 castLabs, Berlin
 *
 * Licensed under the Apache License, Version 2.0 (the License);
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an AS IS BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package com.googlecode.mp4parser.boxes.mp4.objectdescriptors;

import com.coremedia.iso.Hex;
import com.coremedia.iso.IsoTypeReader;
import com.coremedia.iso.IsoTypeWriter;

import java.io.IOException;
import java.nio.ByteBuffer;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.logging.Logger;

/**
 * class DecoderConfigDescriptor extends BaseDescriptor : bit(8)
 * tag=DecoderConfigDescrTag {
 * bit(8) objectTypeIndication;
 * bit(6) streamType;
 * bit(1) upStream;
 * const bit(1) reserved=1;
 * bit(24) bufferSizeDB;
 * bit(32) maxBitrate;
 * bit(32) avgBitrate;
 * DecoderSpecificInfo decSpecificInfo[0 .. 1];
 * profileLevelIndicationIndexDescriptor profileLevelIndicationIndexDescr
 * [0..255];
 * }
 */
@Descriptor(tags = {0x04})
public class DecoderConfigDescriptor extends BaseDescriptor {
    private static Logger log = Logger.getLogger(DecoderConfigDescriptor.class.getName());


    int objectTypeIndication;
    int streamType;
    int upStream;
    int bufferSizeDB;
    long maxBitRate;
    long avgBitRate;

    DecoderSpecificInfo decoderSpecificInfo;
    AudioSpecificConfig audioSpecificInfo;
    List<ProfileLevelIndicationDescriptor> profileLevelIndicationDescriptors = new ArrayList<ProfileLevelIndicationDescriptor>();
    byte[] configDescriptorDeadBytes;

    @Override
    public void parseDetail(ByteBuffer bb) throws IOException {
        objectTypeIndication = IsoTypeReader.readUInt8(bb);

        int data = IsoTypeReader.readUInt8(bb);
        streamType = data >>> 2;
        upStream = (data >> 1) & 0x1;

        bufferSizeDB = IsoTypeReader.readUInt24(bb);
        maxBitRate = IsoTypeReader.readUInt32(bb);
        avgBitRate = IsoTypeReader.readUInt32(bb);



        BaseDescriptor descriptor;
        if (bb.remaining() > 2) { //1byte tag + at least 1byte size
            final int begin = bb.position();
            descriptor = ObjectDescriptorFactory.createFrom(objectTypeIndication, bb);
            final int read = bb.position() - begin;
            log.finer(descriptor + " - DecoderConfigDescr1 read: " + read + ", size: " + (descriptor != null ? descriptor.getSize() : null));
            if (descriptor != null) {
                final int size = descriptor.getSize();
                if (read < size) {
                    //skip
                    configDescriptorDeadBytes = new byte[size - read];
                    bb.get(configDescriptorDeadBytes);
                }
            }
            if (descriptor instanceof DecoderSpecificInfo) {
                decoderSpecificInfo = (DecoderSpecificInfo) descriptor;
            }
            if (descriptor instanceof AudioSpecificConfig) {
                audioSpecificInfo = (AudioSpecificConfig) descriptor;
            }
        }

        while (bb.remaining() > 2) {
            final long begin = bb.position();
            descriptor = ObjectDescriptorFactory.createFrom(objectTypeIndication, bb);
            final long read = bb.position() - begin;
            log.finer(descriptor + " - DecoderConfigDescr2 read: " + read + ", size: " + (descriptor != null ? descriptor.getSize() : null));
            if (descriptor instanceof ProfileLevelIndicationDescriptor) {
                profileLevelIndicationDescriptors.add((ProfileLevelIndicationDescriptor) descriptor);
            }
        }
    }
    public int serializedSize() {
        return 15 + audioSpecificInfo.serializedSize();
    }

    public ByteBuffer serialize() {
        ByteBuffer out = ByteBuffer.allocate(serializedSize());
        IsoTypeWriter.writeUInt8(out, 4);
        IsoTypeWriter.writeUInt8(out, serializedSize() - 2);
        IsoTypeWriter.writeUInt8(out, objectTypeIndication);
        int flags = (streamType << 2) | (upStream << 1) | 1;
        IsoTypeWriter.writeUInt8(out, flags);
        IsoTypeWriter.writeUInt24(out, bufferSizeDB);
        IsoTypeWriter.writeUInt32(out, maxBitRate);
        IsoTypeWriter.writeUInt32(out, avgBitRate);
        out.put(audioSpecificInfo.serialize().array());
        return out;
    }

    public DecoderSpecificInfo getDecoderSpecificInfo() {
        return decoderSpecificInfo;
    }

    public AudioSpecificConfig getAudioSpecificInfo() {
        return audioSpecificInfo;
    }

    public void setAudioSpecificInfo(AudioSpecificConfig audioSpecificInfo) {
        this.audioSpecificInfo = audioSpecificInfo;
    }

    public List<ProfileLevelIndicationDescriptor> getProfileLevelIndicationDescriptors() {
        return profileLevelIndicationDescriptors;
    }

    public int getObjectTypeIndication() {
        return objectTypeIndication;
    }

    public void setObjectTypeIndication(int objectTypeIndication) {
        this.objectTypeIndication = objectTypeIndication;
    }

    public int getStreamType() {
        return streamType;
    }

    public void setStreamType(int streamType) {
        this.streamType = streamType;
    }

    public int getUpStream() {
        return upStream;
    }

    public void setUpStream(int upStream) {
        this.upStream = upStream;
    }

    public int getBufferSizeDB() {
        return bufferSizeDB;
    }

    public void setBufferSizeDB(int bufferSizeDB) {
        this.bufferSizeDB = bufferSizeDB;
    }

    public long getMaxBitRate() {
        return maxBitRate;
    }

    public void setMaxBitRate(long maxBitRate) {
        this.maxBitRate = maxBitRate;
    }

    public long getAvgBitRate() {
        return avgBitRate;
    }

    public void setAvgBitRate(long avgBitRate) {
        this.avgBitRate = avgBitRate;
    }

    @Override
    public String toString() {
        final StringBuilder sb = new StringBuilder();
        sb.append("DecoderConfigDescriptor");
        sb.append("{objectTypeIndication=").append(objectTypeIndication);
        sb.append(", streamType=").append(streamType);
        sb.append(", upStream=").append(upStream);
        sb.append(", bufferSizeDB=").append(bufferSizeDB);
        sb.append(", maxBitRate=").append(maxBitRate);
        sb.append(", avgBitRate=").append(avgBitRate);
        sb.append(", decoderSpecificInfo=").append(decoderSpecificInfo);
        sb.append(", audioSpecificInfo=").append(audioSpecificInfo);
        sb.append(", configDescriptorDeadBytes=").append(Hex.encodeHex(configDescriptorDeadBytes != null ? configDescriptorDeadBytes : new byte[]{}));
        sb.append(", profileLevelIndicationDescriptors=").append(profileLevelIndicationDescriptors == null ? "null" : Arrays.asList(profileLevelIndicationDescriptors).toString());
        sb.append('}');
        return sb.toString();
    }
    /*objectTypeIndication values
      0x00 Forbidden
    0x01 Systems ISO/IEC 14496-1 a
    0x02 Systems ISO/IEC 14496-1 b
    0x03 Interaction Stream
    0x04 Systems ISO/IEC 14496-1 Extended BIFS Configuration c
    0x05 Systems ISO/IEC 14496-1 AFX d
    0x06 Font Data Stream
    0x07 Synthesized Texture Stream
    0x08 Streaming Text Stream
    0x09-0x1F reserved for ISO use
    0x20 Visual ISO/IEC 14496-2 e
    0x21 Visual ITU-T Recommendation H.264 | ISO/IEC 14496-10 f
    0x22 Parameter Sets for ITU-T Recommendation H.264 | ISO/IEC 14496-10 f
    0x23-0x3F reserved for ISO use
    0x40 Audio ISO/IEC 14496-3 g
    0x41-0x5F reserved for ISO use
    0x60 Visual ISO/IEC 13818-2 Simple Profile
    0x61 Visual ISO/IEC 13818-2 Main Profile
    0x62 Visual ISO/IEC 13818-2 SNR Profile
    0x63 Visual ISO/IEC 13818-2 Spatial Profile
    0x64 Visual ISO/IEC 13818-2 High Profile
    0x65 Visual ISO/IEC 13818-2 422 Profile
    0x66 Audio ISO/IEC 13818-7 Main Profile
    0x67 Audio ISO/IEC 13818-7 LowComplexity Profile
    0x68 Audio ISO/IEC 13818-7 Scaleable Sampling Rate Profile
    0x69 Audio ISO/IEC 13818-3
    0x6A Visual ISO/IEC 11172-2
    0x6B Audio ISO/IEC 11172-3
    0x6C Visual ISO/IEC 10918-1
    0x6D reserved for registration authority i
    0x6E Visual ISO/IEC 15444-1
    0x6F - 0x9F reserved for ISO use
    0xA0 - 0xBF reserved for registration authority i
    0xC0 - 0xE0 user private
    0xE1 reserved for registration authority i
    0xE2 - 0xFE user private
    0xFF no object type specified h
    */
    /* streamType values
      0x00 Forbidden
    0x01 ObjectDescriptorStream (see 7.2.5)
    0x02 ClockReferenceStream (see 7.3.2.5)
    0x03 SceneDescriptionStream (see ISO/IEC 14496-11)
    0x04 VisualStream
    0x05 AudioStream
    0x06 MPEG7Stream
    0x07 IPMPStream (see 7.2.3.2)
    0x08 ObjectContentInfoStream (see 7.2.4.2)
    0x09 MPEGJStream
    0x0A Interaction Stream
    0x0B IPMPToolStream (see [ISO/IEC 14496-13])
    0x0C - 0x1F reserved for ISO use
    0x20 - 0x3F user private
    */
}