summaryrefslogtreecommitdiff
path: root/audio_proxy/service/StreamOutImpl.h
blob: 5a811f85bc8c06327a3630f2d0b49df2a5d9dd96 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
// Copyright (C) 2021 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.

#pragma once

// clang-format off
#include PATH(android/hardware/audio/FILE_VERSION/IStreamOut.h)
// clang-format on

#include <fmq/EventFlag.h>
#include <fmq/MessageQueue.h>
#include <hidl/MQDescriptor.h>
#include <hidl/Status.h>
#include <utils/Thread.h>

using android::sp;
using android::Thread;
using android::hardware::EventFlag;
using android::hardware::hidl_bitfield;
using android::hardware::hidl_string;
using android::hardware::hidl_vec;
using android::hardware::kSynchronizedReadWrite;
using android::hardware::MessageQueue;
using android::hardware::Return;
using android::hardware::Void;
using namespace android::hardware::audio::common::CPP_VERSION;
using namespace android::hardware::audio::CPP_VERSION;

namespace audio_proxy::service {

class BusOutputStream;
class WriteThread;

typedef void (*EventFlagDeleter)(EventFlag*);

class StreamOutImpl : public IStreamOut {
 public:
  using CommandMQ = MessageQueue<WriteCommand, kSynchronizedReadWrite>;
  using DataMQ = MessageQueue<uint8_t, kSynchronizedReadWrite>;
  using StatusMQ = MessageQueue<WriteStatus, kSynchronizedReadWrite>;

  StreamOutImpl(std::shared_ptr<BusOutputStream> stream, uint32_t bufferSizeMs,
                uint32_t latencyMs);
  ~StreamOutImpl() override;

  std::shared_ptr<BusOutputStream> getOutputStream();
  void updateOutputStream(std::shared_ptr<BusOutputStream> stream);

  // Methods from ::android::hardware::audio::CPP_VERSION::IStream follow.
  Return<uint64_t> getFrameSize() override;
  Return<uint64_t> getFrameCount() override;
  Return<uint64_t> getBufferSize() override;

#if MAJOR_VERSION >= 7
  Return<void> getSupportedProfiles(getSupportedProfiles_cb _hidl_cb) override;
  Return<Result> setAudioProperties(
      const AudioConfigBaseOptional& config) override;
#else
  Return<uint32_t> getSampleRate() override;
  Return<void> getSupportedSampleRates(
      AudioFormat format, getSupportedSampleRates_cb _hidl_cb) override;
  Return<void> getSupportedChannelMasks(
      AudioFormat format, getSupportedChannelMasks_cb _hidl_cb) override;
  Return<Result> setSampleRate(uint32_t sampleRateHz) override;
  Return<hidl_bitfield<AudioChannelMask>> getChannelMask() override;
  Return<Result> setChannelMask(hidl_bitfield<AudioChannelMask> mask) override;
  Return<AudioFormat> getFormat() override;
  Return<void> getSupportedFormats(getSupportedFormats_cb _hidl_cb) override;
  Return<Result> setFormat(AudioFormat format) override;
#endif

  Return<void> getAudioProperties(getAudioProperties_cb _hidl_cb) override;
  Return<Result> addEffect(uint64_t effectId) override;
  Return<Result> removeEffect(uint64_t effectId) override;
  Return<Result> standby() override;
  Return<void> getDevices(getDevices_cb _hidl_cb) override;
  Return<Result> setDevices(const hidl_vec<DeviceAddress>& devices) override;
  Return<void> getParameters(const hidl_vec<ParameterValue>& context,
                             const hidl_vec<hidl_string>& keys,
                             getParameters_cb _hidl_cb) override;
  Return<Result> setParameters(
      const hidl_vec<ParameterValue>& context,
      const hidl_vec<ParameterValue>& parameters) override;
  Return<Result> setHwAvSync(uint32_t hwAvSync) override;
  Return<Result> close() override;

  // Methods from ::android::hardware::audio::CPP_VERSION::IStreamOut follow.
  Return<uint32_t> getLatency() override;
  Return<Result> setVolume(float left, float right) override;
  Return<void> prepareForWriting(uint32_t frameSize, uint32_t framesCount,
                                 prepareForWriting_cb _hidl_cb) override;
  Return<void> getRenderPosition(getRenderPosition_cb _hidl_cb) override;
  Return<void> getNextWriteTimestamp(
      getNextWriteTimestamp_cb _hidl_cb) override;
  Return<Result> setCallback(const sp<IStreamOutCallback>& callback) override;
  Return<Result> clearCallback() override;
  Return<void> supportsPauseAndResume(
      supportsPauseAndResume_cb _hidl_cb) override;
  Return<Result> pause() override;
  Return<Result> resume() override;
  Return<bool> supportsDrain() override;
  Return<Result> drain(AudioDrain type) override;
  Return<Result> flush() override;
  Return<void> getPresentationPosition(
      getPresentationPosition_cb _hidl_cb) override;
  Return<Result> start() override;
  Return<Result> stop() override;
  Return<void> createMmapBuffer(int32_t minSizeFrames,
                                createMmapBuffer_cb _hidl_cb) override;
  Return<void> getMmapPosition(getMmapPosition_cb _hidl_cb) override;
#if MAJOR_VERSION >= 7
  Return<Result> updateSourceMetadata(
      const SourceMetadata& sourceMetadata) override;
#else
  Return<void> updateSourceMetadata(
      const SourceMetadata& sourceMetadata) override;
#endif
  Return<Result> selectPresentation(int32_t presentationId,
                                    int32_t programId) override;

#if MAJOR_VERSION >= 6
  Return<Result> setEventCallback(
      const sp<IStreamOutEventCallback>& callback) override;
  Return<void> getDualMonoMode(getDualMonoMode_cb _hidl_cb) override;
  Return<Result> setDualMonoMode(DualMonoMode mode) override;
  Return<void> getAudioDescriptionMixLevel(
      getAudioDescriptionMixLevel_cb _hidl_cb) override;
  Return<Result> setAudioDescriptionMixLevel(float leveldB) override;
  Return<void> getPlaybackRateParameters(
      getPlaybackRateParameters_cb _hidl_cb) override;
  Return<Result> setPlaybackRateParameters(
      const PlaybackRate& playbackRate) override;
#endif

 private:
  uint64_t estimateTotalPlayedFrames() const;

  // The object is always valid until close is called.
  std::shared_ptr<BusOutputStream> mStream;
#if MAJOR_VERSION >= 7
  const AudioConfigBase mConfig;
#else
  const AudioConfig mConfig;
#endif

  const uint32_t mBufferSizeMs;
  const uint32_t mLatencyMs;

  std::unique_ptr<CommandMQ> mCommandMQ;
  std::unique_ptr<DataMQ> mDataMQ;
  std::unique_ptr<StatusMQ> mStatusMQ;
  std::unique_ptr<EventFlag, EventFlagDeleter> mEventFlag;
  sp<WriteThread> mWriteThread;

  uint64_t mTotalPlayedFramesSinceStandby = 0;

  // Whether pause is called. It's used to avoid resuming when not paused.
  bool mIsPaused = false;
};

}  // namespace audio_proxy::service