blob: 221a072af3b2d046e2b49d1ce078d370c1279d9b [file] [log] [blame]
Tim Yao72bc0fb2019-12-03 11:04:19 -08001/*
2 * Copyright 2014, 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#include <stdint.h>
18#include <string.h>
19
20#define LOG_TAG "AudioSPDIF"
21#include <cutils/log.h>
22#include <audio_utils/spdif/SPDIFEncoder.h>
23
24#include "AC3FrameScanner.h"
25#include "DTSFrameScanner.h"
26
27namespace android {
28
29// Burst Preamble defined in IEC61937-1
30const uint16_t SPDIFEncoder::kSPDIFSync1 = 0xF872; // Pa
31const uint16_t SPDIFEncoder::kSPDIFSync2 = 0x4E1F; // Pb
32
33static int32_t sEndianDetector = 1;
34#define isLittleEndian() (*((uint8_t *)&sEndianDetector))
35
36SPDIFEncoder::SPDIFEncoder(audio_format_t format)
37 : mFramer(NULL)
38 , mSampleRate(48000)
39 , mBurstBuffer(NULL)
40 , mBurstBufferSizeBytes(0)
41 , mRateMultiplier(1)
42 , mBurstFrames(0)
43 , mByteCursor(0)
44 , mBitstreamNumber(0)
45 , mPayloadBytesPending(0)
46 , mScanning(true)
47{
48 switch(format) {
49 case AUDIO_FORMAT_AC3:
50 case AUDIO_FORMAT_E_AC3:
51 mFramer = new AC3FrameScanner(format);
52 break;
53 case AUDIO_FORMAT_DTS:
54 case AUDIO_FORMAT_DTS_HD:
55 mFramer = new DTSFrameScanner();
56 break;
57 default:
58 break;
59 }
60
61 // This a programmer error. Call isFormatSupported() first.
62 LOG_ALWAYS_FATAL_IF((mFramer == NULL),
63 "SPDIFEncoder: invalid audio format = 0x%08X", format);
64
65 mBurstBufferSizeBytes = sizeof(uint16_t)
66 * SPDIF_ENCODED_CHANNEL_COUNT
67 * mFramer->getMaxSampleFramesPerSyncFrame();
68
69 ALOGI("SPDIFEncoder: mBurstBufferSizeBytes = %zu, littleEndian = %d",
70 mBurstBufferSizeBytes, isLittleEndian());
71 mBurstBuffer = new uint16_t[mBurstBufferSizeBytes >> 1];
72 clearBurstBuffer();
73}
74
75SPDIFEncoder::SPDIFEncoder()
76 : SPDIFEncoder(AUDIO_FORMAT_AC3)
77{
78}
79
80SPDIFEncoder::~SPDIFEncoder()
81{
82 delete[] mBurstBuffer;
83 delete mFramer;
84}
85
86bool SPDIFEncoder::isFormatSupported(audio_format_t format)
87{
88 switch(format) {
89 case AUDIO_FORMAT_AC3:
90 case AUDIO_FORMAT_E_AC3:
91 case AUDIO_FORMAT_DTS:
92 case AUDIO_FORMAT_DTS_HD:
93 return true;
94 default:
95 return false;
96 }
97}
98
99int SPDIFEncoder::getBytesPerOutputFrame()
100{
101 return SPDIF_ENCODED_CHANNEL_COUNT * sizeof(int16_t);
102}
103
104void SPDIFEncoder::writeBurstBufferShorts(const uint16_t *buffer, size_t numShorts)
105{
106 // avoid static analyser warning
107 LOG_ALWAYS_FATAL_IF((mBurstBuffer == NULL), "mBurstBuffer never allocated");
108 mByteCursor = (mByteCursor + 1) & ~1; // round up to even byte
109 size_t bytesToWrite = numShorts * sizeof(uint16_t);
110 if ((mByteCursor + bytesToWrite) > mBurstBufferSizeBytes) {
111 ALOGE("SPDIFEncoder: Burst buffer overflow!");
112 reset();
113 return;
114 }
115 memcpy(&mBurstBuffer[mByteCursor >> 1], buffer, bytesToWrite);
116 mByteCursor += bytesToWrite;
117}
118
119// Pack the bytes into the short buffer in the order:
120// byte[0] -> short[0] MSB
121// byte[1] -> short[0] LSB
122// byte[2] -> short[1] MSB
123// byte[3] -> short[1] LSB
124// etcetera
125// This way they should come out in the correct order for SPDIF on both
126// Big and Little Endian CPUs.
127void SPDIFEncoder::writeBurstBufferBytes(const uint8_t *buffer, size_t numBytes)
128{
129 size_t bytesToWrite = numBytes;
130 if ((mByteCursor + bytesToWrite) > mBurstBufferSizeBytes) {
131 ALOGE("SPDIFEncoder: Burst buffer overflow!");
132 clearBurstBuffer();
133 return;
134 }
135 uint16_t pad = mBurstBuffer[mByteCursor >> 1];
136 for (size_t i = 0; i < bytesToWrite; i++) {
137 if (mByteCursor & 1 ) {
138 pad |= *buffer++; // put second byte in LSB
139 mBurstBuffer[mByteCursor >> 1] = pad;
140 pad = 0;
141 } else {
142 pad |= (*buffer++) << 8; // put first byte in MSB
143 }
144 mByteCursor++;
145 }
146 // Save partially filled short.
147 if (mByteCursor & 1 ){
148 mBurstBuffer[mByteCursor >> 1] = pad;
149 }
150}
151
152void SPDIFEncoder::sendZeroPad()
153{
154 // Pad remainder of burst with zeros.
155 size_t burstSize = mFramer->getSampleFramesPerSyncFrame() * sizeof(uint16_t)
156 * SPDIF_ENCODED_CHANNEL_COUNT;
157 if (mByteCursor > burstSize) {
158 ALOGE("SPDIFEncoder: Burst buffer, contents too large!");
159 clearBurstBuffer();
160 } else {
161 // We don't have to write zeros because buffer already set to zero
162 // by clearBurstBuffer(). Just pretend we wrote zeros by
163 // incrementing cursor.
164 mByteCursor = burstSize;
165 }
166}
167
168void SPDIFEncoder::reset()
169{
170 ALOGV("SPDIFEncoder: reset()");
171 clearBurstBuffer();
172 if (mFramer != NULL) {
173 mFramer->resetBurst();
174 }
175 mPayloadBytesPending = 0;
176 mScanning = true;
177}
178
179void SPDIFEncoder::flushBurstBuffer()
180{
181 const int preambleSize = 4 * sizeof(uint16_t);
182 if (mByteCursor > preambleSize) {
183 // Set lengthCode for valid payload before zeroPad.
184 uint16_t numBytes = (mByteCursor - preambleSize);
185 mBurstBuffer[3] = mFramer->convertBytesToLengthCode(numBytes);
186
187 sendZeroPad();
188 writeOutput(mBurstBuffer, mByteCursor);
189 }
190 reset();
191}
192
193void SPDIFEncoder::clearBurstBuffer()
194{
195 if (mBurstBuffer) {
196 memset(mBurstBuffer, 0, mBurstBufferSizeBytes);
197 }
198 mByteCursor = 0;
199}
200
201void SPDIFEncoder::startDataBurst()
202{
203 // Encode IEC61937-1 Burst Preamble
204 uint16_t preamble[4];
205
206 uint16_t burstInfo = (mBitstreamNumber << 13)
207 | (mFramer->getDataTypeInfo() << 8)
208 | mFramer->getDataType();
209
210 mRateMultiplier = mFramer->getRateMultiplier();
211
212 preamble[0] = kSPDIFSync1;
213 preamble[1] = kSPDIFSync2;
214 preamble[2] = burstInfo;
215 preamble[3] = 0; // lengthCode - This will get set after the buffer is full.
216 writeBurstBufferShorts(preamble, 4);
217}
218
219size_t SPDIFEncoder::startSyncFrame()
220{
221 // Write start of encoded frame that was buffered in frame detector.
222 size_t syncSize = mFramer->getHeaderSizeBytes();
223 writeBurstBufferBytes(mFramer->getHeaderAddress(), syncSize);
224 return mFramer->getFrameSizeBytes() - syncSize;
225}
226
227// Wraps raw encoded data into a data burst.
228ssize_t SPDIFEncoder::write( const void *buffer, size_t numBytes )
229{
230 size_t bytesLeft = numBytes;
231 const uint8_t *data = (const uint8_t *)buffer;
232 ALOGV("SPDIFEncoder: mScanning = %d, write(buffer[0] = 0x%02X, numBytes = %zu)",
233 mScanning, (uint) *data, numBytes);
234 while (bytesLeft > 0) {
235 if (mScanning) {
236 // Look for beginning of next encoded frame.
237 if (mFramer->scan(*data)) {
238 if (mByteCursor == 0) {
239 startDataBurst();
240 } else if (mFramer->isFirstInBurst()) {
241 // Make sure that this frame is at the beginning of the data burst.
242 flushBurstBuffer();
243 startDataBurst();
244 }
245 mPayloadBytesPending = startSyncFrame();
246 mScanning = false;
247 }
248 data++;
249 bytesLeft--;
250 } else {
251 // Write payload until we hit end of frame.
252 size_t bytesToWrite = bytesLeft;
253 // Only write as many as we need to finish the frame.
254 if (bytesToWrite > mPayloadBytesPending) {
255 bytesToWrite = mPayloadBytesPending;
256 }
257 writeBurstBufferBytes(data, bytesToWrite);
258
259 data += bytesToWrite;
260 bytesLeft -= bytesToWrite;
261 mPayloadBytesPending -= bytesToWrite;
262
263 // If we have all the payload then send a data burst.
264 if (mPayloadBytesPending == 0) {
265 if (mFramer->isLastInBurst()) {
266 flushBurstBuffer();
267 }
268 mScanning = true;
269 }
270 }
271 }
272 return numBytes;
273}
274
275} // namespace android