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.IsoTypeReader; 20 21 import java.io.IOException; 22 import java.lang.reflect.Modifier; 23 import java.nio.ByteBuffer; 24 import java.util.HashMap; 25 import java.util.HashSet; 26 import java.util.Map; 27 import java.util.Set; 28 import java.util.logging.Level; 29 import java.util.logging.Logger; 30 31 /* class tag values of 14496-1 32 0x00 Forbidden 33 0x01 ObjectDescrTag 34 0x02 InitialObjectDescrTag 35 0x03 ES_DescrTag 36 0x04 DecoderConfigDescrTag 37 0x05 DecSpecificInfoTag 38 0x06 SLConfigDescrTag 39 0x07 ContentIdentDescrTag 40 0x08 SupplContentIdentDescrTag 41 0x09 IPI_DescrPointerTag 42 0x0A IPMP_DescrPointerTag 43 0x0B IPMP_DescrTag 44 0x0C QoS_DescrTag 45 0x0D RegistrationDescrTag 46 0x0E ES_ID_IncTag 47 0x0F ES_ID_RefTag 48 0x10 MP4_IOD_Tag 49 0x11 MP4_OD_Tag 50 0x12 IPL_DescrPointerRefTag 51 0x13 ExtensionProfileLevelDescrTag 52 0x14 profileLevelIndicationIndexDescrTag 53 0x15-0x3F Reserved for ISO use 54 0x40 ContentClassificationDescrTag 55 0x41 KeyWordDescrTag 56 0x42 RatingDescrTag 57 0x43 LanguageDescrTag 58 0x44 ShortTextualDescrTag 59 0x45 ExpandedTextualDescrTag 60 0x46 ContentCreatorNameDescrTag 61 0x47 ContentCreationDateDescrTag 62 0x48 OCICreatorNameDescrTag 63 0x49 OCICreationDateDescrTag 64 0x4A SmpteCameraPositionDescrTag 65 0x4B SegmentDescrTag 66 0x4C MediaTimeDescrTag 67 0x4D-0x5F Reserved for ISO use (OCI extensions) 68 0x60 IPMP_ToolsListDescrTag 69 0x61 IPMP_ToolTag 70 0x62 M4MuxTimingDescrTag 71 0x63 M4MuxCodeTableDescrTag 72 0x64 ExtSLConfigDescrTag 73 0x65 M4MuxBufferSizeDescrTag 74 0x66 M4MuxIdentDescrTag 75 0x67 DependencyPointerTag 76 0x68 DependencyMarkerTag 77 0x69 M4MuxChannelDescrTag 78 0x6A-0xBF Reserved for ISO use 79 0xC0-0xFE User private 80 0xFF Forbidden 81 */ 82 83 /* objectTypeIndication as of 14496-1 84 0x00 Forbidden 85 0x01 Systems ISO/IEC 14496-1 a 86 0x02 Systems ISO/IEC 14496-1 b 87 0x03 Interaction Stream 88 0x04 Systems ISO/IEC 14496-1 Extended BIFS Configuration c 89 0x05 Systems ISO/IEC 14496-1 AFX d 90 0x06 Font Data Stream 91 0x07 Synthesized Texture Stream 92 0x08 Streaming Text Stream 93 0x09-0x1F reserved for ISO use 94 0x20 Visual ISO/IEC 14496-2 e 95 0x21 Visual ITU-T Recommendation H.264 | ISO/IEC 14496-10 f 96 0x22 Parameter Sets for ITU-T Recommendation H.264 | ISO/IEC 14496-10 f 97 0x23-0x3F reserved for ISO use 98 0x40 Audio ISO/IEC 14496-3 g 99 0x41-0x5F reserved for ISO use 100 0x60 Visual ISO/IEC 13818-2 Simple Profile 101 0x61 Visual ISO/IEC 13818-2 Main Profile 102 0x62 Visual ISO/IEC 13818-2 SNR Profile 103 0x63 Visual ISO/IEC 13818-2 Spatial Profile 104 0x64 Visual ISO/IEC 13818-2 High Profile 105 0x65 Visual ISO/IEC 13818-2 422 Profile 106 0x66 Audio ISO/IEC 13818-7 Main Profile 107 0x67 Audio ISO/IEC 13818-7 LowComplexity Profile 108 0x68 Audio ISO/IEC 13818-7 Scaleable Sampling Rate Profile 109 0x69 Audio ISO/IEC 13818-3 110 0x6A Visual ISO/IEC 11172-2 111 0x6B Audio ISO/IEC 11172-3 112 0x6C Visual ISO/IEC 10918-1 113 0x6D reserved for registration authority 114 0x6E Visual ISO/IEC 15444-1 115 0x6F - 0x9F reserved for ISO use 116 0xA0 - 0xBF reserved for registration authority i 117 0xC0 - 0xE0 user private 118 0xE1 reserved for registration authority i 119 0xE2 - 0xFE user private 120 0xFF no object type specified h 121 */ 122 public class ObjectDescriptorFactory { 123 protected static Logger log = Logger.getLogger(ObjectDescriptorFactory.class.getName()); 124 125 protected static Map<Integer, Map<Integer, Class<? extends BaseDescriptor>>> descriptorRegistry = new HashMap<Integer, Map<Integer, Class<? extends BaseDescriptor>>>(); 126 127 static { 128 Set<Class<? extends BaseDescriptor>> annotated = new HashSet<Class<? extends BaseDescriptor>>(); 129 130 annotated.add(DecoderSpecificInfo.class); 131 annotated.add(SLConfigDescriptor.class); 132 annotated.add(BaseDescriptor.class); 133 annotated.add(ExtensionDescriptor.class); 134 annotated.add(ObjectDescriptorBase.class); 135 annotated.add(ProfileLevelIndicationDescriptor.class); 136 annotated.add(AudioSpecificConfig.class); 137 annotated.add(ExtensionProfileLevelDescriptor.class); 138 annotated.add(ESDescriptor.class); 139 annotated.add(DecoderConfigDescriptor.class); 140 //annotated.add(ObjectDescriptor.class); 141 142 for (Class<? extends BaseDescriptor> clazz : annotated) { 143 final Descriptor descriptor = clazz.getAnnotation(Descriptor.class); 144 final int[] tags = descriptor.tags(); 145 final int objectTypeInd = descriptor.objectTypeIndication(); 146 147 Map<Integer, Class<? extends BaseDescriptor>> tagMap = descriptorRegistry.get(objectTypeInd); 148 if (tagMap == null) { 149 tagMap = new HashMap<Integer, Class<? extends BaseDescriptor>>(); 150 } 151 for (int tag : tags) { tagMap.put(tag, clazz)152 tagMap.put(tag, clazz); 153 } descriptorRegistry.put(objectTypeInd, tagMap)154 descriptorRegistry.put(objectTypeInd, tagMap); 155 } 156 } 157 createFrom(int objectTypeIndication, ByteBuffer bb)158 public static BaseDescriptor createFrom(int objectTypeIndication, ByteBuffer bb) throws IOException { 159 int tag = IsoTypeReader.readUInt8(bb); 160 161 Map<Integer, Class<? extends BaseDescriptor>> tagMap = descriptorRegistry.get(objectTypeIndication); 162 if (tagMap == null) { 163 tagMap = descriptorRegistry.get(-1); 164 } 165 Class<? extends BaseDescriptor> aClass = tagMap.get(tag); 166 167 // if (tag == 0x00) { 168 // log.warning("Found illegal tag 0x00! objectTypeIndication " + Integer.toHexString(objectTypeIndication) + 169 // " and tag " + Integer.toHexString(tag) + " using: " + aClass); 170 // aClass = BaseDescriptor.class; 171 // } 172 173 BaseDescriptor baseDescriptor; 174 if (aClass == null || aClass.isInterface() || Modifier.isAbstract(aClass.getModifiers())) { 175 log.warning("No ObjectDescriptor found for objectTypeIndication " + Integer.toHexString(objectTypeIndication) + 176 " and tag " + Integer.toHexString(tag) + " found: " + aClass); 177 baseDescriptor = new UnknownDescriptor(); 178 } else { 179 try { 180 baseDescriptor = aClass.newInstance(); 181 } catch (Exception e) { 182 log.log(Level.SEVERE, "Couldn't instantiate BaseDescriptor class " + aClass + " for objectTypeIndication " + objectTypeIndication + " and tag " + tag, e); 183 throw new RuntimeException(e); 184 } 185 } 186 baseDescriptor.parse(tag, bb); 187 return baseDescriptor; 188 } 189 } 190