1 /*
2 * Copyright (c) 2023 Shenzhen Kaihong Digital Industry Development 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 #include "audio_sink.h"
17 #include "common/media_log.h"
18
19 namespace OHOS {
20 namespace Sharing {
21
AudioSink(uint32_t playerId)22 AudioSink::AudioSink(uint32_t playerId) : audioRenderer_(nullptr)
23 {
24 SHARING_LOGD("playerId: %{public}u tid: %{public}d.", playerId, gettid());
25 playerId_ = playerId;
26 }
27
~AudioSink()28 AudioSink::~AudioSink()
29 {
30 SHARING_LOGD("playerId: %{public}u.", playerId_);
31 Stop();
32 Release();
33 SHARING_LOGD("renderthread release success,playerId: %{public}u.", playerId_);
34 }
35
Prepare()36 int32_t AudioSink::Prepare()
37 {
38 SHARING_LOGD("playerId: %{public}u.", playerId_);
39 audioRenderer_ = AudioStandard::AudioRenderer::Create(AudioStandard::AudioStreamType::STREAM_MUSIC);
40 if (!audioRenderer_) {
41 SHARING_LOGE("audioRenderer_ is NULL.");
42 return PLAYER_ERROR_EMPTY_INSTANCE;
43 }
44
45 return PLAYER_SUCCESS;
46 }
47
Prepare(int32_t channels,int32_t sampleRate)48 int32_t AudioSink::Prepare(int32_t channels, int32_t sampleRate)
49 {
50 SHARING_LOGD("channels(%{public}d) sampleRate(%{public}d) playerId: %{public}u.", channels, sampleRate, playerId_);
51 audioRenderer_ = AudioStandard::AudioRenderer::Create(AudioStandard::AudioStreamType::STREAM_MUSIC);
52 if (!audioRenderer_) {
53 SHARING_LOGE("audioRenderer_ is NULL.");
54 return PLAYER_ERROR_EMPTY_INSTANCE;
55 }
56
57 int32_t res = SetParameters(16, channels, sampleRate);
58 SHARING_LOGD("leave.");
59 return res;
60 }
61
Start()62 int32_t AudioSink::Start()
63 {
64 SHARING_LOGD("playerId: %{public}u.", playerId_);
65 if (!audioRenderer_) {
66 SHARING_LOGE("audioRenderer_ is NULL.");
67 return PLAYER_ERROR_EMPTY_INSTANCE;
68 }
69
70 audioRenderer_->Start();
71 running_ = true;
72 return PLAYER_SUCCESS;
73 }
74
Stop()75 int32_t AudioSink::Stop()
76 {
77 SHARING_LOGD("playerId: %{public}u.", playerId_);
78 if (!audioRenderer_) {
79 SHARING_LOGE("audioRenderer_ is NULL playerId: %{public}u!", playerId_);
80 return PLAYER_ERROR_EMPTY_INSTANCE;
81 }
82
83 if (!running_) {
84 SHARING_LOGE("running_ is false playerId: %{public}u!", playerId_);
85 return PLAYER_ERROR_INVALID_STATE;
86 }
87
88 running_ = false;
89 audioRenderer_->Stop();
90 SHARING_LOGD("success, playerId: %{public}u.", playerId_);
91 return PLAYER_SUCCESS;
92 }
93
Pause()94 int32_t AudioSink::Pause()
95 {
96 SHARING_LOGD("playerId: %{public}u.", playerId_);
97 if (!audioRenderer_) {
98 SHARING_LOGE("audioRenderer_ is NULL.");
99 return PLAYER_ERROR_EMPTY_INSTANCE;
100 }
101
102 if (audioRenderer_->Pause() != true) {
103 SHARING_LOGE("failed!");
104 return -1;
105 }
106
107 return PLAYER_SUCCESS;
108 }
109
Drain()110 int32_t AudioSink::Drain()
111 {
112 SHARING_LOGD("playerId: %{public}u.", playerId_);
113 if (!audioRenderer_) {
114 SHARING_LOGE("audioRenderer_ is NULL.");
115 return PLAYER_ERROR_EMPTY_INSTANCE;
116 }
117
118 if (audioRenderer_->Drain() != true) {
119 SHARING_LOGE("failed!");
120 return -1;
121 }
122
123 return PLAYER_SUCCESS;
124 }
125
Flush()126 int32_t AudioSink::Flush()
127 {
128 SHARING_LOGD("playerId: %{public}u.", playerId_);
129 if (!audioRenderer_) {
130 SHARING_LOGE("audioRenderer_ is NULL.");
131 return PLAYER_ERROR_EMPTY_INSTANCE;
132 }
133
134 if (audioRenderer_->Flush() != true) {
135 SHARING_LOGE("failed!");
136 return -1;
137 }
138
139 return PLAYER_SUCCESS;
140 }
141
Release()142 int32_t AudioSink::Release()
143 {
144 SHARING_LOGD("playerId: %{public}u.", playerId_);
145 if (!audioRenderer_) {
146 SHARING_LOGE("audioRenderer_ is NULL.");
147 return PLAYER_ERROR_EMPTY_INSTANCE;
148 }
149
150 audioRenderer_ = nullptr;
151 return PLAYER_SUCCESS;
152 }
153
SetParameters(int32_t bitsPerSample,int32_t channels,int32_t sampleRate)154 int32_t AudioSink::SetParameters(int32_t bitsPerSample, int32_t channels, int32_t sampleRate)
155 {
156 SHARING_LOGD("playerId: %{public}u.", playerId_);
157 (void)bitsPerSample;
158 SHARING_LOGD("enter, channels:%{public}d, sampleRate:%{public}d.", channels, sampleRate);
159
160 if (!audioRenderer_) {
161 SHARING_LOGE("audioRenderer_ is NULL.");
162 return PLAYER_ERROR_EMPTY_INSTANCE;
163 }
164
165 AudioStandard::AudioRendererParams params;
166 std::vector<AudioStandard::AudioSamplingRate> supportedSampleList =
167 AudioStandard::AudioRenderer::GetSupportedSamplingRates();
168 if (supportedSampleList.empty()) {
169 SHARING_LOGE("GetSupportedSamplingRates empty.");
170 return -1;
171 }
172
173 bool isValidSampleRate = false;
174 for (size_t i = 0; i < supportedSampleList.size(); i++) {
175 if (sampleRate <= supportedSampleList[i] && supportedSampleList[i] > 0) {
176 params.sampleRate = supportedSampleList[i];
177 isValidSampleRate = true;
178 break;
179 }
180 }
181
182 if (!isValidSampleRate) {
183 SHARING_LOGE("Unsupported sample ratefailed.");
184 return -1;
185 }
186
187 std::vector<AudioStandard::AudioChannel> supportedChannelsList =
188 AudioStandard::AudioRenderer::GetSupportedChannels();
189 if (supportedChannelsList.empty()) {
190 SHARING_LOGE("GetSupportedChannels empty.");
191 return -1;
192 }
193
194 bool isValidChannels = false;
195 for (size_t i = 0; i < supportedChannelsList.size(); i++) {
196 if (channels == supportedChannelsList[i] && supportedChannelsList[i] > 0) {
197 params.channelCount = supportedChannelsList[i];
198 isValidChannels = true;
199 break;
200 }
201 }
202
203 if (!isValidChannels) {
204 SHARING_LOGE("Unsupported sample ratefailed.");
205 return -1;
206 }
207
208 params.sampleFormat = AudioStandard::SAMPLE_S16LE;
209 params.encodingType = AudioStandard::ENCODING_PCM;
210 SHARING_LOGD("channels:%{public}d, sampleRate:%{public}d.", params.channelCount, params.sampleRate);
211
212 if (audioRenderer_->SetParams(params) != 0) {
213 SHARING_LOGE("failed.");
214 return -1;
215 }
216
217 return PLAYER_SUCCESS;
218 }
219
GetParameters(int32_t & bitsPerSample,int32_t & channels,int32_t & sampleRate)220 int32_t AudioSink::GetParameters(int32_t &bitsPerSample, int32_t &channels, int32_t &sampleRate)
221 {
222 SHARING_LOGD("playerId: %{public}u.", playerId_);
223 if (!audioRenderer_) {
224 SHARING_LOGE("audioRenderer_ is NULL.");
225 return PLAYER_ERROR_EMPTY_INSTANCE;
226 }
227
228 AudioStandard::AudioRendererParams params;
229 if (audioRenderer_->GetParams(params) != 0) {
230 SHARING_LOGE("failed.");
231 return -1;
232 }
233
234 channels = params.channelCount;
235 sampleRate = params.sampleRate;
236 bitsPerSample = (int32_t)params.sampleFormat;
237 return PLAYER_SUCCESS;
238 }
239
GetBufferSize(int32_t & bufferSize)240 int32_t AudioSink::GetBufferSize(int32_t &bufferSize)
241 {
242 SHARING_LOGD("playerId: %{public}u.", playerId_);
243 if (!audioRenderer_) {
244 SHARING_LOGE("audioRenderer_ is NULL.");
245 return PLAYER_ERROR_EMPTY_INSTANCE;
246 }
247
248 size_t size = 0;
249 if (audioRenderer_->GetBufferSize(size) != 0) {
250 SHARING_LOGE("failed!");
251 return -1;
252 }
253
254 bufferSize = (int32_t)size;
255 return PLAYER_SUCCESS;
256 }
257
SetVolume(float volume)258 int32_t AudioSink::SetVolume(float volume)
259 {
260 SHARING_LOGD("playerId: %{public}u.", playerId_);
261 if (!audioRenderer_) {
262 SHARING_LOGE("audioRenderer_ is NULL.");
263 return PLAYER_ERROR_EMPTY_INSTANCE;
264 }
265
266 if (audioRenderer_->SetVolume(volume) != 0) {
267 SHARING_LOGE("failed!");
268 return -1;
269 }
270
271 return PLAYER_SUCCESS;
272 }
273
GetVolume(float & volume)274 int32_t AudioSink::GetVolume(float &volume)
275 {
276 SHARING_LOGD("playerId: %{public}u.", playerId_);
277 if (!audioRenderer_) {
278 SHARING_LOGE("audioRenderer_ is NULL.");
279 return PLAYER_ERROR_EMPTY_INSTANCE;
280 }
281
282 volume = audioRenderer_->GetVolume();
283 return PLAYER_SUCCESS;
284 }
285
Write(uint8_t * buffer,size_t size)286 int32_t AudioSink::Write(uint8_t *buffer, size_t size)
287 {
288 MEDIA_LOGD("playerId: %{public}u.", playerId_);
289 if (!audioRenderer_) {
290 SHARING_LOGE("audioRenderer_ is NULL.");
291 return PLAYER_ERROR_EMPTY_INSTANCE;
292 }
293
294 size_t bytesWritten = 0;
295 int32_t bytesSingle = 0;
296 while (audioRenderer_ && bytesWritten < size && running_) {
297 bytesSingle = audioRenderer_->Write(buffer + bytesWritten, size - bytesWritten);
298 if (bytesSingle <= 0) {
299 MEDIA_LOGE("audioRenderer Write failed. playerId: %{public}u.", playerId_);
300 continue;
301 }
302
303 bytesWritten += static_cast<size_t>(bytesSingle);
304 if (bytesWritten < static_cast<size_t>(bytesSingle)) {
305 MEDIA_LOGE("audioRenderer Write failed playerId: %{public}u.", playerId_);
306 continue;
307 }
308 MEDIA_LOGD("audioRenderer Write end. playerId: %{public}u.", playerId_);
309 }
310
311 MEDIA_LOGD("recv data(len:%{public}zu.)", size);
312 return PLAYER_SUCCESS;
313 }
314
315 } // namespace Sharing
316 } // namespace OHOS