blob: 941e8b9e392a16f637d09e8313490f9300ce1d59 [file] [log] [blame]
Tim Yao72bc0fb2019-12-03 11:04:19 -08001/*
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 <cutils/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 (void) /* uint32_t ftype = */ parser.readBits(1);
85 (void) /* 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 (void) /* 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 = %zu",
133 mSampleRate, mRateMultiplier, mFrameSizeBytes);
134 mFormatDumpCount++;
135 return true;
136}
137
138
139} // namespace android