• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 &timestamp, 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 &timestamp, 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 &params, 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 &timestamp, 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 &timestamp, 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