| /* |
| * Copyright 2008 CoreMedia AG, Hamburg |
| * |
| * 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.coremedia.iso.boxes.sampleentry; |
| |
| import com.coremedia.iso.BoxParser; |
| import com.coremedia.iso.IsoTypeReader; |
| import com.coremedia.iso.IsoTypeWriter; |
| import com.coremedia.iso.boxes.Box; |
| import com.coremedia.iso.boxes.ContainerBox; |
| |
| import java.nio.ByteBuffer; |
| |
| /** |
| * Contains basic information about the audio samples in this track. Format-specific information |
| * is appened as boxes after the data described in ISO/IEC 14496-12 chapter 8.16.2. |
| */ |
| public class AudioSampleEntry extends SampleEntry implements ContainerBox { |
| |
| public static final String TYPE1 = "samr"; |
| public static final String TYPE2 = "sawb"; |
| public static final String TYPE3 = "mp4a"; |
| public static final String TYPE4 = "drms"; |
| public static final String TYPE5 = "alac"; |
| public static final String TYPE7 = "owma"; |
| public static final String TYPE8 = "ac-3"; /* ETSI TS 102 366 1.2.1 Annex F */ |
| public static final String TYPE9 = "ec-3"; /* ETSI TS 102 366 1.2.1 Annex F */ |
| public static final String TYPE10 = "mlpa"; |
| public static final String TYPE11 = "dtsl"; |
| public static final String TYPE12 = "dtsh"; |
| public static final String TYPE13 = "dtse"; |
| |
| /** |
| * Identifier for an encrypted audio track. |
| * |
| * @see com.coremedia.iso.boxes.ProtectionSchemeInformationBox |
| */ |
| public static final String TYPE_ENCRYPTED = "enca"; |
| |
| private int channelCount; |
| private int sampleSize; |
| private long sampleRate; |
| private int soundVersion; |
| private int compressionId; |
| private int packetSize; |
| private long samplesPerPacket; |
| private long bytesPerPacket; |
| private long bytesPerFrame; |
| private long bytesPerSample; |
| |
| private int reserved1; |
| private long reserved2; |
| private byte[] soundVersion2Data; |
| private BoxParser boxParser; |
| |
| public AudioSampleEntry(String type) { |
| super(type); |
| } |
| |
| public int getChannelCount() { |
| return channelCount; |
| } |
| |
| public int getSampleSize() { |
| return sampleSize; |
| } |
| |
| public long getSampleRate() { |
| return sampleRate; |
| } |
| |
| public int getSoundVersion() { |
| return soundVersion; |
| } |
| |
| public int getCompressionId() { |
| return compressionId; |
| } |
| |
| public int getPacketSize() { |
| return packetSize; |
| } |
| |
| public long getSamplesPerPacket() { |
| return samplesPerPacket; |
| } |
| |
| public long getBytesPerPacket() { |
| return bytesPerPacket; |
| } |
| |
| public long getBytesPerFrame() { |
| return bytesPerFrame; |
| } |
| |
| public long getBytesPerSample() { |
| return bytesPerSample; |
| } |
| |
| public byte[] getSoundVersion2Data() { |
| return soundVersion2Data; |
| } |
| |
| public int getReserved1() { |
| return reserved1; |
| } |
| |
| public long getReserved2() { |
| return reserved2; |
| } |
| |
| public void setChannelCount(int channelCount) { |
| this.channelCount = channelCount; |
| } |
| |
| public void setSampleSize(int sampleSize) { |
| this.sampleSize = sampleSize; |
| } |
| |
| public void setSampleRate(long sampleRate) { |
| this.sampleRate = sampleRate; |
| } |
| |
| public void setSoundVersion(int soundVersion) { |
| this.soundVersion = soundVersion; |
| } |
| |
| public void setCompressionId(int compressionId) { |
| this.compressionId = compressionId; |
| } |
| |
| public void setPacketSize(int packetSize) { |
| this.packetSize = packetSize; |
| } |
| |
| public void setSamplesPerPacket(long samplesPerPacket) { |
| this.samplesPerPacket = samplesPerPacket; |
| } |
| |
| public void setBytesPerPacket(long bytesPerPacket) { |
| this.bytesPerPacket = bytesPerPacket; |
| } |
| |
| public void setBytesPerFrame(long bytesPerFrame) { |
| this.bytesPerFrame = bytesPerFrame; |
| } |
| |
| public void setBytesPerSample(long bytesPerSample) { |
| this.bytesPerSample = bytesPerSample; |
| } |
| |
| public void setReserved1(int reserved1) { |
| this.reserved1 = reserved1; |
| } |
| |
| public void setReserved2(long reserved2) { |
| this.reserved2 = reserved2; |
| } |
| |
| public void setSoundVersion2Data(byte[] soundVersion2Data) { |
| this.soundVersion2Data = soundVersion2Data; |
| } |
| |
| public void setBoxParser(BoxParser boxParser) { |
| this.boxParser = boxParser; |
| } |
| |
| @Override |
| public void _parseDetails(ByteBuffer content) { |
| _parseReservedAndDataReferenceIndex(content); //parses the six reserved bytes and dataReferenceIndex |
| // 8 bytes already parsed |
| //reserved bits - used by qt |
| soundVersion = IsoTypeReader.readUInt16(content); |
| |
| //reserved |
| reserved1 = IsoTypeReader.readUInt16(content); |
| reserved2 = IsoTypeReader.readUInt32(content); |
| |
| channelCount = IsoTypeReader.readUInt16(content); |
| sampleSize = IsoTypeReader.readUInt16(content); |
| //reserved bits - used by qt |
| compressionId = IsoTypeReader.readUInt16(content); |
| //reserved bits - used by qt |
| packetSize = IsoTypeReader.readUInt16(content); |
| //sampleRate = in.readFixedPoint1616(); |
| sampleRate = IsoTypeReader.readUInt32(content); |
| if (!type.equals("mlpa")) { |
| sampleRate = sampleRate >>> 16; |
| } |
| |
| //more qt stuff - see http://mp4v2.googlecode.com/svn-history/r388/trunk/src/atom_sound.cpp |
| if (soundVersion > 0) { |
| samplesPerPacket = IsoTypeReader.readUInt32(content); |
| bytesPerPacket = IsoTypeReader.readUInt32(content); |
| bytesPerFrame = IsoTypeReader.readUInt32(content); |
| bytesPerSample = IsoTypeReader.readUInt32(content); |
| } |
| if (soundVersion == 2) { |
| |
| soundVersion2Data = new byte[20]; |
| content.get(20); |
| } |
| _parseChildBoxes(content); |
| |
| } |
| |
| |
| @Override |
| protected long getContentSize() { |
| long contentSize = 28; |
| contentSize += soundVersion > 0 ? 16 : 0; |
| contentSize += soundVersion == 2 ? 20 : 0; |
| for (Box boxe : boxes) { |
| contentSize += boxe.getSize(); |
| } |
| return contentSize; |
| } |
| |
| @Override |
| public String toString() { |
| return "AudioSampleEntry{" + |
| "bytesPerSample=" + bytesPerSample + |
| ", bytesPerFrame=" + bytesPerFrame + |
| ", bytesPerPacket=" + bytesPerPacket + |
| ", samplesPerPacket=" + samplesPerPacket + |
| ", packetSize=" + packetSize + |
| ", compressionId=" + compressionId + |
| ", soundVersion=" + soundVersion + |
| ", sampleRate=" + sampleRate + |
| ", sampleSize=" + sampleSize + |
| ", channelCount=" + channelCount + |
| ", boxes=" + getBoxes() + |
| '}'; |
| } |
| |
| @Override |
| protected void getContent(ByteBuffer byteBuffer) { |
| _writeReservedAndDataReferenceIndex(byteBuffer); |
| IsoTypeWriter.writeUInt16(byteBuffer, soundVersion); |
| IsoTypeWriter.writeUInt16(byteBuffer, reserved1); |
| IsoTypeWriter.writeUInt32(byteBuffer, reserved2); |
| IsoTypeWriter.writeUInt16(byteBuffer, channelCount); |
| IsoTypeWriter.writeUInt16(byteBuffer, sampleSize); |
| IsoTypeWriter.writeUInt16(byteBuffer, compressionId); |
| IsoTypeWriter.writeUInt16(byteBuffer, packetSize); |
| //isos.writeFixedPont1616(getSampleRate()); |
| if (type.equals("mlpa")) { |
| IsoTypeWriter.writeUInt32(byteBuffer, getSampleRate()); |
| } else { |
| IsoTypeWriter.writeUInt32(byteBuffer, getSampleRate() << 16); |
| } |
| |
| if (soundVersion > 0) { |
| IsoTypeWriter.writeUInt32(byteBuffer, samplesPerPacket); |
| IsoTypeWriter.writeUInt32(byteBuffer, bytesPerPacket); |
| IsoTypeWriter.writeUInt32(byteBuffer, bytesPerFrame); |
| IsoTypeWriter.writeUInt32(byteBuffer, bytesPerSample); |
| } |
| |
| if (soundVersion == 2) { |
| byteBuffer.put(soundVersion2Data); |
| } |
| _writeChildBoxes(byteBuffer); |
| } |
| } |