| /* |
| ** |
| ** Copyright 2015, 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_SPDIF_STREAM_OUT_H |
| #define ANDROID_SPDIF_STREAM_OUT_H |
| |
| #include <stdint.h> |
| #include <sys/types.h> |
| |
| #include <system/audio.h> |
| |
| #include "AudioStreamOut.h" |
| |
| #include <afutils/NBAIO_Tee.h> |
| #include <audio_utils/spdif/SPDIFEncoder.h> |
| |
| namespace android { |
| |
| /** |
| * Stream that is a PCM data burst in the HAL but looks like an encoded stream |
| * to the AudioFlinger. Wraps encoded data in an SPDIF wrapper per IEC61973-3. |
| */ |
| class SpdifStreamOut : public AudioStreamOut { |
| public: |
| |
| SpdifStreamOut(AudioHwDevice *dev, audio_output_flags_t flags, |
| audio_format_t format); |
| |
| ~SpdifStreamOut() override = default; |
| |
| status_t open( |
| audio_io_handle_t handle, |
| audio_devices_t devices, |
| struct audio_config *config, |
| const char *address) override; |
| |
| /** |
| * Write audio buffer to driver. Returns number of bytes written, or a |
| * negative status_t. If at least one frame was written successfully prior to the error, |
| * it is suggested that the driver return that successful (short) byte count |
| * and then return an error in the subsequent call. |
| * |
| * If set_callback() has previously been called to enable non-blocking mode |
| * the write() is not allowed to block. It must write only the number of |
| * bytes that currently fit in the driver/hardware buffer and then return |
| * this byte count. If this is less than the requested write size the |
| * callback function must be called when more space is available in the |
| * driver/hardware buffer. |
| */ |
| ssize_t write(const void* buffer, size_t bytes) override; |
| |
| /** |
| * @return frame size from the perspective of the application and the AudioFlinger. |
| */ |
| [[nodiscard]] size_t getFrameSize() const override { return sizeof(int8_t); } |
| |
| /** |
| * @return audio_config_base_t from the perspective of the application and the AudioFlinger. |
| */ |
| [[nodiscard]] audio_config_base_t getAudioProperties() const override { |
| return mApplicationConfig; |
| } |
| |
| /** |
| * @return format from the perspective of the application and the AudioFlinger. |
| */ |
| [[nodiscard]] virtual audio_format_t getFormat() const { return mApplicationConfig.format; } |
| |
| /** |
| * The HAL may be running at a higher sample rate if, for example, playing wrapped EAC3. |
| * @return sample rate from the perspective of the application and the AudioFlinger. |
| */ |
| [[nodiscard]] virtual uint32_t getSampleRate() const { return mApplicationConfig.sample_rate; } |
| |
| /** |
| * The HAL is in stereo mode when playing multi-channel compressed audio over HDMI. |
| * @return channel mask from the perspective of the application and the AudioFlinger. |
| */ |
| [[nodiscard]] virtual audio_channel_mask_t getChannelMask() const { |
| return mApplicationConfig.channel_mask; |
| } |
| |
| status_t flush() override; |
| status_t standby() override; |
| |
| private: |
| |
| class MySPDIFEncoder : public SPDIFEncoder |
| { |
| public: |
| MySPDIFEncoder(SpdifStreamOut *spdifStreamOut, audio_format_t format) |
| : SPDIFEncoder(format) |
| , mSpdifStreamOut(spdifStreamOut) |
| { |
| } |
| |
| ssize_t writeOutput(const void* buffer, size_t bytes) override |
| { |
| return mSpdifStreamOut->writeDataBurst(buffer, bytes); |
| } |
| protected: |
| SpdifStreamOut * const mSpdifStreamOut; |
| }; |
| |
| MySPDIFEncoder mSpdifEncoder; |
| audio_config_base_t mApplicationConfig = AUDIO_CONFIG_BASE_INITIALIZER; |
| |
| ssize_t writeDataBurst(const void* data, size_t bytes); |
| |
| #ifdef TEE_SINK |
| NBAIO_Tee mTee; |
| #endif |
| |
| }; |
| |
| } // namespace android |
| |
| #endif // ANDROID_SPDIF_STREAM_OUT_H |