blob: 3c84d73cd19cced9aa1a625c0169210b0a8ca69b [file] [log] [blame]
/*
* 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.
*/
#ifndef ANDROID_AUDIO_SPDIF_ENCODER_H
#define ANDROID_AUDIO_SPDIF_ENCODER_H
#include <stdint.h>
#include <system/audio.h>
#include <audio_utils/spdif/FrameScanner.h>
namespace android {
/**
* Scan the incoming byte stream for a frame sync.
* Then wrap the encoded frame in a data burst and send it as if it were PCM.
* The receiver will see the data burst header and decode the wrapped frame.
*/
#define SPDIF_MAX_CHANNELS 8
#define SPDIF_ENCODED_CHANNEL_COUNT 2
class SPDIFEncoder {
public:
explicit SPDIFEncoder(audio_format_t format);
// Defaults to AC3 format. Was in original API.
SPDIFEncoder();
virtual ~SPDIFEncoder();
/**
* Write encoded data to be wrapped for SPDIF.
* The compressed frames do not have to be aligned.
* @return number of bytes written or negative error
*/
ssize_t write( const void* buffer, size_t numBytes );
/**
* Called by SPDIFEncoder when it is ready to output a data burst.
* Must be implemented in the subclass.
* @return number of bytes written or negative error
*/
virtual ssize_t writeOutput( const void* buffer, size_t numBytes ) = 0;
/**
* Get ratio of the encoded data burst sample rate to the encoded rate.
* For example, EAC3 data bursts are 4X the encoded rate.
*/
uint32_t getRateMultiplier() const { return mRateMultiplier; }
/**
* @return number of PCM frames in a data burst
*/
uint32_t getBurstFrames() const { return mBurstFrames; }
/**
* @return number of bytes per PCM frame for the data burst
*/
int getBytesPerOutputFrame();
/**
* @return true if we can wrap this format in an SPDIF stream
*/
static bool isFormatSupported(audio_format_t format);
/**
* Discard any data in the buffer. Reset frame scanners.
* This should be called when seeking to a new position in the stream.
*/
void reset();
protected:
void clearBurstBuffer();
void writeBurstBufferShorts(const uint16_t* buffer, size_t numBytes);
void writeBurstBufferBytes(const uint8_t* buffer, size_t numBytes);
void sendZeroPad();
void flushBurstBuffer();
void startDataBurst();
size_t startSyncFrame();
// Works with various formats including AC3.
FrameScanner *mFramer;
uint32_t mSampleRate;
size_t mFrameSize; // size of sync frame in bytes
uint16_t *mBurstBuffer; // ALSA wants to get SPDIF data as shorts.
size_t mBurstBufferSizeBytes;
uint32_t mRateMultiplier;
uint32_t mBurstFrames;
size_t mByteCursor; // cursor into data burst
int mBitstreamNumber;
size_t mPayloadBytesPending; // number of bytes needed to finish burst
// state variable, true if scanning for start of frame
bool mScanning;
static const uint16_t kSPDIFSync1; // Pa
static const uint16_t kSPDIFSync2; // Pb
};
} // namespace android
#endif // ANDROID_AUDIO_SPDIF_ENCODER_H