1 /* 2 * Copyright (C) 2016 The Android Open Source Project 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 package com.google.android.exoplayer2.audio; 17 18 import androidx.annotation.Nullable; 19 import com.google.android.exoplayer2.Format; 20 import com.google.android.exoplayer2.drm.DrmInitData; 21 import com.google.android.exoplayer2.util.MimeTypes; 22 import com.google.android.exoplayer2.util.ParsableBitArray; 23 import java.nio.ByteBuffer; 24 import java.util.Arrays; 25 26 /** 27 * Utility methods for parsing DTS frames. 28 */ 29 public final class DtsUtil { 30 31 /** 32 * Maximum rate for a DTS audio stream, in bytes per second. 33 * 34 * <p>DTS allows an 'open' bitrate, but we assume the maximum listed value: 1536 kbit/s. 35 */ 36 public static final int DTS_MAX_RATE_BYTES_PER_SECOND = 1536 * 1000 / 8; 37 /** Maximum rate for a DTS-HD audio stream, in bytes per second. */ 38 public static final int DTS_HD_MAX_RATE_BYTES_PER_SECOND = 18000 * 1000 / 8; 39 40 private static final int SYNC_VALUE_BE = 0x7FFE8001; 41 private static final int SYNC_VALUE_14B_BE = 0x1FFFE800; 42 private static final int SYNC_VALUE_LE = 0xFE7F0180; 43 private static final int SYNC_VALUE_14B_LE = 0xFF1F00E8; 44 private static final byte FIRST_BYTE_BE = (byte) (SYNC_VALUE_BE >>> 24); 45 private static final byte FIRST_BYTE_14B_BE = (byte) (SYNC_VALUE_14B_BE >>> 24); 46 private static final byte FIRST_BYTE_LE = (byte) (SYNC_VALUE_LE >>> 24); 47 private static final byte FIRST_BYTE_14B_LE = (byte) (SYNC_VALUE_14B_LE >>> 24); 48 49 /** 50 * Maps AMODE to the number of channels. See ETSI TS 102 114 table 5.4. 51 */ 52 private static final int[] CHANNELS_BY_AMODE = new int[] {1, 2, 2, 2, 2, 3, 3, 4, 4, 5, 6, 6, 6, 53 7, 8, 8}; 54 55 /** 56 * Maps SFREQ to the sampling frequency in Hz. See ETSI TS 102 144 table 5.5. 57 */ 58 private static final int[] SAMPLE_RATE_BY_SFREQ = new int[] {-1, 8000, 16000, 32000, -1, -1, 59 11025, 22050, 44100, -1, -1, 12000, 24000, 48000, -1, -1}; 60 61 /** 62 * Maps RATE to 2 * bitrate in kbit/s. See ETSI TS 102 144 table 5.7. 63 */ 64 private static final int[] TWICE_BITRATE_KBPS_BY_RATE = new int[] {64, 112, 128, 192, 224, 256, 65 384, 448, 512, 640, 768, 896, 1024, 1152, 1280, 1536, 1920, 2048, 2304, 2560, 2688, 2816, 66 2823, 2944, 3072, 3840, 4096, 6144, 7680}; 67 68 /** 69 * Returns whether a given integer matches a DTS sync word. Synchronization and storage modes are 70 * defined in ETSI TS 102 114 V1.1.1 (2002-08), Section 5.3. 71 * 72 * @param word An integer. 73 * @return Whether a given integer matches a DTS sync word. 74 */ isSyncWord(int word)75 public static boolean isSyncWord(int word) { 76 return word == SYNC_VALUE_BE 77 || word == SYNC_VALUE_LE 78 || word == SYNC_VALUE_14B_BE 79 || word == SYNC_VALUE_14B_LE; 80 } 81 82 /** 83 * Returns the DTS format given {@code data} containing the DTS frame according to ETSI TS 102 114 84 * subsections 5.3/5.4. 85 * 86 * @param frame The DTS frame to parse. 87 * @param trackId The track identifier to set on the format. 88 * @param language The language to set on the format. 89 * @param drmInitData {@link DrmInitData} to be included in the format. 90 * @return The DTS format parsed from data in the header. 91 */ parseDtsFormat( byte[] frame, @Nullable String trackId, @Nullable String language, @Nullable DrmInitData drmInitData)92 public static Format parseDtsFormat( 93 byte[] frame, 94 @Nullable String trackId, 95 @Nullable String language, 96 @Nullable DrmInitData drmInitData) { 97 ParsableBitArray frameBits = getNormalizedFrameHeader(frame); 98 frameBits.skipBits(32 + 1 + 5 + 1 + 7 + 14); // SYNC, FTYPE, SHORT, CPF, NBLKS, FSIZE 99 int amode = frameBits.readBits(6); 100 int channelCount = CHANNELS_BY_AMODE[amode]; 101 int sfreq = frameBits.readBits(4); 102 int sampleRate = SAMPLE_RATE_BY_SFREQ[sfreq]; 103 int rate = frameBits.readBits(5); 104 int bitrate = rate >= TWICE_BITRATE_KBPS_BY_RATE.length ? Format.NO_VALUE 105 : TWICE_BITRATE_KBPS_BY_RATE[rate] * 1000 / 2; 106 frameBits.skipBits(10); // MIX, DYNF, TIMEF, AUXF, HDCD, EXT_AUDIO_ID, EXT_AUDIO, ASPF 107 channelCount += frameBits.readBits(2) > 0 ? 1 : 0; // LFF 108 return new Format.Builder() 109 .setId(trackId) 110 .setSampleMimeType(MimeTypes.AUDIO_DTS) 111 .setAverageBitrate(bitrate) 112 .setChannelCount(channelCount) 113 .setSampleRate(sampleRate) 114 .setDrmInitData(drmInitData) 115 .setLanguage(language) 116 .build(); 117 } 118 119 /** 120 * Returns the number of audio samples represented by the given DTS frame. 121 * 122 * @param data The frame to parse. 123 * @return The number of audio samples represented by the frame. 124 */ parseDtsAudioSampleCount(byte[] data)125 public static int parseDtsAudioSampleCount(byte[] data) { 126 int nblks; 127 switch (data[0]) { 128 case FIRST_BYTE_LE: 129 nblks = ((data[5] & 0x01) << 6) | ((data[4] & 0xFC) >> 2); 130 break; 131 case FIRST_BYTE_14B_LE: 132 nblks = ((data[4] & 0x07) << 4) | ((data[7] & 0x3C) >> 2); 133 break; 134 case FIRST_BYTE_14B_BE: 135 nblks = ((data[5] & 0x07) << 4) | ((data[6] & 0x3C) >> 2); 136 break; 137 default: 138 // We blindly assume FIRST_BYTE_BE if none of the others match. 139 nblks = ((data[4] & 0x01) << 6) | ((data[5] & 0xFC) >> 2); 140 } 141 return (nblks + 1) * 32; 142 } 143 144 /** 145 * Like {@link #parseDtsAudioSampleCount(byte[])} but reads from a {@link ByteBuffer}. The 146 * buffer's position is not modified. 147 * 148 * @param buffer The {@link ByteBuffer} from which to read. 149 * @return The number of audio samples represented by the syncframe. 150 */ parseDtsAudioSampleCount(ByteBuffer buffer)151 public static int parseDtsAudioSampleCount(ByteBuffer buffer) { 152 // See ETSI TS 102 114 subsection 5.4.1. 153 int position = buffer.position(); 154 int nblks; 155 switch (buffer.get(position)) { 156 case FIRST_BYTE_LE: 157 nblks = ((buffer.get(position + 5) & 0x01) << 6) | ((buffer.get(position + 4) & 0xFC) >> 2); 158 break; 159 case FIRST_BYTE_14B_LE: 160 nblks = ((buffer.get(position + 4) & 0x07) << 4) | ((buffer.get(position + 7) & 0x3C) >> 2); 161 break; 162 case FIRST_BYTE_14B_BE: 163 nblks = ((buffer.get(position + 5) & 0x07) << 4) | ((buffer.get(position + 6) & 0x3C) >> 2); 164 break; 165 default: 166 // We blindly assume FIRST_BYTE_BE if none of the others match. 167 nblks = ((buffer.get(position + 4) & 0x01) << 6) | ((buffer.get(position + 5) & 0xFC) >> 2); 168 } 169 return (nblks + 1) * 32; 170 } 171 172 /** 173 * Returns the size in bytes of the given DTS frame. 174 * 175 * @param data The frame to parse. 176 * @return The frame's size in bytes. 177 */ getDtsFrameSize(byte[] data)178 public static int getDtsFrameSize(byte[] data) { 179 int fsize; 180 boolean uses14BitPerWord = false; 181 switch (data[0]) { 182 case FIRST_BYTE_14B_BE: 183 fsize = (((data[6] & 0x03) << 12) | ((data[7] & 0xFF) << 4) | ((data[8] & 0x3C) >> 2)) + 1; 184 uses14BitPerWord = true; 185 break; 186 case FIRST_BYTE_LE: 187 fsize = (((data[4] & 0x03) << 12) | ((data[7] & 0xFF) << 4) | ((data[6] & 0xF0) >> 4)) + 1; 188 break; 189 case FIRST_BYTE_14B_LE: 190 fsize = (((data[7] & 0x03) << 12) | ((data[6] & 0xFF) << 4) | ((data[9] & 0x3C) >> 2)) + 1; 191 uses14BitPerWord = true; 192 break; 193 default: 194 // We blindly assume FIRST_BYTE_BE if none of the others match. 195 fsize = (((data[5] & 0x03) << 12) | ((data[6] & 0xFF) << 4) | ((data[7] & 0xF0) >> 4)) + 1; 196 } 197 198 // If the frame is stored in 14-bit mode, adjust the frame size to reflect the actual byte size. 199 return uses14BitPerWord ? fsize * 16 / 14 : fsize; 200 } 201 getNormalizedFrameHeader(byte[] frameHeader)202 private static ParsableBitArray getNormalizedFrameHeader(byte[] frameHeader) { 203 if (frameHeader[0] == FIRST_BYTE_BE) { 204 // The frame is already 16-bit mode, big endian. 205 return new ParsableBitArray(frameHeader); 206 } 207 // Data is not normalized, but we don't want to modify frameHeader. 208 frameHeader = Arrays.copyOf(frameHeader, frameHeader.length); 209 if (isLittleEndianFrameHeader(frameHeader)) { 210 // Change endianness. 211 for (int i = 0; i < frameHeader.length - 1; i += 2) { 212 byte temp = frameHeader[i]; 213 frameHeader[i] = frameHeader[i + 1]; 214 frameHeader[i + 1] = temp; 215 } 216 } 217 ParsableBitArray frameBits = new ParsableBitArray(frameHeader); 218 if (frameHeader[0] == (byte) (SYNC_VALUE_14B_BE >> 24)) { 219 // Discard the 2 most significant bits of each 16 bit word. 220 ParsableBitArray scratchBits = new ParsableBitArray(frameHeader); 221 while (scratchBits.bitsLeft() >= 16) { 222 scratchBits.skipBits(2); 223 frameBits.putInt(scratchBits.readBits(14), 14); 224 } 225 } 226 frameBits.reset(frameHeader); 227 return frameBits; 228 } 229 isLittleEndianFrameHeader(byte[] frameHeader)230 private static boolean isLittleEndianFrameHeader(byte[] frameHeader) { 231 return frameHeader[0] == FIRST_BYTE_LE || frameHeader[0] == FIRST_BYTE_14B_LE; 232 } 233 DtsUtil()234 private DtsUtil() {} 235 236 } 237