1 /*
2  * Copyright 2023, 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 // #define LOG_NDEBUG 0
22 #include <log/log.h>
23 #include <audio_utils/spdif/SPDIFDecoder.h>
24 
25 #include "SPDIFFrameScanner.h"
26 
27 namespace android {
28 
SPDIFDecoder(audio_format_t format)29 SPDIFDecoder::SPDIFDecoder(audio_format_t format)
30   : mFramer(std::make_unique<SPDIFFrameScanner>(format))
31   , mBurstDataBuffer(sizeof(uint16_t) * kSpdifEncodedChannelCount
32             * mFramer->getMaxSampleFramesPerSyncFrame())
33   , mPayloadBytesPending(0)
34   , mPayloadBytesRead(0)
35   , mScanning(true) {
36 }
37 
isFormatSupported(audio_format_t format)38 bool SPDIFDecoder::isFormatSupported(audio_format_t format) {
39     switch (format) {
40         case AUDIO_FORMAT_AC3:
41         case AUDIO_FORMAT_E_AC3:
42         case AUDIO_FORMAT_E_AC3_JOC:
43             return true;
44         default:
45             return false;
46     }
47 }
48 
reset()49 void SPDIFDecoder::reset() {
50     ALOGV("SPDIFDecoder: reset()");
51     if (mFramer != NULL) {
52         mFramer->resetBurst();
53     }
54     mPayloadBytesPending = 0;
55     mPayloadBytesRead = 0;
56     mScanning = true;
57 }
58 
fillBurstDataBuffer()59 ssize_t SPDIFDecoder::fillBurstDataBuffer() {
60     const auto bytesToFill = mBurstDataBuffer.availableToWrite();
61     std::vector<uint8_t> tmpBuffer(bytesToFill);
62     auto bytesRead = readInput(&tmpBuffer[0], bytesToFill);
63     if (bytesRead > 0) {
64         ALOGV("SPDIFDecoder: read %zd burst data bytes", bytesRead);
65         auto written = mBurstDataBuffer.write(tmpBuffer.data(), bytesRead);
66         LOG_ALWAYS_FATAL_IF(written != bytesRead);
67     }
68     return bytesRead;
69 }
70 
71 // Read burst payload data.
read(void * buffer,size_t numBytes)72 ssize_t SPDIFDecoder::read(void *buffer, size_t numBytes) {
73     size_t bytesRead = 0;
74     uint16_t *buf = reinterpret_cast<uint16_t *>(buffer);
75     ALOGV("SPDIFDecoder: mScanning = %d numBytes = %zu", mScanning, numBytes);
76     while (bytesRead < numBytes) {
77         if (mBurstDataBuffer.empty()) {
78             if (fillBurstDataBuffer() <= 0) {
79               return -1;
80             }
81             if (bytesRead > 0) {
82                 return bytesRead;
83             }
84         }
85         if (mScanning) {
86             // Look for beginning of next IEC61937 frame.
87             if (!mBurstDataBuffer.empty() && mFramer->scan(mBurstDataBuffer.readByte())) {
88                 mPayloadBytesPending = mFramer->getFrameSizeBytes();
89                 mPayloadBytesRead = 0;
90                 mScanning = false;
91             }
92         } else {
93             // Read until we hit end of burst payload.
94             size_t bytesToRead = std::min(numBytes, mBurstDataBuffer.availableToRead());
95             // Only read as many as we need to finish the frame.
96             if (bytesToRead > mPayloadBytesPending) {
97                 bytesToRead = mPayloadBytesPending;
98             }
99             // Unpack the bytes from short buffer into byte array in the order:
100             //   short[0] MSB -> byte[0]
101             //   short[0] LSB -> byte[1]
102             //   short[1] MSB -> byte[2]
103             //   short[1] LSB -> byte[3]
104             //   ...
105             // This way the payload should be extracted correctly on both
106             // Big and Little Endian CPUs.
107             uint16_t pad = 0;
108             size_t actualBytesRead = 0;
109             for (; !mBurstDataBuffer.empty() && actualBytesRead < bytesToRead; ++actualBytesRead) {
110                 if (mPayloadBytesRead & 1) {
111                     pad |= mBurstDataBuffer.readByte();  // Read second byte from LSB
112                     buf[bytesRead >> 1] = pad;
113                     pad = 0;
114                 } else {
115                     pad |= mBurstDataBuffer.readByte() << 8;  // Read first byte from MSB
116                 }
117                 mPayloadBytesRead++;
118                 bytesRead++;
119             }
120             // Read out last byte from partially filled short.
121             if (mPayloadBytesRead & 1) {
122                 reinterpret_cast<uint8_t *>(buffer)[bytesRead] = pad >> 8;
123             }
124 
125             buf += (bytesRead >> 1);
126             mPayloadBytesPending -= actualBytesRead;
127             mPayloadBytesRead += actualBytesRead;
128 
129             // If we have read the entire payload, prepare to look for the next IEC61937 frame.
130             if (mPayloadBytesPending == 0) {
131                 reset();
132             }
133         }
134     }
135     return numBytes;
136 }
137 
138 }  // namespace android
139