DTSFrameScanner.cpp revision b9cc914d10e31266b43bcefee4cfdd72cd81ec10
1/* 2 * Copyright 2015, 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 17#define LOG_TAG "AudioSPDIF" 18//#define LOG_NDEBUG 0 19 20#include <assert.h> 21#include <string.h> 22 23#include <utils/Log.h> 24#include <audio_utils/spdif/FrameScanner.h> 25 26#include "BitFieldParser.h" 27#include "DTSFrameScanner.h" 28 29namespace android { 30 31// TODO Handle termination frames. 32// TODO assert if parse past end of header buffer 33// TODO Handle DTS_HD 34 35const uint8_t DTSFrameScanner::kSyncBytes[] = 36 { 0x7F, 0xFE, 0x80, 0x01 }; 37 38const int32_t DTSFrameScanner::kDTSSampleRateTable[DTS_NUM_SAMPLE_RATE_TABLE_ENTRIES] 39 = { -1, 8000, 16000, 32000, -1, -1, 40 11025, 22050, 44100, -1, -1, 12000, 24000, 48000, -1, -1 }; 41 42// Defined in IEC61937-2 43#define IEC61937_DATA_TYPE_DTS_I 11 44#define IEC61937_DATA_TYPE_DTS_II 12 45#define IEC61937_DATA_TYPE_DTS_III 13 46#define IEC61937_DATA_TYPE_DTS_IV 17 47 48#define IEC61937_MAX_SAMPLES_TYPE_I 512 49#define IEC61937_MAX_SAMPLES_TYPE_II 1024 50#define IEC61937_MAX_SAMPLES_TYPE_III 2048 51 52// Limits defined in DTS spec paragraph 5.3.1 53#define DTS_MINIMUM_NBLKS 5 54#define DTS_MINIMUM_FSIZE 95 55 56#define DTS_HEADER_BYTES_NEEDED 12 57 58// Scanner for DTS byte streams. 59DTSFrameScanner::DTSFrameScanner() 60 : FrameScanner(IEC61937_DATA_TYPE_DTS_I, 61 DTSFrameScanner::kSyncBytes, 62 sizeof(DTSFrameScanner::kSyncBytes), 63 DTS_HEADER_BYTES_NEEDED) 64 , mSampleFramesPerSyncFrame(0) 65{ 66} 67 68DTSFrameScanner::~DTSFrameScanner() 69{ 70} 71 72// Parse DTS header. 73// Detect whether the stream is DTS or DTS_HD. Extract data depending on type. 74// Sets mDataType, mFrameSizeBytes, 75// mSampleRate, mRateMultiplier, mLengthCode. 76// 77// @return true if valid 78bool DTSFrameScanner::parseHeader() 79{ 80 BitFieldParser parser(&mHeaderBuffer[mSyncLength]); 81 82 // These variables are named after the fields in the DTS spec 5.3.1 83 // Extract field in order. 84 uint32_t ftype = parser.readBits(1); 85 uint32_t deficit = parser.readBits(5); // "short" 86 uint32_t cpf = parser.readBits(1); 87 uint32_t nblks = parser.readBits(7); 88 uint32_t fsize = parser.readBits(14); 89 uint32_t amode = parser.readBits(6); 90 uint32_t sfreq = parser.readBits(4); 91 // make sure we did not read past collected data 92 ALOG_ASSERT((mSyncLength + ((parser.getBitCursor() + 7) >> 3)) 93 <= mHeaderLength); 94 95 // Validate fields. 96 if (cpf != 0) { 97 ALOGE("DTSFrameScanner: ERROR - CPF not zero!"); 98 return false; 99 } 100 if (nblks < DTS_MINIMUM_NBLKS) { 101 ALOGE("DTSFrameScanner: ERROR - nblks = %u", nblks); 102 return false; 103 } 104 if (fsize < DTS_MINIMUM_FSIZE) { 105 ALOGE("DTSFrameScanner: ERROR - fsize = %u", fsize); 106 return false; 107 } 108 109 int32_t sampleRate = kDTSSampleRateTable[sfreq]; 110 if (sampleRate < 0) { 111 ALOGE("DTSFrameScanner: ERROR - invalid sampleRate[%u] = %d", sfreq, sampleRate); 112 return false; 113 } 114 mSampleRate = (uint32_t) sampleRate; 115 116 mSampleFramesPerSyncFrame = (nblks + 1) * DTS_PCM_FRAMES_PER_BLOCK; 117 if (mSampleFramesPerSyncFrame <= IEC61937_MAX_SAMPLES_TYPE_I) { 118 mDataType = IEC61937_DATA_TYPE_DTS_I; 119 } else if (mSampleFramesPerSyncFrame <= IEC61937_MAX_SAMPLES_TYPE_II) { 120 mDataType = IEC61937_DATA_TYPE_DTS_II; 121 } else if (mSampleFramesPerSyncFrame <= IEC61937_MAX_SAMPLES_TYPE_III) { 122 mDataType = IEC61937_DATA_TYPE_DTS_III; 123 } else { 124 mDataType = IEC61937_DATA_TYPE_DTS_IV; 125 // TODO set bits 8,10 126 } 127 128 mFrameSizeBytes = fsize + 1; 129 130 mRateMultiplier = 1; // TODO what about "frequency extension"? 131 ALOGI_IF((mFormatDumpCount == 0), 132 "DTS frame rate = %d * %d, size = %d\n", 133 mSampleRate, mRateMultiplier, mFrameSizeBytes); 134 mFormatDumpCount++; 135 return true; 136} 137 138 139} // namespace android 140