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