1 /* 2 * 3 * Copyright 2015, The Android Open Source Project 4 * 5 * Licensed under the Apache License, Version 2.0 (the "License"); 6 * you may not use this file except in compliance with the License. 7 * You may obtain a copy of the License at 8 * 9 * http://www.apache.org/licenses/LICENSE-2.0 10 * 11 * Unless required by applicable law or agreed to in writing, software 12 * distributed under the License is distributed on an "AS IS" BASIS, 13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 * See the License for the specific language governing permissions and 15 * limitations under the License. 16 */ 17 18 #pragma once 19 20 #include <stdint.h> 21 #include <sys/types.h> 22 23 #include <system/audio.h> 24 25 #include "AudioStreamOut.h" 26 27 #include <afutils/NBAIO_Tee.h> 28 #include <audio_utils/spdif/SPDIFEncoder.h> 29 30 namespace android { 31 32 /** 33 * Stream that is a PCM data burst in the HAL but looks like an encoded stream 34 * to the AudioFlinger. Wraps encoded data in an SPDIF wrapper per IEC61973-3. 35 */ 36 class SpdifStreamOut : public AudioStreamOut { 37 public: 38 39 SpdifStreamOut(AudioHwDevice *dev, audio_output_flags_t flags, 40 audio_format_t format); 41 42 status_t open( 43 audio_io_handle_t handle, 44 audio_devices_t devices, 45 struct audio_config *config, 46 const char *address) override; 47 48 /** 49 * Write audio buffer to driver. Returns number of bytes written, or a 50 * negative status_t. If at least one frame was written successfully prior to the error, 51 * it is suggested that the driver return that successful (short) byte count 52 * and then return an error in the subsequent call. 53 * 54 * If set_callback() has previously been called to enable non-blocking mode 55 * the write() is not allowed to block. It must write only the number of 56 * bytes that currently fit in the driver/hardware buffer and then return 57 * this byte count. If this is less than the requested write size the 58 * callback function must be called when more space is available in the 59 * driver/hardware buffer. 60 */ 61 ssize_t write(const void* buffer, size_t bytes) override; 62 63 /** 64 * @return frame size from the perspective of the application and the AudioFlinger. 65 */ getFrameSize()66 [[nodiscard]] size_t getFrameSize() const override { return sizeof(int8_t); } 67 68 /** 69 * @return audio_config_base_t from the perspective of the application and the AudioFlinger. 70 */ getAudioProperties()71 [[nodiscard]] audio_config_base_t getAudioProperties() const override { 72 return mApplicationConfig; 73 } 74 75 /** 76 * @return format from the perspective of the application and the AudioFlinger. 77 */ getFormat()78 [[nodiscard]] virtual audio_format_t getFormat() const { return mApplicationConfig.format; } 79 80 /** 81 * The HAL may be running at a higher sample rate if, for example, playing wrapped EAC3. 82 * @return sample rate from the perspective of the application and the AudioFlinger. 83 */ getSampleRate()84 [[nodiscard]] virtual uint32_t getSampleRate() const { return mApplicationConfig.sample_rate; } 85 86 /** 87 * The HAL is in stereo mode when playing multi-channel compressed audio over HDMI. 88 * @return channel mask from the perspective of the application and the AudioFlinger. 89 */ getChannelMask()90 [[nodiscard]] virtual audio_channel_mask_t getChannelMask() const { 91 return mApplicationConfig.channel_mask; 92 } 93 94 status_t flush() override; 95 status_t standby() override; 96 97 private: 98 99 class MySPDIFEncoder : public SPDIFEncoder 100 { 101 public: MySPDIFEncoder(SpdifStreamOut * spdifStreamOut,audio_format_t format)102 MySPDIFEncoder(SpdifStreamOut *spdifStreamOut, audio_format_t format) 103 : SPDIFEncoder(format) 104 , mSpdifStreamOut(spdifStreamOut) 105 { 106 } 107 writeOutput(const void * buffer,size_t bytes)108 ssize_t writeOutput(const void* buffer, size_t bytes) override 109 { 110 return mSpdifStreamOut->writeDataBurst(buffer, bytes); 111 } 112 protected: 113 SpdifStreamOut * const mSpdifStreamOut; 114 }; 115 116 MySPDIFEncoder mSpdifEncoder; 117 audio_config_base_t mApplicationConfig = AUDIO_CONFIG_BASE_INITIALIZER; 118 119 ssize_t writeDataBurst(const void* data, size_t bytes); 120 121 #ifdef TEE_SINK 122 NBAIO_Tee mTee; 123 #endif 124 125 }; 126 127 } // namespace android 128