• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2023 Huawei Device Co., Ltd.
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 
16 #ifndef AUDIO_ENDPOINT_H
17 #define AUDIO_ENDPOINT_H
18 
19 #include <sstream>
20 #include <memory>
21 #include <thread>
22 
23 #include "i_audio_renderer_sink.h"
24 #include "i_process_status_listener.h"
25 #include "linear_pos_time_model.h"
26 #include "audio_device_descriptor.h"
27 
28 namespace OHOS {
29 namespace AudioStandard {
30 // When AudioEndpoint is offline, notify the owner.
31 class IAudioEndpointStatusListener {
32 public:
33     enum HdiDeviceStatus : uint32_t {
34         STATUS_ONLINE = 0,
35         STATUS_OFFLINE,
36         STATUS_INVALID,
37     };
38 
39     /**
40      * When AudioEndpoint changed status, we need to notify AudioProcessStream.
41     */
42     virtual int32_t OnEndpointStatusChange(HdiDeviceStatus status) = 0;
43 };
44 
45 class AudioEndpoint : public IProcessStatusListener {
46 public:
47     static constexpr int32_t MAX_LINKED_PROCESS = 6; // 6
48     enum EndpointType : uint32_t {
49         TYPE_MMAP = 0,
50         TYPE_INVALID,
51         TYPE_INDEPENDENT,
52         TYPE_VOIP_MMAP
53     };
54 
55     enum EndpointStatus : uint32_t {
56         INVALID = 0,
57         UNLINKED, // no process linked
58         IDEL,     // no running process
59         STARTING, // calling start sink
60         RUNNING,  // at least one process is running
61         STOPPING, // calling stop sink
62         STOPPED   // sink stoped
63     };
64 
65     static std::shared_ptr<AudioEndpoint> CreateEndpoint(EndpointType type, uint64_t id,
66         const AudioProcessConfig &clientConfig, const AudioDeviceDescriptor &deviceInfo);
67     static std::string GenerateEndpointKey(AudioDeviceDescriptor &deviceInfo, int32_t endpointFlag);
68 
69     virtual std::string GetEndpointName() = 0;
70 
71     virtual EndpointType GetEndpointType() = 0;
72     virtual int32_t SetVolume(AudioStreamType streamType, float volume) = 0;
73     virtual int32_t ResolveBuffer(std::shared_ptr<OHAudioBuffer> &buffer) = 0;
74     virtual std::shared_ptr<OHAudioBuffer> GetBuffer() = 0;
75 
76     virtual EndpointStatus GetStatus() = 0;
77 
78     virtual void Release() = 0;
79 
80     virtual bool ShouldInnerCap() = 0;
81     virtual int32_t EnableFastInnerCap() = 0;
82     virtual int32_t DisableFastInnerCap() = 0;
83 
84     virtual int32_t LinkProcessStream(IAudioProcessStream *processStream) = 0;
85     virtual int32_t UnlinkProcessStream(IAudioProcessStream *processStream) = 0;
86 
87     virtual int32_t GetPreferBufferInfo(uint32_t &totalSizeInframe, uint32_t &spanSizeInframe) = 0;
88 
89     virtual void Dump(std::string &dumpString) = 0;
90 
91     virtual DeviceRole GetDeviceRole() = 0;
92     virtual AudioDeviceDescriptor &GetDeviceInfo() = 0;
93     virtual float GetMaxAmplitude() = 0;
94     virtual uint32_t GetLinkedProcessCount() = 0;
95 
96     virtual ~AudioEndpoint() = default;
97 private:
98     virtual bool Config(const AudioDeviceDescriptor &deviceInfo) = 0;
99 };
100 
101 class AudioEndpointSeparate : public AudioEndpoint {
102 public:
103     explicit AudioEndpointSeparate(EndpointType type, uint64_t id, AudioStreamType streamType);
104     ~AudioEndpointSeparate();
105 
106     bool Config(const AudioDeviceDescriptor &deviceInfo) override;
107     bool StartDevice();
108     bool StopDevice();
109 
110     // when audio process start.
111     int32_t OnStart(IAudioProcessStream *processStream) override;
112     // when audio process pause.
113     int32_t OnPause(IAudioProcessStream *processStream) override;
114     // when audio process request update handle info.
115     int32_t OnUpdateHandleInfo(IAudioProcessStream *processStream) override;
116     int32_t LinkProcessStream(IAudioProcessStream *processStream) override;
117     int32_t UnlinkProcessStream(IAudioProcessStream *processStream) override;
118     int32_t GetPreferBufferInfo(uint32_t &totalSizeInframe, uint32_t &spanSizeInframe) override;
119 
120     void Dump(std::string &dumpString) override;
121 
122     std::string GetEndpointName() override;
123 
GetEndpointType()124     inline EndpointType GetEndpointType() override
125     {
126         return endpointType_;
127     }
128 
129     // for inner-cap
130     bool ShouldInnerCap() override;
131     int32_t EnableFastInnerCap() override;
132     int32_t DisableFastInnerCap() override;
133 
134     int32_t SetVolume(AudioStreamType streamType, float volume) override;
135 
136     int32_t ResolveBuffer(std::shared_ptr<OHAudioBuffer> &buffer) override;
137 
138     std::shared_ptr<OHAudioBuffer> GetBuffer() override;
139 
140     EndpointStatus GetStatus() override;
141 
142     void Release() override;
143 
GetDeviceInfo()144     AudioDeviceDescriptor &GetDeviceInfo() override
145     {
146         return deviceInfo_;
147     }
148 
GetDeviceRole()149     DeviceRole GetDeviceRole() override
150     {
151         return deviceInfo_.deviceRole_;
152     }
153 
154     float GetMaxAmplitude() override;
155     uint32_t GetLinkedProcessCount() override;
156 private:
157     int32_t PrepareDeviceBuffer(const AudioDeviceDescriptor &deviceInfo);
158     int32_t GetAdapterBufferInfo(const AudioDeviceDescriptor &deviceInfo);
159     void ResyncPosition();
160     void InitAudiobuffer(bool resetReadWritePos);
161     void ProcessData(const std::vector<AudioStreamData> &srcDataList, const AudioStreamData &dstData);
162 
163     bool GetDeviceHandleInfo(uint64_t &frames, int64_t &nanoTime);
164     int32_t GetProcLastWriteDoneInfo(const std::shared_ptr<OHAudioBuffer> processBuffer, uint64_t curWriteFrame,
165         uint64_t &proHandleFrame, int64_t &proHandleTime);
166 
167     bool IsAnyProcessRunning();
168 
169     std::string GetStatusStr(EndpointStatus status);
170 
171     int32_t WriteToSpecialProcBuf(const std::shared_ptr<OHAudioBuffer> &procBuf, const BufferDesc &readBuf);
172     void WriteToProcessBuffers(const BufferDesc &readBuf);
173 
174 private:
175     static constexpr int64_t ONE_MILLISECOND_DURATION = 1000000; // 1ms
176     // SamplingRate EncodingType SampleFormat Channel
177     AudioDeviceDescriptor deviceInfo_ = AudioDeviceDescriptor(AudioDeviceDescriptor::DEVICE_INFO);
178     AudioStreamInfo dstStreamInfo_;
179     EndpointType endpointType_;
180     uint64_t id_ = 0;
181     AudioStreamType streamType_ = STREAM_DEFAULT;
182     std::mutex listLock_;
183     std::vector<IAudioProcessStream *> processList_;
184     std::vector<std::shared_ptr<OHAudioBuffer>> processBufferList_;
185 
186     std::atomic<bool> isInited_ = false;
187     std::shared_ptr<IMmapAudioRendererSink> fastSink_ = nullptr;
188     int64_t spanDuration_ = 0; // nano second
189     int64_t serverAheadReadTime_ = 0;
190     int dstBufferFd_ = -1; // -1: invalid fd.
191     uint32_t dstTotalSizeInframe_ = 0;
192     uint32_t dstSpanSizeInframe_ = 0;
193     uint32_t dstByteSizePerFrame_ = 0;
194     std::shared_ptr<OHAudioBuffer> dstAudioBuffer_ = nullptr;
195     std::atomic<EndpointStatus> endpointStatus_ = INVALID;
196 
197     std::mutex loopThreadLock_;
198     std::condition_variable workThreadCV_;
199 
200     bool isDeviceRunningInIdel_ = true; // will call start sink when linked.
201     bool needResyncPosition_ = true;
202 };
203 
204 } // namespace AudioStandard
205 } // namespace OHOS
206 #endif // AUDIO_ENDPOINT_H
207