1 // Copyright (C) 2021 The Android Open Source Project
2 //
3 // Licensed under the Apache License, Version 2.0 (the "License");
4 // you may not use this file except in compliance with the License.
5 // You may obtain a copy of the License at
6 //
7 //      http://www.apache.org/licenses/LICENSE-2.0
8 //
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS,
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 // See the License for the specific language governing permissions and
13 // limitations under the License.
14 
15 #pragma once
16 
17 #include <aidl/device/google/atv/audio_proxy/BnOutputStream.h>
18 #include <fmq/AidlMessageQueue.h>
19 #include <fmq/EventFlag.h>
20 #include <utils/Thread.h>
21 
22 using aidl::android::hardware::common::fmq::MQDescriptor;
23 using aidl::android::hardware::common::fmq::SynchronizedReadWrite;
24 using android::AidlMessageQueue;
25 using android::sp;
26 using android::Thread;
27 using android::hardware::EventFlag;
28 
29 using aidl::device::google::atv::audio_proxy::AudioDrain;
30 using aidl::device::google::atv::audio_proxy::BnOutputStream;
31 using aidl::device::google::atv::audio_proxy::MmapBufferInfo;
32 using aidl::device::google::atv::audio_proxy::PresentationPosition;
33 using aidl::device::google::atv::audio_proxy::WriteStatus;
34 
35 namespace audio_proxy {
36 class AudioProxyStreamOut;
37 
38 class OutputStreamImpl : public BnOutputStream {
39  public:
40   using DataMQ = AidlMessageQueue<int8_t, SynchronizedReadWrite>;
41   using DataMQDesc = MQDescriptor<int8_t, SynchronizedReadWrite>;
42   using StatusMQ = AidlMessageQueue<WriteStatus, SynchronizedReadWrite>;
43   using StatusMQDesc = MQDescriptor<WriteStatus, SynchronizedReadWrite>;
44 
45   explicit OutputStreamImpl(std::unique_ptr<AudioProxyStreamOut> stream);
46   ~OutputStreamImpl() override;
47 
48   ndk::ScopedAStatus prepareForWriting(int32_t frameSize, int32_t framesCount,
49                                        DataMQDesc* dataMQDesc,
50                                        StatusMQDesc* statusMQDesc) override;
51 
52   ndk::ScopedAStatus standby() override;
53   ndk::ScopedAStatus close() override;
54   ndk::ScopedAStatus pause() override;
55   ndk::ScopedAStatus resume() override;
56   ndk::ScopedAStatus drain(AudioDrain type) override;
57   ndk::ScopedAStatus flush() override;
58 
59   ndk::ScopedAStatus setVolume(float left, float right) override;
60 
61   ndk::ScopedAStatus getBufferSizeBytes(int64_t* bufferSizeBytes) override;
62   ndk::ScopedAStatus getLatencyMs(int32_t* latencyMs) override;
63 
64   ndk::ScopedAStatus start() override;
65   ndk::ScopedAStatus stop() override;
66   ndk::ScopedAStatus createMmapBuffer(int32_t minBufferSizeFrames,
67                                       MmapBufferInfo* info) override;
68   ndk::ScopedAStatus getMmapPosition(PresentationPosition* position) override;
69 
70  private:
71   typedef void (*EventFlagDeleter)(EventFlag*);
72 
73   ndk::ScopedAStatus closeImpl();
74 
75   std::unique_ptr<AudioProxyStreamOut> mStream;
76 
77   std::unique_ptr<DataMQ> mDataMQ;
78   std::unique_ptr<StatusMQ> mStatusMQ;
79   std::unique_ptr<EventFlag, EventFlagDeleter> mEventFlag;
80   std::atomic<bool> mStopWriteThread = false;
81   sp<Thread> mWriteThread;
82 };
83 
84 }  // namespace audio_proxy