1 /*
2 * Copyright (c) 2024-2025 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 #ifndef LOG_TAG
16 #define LOG_TAG "RendererInClientInnerPublic"
17 #endif
18
19 #include "renderer_in_client.h"
20 #include "renderer_in_client_private.h"
21
22 #include <atomic>
23 #include <cinttypes>
24 #include <condition_variable>
25 #include <sstream>
26 #include <string>
27 #include <mutex>
28 #include <thread>
29
30 #include "iservice_registry.h"
31 #include "system_ability_definition.h"
32 #include "securec.h"
33 #include "hisysevent.h"
34
35 #include "audio_errors.h"
36 #include "audio_policy_manager.h"
37 #include "audio_manager_base.h"
38 #include "audio_renderer_log.h"
39 #include "audio_ring_cache.h"
40 #include "audio_channel_blend.h"
41 #include "audio_server_death_recipient.h"
42 #include "audio_stream_tracker.h"
43 #include "audio_system_manager.h"
44 #include "futex_tool.h"
45 #include "ipc_stream_listener_impl.h"
46 #include "ipc_stream_listener_stub.h"
47 #include "volume_ramp.h"
48 #include "callback_handler.h"
49 #include "audio_speed.h"
50 #include "audio_spatial_channel_converter.h"
51 #include "audio_policy_manager.h"
52 #include "audio_spatialization_manager.h"
53 #include "policy_handler.h"
54 #include "volume_tools.h"
55 #include "audio_manager_util.h"
56 #include "audio_effect_map.h"
57
58 #include "media_monitor_manager.h"
59
60 using namespace OHOS::HiviewDFX;
61 using namespace OHOS::AppExecFwk;
62
63 namespace OHOS {
64 namespace AudioStandard {
65 namespace {
66 const uint64_t OLD_BUF_DURATION_IN_USEC = 92880; // This value is used for compatibility purposes.
67 const uint64_t AUDIO_US_PER_MS = 1000;
68 const uint64_t AUDIO_NS_PER_US = 1000;
69 const uint64_t AUDIO_US_PER_S = 1000000;
70 const uint64_t AUDIO_MS_PER_S = 1000;
71 static constexpr int CB_QUEUE_CAPACITY = 3;
72 const uint64_t AUDIO_FIRST_FRAME_LATENCY = 120; //ms
73 static const int32_t CREATE_TIMEOUT_IN_SECOND = 9; // 9S
74 constexpr int32_t MAX_BUFFER_SIZE = 100000;
75 const uint64_t MAX_CBBUF_IN_USEC = 100000;
76 const uint64_t MIN_CBBUF_IN_USEC = 20000;
77 static const int32_t OPERATION_TIMEOUT_IN_MS = 1000; // 1000ms
78 static const int32_t SHORT_TIMEOUT_IN_MS = 20; // ms
79 static const int32_t DATA_CONNECTION_TIMEOUT_IN_MS = 300; // ms
80 } // namespace
GetInstance(AudioStreamType eStreamType,int32_t appUid)81 std::shared_ptr<RendererInClient> RendererInClient::GetInstance(AudioStreamType eStreamType, int32_t appUid)
82 {
83 return std::make_shared<RendererInClientInner>(eStreamType, appUid);
84 }
85
RendererInClientInner(AudioStreamType eStreamType,int32_t appUid)86 RendererInClientInner::RendererInClientInner(AudioStreamType eStreamType, int32_t appUid)
87 : eStreamType_(eStreamType), appUid_(appUid), cbBufferQueue_(CB_QUEUE_CAPACITY)
88 {
89 AUDIO_INFO_LOG("Create with StreamType:%{public}d appUid:%{public}d ", eStreamType_, appUid_);
90 audioStreamTracker_ = std::make_unique<AudioStreamTracker>(AUDIO_MODE_PLAYBACK, appUid);
91 state_ = NEW;
92 }
93
~RendererInClientInner()94 RendererInClientInner::~RendererInClientInner()
95 {
96 AUDIO_INFO_LOG("~RendererInClientInner()");
97 DumpFileUtil::CloseDumpFile(&dumpOutFd_);
98 RendererInClientInner::ReleaseAudioStream(true);
99 std::lock_guard<std::mutex> runnerlock(runnerMutex_);
100 if (!runnerReleased_ && callbackHandler_ != nullptr) {
101 AUDIO_INFO_LOG("runner remove");
102 callbackHandler_->ReleaseEventRunner();
103 runnerReleased_ = true;
104 callbackHandler_ = nullptr;
105 }
106 UnregisterSpatializationStateEventListener(spatializationRegisteredSessionID_);
107 AUDIO_INFO_LOG("[%{public}s] volume data counts: %{public}" PRId64, logUtilsTag_.c_str(), volumeDataCount_);
108 }
109
OnOperationHandled(Operation operation,int64_t result)110 int32_t RendererInClientInner::OnOperationHandled(Operation operation, int64_t result)
111 {
112 Trace trace(traceTag_ + " OnOperationHandled:" + std::to_string(operation));
113 AUDIO_INFO_LOG("sessionId %{public}d recv operation:%{public}d result:%{public}" PRId64".", sessionId_, operation,
114 result);
115 if (operation == SET_OFFLOAD_ENABLE) {
116 AUDIO_INFO_LOG("SET_OFFLOAD_ENABLE result:%{public}" PRId64".", result);
117 if (!offloadEnable_ && static_cast<bool>(result)) {
118 offloadStartReadPos_ = 0;
119 }
120 offloadEnable_ = static_cast<bool>(result);
121 rendererInfo_.pipeType = offloadEnable_ ? PIPE_TYPE_OFFLOAD : PIPE_TYPE_NORMAL_OUT;
122 return SUCCESS;
123 } else if (operation == DATA_LINK_CONNECTING) {
124 isDataLinkConnected_ = false;
125 return SUCCESS;
126 } else if (operation == DATA_LINK_CONNECTED) {
127 isDataLinkConnected_ = true;
128 dataConnectionCV_.notify_all();
129 return SUCCESS;
130 }
131
132 if (operation == RESTORE_SESSION) {
133 // fix it when restoreAudioStream work right
134 if (audioStreamTracker_ && audioStreamTracker_.get()) {
135 audioStreamTracker_->FetchOutputDeviceForTrack(sessionId_,
136 state_, clientPid_, rendererInfo_, AudioStreamDeviceChangeReasonExt::ExtEnum::UNKNOWN);
137 }
138 return SUCCESS;
139 }
140
141 std::unique_lock<std::mutex> lock(callServerMutex_);
142 notifiedOperation_ = operation;
143 notifiedResult_ = result;
144
145 if (notifiedResult_ == SUCCESS) {
146 HandleStatusChangeOperation(operation);
147 } else {
148 AUDIO_ERR_LOG("operation %{public}d failed, result: %{public}" PRId64 "", operation, result);
149 }
150
151 callServerCV_.notify_all();
152 return SUCCESS;
153 }
154
HandleStatusChangeOperation(Operation operation)155 void RendererInClientInner::HandleStatusChangeOperation(Operation operation)
156 {
157 std::unique_lock<std::mutex> lock(streamCbMutex_);
158 std::shared_ptr<AudioStreamCallback> streamCb = streamCallback_.lock();
159 switch (operation) {
160 case START_STREAM :
161 state_ = RUNNING;
162 break;
163 case PAUSE_STREAM :
164 state_ = PAUSED;
165 break;
166 case STOP_STREAM :
167 state_ = STOPPED;
168 break;
169 default :
170 break;
171 }
172 if (streamCb != nullptr) {
173 streamCb->OnStateChange(state_, CMD_FROM_SYSTEM);
174 }
175 }
176
SetClientID(int32_t clientPid,int32_t clientUid,uint32_t appTokenId,uint64_t fullTokenId)177 void RendererInClientInner::SetClientID(int32_t clientPid, int32_t clientUid, uint32_t appTokenId, uint64_t fullTokenId)
178 {
179 AUDIO_INFO_LOG("PID:%{public}d UID:%{public}d.", clientPid, clientUid);
180 clientPid_ = clientPid;
181 clientUid_ = clientUid;
182 appTokenId_ = appTokenId;
183 fullTokenId_ = fullTokenId;
184 }
185
UpdatePlaybackCaptureConfig(const AudioPlaybackCaptureConfig & config)186 int32_t RendererInClientInner::UpdatePlaybackCaptureConfig(const AudioPlaybackCaptureConfig &config)
187 {
188 AUDIO_ERR_LOG("Unsupported operation!");
189 return ERR_NOT_SUPPORTED;
190 }
191
SetRendererInfo(const AudioRendererInfo & rendererInfo)192 void RendererInClientInner::SetRendererInfo(const AudioRendererInfo &rendererInfo)
193 {
194 rendererInfo_ = rendererInfo;
195
196 rendererInfo_.sceneType = AudioManagerUtil::GetEffectSceneName(rendererInfo_.streamUsage);
197
198 const std::unordered_map<AudioEffectScene, std::string> &audioSupportedSceneTypes = GetSupportedSceneType();
199
200 if (rendererInfo_.sceneType == audioSupportedSceneTypes.find(SCENE_OTHERS)->second) {
201 effectMode_ = EFFECT_NONE;
202 rendererInfo_.effectMode = EFFECT_NONE;
203 }
204
205 AUDIO_PRERELEASE_LOGI("SetRendererInfo with flag %{public}d, sceneType %{public}s", rendererInfo_.rendererFlags,
206 rendererInfo_.sceneType.c_str());
207 AudioSpatializationState spatializationState =
208 AudioPolicyManager::GetInstance().GetSpatializationState(rendererInfo_.streamUsage);
209 rendererInfo_.spatializationEnabled = spatializationState.spatializationEnabled;
210 rendererInfo_.headTrackingEnabled = spatializationState.headTrackingEnabled;
211 rendererInfo_.encodingType = curStreamParams_.encoding;
212 rendererInfo_.channelLayout = curStreamParams_.channelLayout;
213 UpdateTracker("UPDATE");
214 }
215
SetCapturerInfo(const AudioCapturerInfo & capturerInfo)216 void RendererInClientInner::SetCapturerInfo(const AudioCapturerInfo &capturerInfo)
217 {
218 AUDIO_WARNING_LOG("SetCapturerInfo is not supported");
219 return;
220 }
221
SetAudioStreamInfo(const AudioStreamParams info,const std::shared_ptr<AudioClientTracker> & proxyObj,const AudioPlaybackCaptureConfig & config)222 int32_t RendererInClientInner::SetAudioStreamInfo(const AudioStreamParams info,
223 const std::shared_ptr<AudioClientTracker> &proxyObj,
224 const AudioPlaybackCaptureConfig &config)
225 {
226 // In plan: If paramsIsSet_ is true, and new info is same as old info, return
227 AUDIO_INFO_LOG("AudioStreamInfo, Sampling rate: %{public}d, channels: %{public}d, format: %{public}d,"
228 " stream type: %{public}d, encoding type: %{public}d", info.samplingRate, info.channels, info.format,
229 eStreamType_, info.encoding);
230
231 AudioXCollie guard("RendererInClientInner::SetAudioStreamInfo", CREATE_TIMEOUT_IN_SECOND);
232 if (!IsFormatValid(info.format) || !IsSamplingRateValid(info.samplingRate) || !IsEncodingTypeValid(info.encoding)) {
233 AUDIO_ERR_LOG("Unsupported audio parameter");
234 return ERR_NOT_SUPPORTED;
235 }
236
237 streamParams_ = curStreamParams_ = info; // keep it for later use
238 if (curStreamParams_.encoding == ENCODING_AUDIOVIVID) {
239 ConverterConfig cfg = AudioPolicyManager::GetInstance().GetConverterConfig();
240 converter_ = std::make_unique<AudioSpatialChannelConverter>();
241 if (converter_ == nullptr || !converter_->Init(curStreamParams_, cfg) || !converter_->AllocateMem()) {
242 AUDIO_ERR_LOG("AudioStream: converter construct error");
243 return ERR_NOT_SUPPORTED;
244 }
245 converter_->ConverterChannels(curStreamParams_.channels, curStreamParams_.channelLayout);
246 }
247
248 if (!IsPlaybackChannelRelatedInfoValid(curStreamParams_.channels, curStreamParams_.channelLayout)) {
249 return ERR_NOT_SUPPORTED;
250 }
251
252 CHECK_AND_RETURN_RET_LOG(IAudioStream::GetByteSizePerFrame(curStreamParams_, sizePerFrameInByte_) == SUCCESS,
253 ERROR_INVALID_PARAM, "GetByteSizePerFrame failed with invalid params");
254
255 if (state_ != NEW) {
256 AUDIO_ERR_LOG("State is not new, release existing stream and recreate, state %{public}d", state_.load());
257 int32_t ret = DeinitIpcStream();
258 CHECK_AND_RETURN_RET_LOG(ret == SUCCESS, ret, "release existing stream failed.");
259 }
260 paramsIsSet_ = true;
261 int32_t initRet = InitIpcStream();
262 CHECK_AND_RETURN_RET_LOG(initRet == SUCCESS, initRet, "Init stream failed: %{public}d", initRet);
263 state_ = PREPARED;
264
265 // eg: 100005_44100_2_1_client_out.pcm
266 dumpOutFile_ = std::to_string(sessionId_) + "_" + std::to_string(curStreamParams_.samplingRate) + "_" +
267 std::to_string(curStreamParams_.channels) + "_" + std::to_string(curStreamParams_.format) + "_client_out.pcm";
268
269 DumpFileUtil::OpenDumpFile(DumpFileUtil::DUMP_CLIENT_PARA, dumpOutFile_, &dumpOutFd_);
270 logUtilsTag_ = "[" + std::to_string(sessionId_) + "]NormalRenderer";
271 InitDirectPipeType();
272
273 proxyObj_ = proxyObj;
274 RegisterTracker(proxyObj);
275 RegisterSpatializationStateEventListener();
276 return SUCCESS;
277 }
278
GetAudioStreamInfo(AudioStreamParams & info)279 int32_t RendererInClientInner::GetAudioStreamInfo(AudioStreamParams &info)
280 {
281 CHECK_AND_RETURN_RET_LOG(paramsIsSet_ == true, ERR_OPERATION_FAILED, "Params is not set");
282 info = streamParams_;
283 return SUCCESS;
284 }
285
GetAudioSessionID(uint32_t & sessionID)286 int32_t RendererInClientInner::GetAudioSessionID(uint32_t &sessionID)
287 {
288 CHECK_AND_RETURN_RET_LOG((state_ != RELEASED) && (state_ != NEW), ERR_ILLEGAL_STATE,
289 "State error %{public}d", state_.load());
290 sessionID = sessionId_;
291 return SUCCESS;
292 }
293
GetAudioPipeType(AudioPipeType & pipeType)294 void RendererInClientInner::GetAudioPipeType(AudioPipeType &pipeType)
295 {
296 pipeType = rendererInfo_.pipeType;
297 }
298
GetState()299 State RendererInClientInner::GetState()
300 {
301 std::lock_guard lock(switchingMutex_);
302 if (switchingInfo_.isSwitching_) {
303 AUDIO_INFO_LOG("switching, return state in switchingInfo");
304 return switchingInfo_.state_;
305 }
306 return state_;
307 }
308
GetAudioTime(Timestamp & timestamp,Timestamp::Timestampbase base)309 bool RendererInClientInner::GetAudioTime(Timestamp ×tamp, Timestamp::Timestampbase base)
310 {
311 CHECK_AND_RETURN_RET_LOG(paramsIsSet_ == true, false, "Params is not set");
312 CHECK_AND_RETURN_RET_LOG(state_ != STOPPED, false, "Invalid status:%{public}d", state_.load());
313
314 uint64_t readPos = 0;
315 int64_t handleTime = 0;
316 CHECK_AND_RETURN_RET_LOG(clientBuffer_ != nullptr, false, "invalid buffer status");
317 clientBuffer_->GetHandleInfo(readPos, handleTime);
318 if (readPos == 0 || handleTime == 0) {
319 AUDIO_WARNING_LOG("GetHandleInfo may failed");
320 }
321
322 timestamp.framePosition = readPos;
323 int64_t audioTimeResult = handleTime;
324
325 if (offloadEnable_) {
326 uint64_t timestampHdi = 0;
327 uint64_t paWriteIndex = 0;
328 uint64_t cacheTimeDsp = 0;
329 uint64_t cacheTimePa = 0;
330 ipcStream_->GetOffloadApproximatelyCacheTime(timestampHdi, paWriteIndex, cacheTimeDsp, cacheTimePa);
331 int64_t cacheTime = static_cast<int64_t>(cacheTimeDsp + cacheTimePa) * AUDIO_NS_PER_US;
332 int64_t timeNow = static_cast<int64_t>(std::chrono::duration_cast<std::chrono::microseconds>(
333 std::chrono::system_clock::now().time_since_epoch()).count());
334 int64_t deltaTimeStamp = (static_cast<int64_t>(timeNow) - static_cast<int64_t>(timestampHdi)) * AUDIO_NS_PER_US;
335 uint64_t paWriteIndexNs = paWriteIndex * AUDIO_NS_PER_US;
336 uint64_t readPosNs = readPos * AUDIO_MS_PER_SECOND / curStreamParams_.samplingRate * AUDIO_US_PER_S;
337
338 int64_t deltaPaWriteIndexNs = static_cast<int64_t>(readPosNs) - static_cast<int64_t>(paWriteIndexNs);
339 int64_t cacheTimeNow = cacheTime - deltaTimeStamp + deltaPaWriteIndexNs;
340 if (offloadStartReadPos_ == 0) {
341 offloadStartReadPos_ = readPosNs;
342 offloadStartHandleTime_ = handleTime;
343 }
344 int64_t offloadDelta = 0;
345 if (offloadStartReadPos_ != 0) {
346 offloadDelta = (static_cast<int64_t>(readPosNs) - static_cast<int64_t>(offloadStartReadPos_)) -
347 (handleTime - offloadStartHandleTime_) - cacheTimeNow;
348 }
349 audioTimeResult += offloadDelta;
350 }
351
352 timestamp.time.tv_sec = static_cast<time_t>(audioTimeResult / AUDIO_NS_PER_SECOND);
353 timestamp.time.tv_nsec = static_cast<time_t>(audioTimeResult % AUDIO_NS_PER_SECOND);
354 AUDIO_DEBUG_LOG("audioTimeResult: %{public}" PRIi64, audioTimeResult);
355 return true;
356 }
357
GetAudioPosition(Timestamp & timestamp,Timestamp::Timestampbase base)358 bool RendererInClientInner::GetAudioPosition(Timestamp ×tamp, Timestamp::Timestampbase base)
359 {
360 CHECK_AND_RETURN_RET_LOG(state_ == RUNNING, false, "Renderer stream state is not RUNNING");
361 uint64_t readIdx = 0;
362 uint64_t timestampVal = 0;
363 uint64_t latency = 0;
364 CHECK_AND_RETURN_RET_LOG(ipcStream_ != nullptr, false, "ipcStream is not inited!");
365 int32_t ret = ipcStream_->GetAudioPosition(readIdx, timestampVal, latency);
366
367 uint64_t framePosition = readIdx > lastFlushReadIndex_ ? readIdx - lastFlushReadIndex_ : 0;
368 framePosition = framePosition > latency ? framePosition - latency : 0;
369
370 // add MCR latency
371 uint32_t mcrLatency = 0;
372 if (converter_ != nullptr) {
373 mcrLatency = converter_->GetLatency() * curStreamParams_.samplingRate / AUDIO_MS_PER_S;
374 framePosition = framePosition > mcrLatency ? framePosition - mcrLatency : 0;
375 }
376
377 if (lastFramePosition_ < framePosition) {
378 lastFramePosition_ = framePosition;
379 lastFrameTimestamp_ = timestampVal;
380 } else {
381 AUDIO_DEBUG_LOG("The frame position should be continuously increasing");
382 framePosition = lastFramePosition_;
383 timestampVal = lastFrameTimestamp_;
384 }
385 AUDIO_DEBUG_LOG("[CLIENT]Latency info: framePosition: %{public}" PRIu64 ", lastFlushReadIndex_ %{public}" PRIu64
386 ", timestamp %{public}" PRIu64 ", mcrLatency %{public}u, Sinklatency %{public}" PRIu64, framePosition,
387 lastFlushReadIndex_, timestampVal, mcrLatency, latency);
388
389 timestamp.framePosition = framePosition;
390 timestamp.time.tv_sec = static_cast<time_t>(timestampVal / AUDIO_NS_PER_SECOND);
391 timestamp.time.tv_nsec = static_cast<time_t>(timestampVal % AUDIO_NS_PER_SECOND);
392 return ret == SUCCESS;
393 }
394
GetBufferSize(size_t & bufferSize)395 int32_t RendererInClientInner::GetBufferSize(size_t &bufferSize)
396 {
397 CHECK_AND_RETURN_RET_LOG(state_ != RELEASED, ERR_ILLEGAL_STATE, "Renderer stream is released");
398 bufferSize = clientSpanSizeInByte_;
399 if (renderMode_ == RENDER_MODE_CALLBACK) {
400 bufferSize = cbBufferSize_;
401 }
402
403 if (curStreamParams_.encoding == ENCODING_AUDIOVIVID) {
404 CHECK_AND_RETURN_RET(converter_ != nullptr && converter_->GetInputBufferSize(bufferSize), ERR_OPERATION_FAILED);
405 }
406
407 AUDIO_INFO_LOG("Buffer size is %{public}zu, mode is %{public}s", bufferSize, renderMode_ == RENDER_MODE_NORMAL ?
408 "RENDER_MODE_NORMAL" : "RENDER_MODE_CALLBACK");
409 return SUCCESS;
410 }
411
GetFrameCount(uint32_t & frameCount)412 int32_t RendererInClientInner::GetFrameCount(uint32_t &frameCount)
413 {
414 CHECK_AND_RETURN_RET_LOG(state_ != RELEASED, ERR_ILLEGAL_STATE, "Renderer stream is released");
415 CHECK_AND_RETURN_RET_LOG(sizePerFrameInByte_ != 0, ERR_ILLEGAL_STATE, "sizePerFrameInByte_ is 0!");
416 frameCount = spanSizeInFrame_;
417 if (renderMode_ == RENDER_MODE_CALLBACK) {
418 frameCount = cbBufferSize_ / sizePerFrameInByte_;
419 if (curStreamParams_.encoding == ENCODING_AUDIOVIVID) {
420 frameCount = frameCount * curStreamParams_.channels / streamParams_.channels;
421 }
422 }
423 AUDIO_INFO_LOG("Frame count is %{public}u, mode is %{public}s", frameCount, renderMode_ == RENDER_MODE_NORMAL ?
424 "RENDER_MODE_NORMAL" : "RENDER_MODE_CALLBACK");
425 return SUCCESS;
426 }
427
GetLatency(uint64_t & latency)428 int32_t RendererInClientInner::GetLatency(uint64_t &latency)
429 {
430 CHECK_AND_RETURN_RET_LOG(ipcStream_ != nullptr, false, "ipcStream is not inited!");
431 return ipcStream_->GetLatency(latency);
432 }
433
SetAudioStreamType(AudioStreamType audioStreamType)434 int32_t RendererInClientInner::SetAudioStreamType(AudioStreamType audioStreamType)
435 {
436 AUDIO_ERR_LOG("Change stream type %{public}d to %{public}d is not supported", eStreamType_, audioStreamType);
437 return SUCCESS;
438 }
439
SetVolume(float volume)440 int32_t RendererInClientInner::SetVolume(float volume)
441 {
442 Trace trace("RendererInClientInner::SetVolume:" + std::to_string(volume));
443 AUDIO_INFO_LOG("[%{public}s]sessionId:%{public}d volume:%{public}f", (offloadEnable_ ? "offload" : "normal"),
444 sessionId_, volume);
445 if (volume < 0.0 || volume > 1.0) {
446 AUDIO_ERR_LOG("SetVolume with invalid volume %{public}f", volume);
447 return ERR_INVALID_PARAM;
448 }
449 if (volumeRamp_.IsActive()) {
450 volumeRamp_.Terminate();
451 }
452 clientVolume_ = volume;
453
454 return SetInnerVolume(volume);
455 }
456
GetVolume()457 float RendererInClientInner::GetVolume()
458 {
459 Trace trace("RendererInClientInner::GetVolume:" + std::to_string(clientVolume_));
460 return clientVolume_;
461 }
462
SetDuckVolume(float volume)463 int32_t RendererInClientInner::SetDuckVolume(float volume)
464 {
465 Trace trace("RendererInClientInner::SetDuckVolume:" + std::to_string(volume));
466 AUDIO_INFO_LOG("sessionId:%{public}d SetDuck:%{public}f", sessionId_, volume);
467 if (volume < 0.0 || volume > 1.0) {
468 AUDIO_ERR_LOG("SetDuckVolume with invalid volume %{public}f", volume);
469 return ERR_INVALID_PARAM;
470 }
471 duckVolume_ = volume;
472 CHECK_AND_RETURN_RET_LOG(clientBuffer_ != nullptr, ERR_OPERATION_FAILED, "buffer is not inited");
473 clientBuffer_->SetDuckFactor(volume);
474 CHECK_AND_RETURN_RET_LOG(ipcStream_ != nullptr, ERR_OPERATION_FAILED, "ipcStream is not inited!");
475 int32_t ret = ipcStream_->SetDuckFactor(volume);
476 if (ret != SUCCESS) {
477 AUDIO_ERR_LOG("Set Duck failed:%{public}u", ret);
478 return ERROR;
479 }
480 return SUCCESS;
481 }
482
SetMute(bool mute)483 int32_t RendererInClientInner::SetMute(bool mute)
484 {
485 Trace trace("RendererInClientInner::SetMute:" + std::to_string(mute));
486 AUDIO_INFO_LOG("sessionId:%{public}d SetMute:%{public}d", sessionId_, mute);
487 muteVolume_ = mute ? 0.0f : 1.0f;
488 CHECK_AND_RETURN_RET_LOG(clientBuffer_ != nullptr, ERR_OPERATION_FAILED, "buffer is not inited");
489 clientBuffer_->SetMuteFactor(muteVolume_);
490 CHECK_AND_RETURN_RET_LOG(ipcStream_ != nullptr, false, "ipcStream is not inited!");
491 int32_t ret = ipcStream_->SetMute(mute);
492 if (ret != SUCCESS) {
493 AUDIO_ERR_LOG("Set Mute failed:%{public}u", ret);
494 return ERROR;
495 }
496 return SUCCESS;
497 }
498
SetRenderRate(AudioRendererRate renderRate)499 int32_t RendererInClientInner::SetRenderRate(AudioRendererRate renderRate)
500 {
501 if (rendererRate_ == renderRate) {
502 AUDIO_INFO_LOG("Set same rate");
503 return SUCCESS;
504 }
505 CHECK_AND_RETURN_RET_LOG(ipcStream_ != nullptr, ERR_ILLEGAL_STATE, "ipcStream is not inited!");
506 rendererRate_ = renderRate;
507 return ipcStream_->SetRate(renderRate);
508 }
509
GetRenderRate()510 AudioRendererRate RendererInClientInner::GetRenderRate()
511 {
512 AUDIO_INFO_LOG("Get RenderRate %{public}d", rendererRate_);
513 return rendererRate_;
514 }
515
SetStreamCallback(const std::shared_ptr<AudioStreamCallback> & callback)516 int32_t RendererInClientInner::SetStreamCallback(const std::shared_ptr<AudioStreamCallback> &callback)
517 {
518 if (callback == nullptr) {
519 AUDIO_ERR_LOG("SetStreamCallback failed. callback == nullptr");
520 return ERR_INVALID_PARAM;
521 }
522
523 std::unique_lock<std::mutex> lock(streamCbMutex_);
524 streamCallback_ = callback;
525 lock.unlock();
526
527 if (state_ != PREPARED) {
528 return SUCCESS;
529 }
530 SafeSendCallbackEvent(STATE_CHANGE_EVENT, PREPARED);
531 return SUCCESS;
532 }
533
SetRendererFirstFrameWritingCallback(const std::shared_ptr<AudioRendererFirstFrameWritingCallback> & callback)534 int32_t RendererInClientInner::SetRendererFirstFrameWritingCallback(
535 const std::shared_ptr<AudioRendererFirstFrameWritingCallback> &callback)
536 {
537 AUDIO_INFO_LOG("SetRendererFirstFrameWritingCallback in.");
538 CHECK_AND_RETURN_RET_LOG(callback, ERR_INVALID_PARAM, "callback is nullptr");
539 std::lock_guard lock(firstFrameWritingMutex_);
540 firstFrameWritingCb_ = callback;
541 return SUCCESS;
542 }
543
OnFirstFrameWriting()544 void RendererInClientInner::OnFirstFrameWriting()
545 {
546 AUDIO_DEBUG_LOG("In");
547 uint64_t latency = AUDIO_FIRST_FRAME_LATENCY;
548
549 std::shared_ptr<AudioRendererFirstFrameWritingCallback> cb = nullptr;
550 {
551 std::lock_guard lock(firstFrameWritingMutex_);
552 CHECK_AND_RETURN_LOG(firstFrameWritingCb_!= nullptr, "firstFrameWritingCb_ is null.");
553 cb = firstFrameWritingCb_;
554 }
555 AUDIO_DEBUG_LOG("OnFirstFrameWriting: latency %{public}" PRIu64 "", latency);
556 cb->OnFirstFrameWriting(latency);
557 }
558
SetSpeed(float speed)559 int32_t RendererInClientInner::SetSpeed(float speed)
560 {
561 if (audioSpeed_ == nullptr) {
562 audioSpeed_ = std::make_unique<AudioSpeed>(curStreamParams_.samplingRate, curStreamParams_.format,
563 curStreamParams_.channels);
564 GetBufferSize(bufferSize_);
565 speedBuffer_ = std::make_unique<uint8_t[]>(MAX_BUFFER_SIZE);
566 }
567 audioSpeed_->SetSpeed(speed);
568 speed_ = speed;
569 AUDIO_DEBUG_LOG("SetSpeed %{public}f, OffloadEnable %{public}d", speed_, offloadEnable_);
570 return SUCCESS;
571 }
572
GetSpeed()573 float RendererInClientInner::GetSpeed()
574 {
575 return speed_;
576 }
577
ChangeSpeed(uint8_t * buffer,int32_t bufferSize,std::unique_ptr<uint8_t[]> & outBuffer,int32_t & outBufferSize)578 int32_t RendererInClientInner::ChangeSpeed(uint8_t *buffer, int32_t bufferSize, std::unique_ptr<uint8_t []> &outBuffer,
579 int32_t &outBufferSize)
580 {
581 return audioSpeed_->ChangeSpeedFunc(buffer, bufferSize, outBuffer, outBufferSize);
582 }
583
InitCallbackLoop()584 void RendererInClientInner::InitCallbackLoop()
585 {
586 cbThreadReleased_ = false;
587 auto weakRef = weak_from_this();
588 // OS_AudioWriteCB
589 std::thread callbackLoop = std::thread([weakRef] {
590 bool keepRunning = true;
591 std::shared_ptr<RendererInClientInner> strongRef = weakRef.lock();
592 if (strongRef != nullptr) {
593 strongRef->cbThreadCv_.notify_one();
594 AUDIO_INFO_LOG("WriteCallbackFunc start, sessionID :%{public}d", strongRef->sessionId_);
595 } else {
596 AUDIO_WARNING_LOG("Strong ref is nullptr, could cause error");
597 }
598 strongRef = nullptr;
599 // start loop
600 while (keepRunning) {
601 strongRef = weakRef.lock();
602 if (strongRef == nullptr) {
603 AUDIO_INFO_LOG("RendererInClientInner destroyed");
604 break;
605 }
606 keepRunning = strongRef->WriteCallbackFunc(); // Main operation in callback loop
607 }
608 if (strongRef != nullptr) {
609 AUDIO_INFO_LOG("CBThread end sessionID :%{public}d", strongRef->sessionId_);
610 }
611 });
612 pthread_setname_np(callbackLoop.native_handle(), "OS_AudioWriteCB");
613 callbackLoop.detach();
614 }
615
SetRenderMode(AudioRenderMode renderMode)616 int32_t RendererInClientInner::SetRenderMode(AudioRenderMode renderMode)
617 {
618 AUDIO_INFO_LOG("SetRenderMode to %{public}s", renderMode == RENDER_MODE_NORMAL ? "RENDER_MODE_NORMAL" :
619 "RENDER_MODE_CALLBACK");
620 if (renderMode_ == renderMode) {
621 return SUCCESS;
622 }
623
624 // renderMode_ is inited as RENDER_MODE_NORMAL, can only be set to RENDER_MODE_CALLBACK.
625 if (renderMode_ == RENDER_MODE_CALLBACK && renderMode == RENDER_MODE_NORMAL) {
626 AUDIO_ERR_LOG("SetRenderMode from callback to normal is not supported.");
627 return ERR_INCORRECT_MODE;
628 }
629
630 // state check
631 if (state_ != PREPARED && state_ != NEW) {
632 AUDIO_ERR_LOG("SetRenderMode failed. invalid state:%{public}d", state_.load());
633 return ERR_ILLEGAL_STATE;
634 }
635 renderMode_ = renderMode;
636
637 // init callbackLoop_
638 InitCallbackLoop();
639
640 std::unique_lock<std::mutex> threadStartlock(statusMutex_);
641 bool stopWaiting = cbThreadCv_.wait_for(threadStartlock, std::chrono::milliseconds(SHORT_TIMEOUT_IN_MS), [this] {
642 return cbThreadReleased_ == false; // When thread is started, cbThreadReleased_ will be false. So stop waiting.
643 });
644 if (!stopWaiting) {
645 AUDIO_WARNING_LOG("Init OS_AudioWriteCB thread time out");
646 }
647
648 InitCallbackBuffer(OLD_BUF_DURATION_IN_USEC);
649 return SUCCESS;
650 }
651
GetRenderMode()652 AudioRenderMode RendererInClientInner::GetRenderMode()
653 {
654 AUDIO_INFO_LOG("Render mode is %{public}s", renderMode_ == RENDER_MODE_NORMAL ? "RENDER_MODE_NORMAL" :
655 "RENDER_MODE_CALLBACK");
656 return renderMode_;
657 }
658
SetRendererWriteCallback(const std::shared_ptr<AudioRendererWriteCallback> & callback)659 int32_t RendererInClientInner::SetRendererWriteCallback(const std::shared_ptr<AudioRendererWriteCallback> &callback)
660 {
661 CHECK_AND_RETURN_RET_LOG(callback != nullptr, ERR_INVALID_PARAM, "Invalid null callback");
662 CHECK_AND_RETURN_RET_LOG(renderMode_ == RENDER_MODE_CALLBACK, ERR_INCORRECT_MODE, "incorrect render mode");
663 std::lock_guard<std::mutex> lock(writeCbMutex_);
664 writeCb_ = callback;
665 return SUCCESS;
666 }
667
SetCaptureMode(AudioCaptureMode captureMode)668 int32_t RendererInClientInner::SetCaptureMode(AudioCaptureMode captureMode)
669 {
670 AUDIO_ERR_LOG("SetCaptureMode is not supported");
671 return ERROR;
672 }
673
GetCaptureMode()674 AudioCaptureMode RendererInClientInner::GetCaptureMode()
675 {
676 AUDIO_ERR_LOG("GetCaptureMode is not supported");
677 return CAPTURE_MODE_NORMAL; // not supported
678 }
679
SetCapturerReadCallback(const std::shared_ptr<AudioCapturerReadCallback> & callback)680 int32_t RendererInClientInner::SetCapturerReadCallback(const std::shared_ptr<AudioCapturerReadCallback> &callback)
681 {
682 AUDIO_ERR_LOG("SetCapturerReadCallback is not supported");
683 return ERROR;
684 }
685
GetBufferDesc(BufferDesc & bufDesc)686 int32_t RendererInClientInner::GetBufferDesc(BufferDesc &bufDesc)
687 {
688 Trace trace("RendererInClientInner::GetBufferDesc");
689 if (renderMode_ != RENDER_MODE_CALLBACK) {
690 AUDIO_ERR_LOG("GetBufferDesc is not supported. Render mode is not callback.");
691 return ERR_INCORRECT_MODE;
692 }
693 std::lock_guard<std::mutex> lock(cbBufferMutex_);
694 bufDesc.buffer = cbBuffer_.get();
695 bufDesc.bufLength = cbBufferSize_;
696 bufDesc.dataLength = cbBufferSize_;
697 if (curStreamParams_.encoding == ENCODING_AUDIOVIVID) {
698 CHECK_AND_RETURN_RET_LOG(converter_ != nullptr, ERR_INVALID_OPERATION, "converter is not inited");
699 bufDesc.metaBuffer = bufDesc.buffer + cbBufferSize_;
700 bufDesc.metaLength = converter_->GetMetaSize();
701 }
702 return SUCCESS;
703 }
704
GetBufQueueState(BufferQueueState & bufState)705 int32_t RendererInClientInner::GetBufQueueState(BufferQueueState &bufState)
706 {
707 Trace trace("RendererInClientInner::GetBufQueueState");
708 if (renderMode_ != RENDER_MODE_CALLBACK) {
709 AUDIO_ERR_LOG("GetBufQueueState is not supported. Render mode is not callback.");
710 return ERR_INCORRECT_MODE;
711 }
712 // only one buffer in queue.
713 bufState.numBuffers = 1;
714 bufState.currentIndex = 0;
715 return SUCCESS;
716 }
717
Enqueue(const BufferDesc & bufDesc)718 int32_t RendererInClientInner::Enqueue(const BufferDesc &bufDesc)
719 {
720 Trace trace("RendererInClientInner::Enqueue " + std::to_string(bufDesc.bufLength));
721 if (renderMode_ != RENDER_MODE_CALLBACK) {
722 AUDIO_ERR_LOG("Enqueue is not supported. Render mode is not callback.");
723 return ERR_INCORRECT_MODE;
724 }
725 CHECK_AND_RETURN_RET_LOG(bufDesc.buffer != nullptr && bufDesc.bufLength != 0, ERR_INVALID_PARAM, "Invalid buffer");
726 CHECK_AND_RETURN_RET_LOG(curStreamParams_.encoding != ENCODING_AUDIOVIVID ||
727 converter_ != nullptr && converter_->CheckInputValid(bufDesc),
728 ERR_INVALID_PARAM, "Invalid buffer desc");
729 if (bufDesc.bufLength > cbBufferSize_ || bufDesc.dataLength > cbBufferSize_) {
730 AUDIO_WARNING_LOG("Invalid bufLength:%{public}zu or dataLength:%{public}zu, should be %{public}zu",
731 bufDesc.bufLength, bufDesc.dataLength, cbBufferSize_);
732 }
733
734 BufferDesc temp = bufDesc;
735
736 if (state_ == RELEASED) {
737 AUDIO_WARNING_LOG("Invalid state: %{public}d", state_.load());
738 return ERR_ILLEGAL_STATE;
739 }
740 // Call write here may block, so put it in loop callbackLoop_
741 cbBufferQueue_.Push(temp);
742 return SUCCESS;
743 }
744
Clear()745 int32_t RendererInClientInner::Clear()
746 {
747 Trace trace("RendererInClientInner::Clear");
748 if (renderMode_ != RENDER_MODE_CALLBACK) {
749 AUDIO_ERR_LOG("Clear is not supported. Render mode is not callback.");
750 return ERR_INCORRECT_MODE;
751 }
752 std::unique_lock<std::mutex> lock(cbBufferMutex_);
753 int32_t ret = memset_s(cbBuffer_.get(), cbBufferSize_, 0, cbBufferSize_);
754 CHECK_AND_RETURN_RET_LOG(ret == EOK, ERR_OPERATION_FAILED, "Clear buffer fail, ret %{public}d.", ret);
755 lock.unlock();
756 FlushAudioStream();
757 return SUCCESS;
758 }
759
SetLowPowerVolume(float volume)760 int32_t RendererInClientInner::SetLowPowerVolume(float volume)
761 {
762 AUDIO_INFO_LOG("Volume number: %{public}f", volume);
763 if (volume < 0.0 || volume > 1.0) {
764 AUDIO_ERR_LOG("Invalid param: %{public}f", volume);
765 return ERR_INVALID_PARAM;
766 }
767 lowPowerVolume_ = volume;
768
769 CHECK_AND_RETURN_RET_LOG(ipcStream_ != nullptr, ERR_ILLEGAL_STATE, "ipcStream is null!");
770 return ipcStream_->SetLowPowerVolume(lowPowerVolume_);
771 }
772
GetLowPowerVolume()773 float RendererInClientInner::GetLowPowerVolume()
774 {
775 return lowPowerVolume_;
776 }
777
SetOffloadMode(int32_t state,bool isAppBack)778 int32_t RendererInClientInner::SetOffloadMode(int32_t state, bool isAppBack)
779 {
780 CHECK_AND_RETURN_RET_LOG(ipcStream_ != nullptr, ERR_ILLEGAL_STATE, "ipcStream is null!");
781 return ipcStream_->SetOffloadMode(state, isAppBack);
782 }
783
UnsetOffloadMode()784 int32_t RendererInClientInner::UnsetOffloadMode()
785 {
786 rendererInfo_.pipeType = PIPE_TYPE_NORMAL_OUT;
787 CHECK_AND_RETURN_RET_LOG(ipcStream_ != nullptr, ERR_ILLEGAL_STATE, "ipcStream is null!");
788 return ipcStream_->UnsetOffloadMode();
789 }
790
GetSingleStreamVolume()791 float RendererInClientInner::GetSingleStreamVolume()
792 {
793 // in plan. For now, keep it consistent with fast_audio_stream
794 return 1.0f;
795 }
796
GetAudioEffectMode()797 AudioEffectMode RendererInClientInner::GetAudioEffectMode()
798 {
799 AUDIO_DEBUG_LOG("Current audio effect mode is %{public}d", effectMode_);
800 return effectMode_;
801 }
802
SetAudioEffectMode(AudioEffectMode effectMode)803 int32_t RendererInClientInner::SetAudioEffectMode(AudioEffectMode effectMode)
804 {
805 if (effectMode_ == effectMode) {
806 AUDIO_INFO_LOG("Set same effect mode");
807 return SUCCESS;
808 }
809
810 CHECK_AND_RETURN_RET_LOG(ipcStream_ != nullptr, ERR_ILLEGAL_STATE, "ipcStream is not inited!");
811 int32_t ret = ipcStream_->SetAudioEffectMode(effectMode);
812 CHECK_AND_RETURN_RET_LOG(ret == SUCCESS, ERR_OPERATION_FAILED, "Set audio effect mode failed");
813 effectMode_ = effectMode;
814 return SUCCESS;
815 }
816
GetFramesWritten()817 int64_t RendererInClientInner::GetFramesWritten()
818 {
819 return totalBytesWritten_ / static_cast<int64_t>(sizePerFrameInByte_);
820 }
821
GetFramesRead()822 int64_t RendererInClientInner::GetFramesRead()
823 {
824 AUDIO_ERR_LOG("not supported");
825 return -1;
826 }
827
SetInnerCapturerState(bool isInnerCapturer)828 void RendererInClientInner::SetInnerCapturerState(bool isInnerCapturer)
829 {
830 AUDIO_ERR_LOG("SetInnerCapturerState is not supported");
831 return;
832 }
833
SetWakeupCapturerState(bool isWakeupCapturer)834 void RendererInClientInner::SetWakeupCapturerState(bool isWakeupCapturer)
835 {
836 AUDIO_ERR_LOG("SetWakeupCapturerState is not supported");
837 return;
838 }
839
SetCapturerSource(int capturerSource)840 void RendererInClientInner::SetCapturerSource(int capturerSource)
841 {
842 AUDIO_ERR_LOG("SetCapturerSource is not supported");
843 return;
844 }
845
SetPrivacyType(AudioPrivacyType privacyType)846 void RendererInClientInner::SetPrivacyType(AudioPrivacyType privacyType)
847 {
848 if (privacyType_ == privacyType) {
849 AUDIO_INFO_LOG("Set same privacy type");
850 return;
851 }
852 privacyType_ = privacyType;
853 CHECK_AND_RETURN_LOG(ipcStream_ != nullptr, "ipcStream is not inited!");
854 int32_t ret = ipcStream_->SetPrivacyType(privacyType);
855 CHECK_AND_RETURN_LOG(ret == SUCCESS, "Set privacy type failed");
856 }
857
StartAudioStream(StateChangeCmdType cmdType,AudioStreamDeviceChangeReasonExt reason)858 bool RendererInClientInner::StartAudioStream(StateChangeCmdType cmdType,
859 AudioStreamDeviceChangeReasonExt reason)
860 {
861 Trace trace("RendererInClientInner::StartAudioStream " + std::to_string(sessionId_));
862 std::unique_lock<std::mutex> statusLock(statusMutex_);
863 if (state_ != PREPARED && state_ != STOPPED && state_ != PAUSED) {
864 AUDIO_ERR_LOG("Start failed Illegal state:%{public}d", state_.load());
865 return false;
866 }
867
868 hasFirstFrameWrited_ = false;
869 if (audioStreamTracker_ && audioStreamTracker_.get()) {
870 audioStreamTracker_->FetchOutputDeviceForTrack(sessionId_, RUNNING, clientPid_, rendererInfo_, reason);
871 }
872 CHECK_AND_RETURN_RET_LOG(ipcStream_ != nullptr, false, "ipcStream is not inited!");
873 int32_t ret = ipcStream_->Start();
874 if (ret != SUCCESS) {
875 AUDIO_ERR_LOG("Start call server failed:%{public}u", ret);
876 return false;
877 }
878 std::unique_lock<std::mutex> waitLock(callServerMutex_);
879 bool stopWaiting = callServerCV_.wait_for(waitLock, std::chrono::milliseconds(OPERATION_TIMEOUT_IN_MS), [this] {
880 return state_ == RUNNING; // will be false when got notified.
881 });
882 if (!stopWaiting) {
883 AUDIO_ERR_LOG("Start failed: timeout");
884 ipcStream_->Stop();
885 return false;
886 }
887
888 waitLock.unlock();
889
890 AUDIO_INFO_LOG("Start SUCCESS, sessionId: %{public}d, uid: %{public}d", sessionId_, clientUid_);
891 UpdateTracker("RUNNING");
892
893 std::unique_lock<std::mutex> dataConnectionWaitLock(dataConnectionMutex_);
894 if (!isDataLinkConnected_) {
895 AUDIO_INFO_LOG("data-connection blocking starts.");
896 stopWaiting = dataConnectionCV_.wait_for(
897 dataConnectionWaitLock, std::chrono::milliseconds(DATA_CONNECTION_TIMEOUT_IN_MS), [this] {
898 return isDataLinkConnected_;
899 });
900 AUDIO_INFO_LOG("data-connection blocking ends.");
901 }
902 dataConnectionWaitLock.unlock();
903
904 offloadStartReadPos_ = 0;
905 if (renderMode_ == RENDER_MODE_CALLBACK) {
906 // start the callback-write thread
907 cbThreadCv_.notify_all();
908 }
909 statusLock.unlock();
910 // in plan: call HiSysEventWrite
911 int64_t param = -1;
912 StateCmdTypeToParams(param, state_, cmdType);
913 SafeSendCallbackEvent(STATE_CHANGE_EVENT, param);
914 preWriteEndTime_ = 0;
915 return true;
916 }
917
PauseAudioStream(StateChangeCmdType cmdType)918 bool RendererInClientInner::PauseAudioStream(StateChangeCmdType cmdType)
919 {
920 Trace trace("RendererInClientInner::PauseAudioStream " + std::to_string(sessionId_));
921 std::unique_lock<std::mutex> statusLock(statusMutex_);
922 if (state_ != RUNNING) {
923 AUDIO_ERR_LOG("State is not RUNNING. Illegal state:%{public}u", state_.load());
924 return false;
925 }
926
927 CHECK_AND_RETURN_RET_LOG(ipcStream_ != nullptr, false, "ipcStream is not inited!");
928 int32_t ret = ipcStream_->Pause();
929 if (ret != SUCCESS) {
930 AUDIO_ERR_LOG("call server failed:%{public}u", ret);
931 return false;
932 }
933 std::unique_lock<std::mutex> waitLock(callServerMutex_);
934 bool stopWaiting = callServerCV_.wait_for(waitLock, std::chrono::milliseconds(OPERATION_TIMEOUT_IN_MS), [this] {
935 return state_ == PAUSED; // will be false when got notified.
936 });
937 if (!stopWaiting) {
938 AUDIO_ERR_LOG("Pause failed: timeout");
939 return false;
940 }
941
942 waitLock.unlock();
943
944 FutexTool::FutexWake(clientBuffer_->GetFutex());
945 statusLock.unlock();
946
947 // in plan: call HiSysEventWrite
948 int64_t param = -1;
949 StateCmdTypeToParams(param, state_, cmdType);
950 SafeSendCallbackEvent(STATE_CHANGE_EVENT, param);
951
952 AUDIO_INFO_LOG("Pause SUCCESS, sessionId %{public}d, uid %{public}d, mode %{public}s", sessionId_,
953 clientUid_, renderMode_ == RENDER_MODE_NORMAL ? "RENDER_MODE_NORMAL" : "RENDER_MODE_CALLBACK");
954 UpdateTracker("PAUSED");
955 return true;
956 }
957
StopAudioStream()958 bool RendererInClientInner::StopAudioStream()
959 {
960 Trace trace("RendererInClientInner::StopAudioStream " + std::to_string(sessionId_));
961 AUDIO_INFO_LOG("Stop begin for sessionId %{public}d uid: %{public}d", sessionId_, clientUid_);
962 std::unique_lock<std::mutex> statusLock(statusMutex_);
963 std::unique_lock<std::mutex> lock(writeMutex_, std::defer_lock);
964 if (!offloadEnable_) {
965 lock.lock();
966 DrainAudioStreamInner(true);
967 }
968
969 if (state_ == STOPPED) {
970 AUDIO_INFO_LOG("Renderer in client is already stopped");
971 return true;
972 }
973 if ((state_ != RUNNING) && (state_ != PAUSED)) {
974 AUDIO_ERR_LOG("Stop failed. Illegal state:%{public}u", state_.load());
975 return false;
976 }
977
978 std::unique_lock<std::mutex> waitLock(callServerMutex_);
979 if (renderMode_ == RENDER_MODE_CALLBACK) {
980 state_ = STOPPING;
981 AUDIO_INFO_LOG("Stop begin in callback mode sessionId %{public}d uid: %{public}d", sessionId_, clientUid_);
982 }
983
984 CHECK_AND_RETURN_RET_LOG(ipcStream_ != nullptr, false, "ipcStream is not inited!");
985 int32_t ret = ipcStream_->Stop();
986 if (ret != SUCCESS) {
987 AUDIO_ERR_LOG("Stop call server failed:%{public}u", ret);
988 return false;
989 }
990
991 bool stopWaiting = callServerCV_.wait_for(waitLock, std::chrono::milliseconds(OPERATION_TIMEOUT_IN_MS), [this] {
992 return state_ == STOPPED; // will be false when got notified.
993 });
994 if (!stopWaiting) {
995 AUDIO_ERR_LOG("Stop failed: timeout");
996 state_ = INVALID;
997 return false;
998 }
999
1000 waitLock.unlock();
1001
1002 FutexTool::FutexWake(clientBuffer_->GetFutex());
1003 statusLock.unlock();
1004
1005 // in plan: call HiSysEventWrite
1006 SafeSendCallbackEvent(STATE_CHANGE_EVENT, state_);
1007
1008 AUDIO_INFO_LOG("Stop SUCCESS, sessionId: %{public}d, uid: %{public}d", sessionId_, clientUid_);
1009 UpdateTracker("STOPPED");
1010 return true;
1011 }
1012
ReleaseAudioStream(bool releaseRunner,bool isSwitchStream)1013 bool RendererInClientInner::ReleaseAudioStream(bool releaseRunner, bool isSwitchStream)
1014 {
1015 (void)isSwitchStream;
1016 AUDIO_PRERELEASE_LOGI("Enter");
1017 std::unique_lock<std::mutex> statusLock(statusMutex_);
1018 if (state_ == RELEASED) {
1019 AUDIO_WARNING_LOG("Already released, do nothing");
1020 return true;
1021 }
1022 state_ = RELEASED;
1023 statusLock.unlock();
1024
1025 Trace trace("RendererInClientInner::ReleaseAudioStream " + std::to_string(sessionId_));
1026 if (ipcStream_ != nullptr) {
1027 ipcStream_->Release();
1028 } else {
1029 AUDIO_WARNING_LOG("release while ipcStream is null");
1030 }
1031
1032 // no lock, call release in any case, include blocked case.
1033 std::unique_lock<std::mutex> runnerlock(runnerMutex_);
1034 if (releaseRunner && callbackHandler_ != nullptr) {
1035 callbackHandler_->ReleaseEventRunner();
1036 runnerReleased_ = true;
1037 callbackHandler_ = nullptr;
1038 }
1039 runnerlock.unlock();
1040
1041 // clear write callback
1042 if (renderMode_ == RENDER_MODE_CALLBACK) {
1043 cbThreadReleased_ = true; // stop loop
1044 cbThreadCv_.notify_all();
1045 FutexTool::FutexWake(clientBuffer_->GetFutex(), IS_PRE_EXIT);
1046 }
1047 paramsIsSet_ = false;
1048
1049 std::unique_lock<std::mutex> lock(streamCbMutex_);
1050 std::shared_ptr<AudioStreamCallback> streamCb = streamCallback_.lock();
1051 if (streamCb != nullptr) {
1052 AUDIO_INFO_LOG("Notify client the state is released");
1053 streamCb->OnStateChange(RELEASED, CMD_FROM_CLIENT);
1054 }
1055 lock.unlock();
1056
1057 UpdateTracker("RELEASED");
1058 AUDIO_INFO_LOG("Release end, sessionId: %{public}d, uid: %{public}d", sessionId_, clientUid_);
1059
1060 audioSpeed_.reset();
1061 audioSpeed_ = nullptr;
1062 return true;
1063 }
1064
FlushAudioStream()1065 bool RendererInClientInner::FlushAudioStream()
1066 {
1067 Trace trace("RendererInClientInner::FlushAudioStream " + std::to_string(sessionId_));
1068 std::unique_lock<std::mutex> statusLock(statusMutex_);
1069 std::lock_guard<std::mutex>lock(writeMutex_);
1070 if ((state_ != RUNNING) && (state_ != PAUSED) && (state_ != STOPPED)) {
1071 AUDIO_ERR_LOG("Flush failed. Illegal state:%{public}u", state_.load());
1072 return false;
1073 }
1074
1075 // clear cbBufferQueue
1076 if (renderMode_ == RENDER_MODE_CALLBACK) {
1077 cbBufferQueue_.Clear();
1078 int chToFill = (clientConfig_.streamInfo.format == SAMPLE_U8) ? 0x7f : 0;
1079 if (memset_s(cbBuffer_.get(), cbBufferSize_, chToFill, cbBufferSize_) != EOK) {
1080 AUDIO_ERR_LOG("memset_s buffer failed");
1081 }
1082 }
1083
1084 CHECK_AND_RETURN_RET_LOG(FlushRingCache() == SUCCESS, false, "Flush cache failed");
1085
1086 CHECK_AND_RETURN_RET_LOG(ipcStream_ != nullptr, false, "ipcStream is not inited!");
1087 int32_t ret = ipcStream_->Flush();
1088 if (ret != SUCCESS) {
1089 AUDIO_ERR_LOG("Flush call server failed:%{public}u", ret);
1090 return false;
1091 }
1092
1093 // clear multichannel render buffer
1094 if (converter_) {
1095 ret = converter_->Flush();
1096 if (ret != SUCCESS) {
1097 AUDIO_ERR_LOG("Flush mcr buffer failed.");
1098 }
1099 }
1100 std::unique_lock<std::mutex> waitLock(callServerMutex_);
1101 bool stopWaiting = callServerCV_.wait_for(waitLock, std::chrono::milliseconds(OPERATION_TIMEOUT_IN_MS), [this] {
1102 return notifiedOperation_ == FLUSH_STREAM; // will be false when got notified.
1103 });
1104
1105 if (notifiedOperation_ != FLUSH_STREAM || notifiedResult_ != SUCCESS) {
1106 AUDIO_ERR_LOG("Flush failed: %{public}s Operation:%{public}d result:%{public}" PRId64".",
1107 (!stopWaiting ? "timeout" : "no timeout"), notifiedOperation_, notifiedResult_);
1108 notifiedOperation_ = MAX_OPERATION_CODE;
1109 return false;
1110 }
1111 notifiedOperation_ = MAX_OPERATION_CODE;
1112 waitLock.unlock();
1113 ResetFramePosition();
1114 AUDIO_INFO_LOG("Flush stream SUCCESS, sessionId: %{public}d", sessionId_);
1115 return true;
1116 }
1117
DrainAudioStream(bool stopFlag)1118 bool RendererInClientInner::DrainAudioStream(bool stopFlag)
1119 {
1120 std::lock_guard<std::mutex> statusLock(statusMutex_);
1121 std::lock_guard<std::mutex> lock(writeMutex_);
1122 bool ret = DrainAudioStreamInner(stopFlag);
1123 return ret;
1124 }
1125
Write(uint8_t * pcmBuffer,size_t pcmBufferSize,uint8_t * metaBuffer,size_t metaBufferSize)1126 int32_t RendererInClientInner::Write(uint8_t *pcmBuffer, size_t pcmBufferSize, uint8_t *metaBuffer,
1127 size_t metaBufferSize)
1128 {
1129 CHECK_AND_RETURN_RET_LOG(renderMode_ != RENDER_MODE_CALLBACK, ERR_INCORRECT_MODE,
1130 "Write with callback is not supported");
1131 int32_t ret = WriteInner(pcmBuffer, pcmBufferSize, metaBuffer, metaBufferSize);
1132 return ret <= 0 ? ret : static_cast<int32_t>(pcmBufferSize);
1133 }
1134
Write(uint8_t * buffer,size_t bufferSize)1135 int32_t RendererInClientInner::Write(uint8_t *buffer, size_t bufferSize)
1136 {
1137 CHECK_AND_RETURN_RET_LOG(renderMode_ != RENDER_MODE_CALLBACK, ERR_INCORRECT_MODE,
1138 "Write with callback is not supported");
1139 return WriteInner(buffer, bufferSize);
1140 }
1141
SetPreferredFrameSize(int32_t frameSize)1142 void RendererInClientInner::SetPreferredFrameSize(int32_t frameSize)
1143 {
1144 std::lock_guard<std::mutex> lockSetPreferredFrameSize(setPreferredFrameSizeMutex_);
1145 userSettedPreferredFrameSize_ = frameSize;
1146 CHECK_AND_RETURN_LOG(curStreamParams_.encoding != ENCODING_AUDIOVIVID,
1147 "playing audiovivid, frameSize is always 1024.");
1148 size_t maxCbBufferSize =
1149 static_cast<size_t>(MAX_CBBUF_IN_USEC * curStreamParams_.samplingRate / AUDIO_US_PER_S) * sizePerFrameInByte_;
1150 size_t minCbBufferSize =
1151 static_cast<size_t>(MIN_CBBUF_IN_USEC * curStreamParams_.samplingRate / AUDIO_US_PER_S) * sizePerFrameInByte_;
1152 size_t preferredCbBufferSize = static_cast<size_t>(frameSize) * sizePerFrameInByte_;
1153 std::lock_guard<std::mutex> lock(cbBufferMutex_);
1154 cbBufferSize_ = (preferredCbBufferSize > maxCbBufferSize || preferredCbBufferSize < minCbBufferSize) ?
1155 (preferredCbBufferSize > maxCbBufferSize ? maxCbBufferSize : minCbBufferSize) : preferredCbBufferSize;
1156 AUDIO_INFO_LOG("Set CallbackBuffer with byte size: %{public}zu", cbBufferSize_);
1157 cbBuffer_ = std::make_unique<uint8_t[]>(cbBufferSize_);
1158 return;
1159 }
1160
Read(uint8_t & buffer,size_t userSize,bool isBlockingRead)1161 int32_t RendererInClientInner::Read(uint8_t &buffer, size_t userSize, bool isBlockingRead)
1162 {
1163 AUDIO_ERR_LOG("Read is not supported");
1164 return ERROR;
1165 }
1166
GetUnderflowCount()1167 uint32_t RendererInClientInner::GetUnderflowCount()
1168 {
1169 CHECK_AND_RETURN_RET_LOG(clientBuffer_ != nullptr, 0, "buffer is not inited");
1170
1171 return clientBuffer_->GetUnderrunCount();
1172 }
1173
GetOverflowCount()1174 uint32_t RendererInClientInner::GetOverflowCount()
1175 {
1176 AUDIO_WARNING_LOG("No Overflow in renderer");
1177 return 0;
1178 }
1179
SetUnderflowCount(uint32_t underflowCount)1180 void RendererInClientInner::SetUnderflowCount(uint32_t underflowCount)
1181 {
1182 CHECK_AND_RETURN_LOG(clientBuffer_ != nullptr, "buffer is not inited");
1183 clientBuffer_->SetUnderrunCount(underflowCount);
1184 }
1185
SetOverflowCount(uint32_t overflowCount)1186 void RendererInClientInner::SetOverflowCount(uint32_t overflowCount)
1187 {
1188 // not support for renderer
1189 AUDIO_WARNING_LOG("No Overflow in renderer");
1190 return;
1191 }
1192
SetRendererPositionCallback(int64_t markPosition,const std::shared_ptr<RendererPositionCallback> & callback)1193 void RendererInClientInner::SetRendererPositionCallback(int64_t markPosition,
1194 const std::shared_ptr<RendererPositionCallback> &callback)
1195 {
1196 // waiting for review
1197 std::lock_guard<std::mutex> lock(markReachMutex_);
1198 CHECK_AND_RETURN_LOG(callback != nullptr, "RendererPositionCallback is nullptr");
1199 rendererPositionCallback_ = callback;
1200 rendererMarkPosition_ = markPosition;
1201 rendererMarkReached_ = false;
1202 }
1203
UnsetRendererPositionCallback()1204 void RendererInClientInner::UnsetRendererPositionCallback()
1205 {
1206 // waiting for review
1207 std::lock_guard<std::mutex> lock(markReachMutex_);
1208 rendererPositionCallback_ = nullptr;
1209 rendererMarkPosition_ = 0;
1210 rendererMarkReached_ = false;
1211 }
1212
SetRendererPeriodPositionCallback(int64_t periodPosition,const std::shared_ptr<RendererPeriodPositionCallback> & callback)1213 void RendererInClientInner::SetRendererPeriodPositionCallback(int64_t periodPosition,
1214 const std::shared_ptr<RendererPeriodPositionCallback> &callback)
1215 {
1216 // waiting for review
1217 std::lock_guard<std::mutex> lock(periodReachMutex_);
1218 CHECK_AND_RETURN_LOG(callback != nullptr, "RendererPeriodPositionCallback is nullptr");
1219 rendererPeriodPositionCallback_ = callback;
1220 rendererPeriodSize_ = periodPosition;
1221 totalBytesWritten_ = 0;
1222 rendererPeriodWritten_ = 0;
1223 }
1224
UnsetRendererPeriodPositionCallback()1225 void RendererInClientInner::UnsetRendererPeriodPositionCallback()
1226 {
1227 // waiting for review
1228 std::lock_guard<std::mutex> lock(periodReachMutex_);
1229 rendererPeriodPositionCallback_ = nullptr;
1230 rendererPeriodSize_ = 0;
1231 totalBytesWritten_ = 0;
1232 rendererPeriodWritten_ = 0;
1233 }
1234
SetCapturerPositionCallback(int64_t markPosition,const std::shared_ptr<CapturerPositionCallback> & callback)1235 void RendererInClientInner::SetCapturerPositionCallback(int64_t markPosition,
1236 const std::shared_ptr<CapturerPositionCallback> &callback)
1237 {
1238 AUDIO_ERR_LOG("SetCapturerPositionCallback is not supported");
1239 return;
1240 }
1241
UnsetCapturerPositionCallback()1242 void RendererInClientInner::UnsetCapturerPositionCallback()
1243 {
1244 AUDIO_ERR_LOG("SetCapturerPositionCallback is not supported");
1245 return;
1246 }
1247
SetCapturerPeriodPositionCallback(int64_t periodPosition,const std::shared_ptr<CapturerPeriodPositionCallback> & callback)1248 void RendererInClientInner::SetCapturerPeriodPositionCallback(int64_t periodPosition,
1249 const std::shared_ptr<CapturerPeriodPositionCallback> &callback)
1250 {
1251 AUDIO_ERR_LOG("SetCapturerPositionCallback is not supported");
1252 return;
1253 }
1254
UnsetCapturerPeriodPositionCallback()1255 void RendererInClientInner::UnsetCapturerPeriodPositionCallback()
1256 {
1257 AUDIO_ERR_LOG("SetCapturerPositionCallback is not supported");
1258 return;
1259 }
1260
SetRendererSamplingRate(uint32_t sampleRate)1261 int32_t RendererInClientInner::SetRendererSamplingRate(uint32_t sampleRate)
1262 {
1263 AUDIO_ERR_LOG("SetRendererSamplingRate to %{public}d is not supported", sampleRate);
1264 return ERROR;
1265 }
1266
GetRendererSamplingRate()1267 uint32_t RendererInClientInner::GetRendererSamplingRate()
1268 {
1269 return curStreamParams_.samplingRate;
1270 }
1271
SetBufferSizeInMsec(int32_t bufferSizeInMsec)1272 int32_t RendererInClientInner::SetBufferSizeInMsec(int32_t bufferSizeInMsec)
1273 {
1274 // bufferSizeInMsec is checked between 5ms and 20ms.
1275 bufferSizeInMsec_ = static_cast<uint32_t>(bufferSizeInMsec);
1276 AUDIO_INFO_LOG("SetBufferSizeInMsec to %{public}d", bufferSizeInMsec_);
1277 if (renderMode_ == RENDER_MODE_CALLBACK) {
1278 uint64_t bufferDurationInUs = bufferSizeInMsec_ * AUDIO_US_PER_MS;
1279 InitCallbackBuffer(bufferDurationInUs);
1280 }
1281 return SUCCESS;
1282 }
1283
SetChannelBlendMode(ChannelBlendMode blendMode)1284 int32_t RendererInClientInner::SetChannelBlendMode(ChannelBlendMode blendMode)
1285 {
1286 if ((state_ != PREPARED) && (state_ != NEW)) {
1287 AUDIO_ERR_LOG("SetChannelBlendMode in invalid status:%{public}d", state_.load());
1288 return ERR_ILLEGAL_STATE;
1289 }
1290 isBlendSet_ = true;
1291 audioBlend_.SetParams(blendMode, curStreamParams_.format, curStreamParams_.channels);
1292 return SUCCESS;
1293 }
1294
SetVolumeWithRamp(float volume,int32_t duration)1295 int32_t RendererInClientInner::SetVolumeWithRamp(float volume, int32_t duration)
1296 {
1297 CHECK_AND_RETURN_RET_LOG((state_ != RELEASED) && (state_ != INVALID) && (state_ != STOPPED),
1298 ERR_ILLEGAL_STATE, "Illegal state %{public}d", state_.load());
1299
1300 if (FLOAT_COMPARE_EQ(clientVolume_, volume)) {
1301 AUDIO_INFO_LOG("set same volume %{public}f", volume);
1302 return SUCCESS;
1303 }
1304
1305 volumeRamp_.SetVolumeRampConfig(volume, clientVolume_, duration);
1306 return SUCCESS;
1307 }
1308
SetStreamTrackerState(bool trackerRegisteredState)1309 void RendererInClientInner::SetStreamTrackerState(bool trackerRegisteredState)
1310 {
1311 streamTrackerRegistered_ = trackerRegisteredState;
1312 }
1313
GetSwitchInfo(IAudioStream::SwitchInfo & info)1314 void RendererInClientInner::GetSwitchInfo(IAudioStream::SwitchInfo& info)
1315 {
1316 info.params = streamParams_;
1317
1318 info.rendererInfo = rendererInfo_;
1319 info.capturerInfo = capturerInfo_;
1320 info.eStreamType = eStreamType_;
1321 info.renderMode = renderMode_;
1322 info.state = state_;
1323 info.sessionId = sessionId_;
1324 info.streamTrackerRegistered = streamTrackerRegistered_;
1325 info.defaultOutputDevice = defaultOutputDevice_;
1326 GetStreamSwitchInfo(info);
1327
1328 {
1329 std::lock_guard<std::mutex> lock(setPreferredFrameSizeMutex_);
1330 info.userSettedPreferredFrameSize = userSettedPreferredFrameSize_;
1331 }
1332 }
1333
GetStreamSwitchInfo(IAudioStream::SwitchInfo & info)1334 void RendererInClientInner::GetStreamSwitchInfo(IAudioStream::SwitchInfo& info)
1335 {
1336 info.underFlowCount = GetUnderflowCount();
1337 info.effectMode = effectMode_;
1338 info.renderRate = rendererRate_;
1339 info.clientPid = clientPid_;
1340 info.clientUid = clientUid_;
1341 info.volume = clientVolume_;
1342 info.silentModeAndMixWithOthers = silentModeAndMixWithOthers_;
1343
1344 info.frameMarkPosition = static_cast<uint64_t>(rendererMarkPosition_);
1345 info.renderPositionCb = rendererPositionCallback_;
1346
1347 info.framePeriodNumber = static_cast<uint64_t>(rendererPeriodSize_);
1348 info.renderPeriodPositionCb = rendererPeriodPositionCallback_;
1349
1350 info.rendererWriteCallback = writeCb_;
1351 }
1352
GetStreamClass()1353 IAudioStream::StreamClass RendererInClientInner::GetStreamClass()
1354 {
1355 return PA_STREAM;
1356 }
1357
OnHandle(uint32_t code,int64_t data)1358 void RendererInClientInner::OnHandle(uint32_t code, int64_t data)
1359 {
1360 AUDIO_DEBUG_LOG("On handle event, event code: %{public}d, data: %{public}" PRIu64 "", code, data);
1361 switch (code) {
1362 case STATE_CHANGE_EVENT:
1363 HandleStateChangeEvent(data);
1364 break;
1365 case RENDERER_MARK_REACHED_EVENT:
1366 HandleRenderMarkReachedEvent(data);
1367 break;
1368 case RENDERER_PERIOD_REACHED_EVENT:
1369 HandleRenderPeriodReachedEvent(data);
1370 break;
1371 default:
1372 break;
1373 }
1374 }
1375
InitCallbackHandler()1376 void RendererInClientInner::InitCallbackHandler()
1377 {
1378 std::lock_guard<std::mutex> lock(runnerMutex_);
1379 if (callbackHandler_ == nullptr) {
1380 callbackHandler_ = CallbackHandler::GetInstance(shared_from_this(), "OS_AudioStateCB");
1381 }
1382 }
1383
SafeSendCallbackEvent(uint32_t eventCode,int64_t data)1384 void RendererInClientInner::SafeSendCallbackEvent(uint32_t eventCode, int64_t data)
1385 {
1386 std::lock_guard<std::mutex> lock(runnerMutex_);
1387 AUDIO_INFO_LOG("Send callback event, code: %{public}u, data: %{public}" PRId64 "", eventCode, data);
1388 CHECK_AND_RETURN_LOG(callbackHandler_ != nullptr && runnerReleased_ == false, "Runner is Released");
1389 callbackHandler_->SendCallbackEvent(eventCode, data);
1390 }
1391
StateCmdTypeToParams(int64_t & params,State state,StateChangeCmdType cmdType)1392 int32_t RendererInClientInner::StateCmdTypeToParams(int64_t ¶ms, State state, StateChangeCmdType cmdType)
1393 {
1394 if (cmdType == CMD_FROM_CLIENT) {
1395 params = static_cast<int64_t>(state);
1396 return SUCCESS;
1397 }
1398 switch (state) {
1399 case RUNNING:
1400 params = HANDLER_PARAM_RUNNING_FROM_SYSTEM;
1401 break;
1402 case PAUSED:
1403 params = HANDLER_PARAM_PAUSED_FROM_SYSTEM;
1404 break;
1405 default:
1406 params = HANDLER_PARAM_INVALID;
1407 break;
1408 }
1409 return SUCCESS;
1410 }
1411
ParamsToStateCmdType(int64_t params,State & state,StateChangeCmdType & cmdType)1412 int32_t RendererInClientInner::ParamsToStateCmdType(int64_t params, State &state, StateChangeCmdType &cmdType)
1413 {
1414 cmdType = CMD_FROM_CLIENT;
1415 switch (params) {
1416 case HANDLER_PARAM_NEW:
1417 state = NEW;
1418 break;
1419 case HANDLER_PARAM_PREPARED:
1420 state = PREPARED;
1421 break;
1422 case HANDLER_PARAM_RUNNING:
1423 state = RUNNING;
1424 break;
1425 case HANDLER_PARAM_STOPPED:
1426 state = STOPPED;
1427 break;
1428 case HANDLER_PARAM_RELEASED:
1429 state = RELEASED;
1430 break;
1431 case HANDLER_PARAM_PAUSED:
1432 state = PAUSED;
1433 break;
1434 case HANDLER_PARAM_STOPPING:
1435 state = STOPPING;
1436 break;
1437 case HANDLER_PARAM_RUNNING_FROM_SYSTEM:
1438 state = RUNNING;
1439 cmdType = CMD_FROM_SYSTEM;
1440 break;
1441 case HANDLER_PARAM_PAUSED_FROM_SYSTEM:
1442 state = PAUSED;
1443 cmdType = CMD_FROM_SYSTEM;
1444 break;
1445 default:
1446 state = INVALID;
1447 break;
1448 }
1449 return SUCCESS;
1450 }
1451
1452 // OnRenderMarkReach by eventHandler
SendRenderMarkReachedEvent(int64_t rendererMarkPosition)1453 void RendererInClientInner::SendRenderMarkReachedEvent(int64_t rendererMarkPosition)
1454 {
1455 SafeSendCallbackEvent(RENDERER_MARK_REACHED_EVENT, rendererMarkPosition);
1456 }
1457
1458 // OnRenderPeriodReach by eventHandler
SendRenderPeriodReachedEvent(int64_t rendererPeriodSize)1459 void RendererInClientInner::SendRenderPeriodReachedEvent(int64_t rendererPeriodSize)
1460 {
1461 SafeSendCallbackEvent(RENDERER_PERIOD_REACHED_EVENT, rendererPeriodSize);
1462 }
1463
HandleRendererPositionChanges(size_t bytesWritten)1464 void RendererInClientInner::HandleRendererPositionChanges(size_t bytesWritten)
1465 {
1466 totalBytesWritten_ += static_cast<int64_t>(bytesWritten);
1467 if (sizePerFrameInByte_ == 0) {
1468 AUDIO_ERR_LOG("HandleRendererPositionChanges: sizePerFrameInByte_ is 0");
1469 return;
1470 }
1471 int64_t writtenFrameNumber = totalBytesWritten_ / static_cast<int64_t>(sizePerFrameInByte_);
1472 AUDIO_DEBUG_LOG("frame size: %{public}zu", sizePerFrameInByte_);
1473
1474 {
1475 std::lock_guard<std::mutex> lock(markReachMutex_);
1476 if (!rendererMarkReached_) {
1477 AUDIO_DEBUG_LOG("Frame mark position: %{public}" PRId64", Total frames written: %{public}" PRId64,
1478 static_cast<int64_t>(rendererMarkPosition_), static_cast<int64_t>(writtenFrameNumber));
1479 if (writtenFrameNumber >= rendererMarkPosition_) {
1480 AUDIO_DEBUG_LOG("OnMarkReached %{public}" PRId64".", rendererMarkPosition_);
1481 SendRenderMarkReachedEvent(rendererMarkPosition_);
1482 rendererMarkReached_ = true;
1483 }
1484 }
1485 }
1486
1487 {
1488 std::lock_guard<std::mutex> lock(periodReachMutex_);
1489 rendererPeriodWritten_ += static_cast<int64_t>((bytesWritten / sizePerFrameInByte_));
1490 AUDIO_DEBUG_LOG("Frame period number: %{public}" PRId64", Total frames written: %{public}" PRId64,
1491 static_cast<int64_t>(rendererPeriodWritten_), static_cast<int64_t>(totalBytesWritten_));
1492 if (rendererPeriodWritten_ >= rendererPeriodSize_ && rendererPeriodSize_ > 0) {
1493 rendererPeriodWritten_ %= rendererPeriodSize_;
1494 AUDIO_DEBUG_LOG("OnPeriodReached, remaining frames: %{public}" PRId64,
1495 static_cast<int64_t>(rendererPeriodWritten_));
1496 SendRenderPeriodReachedEvent(rendererPeriodSize_);
1497 }
1498 }
1499 }
1500
HandleStateChangeEvent(int64_t data)1501 void RendererInClientInner::HandleStateChangeEvent(int64_t data)
1502 {
1503 State state = INVALID;
1504 StateChangeCmdType cmdType = CMD_FROM_CLIENT;
1505 ParamsToStateCmdType(data, state, cmdType);
1506 std::unique_lock<std::mutex> lock(streamCbMutex_);
1507 std::shared_ptr<AudioStreamCallback> streamCb = streamCallback_.lock();
1508 if (streamCb != nullptr) {
1509 state = state != STOPPING ? state : STOPPED; // client only need STOPPED
1510 streamCb->OnStateChange(state, cmdType);
1511 }
1512 }
1513
HandleRenderMarkReachedEvent(int64_t rendererMarkPosition)1514 void RendererInClientInner::HandleRenderMarkReachedEvent(int64_t rendererMarkPosition)
1515 {
1516 AUDIO_DEBUG_LOG("Start HandleRenderMarkReachedEvent");
1517 std::unique_lock<std::mutex> lock(markReachMutex_);
1518 if (rendererPositionCallback_) {
1519 rendererPositionCallback_->OnMarkReached(rendererMarkPosition);
1520 }
1521 }
1522
HandleRenderPeriodReachedEvent(int64_t rendererPeriodNumber)1523 void RendererInClientInner::HandleRenderPeriodReachedEvent(int64_t rendererPeriodNumber)
1524 {
1525 AUDIO_DEBUG_LOG("Start HandleRenderPeriodReachedEvent");
1526 std::unique_lock<std::mutex> lock(periodReachMutex_);
1527 if (rendererPeriodPositionCallback_) {
1528 rendererPeriodPositionCallback_->OnPeriodReached(rendererPeriodNumber);
1529 }
1530 }
1531
OnSpatializationStateChange(const AudioSpatializationState & spatializationState)1532 void RendererInClientInner::OnSpatializationStateChange(const AudioSpatializationState &spatializationState)
1533 {
1534 CHECK_AND_RETURN_LOG(ipcStream_ != nullptr, "Object ipcStream is nullptr");
1535 CHECK_AND_RETURN_LOG(ipcStream_->UpdateSpatializationState(spatializationState.spatializationEnabled,
1536 spatializationState.headTrackingEnabled) == SUCCESS, "Update spatialization state failed");
1537 }
1538
UpdateLatencyTimestamp(std::string & timestamp,bool isRenderer)1539 void RendererInClientInner::UpdateLatencyTimestamp(std::string ×tamp, bool isRenderer)
1540 {
1541 sptr<IStandardAudioService> gasp = RendererInClientInner::GetAudioServerProxy();
1542 if (gasp == nullptr) {
1543 AUDIO_ERR_LOG("LatencyMeas failed to get AudioServerProxy");
1544 return;
1545 }
1546 gasp->UpdateLatencyTimestamp(timestamp, isRenderer);
1547 }
1548
SetSourceDuration(int64_t duration)1549 int32_t RendererInClientInner::SetSourceDuration(int64_t duration)
1550 {
1551 CHECK_AND_RETURN_RET_LOG(ipcStream_ != nullptr, ERR_OPERATION_FAILED, "ipcStream is not inited!");
1552 int32_t ret = ipcStream_->SetSourceDuration(duration);
1553 if (ret != SUCCESS) {
1554 AUDIO_ERR_LOG("Set Source Duration failed:%{public}d", ret);
1555 return ERROR;
1556 }
1557 return SUCCESS;
1558 }
1559
GetOffloadEnable()1560 bool RendererInClientInner::GetOffloadEnable()
1561 {
1562 return offloadEnable_;
1563 }
1564
GetSpatializationEnabled()1565 bool RendererInClientInner::GetSpatializationEnabled()
1566 {
1567 return rendererInfo_.spatializationEnabled;
1568 }
1569
GetHighResolutionEnabled()1570 bool RendererInClientInner::GetHighResolutionEnabled()
1571 {
1572 return AudioPolicyManager::GetInstance().IsHighResolutionExist();
1573 }
1574
SetSilentModeAndMixWithOthers(bool on)1575 void RendererInClientInner::SetSilentModeAndMixWithOthers(bool on)
1576 {
1577 AUDIO_PRERELEASE_LOGI("SetSilentModeAndMixWithOthers %{public}d", on);
1578 silentModeAndMixWithOthers_ = on;
1579 CHECK_AND_RETURN_LOG(ipcStream_ != nullptr, "Object ipcStream is nullptr");
1580 ipcStream_->SetSilentModeAndMixWithOthers(on);
1581 return;
1582 }
1583
GetSilentModeAndMixWithOthers()1584 bool RendererInClientInner::GetSilentModeAndMixWithOthers()
1585 {
1586 return silentModeAndMixWithOthers_;
1587 }
1588
RestoreAudioStream(bool needStoreState)1589 bool RendererInClientInner::RestoreAudioStream(bool needStoreState)
1590 {
1591 CHECK_AND_RETURN_RET_LOG(proxyObj_ != nullptr, false, "proxyObj_ is null");
1592 CHECK_AND_RETURN_RET_LOG(state_ != NEW && state_ != INVALID && state_ != RELEASED, true,
1593 "state_ is %{public}d, no need for restore", state_.load());
1594 bool result = true;
1595 State oldState = state_;
1596 state_ = NEW;
1597 SetStreamTrackerState(false);
1598 // If pipe type is offload, need reset to normal.
1599 // Otherwise, unable to enter offload mode.
1600 if (rendererInfo_.pipeType == PIPE_TYPE_OFFLOAD) {
1601 rendererInfo_.pipeType = PIPE_TYPE_NORMAL_OUT;
1602 }
1603 int32_t ret = SetAudioStreamInfo(streamParams_, proxyObj_);
1604 if (ret != SUCCESS) {
1605 goto error;
1606 }
1607 if (!needStoreState) {
1608 AUDIO_INFO_LOG("telephony scene, return directly");
1609 return ret == SUCCESS;
1610 }
1611
1612 SetDefaultOutputDevice(defaultOutputDevice_);
1613
1614 switch (oldState) {
1615 case RUNNING:
1616 result = StartAudioStream();
1617 break;
1618 case PAUSED:
1619 result = StartAudioStream() && PauseAudioStream();
1620 break;
1621 case STOPPED:
1622 case STOPPING:
1623 result = StartAudioStream() && StopAudioStream();
1624 break;
1625 default:
1626 state_ = oldState;
1627 break;
1628 }
1629 if (!result) {
1630 goto error;
1631 }
1632 return result;
1633
1634 error:
1635 AUDIO_ERR_LOG("RestoreAudioStream failed");
1636 state_ = oldState;
1637 return false;
1638 }
1639
SetDefaultOutputDevice(const DeviceType defaultOutputDevice)1640 int32_t RendererInClientInner::SetDefaultOutputDevice(const DeviceType defaultOutputDevice)
1641 {
1642 CHECK_AND_RETURN_RET_LOG(ipcStream_ != nullptr, ERR_ILLEGAL_STATE, "ipcStream is not inited!");
1643 int32_t ret = ipcStream_->SetDefaultOutputDevice(defaultOutputDevice);
1644 if (ret == SUCCESS) {
1645 defaultOutputDevice_ = defaultOutputDevice;
1646 }
1647 return ret;
1648 }
1649
GetDefaultOutputDevice()1650 DeviceType RendererInClientInner::GetDefaultOutputDevice()
1651 {
1652 return defaultOutputDevice_;
1653 }
1654
GetAudioTimestampInfo(Timestamp & timestamp,Timestamp::Timestampbase base)1655 int32_t RendererInClientInner::GetAudioTimestampInfo(Timestamp ×tamp, Timestamp::Timestampbase base)
1656 {
1657 CHECK_AND_RETURN_RET_LOG(state_ == RUNNING, ERR_ILLEGAL_STATE, "Renderer stream state is not RUNNING");
1658 CHECK_AND_RETURN_RET_LOG(ipcStream_ != nullptr, ERR_ILLEGAL_STATE, "ipcStream is not inited!");
1659 uint64_t readIdx = 0;
1660 uint64_t timestampVal = 0;
1661 uint64_t latency = 0;
1662 int32_t ret = ipcStream_->GetAudioPosition(readIdx, timestampVal, latency);
1663 readIdx = readIdx > lastFlushReadIndex_ ? readIdx - lastFlushReadIndex_ : 0;
1664 uint64_t framePosition = lastFramePosition_;
1665 if (readIdx >= latency + lastReadIdx_) { // happen when last speed latency consumed
1666 framePosition += lastLatencyPosition_ + (readIdx - lastReadIdx_ - latency) * speed_;
1667 lastLatency_ = latency;
1668 lastLatencyPosition_ = latency * speed_;
1669 lastReadIdx_ = readIdx;
1670 } else { // happen when last speed latency not consumed
1671 if (lastLatency_ + readIdx > latency + lastReadIdx_) {
1672 framePosition += lastLatencyPosition_ * (lastLatency_ + readIdx - latency - lastReadIdx_) / lastLatency_;
1673 lastLatencyPosition_ = lastLatencyPosition_ * (latency + lastReadIdx_ - readIdx) / lastLatency_;
1674 lastLatency_ = latency + lastReadIdx_ - readIdx;
1675 }
1676 }
1677 // add MCR latency
1678 uint32_t mcrLatency = 0;
1679 if (converter_ != nullptr) {
1680 mcrLatency = converter_->GetLatency() * curStreamParams_.samplingRate / AUDIO_MS_PER_S;
1681 framePosition = framePosition > mcrLatency ? framePosition - mcrLatency : 0;
1682 }
1683
1684 if (lastFramePosition_ < framePosition) {
1685 lastFramePosition_ = framePosition;
1686 lastFrameTimestamp_ = timestampVal;
1687 } else {
1688 AUDIO_DEBUG_LOG("The frame position should be continuously increasing");
1689 framePosition = lastFramePosition_;
1690 timestampVal = lastFrameTimestamp_;
1691 }
1692 AUDIO_DEBUG_LOG("[CLIENT]Latency info: framePosition: %{public}" PRIu64 ", lastFlushReadIndex_ %{public}" PRIu64
1693 ", timestamp %{public}" PRIu64 ", lastLatencyPosition_ %{public}" PRIu64 ", totlatency %{public}" PRIu64,
1694 framePosition, lastFlushReadIndex_, timestampVal, lastLatencyPosition_, latency + mcrLatency);
1695
1696 timestamp.framePosition = framePosition;
1697 timestamp.time.tv_sec = static_cast<time_t>(timestampVal / AUDIO_NS_PER_SECOND);
1698 timestamp.time.tv_nsec = static_cast<time_t>(timestampVal % AUDIO_NS_PER_SECOND);
1699 return ret;
1700 }
1701
SetSwitchingStatus(bool isSwitching)1702 void RendererInClientInner::SetSwitchingStatus(bool isSwitching)
1703 {
1704 std::lock_guard lock(switchingMutex_);
1705 if (isSwitching) {
1706 switchingInfo_ = {true, state_};
1707 } else {
1708 switchingInfo_ = {false, INVALID};
1709 }
1710 }
1711
GetRestoreInfo(RestoreInfo & restoreInfo)1712 void RendererInClientInner::GetRestoreInfo(RestoreInfo &restoreInfo)
1713 {
1714 CHECK_AND_RETURN_LOG(clientBuffer_ != nullptr, "Client OHAudioBuffer is nullptr");
1715 clientBuffer_->GetRestoreInfo(restoreInfo);
1716 return;
1717 }
1718
SetRestoreInfo(RestoreInfo & restoreInfo)1719 void RendererInClientInner::SetRestoreInfo(RestoreInfo &restoreInfo)
1720 {
1721 if (restoreInfo.restoreReason == SERVER_DIED) {
1722 cbThreadReleased_ = true;
1723 }
1724 CHECK_AND_RETURN_LOG(clientBuffer_ != nullptr, "Client OHAudioBuffer is nullptr");
1725 clientBuffer_->SetRestoreInfo(restoreInfo);
1726 return;
1727 }
1728
CheckRestoreStatus()1729 RestoreStatus RendererInClientInner::CheckRestoreStatus()
1730 {
1731 CHECK_AND_RETURN_RET_LOG(clientBuffer_ != nullptr, RESTORE_ERROR, "Client OHAudioBuffer is nullptr");
1732 return clientBuffer_->CheckRestoreStatus();
1733 }
1734
SetRestoreStatus(RestoreStatus restoreStatus)1735 RestoreStatus RendererInClientInner::SetRestoreStatus(RestoreStatus restoreStatus)
1736 {
1737 CHECK_AND_RETURN_RET_LOG(clientBuffer_ != nullptr, RESTORE_ERROR, "Client OHAudioBuffer is nullptr");
1738 return clientBuffer_->SetRestoreStatus(restoreStatus);
1739 }
1740
FetchDeviceForSplitStream()1741 void RendererInClientInner::FetchDeviceForSplitStream()
1742 {
1743 AUDIO_INFO_LOG("Fetch output device for split stream %{public}u", sessionId_);
1744 if (audioStreamTracker_ && audioStreamTracker_.get()) {
1745 audioStreamTracker_->FetchOutputDeviceForTrack(sessionId_,
1746 state_, clientPid_, rendererInfo_, AudioStreamDeviceChangeReasonExt::ExtEnum::UNKNOWN);
1747 } else {
1748 AUDIO_WARNING_LOG("Tracker is nullptr, fail to split stream %{public}u", sessionId_);
1749 }
1750 SetRestoreStatus(NO_NEED_FOR_RESTORE);
1751 }
1752 } // namespace AudioStandard
1753 } // namespace OHOS