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 19namespace OHOS { 20namespace Sharing { 21 22AudioSink::AudioSink(uint32_t playerId) : audioRenderer_(nullptr) 23{ 24 SHARING_LOGD("playerId: %{public}u tid: %{public}d.", playerId, gettid()); 25 playerId_ = playerId; 26} 27 28AudioSink::~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 36int32_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 48int32_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 62int32_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 75int32_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 94int32_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 110int32_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 126int32_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 142int32_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 154int32_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 220int32_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 240int32_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 258int32_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 274int32_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 286int32_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