/* ** ** Copyright 2014, The Android Open Source Project ** ** Licensed under the Apache License, Version 2.0 (the "License"); ** you may not use this file except in compliance with the License. ** You may obtain a copy of the License at ** ** http://www.apache.org/licenses/LICENSE-2.0 ** ** Unless required by applicable law or agreed to in writing, software ** distributed under the License is distributed on an "AS IS" BASIS, ** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. ** See the License for the specific language governing permissions and ** limitations under the License. */ #define LOG_TAG "AudioSPDIF" #include <utils/Log.h> #include <audio_utils/spdif/FrameScanner.h> namespace android { #define SPDIF_DATA_TYPE_AC3 1 #define SPDIF_DATA_TYPE_E_AC3 21 #define AC3_SYNCWORD_SIZE 2 FrameScanner::FrameScanner(int dataType) : mSampleRate(0) , mRateMultiplier(1) , mFrameSizeBytes(0) , mDataType(dataType) , mDataTypeInfo(0) { } FrameScanner::~FrameScanner() { } // ------------------- AC3 ----------------------------------------------------- // These values are from the AC3 spec. Do not change them. const uint8_t AC3FrameScanner::kAC3SyncByte1 = 0x0B; const uint8_t AC3FrameScanner::kAC3SyncByte2 = 0x77; const uint16_t AC3FrameScanner::kAC3SampleRateTable[AC3_NUM_SAMPLE_RATE_TABLE_ENTRIES] = { 48000, 44100, 32000 }; // Table contains number of 16-bit words in an AC3 frame. const uint16_t AC3FrameScanner::kAC3FrameSizeTable[AC3_NUM_FRAME_SIZE_TABLE_ENTRIES] [AC3_NUM_SAMPLE_RATE_TABLE_ENTRIES] = { { 64, 69, 96 }, { 64, 70, 96 }, { 80, 87, 120 }, { 80, 88, 120 }, { 96, 104, 144 }, { 96, 105, 144 }, { 112, 121, 168 }, { 112, 122, 168 }, { 128, 139, 192 }, { 128, 140, 192 }, { 160, 174, 240 }, { 160, 175, 240 }, { 192, 208, 288 }, { 192, 209, 288 }, { 224, 243, 336 }, { 224, 244, 336 }, { 256, 278, 384 }, { 256, 279, 384 }, { 320, 348, 480 }, { 320, 349, 480 }, { 384, 417, 576 }, { 384, 418, 576 }, { 448, 487, 672 }, { 448, 488, 672 }, { 512, 557, 768 }, { 512, 558, 768 }, { 640, 696, 960 }, { 640, 697, 960 }, { 768, 835, 1152 }, { 768, 836, 1152 }, { 896, 975, 1344 }, { 896, 976, 1344 }, { 1024, 1114, 1536 }, { 1024, 1115, 1536 }, { 1152, 1253, 1728 }, { 1152, 1254, 1728 }, { 1280, 1393, 1920 }, { 1280, 1394, 1920 } }; const uint16_t AC3FrameScanner::kEAC3ReducedSampleRateTable[AC3_NUM_SAMPLE_RATE_TABLE_ENTRIES] = { 24000, 22050, 16000 }; const uint16_t AC3FrameScanner::kEAC3BlocksPerFrameTable[EAC3_NUM_BLOCKS_PER_FRAME_TABLE_ENTRIES] = { 1, 2, 3, 6 }; // ----------------------------------------------------------------------------- // Scanner for AC3 byte streams. AC3FrameScanner::AC3FrameScanner() : FrameScanner(SPDIF_DATA_TYPE_AC3) , mState(STATE_EXPECTING_SYNC_1) , mBytesSkipped(0) , mAudioBlocksPerSyncFrame(6) , mCursor(AC3_SYNCWORD_SIZE) // past sync word , mStreamType(0) , mSubstreamID(0) , mFormatDumpCount(0) { memset(mSubstreamBlockCounts, 0, sizeof(mSubstreamBlockCounts)); // Define beginning of syncinfo for getSyncAddress() mHeaderBuffer[0] = kAC3SyncByte1; mHeaderBuffer[1] = kAC3SyncByte2; } AC3FrameScanner::~AC3FrameScanner() { } int AC3FrameScanner::getSampleFramesPerSyncFrame() const { return mRateMultiplier * AC3_MAX_BLOCKS_PER_SYNC_FRAME_BLOCK * AC3_PCM_FRAMES_PER_BLOCK; } void AC3FrameScanner::resetBurst() { for (int i = 0; i < EAC3_MAX_SUBSTREAMS; i++) { if (mSubstreamBlockCounts[i] >= AC3_MAX_BLOCKS_PER_SYNC_FRAME_BLOCK) { mSubstreamBlockCounts[i] -= AC3_MAX_BLOCKS_PER_SYNC_FRAME_BLOCK; } else if (mSubstreamBlockCounts[i] > 0) { ALOGW("EAC3 substream[%d] has only %d audio blocks!", i, mSubstreamBlockCounts[i]); mSubstreamBlockCounts[i] = 0; } } } // per IEC 61973-3 Paragraph 5.3.3 // We have to send 6 audio blocks on all active substreams. // Substream zero must be the first. // We don't know if we have all the blocks we need until we see // the 7th block of substream#0. bool AC3FrameScanner::isFirstInBurst() { if (mDataType == SPDIF_DATA_TYPE_E_AC3) { if (((mStreamType == 0) || (mStreamType == 2)) && (mSubstreamID == 0) // The ">" is intentional. We have to see the beginning of the block // in the next burst before we can send the current burst. && (mSubstreamBlockCounts[0] > AC3_MAX_BLOCKS_PER_SYNC_FRAME_BLOCK)) { return true; } } return false; } bool AC3FrameScanner::isLastInBurst() { // For EAC3 we don't know if we are the end until we see a // frame that must be at the beginning. See isFirstInBurst(). return (mDataType != SPDIF_DATA_TYPE_E_AC3); // Just one AC3 frame per burst. } // Parse AC3 header. // Detect whether the stream is AC3 or EAC3. Extract data depending on type. // Sets mDataType, mFrameSizeBytes, mAudioBlocksPerSyncFrame, // mSampleRate, mRateMultiplier, mLengthCode. // // @return next state for scanner AC3FrameScanner::State AC3FrameScanner::parseHeader() { // Interpret bsid based on paragraph E2.3.1.6 of EAC3 spec. int bsid = mHeaderBuffer[5] >> 3; // bitstream ID // Check BSID to see if this is EAC3 or regular AC3 if ((bsid >= 10) && (bsid <= 16)) { mDataType = SPDIF_DATA_TYPE_E_AC3; } else if ((bsid >= 0) && (bsid <= 8)) { mDataType = SPDIF_DATA_TYPE_AC3; } else { ALOGW("AC3 bsid = %d not supported", bsid); return STATE_EXPECTING_SYNC_1; } // The names fscod, frmsiz are from the AC3 spec. int fscod = mHeaderBuffer[4] >> 6; if (mDataType == SPDIF_DATA_TYPE_E_AC3) { mStreamType = mHeaderBuffer[2] >> 6; // strmtyp in spec mSubstreamID = (mHeaderBuffer[2] >> 3) & 0x07; // Frame size is explicit in EAC3. Paragraph E2.3.1.3 int frmsiz = ((mHeaderBuffer[2] & 0x07) << 8) + mHeaderBuffer[3]; mFrameSizeBytes = (frmsiz + 1) * sizeof(int16_t); int numblkscod = 3; // 6 blocks default if (fscod == 3) { int fscod2 = (mHeaderBuffer[4] >> 4) & 0x03; if (fscod2 >= AC3_NUM_SAMPLE_RATE_TABLE_ENTRIES) { ALOGW("Invalid EAC3 fscod2 = %d\n", fscod2); return STATE_EXPECTING_SYNC_1; } else { mSampleRate = kEAC3ReducedSampleRateTable[fscod2]; } } else { mSampleRate = kAC3SampleRateTable[fscod]; numblkscod = (mHeaderBuffer[4] >> 4) & 0x03; } mRateMultiplier = EAC3_RATE_MULTIPLIER; // per IEC 61973-3 Paragraph 5.3.3 // Don't send data burst until we have 6 blocks per substream. mAudioBlocksPerSyncFrame = kEAC3BlocksPerFrameTable[numblkscod]; // Keep track of how many audio blocks we have for each substream. // This should be safe because mSubstreamID is ANDed with 0x07 above. // And the array is allocated as [8]. mSubstreamBlockCounts[mSubstreamID] += mAudioBlocksPerSyncFrame; // Print enough so we can see all the substreams. ALOGD_IF((mFormatDumpCount < 3*8 ), "EAC3 mStreamType = %d, mSubstreamID = %d", mStreamType, mSubstreamID); } else { // regular AC3 // Extract sample rate and frame size from codes. unsigned int frmsizcod = mHeaderBuffer[4] & 0x3F; // frame size code if (fscod >= AC3_NUM_SAMPLE_RATE_TABLE_ENTRIES) { ALOGW("Invalid AC3 sampleRateCode = %d\n", fscod); return STATE_EXPECTING_SYNC_1; } else if (frmsizcod >= AC3_NUM_FRAME_SIZE_TABLE_ENTRIES) { ALOGW("Invalid AC3 frameSizeCode = %d\n", frmsizcod); return STATE_EXPECTING_SYNC_1; } else { mSampleRate = kAC3SampleRateTable[fscod]; mRateMultiplier = 1; mFrameSizeBytes = sizeof(uint16_t) * kAC3FrameSizeTable[frmsizcod][fscod]; } mAudioBlocksPerSyncFrame = 6; } ALOGI_IF((mFormatDumpCount == 0), "AC3 frame rate = %d * %d, size = %d, audioBlocksPerSyncFrame = %d\n", mSampleRate, mRateMultiplier, mFrameSizeBytes, mAudioBlocksPerSyncFrame); mFormatDumpCount++; return STATE_GOT_HEADER; } // State machine that scans for AC3 headers in a byte stream. // @return true if we have detected a complete and valid header. bool AC3FrameScanner::scan(uint8_t byte) { State nextState = mState; switch (mState) { case STATE_GOT_HEADER: nextState = STATE_EXPECTING_SYNC_1; // deliberately fall through case STATE_EXPECTING_SYNC_1: if (byte == kAC3SyncByte1) { nextState = STATE_EXPECTING_SYNC_2; // advance } else { mBytesSkipped += 1; // skip unsynchronized data } break; case STATE_EXPECTING_SYNC_2: if (byte == kAC3SyncByte2) { if (mBytesSkipped > 0) { ALOGI("WARNING AC3 skipped %u bytes looking for a valid header.\n", mBytesSkipped); mBytesSkipped = 0; } mCursor = AC3_SYNCWORD_SIZE; nextState = STATE_GATHERING; // advance } else if (byte == kAC3SyncByte1) { nextState = STATE_EXPECTING_SYNC_2; // resync } else { nextState = STATE_EXPECTING_SYNC_1; // restart } break; case STATE_GATHERING: mHeaderBuffer[mCursor++] = byte; // save for getSyncAddress() if (mCursor >= sizeof(mHeaderBuffer)) { nextState = parseHeader(); } break; default: ALOGE("AC3FrameScanner: invalid state = %d\n", mState); nextState = STATE_EXPECTING_SYNC_1; // restart break; } mState = nextState; return mState == STATE_GOT_HEADER; } } // namespace android