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 17 package com.googlecode.mp4parser.boxes.mp4.objectdescriptors; 18 19 import com.coremedia.iso.Hex; 20 import com.coremedia.iso.IsoTypeReader; 21 import com.coremedia.iso.IsoTypeWriter; 22 23 import java.io.IOException; 24 import java.nio.ByteBuffer; 25 import java.util.ArrayList; 26 import java.util.Arrays; 27 import java.util.List; 28 import java.util.logging.Logger; 29 30 /** 31 * class DecoderConfigDescriptor extends BaseDescriptor : bit(8) 32 * tag=DecoderConfigDescrTag { 33 * bit(8) objectTypeIndication; 34 * bit(6) streamType; 35 * bit(1) upStream; 36 * const bit(1) reserved=1; 37 * bit(24) bufferSizeDB; 38 * bit(32) maxBitrate; 39 * bit(32) avgBitrate; 40 * DecoderSpecificInfo decSpecificInfo[0 .. 1]; 41 * profileLevelIndicationIndexDescriptor profileLevelIndicationIndexDescr 42 * [0..255]; 43 * } 44 */ 45 @Descriptor(tags = {0x04}) 46 public class DecoderConfigDescriptor extends BaseDescriptor { 47 private static Logger log = Logger.getLogger(DecoderConfigDescriptor.class.getName()); 48 49 50 int objectTypeIndication; 51 int streamType; 52 int upStream; 53 int bufferSizeDB; 54 long maxBitRate; 55 long avgBitRate; 56 57 DecoderSpecificInfo decoderSpecificInfo; 58 AudioSpecificConfig audioSpecificInfo; 59 List<ProfileLevelIndicationDescriptor> profileLevelIndicationDescriptors = new ArrayList<ProfileLevelIndicationDescriptor>(); 60 byte[] configDescriptorDeadBytes; 61 62 @Override parseDetail(ByteBuffer bb)63 public void parseDetail(ByteBuffer bb) throws IOException { 64 objectTypeIndication = IsoTypeReader.readUInt8(bb); 65 66 int data = IsoTypeReader.readUInt8(bb); 67 streamType = data >>> 2; 68 upStream = (data >> 1) & 0x1; 69 70 bufferSizeDB = IsoTypeReader.readUInt24(bb); 71 maxBitRate = IsoTypeReader.readUInt32(bb); 72 avgBitRate = IsoTypeReader.readUInt32(bb); 73 74 75 76 BaseDescriptor descriptor; 77 if (bb.remaining() > 2) { //1byte tag + at least 1byte size 78 final int begin = bb.position(); 79 descriptor = ObjectDescriptorFactory.createFrom(objectTypeIndication, bb); 80 final int read = bb.position() - begin; 81 log.finer(descriptor + " - DecoderConfigDescr1 read: " + read + ", size: " + (descriptor != null ? descriptor.getSize() : null)); 82 if (descriptor != null) { 83 final int size = descriptor.getSize(); 84 if (read < size) { 85 //skip 86 configDescriptorDeadBytes = new byte[size - read]; 87 bb.get(configDescriptorDeadBytes); 88 } 89 } 90 if (descriptor instanceof DecoderSpecificInfo) { 91 decoderSpecificInfo = (DecoderSpecificInfo) descriptor; 92 } 93 if (descriptor instanceof AudioSpecificConfig) { 94 audioSpecificInfo = (AudioSpecificConfig) descriptor; 95 } 96 } 97 98 while (bb.remaining() > 2) { 99 final long begin = bb.position(); 100 descriptor = ObjectDescriptorFactory.createFrom(objectTypeIndication, bb); 101 final long read = bb.position() - begin; 102 log.finer(descriptor + " - DecoderConfigDescr2 read: " + read + ", size: " + (descriptor != null ? descriptor.getSize() : null)); 103 if (descriptor instanceof ProfileLevelIndicationDescriptor) { 104 profileLevelIndicationDescriptors.add((ProfileLevelIndicationDescriptor) descriptor); 105 } 106 } 107 } serializedSize()108 public int serializedSize() { 109 return 15 + audioSpecificInfo.serializedSize(); 110 } 111 serialize()112 public ByteBuffer serialize() { 113 ByteBuffer out = ByteBuffer.allocate(serializedSize()); 114 IsoTypeWriter.writeUInt8(out, 4); 115 IsoTypeWriter.writeUInt8(out, serializedSize() - 2); 116 IsoTypeWriter.writeUInt8(out, objectTypeIndication); 117 int flags = (streamType << 2) | (upStream << 1) | 1; 118 IsoTypeWriter.writeUInt8(out, flags); 119 IsoTypeWriter.writeUInt24(out, bufferSizeDB); 120 IsoTypeWriter.writeUInt32(out, maxBitRate); 121 IsoTypeWriter.writeUInt32(out, avgBitRate); 122 out.put(audioSpecificInfo.serialize().array()); 123 return out; 124 } 125 getDecoderSpecificInfo()126 public DecoderSpecificInfo getDecoderSpecificInfo() { 127 return decoderSpecificInfo; 128 } 129 getAudioSpecificInfo()130 public AudioSpecificConfig getAudioSpecificInfo() { 131 return audioSpecificInfo; 132 } 133 setAudioSpecificInfo(AudioSpecificConfig audioSpecificInfo)134 public void setAudioSpecificInfo(AudioSpecificConfig audioSpecificInfo) { 135 this.audioSpecificInfo = audioSpecificInfo; 136 } 137 getProfileLevelIndicationDescriptors()138 public List<ProfileLevelIndicationDescriptor> getProfileLevelIndicationDescriptors() { 139 return profileLevelIndicationDescriptors; 140 } 141 getObjectTypeIndication()142 public int getObjectTypeIndication() { 143 return objectTypeIndication; 144 } 145 setObjectTypeIndication(int objectTypeIndication)146 public void setObjectTypeIndication(int objectTypeIndication) { 147 this.objectTypeIndication = objectTypeIndication; 148 } 149 getStreamType()150 public int getStreamType() { 151 return streamType; 152 } 153 setStreamType(int streamType)154 public void setStreamType(int streamType) { 155 this.streamType = streamType; 156 } 157 getUpStream()158 public int getUpStream() { 159 return upStream; 160 } 161 setUpStream(int upStream)162 public void setUpStream(int upStream) { 163 this.upStream = upStream; 164 } 165 getBufferSizeDB()166 public int getBufferSizeDB() { 167 return bufferSizeDB; 168 } 169 setBufferSizeDB(int bufferSizeDB)170 public void setBufferSizeDB(int bufferSizeDB) { 171 this.bufferSizeDB = bufferSizeDB; 172 } 173 getMaxBitRate()174 public long getMaxBitRate() { 175 return maxBitRate; 176 } 177 setMaxBitRate(long maxBitRate)178 public void setMaxBitRate(long maxBitRate) { 179 this.maxBitRate = maxBitRate; 180 } 181 getAvgBitRate()182 public long getAvgBitRate() { 183 return avgBitRate; 184 } 185 setAvgBitRate(long avgBitRate)186 public void setAvgBitRate(long avgBitRate) { 187 this.avgBitRate = avgBitRate; 188 } 189 190 @Override toString()191 public String toString() { 192 final StringBuilder sb = new StringBuilder(); 193 sb.append("DecoderConfigDescriptor"); 194 sb.append("{objectTypeIndication=").append(objectTypeIndication); 195 sb.append(", streamType=").append(streamType); 196 sb.append(", upStream=").append(upStream); 197 sb.append(", bufferSizeDB=").append(bufferSizeDB); 198 sb.append(", maxBitRate=").append(maxBitRate); 199 sb.append(", avgBitRate=").append(avgBitRate); 200 sb.append(", decoderSpecificInfo=").append(decoderSpecificInfo); 201 sb.append(", audioSpecificInfo=").append(audioSpecificInfo); 202 sb.append(", configDescriptorDeadBytes=").append(Hex.encodeHex(configDescriptorDeadBytes != null ? configDescriptorDeadBytes : new byte[]{})); 203 sb.append(", profileLevelIndicationDescriptors=").append(profileLevelIndicationDescriptors == null ? "null" : Arrays.asList(profileLevelIndicationDescriptors).toString()); 204 sb.append('}'); 205 return sb.toString(); 206 } 207 /*objectTypeIndication values 208 0x00 Forbidden 209 0x01 Systems ISO/IEC 14496-1 a 210 0x02 Systems ISO/IEC 14496-1 b 211 0x03 Interaction Stream 212 0x04 Systems ISO/IEC 14496-1 Extended BIFS Configuration c 213 0x05 Systems ISO/IEC 14496-1 AFX d 214 0x06 Font Data Stream 215 0x07 Synthesized Texture Stream 216 0x08 Streaming Text Stream 217 0x09-0x1F reserved for ISO use 218 0x20 Visual ISO/IEC 14496-2 e 219 0x21 Visual ITU-T Recommendation H.264 | ISO/IEC 14496-10 f 220 0x22 Parameter Sets for ITU-T Recommendation H.264 | ISO/IEC 14496-10 f 221 0x23-0x3F reserved for ISO use 222 0x40 Audio ISO/IEC 14496-3 g 223 0x41-0x5F reserved for ISO use 224 0x60 Visual ISO/IEC 13818-2 Simple Profile 225 0x61 Visual ISO/IEC 13818-2 Main Profile 226 0x62 Visual ISO/IEC 13818-2 SNR Profile 227 0x63 Visual ISO/IEC 13818-2 Spatial Profile 228 0x64 Visual ISO/IEC 13818-2 High Profile 229 0x65 Visual ISO/IEC 13818-2 422 Profile 230 0x66 Audio ISO/IEC 13818-7 Main Profile 231 0x67 Audio ISO/IEC 13818-7 LowComplexity Profile 232 0x68 Audio ISO/IEC 13818-7 Scaleable Sampling Rate Profile 233 0x69 Audio ISO/IEC 13818-3 234 0x6A Visual ISO/IEC 11172-2 235 0x6B Audio ISO/IEC 11172-3 236 0x6C Visual ISO/IEC 10918-1 237 0x6D reserved for registration authority i 238 0x6E Visual ISO/IEC 15444-1 239 0x6F - 0x9F reserved for ISO use 240 0xA0 - 0xBF reserved for registration authority i 241 0xC0 - 0xE0 user private 242 0xE1 reserved for registration authority i 243 0xE2 - 0xFE user private 244 0xFF no object type specified h 245 */ 246 /* streamType values 247 0x00 Forbidden 248 0x01 ObjectDescriptorStream (see 7.2.5) 249 0x02 ClockReferenceStream (see 7.3.2.5) 250 0x03 SceneDescriptionStream (see ISO/IEC 14496-11) 251 0x04 VisualStream 252 0x05 AudioStream 253 0x06 MPEG7Stream 254 0x07 IPMPStream (see 7.2.3.2) 255 0x08 ObjectContentInfoStream (see 7.2.4.2) 256 0x09 MPEGJStream 257 0x0A Interaction Stream 258 0x0B IPMPToolStream (see [ISO/IEC 14496-13]) 259 0x0C - 0x1F reserved for ISO use 260 0x20 - 0x3F user private 261 */ 262 } 263