1 /*
2 * Copyright (c) 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 #undef LOG_TAG
16 #define LOG_TAG "AudioRenderDfxCollector"
17
18 #include <map>
19 #include <cinttypes>
20
21 #include "audio_renderer_dfx_collector.h"
22 #include "media_monitor_manager.h"
23 #include "audio_common_log.h"
24 #include "dfx_msg_manager.h"
25
26 namespace OHOS {
27 namespace AudioStandard {
28
29 static const std::map<PlayerType, DfxPlayerType> DFX_PLAYER_TYPE_MAP = {
30 {PLAYER_TYPE_DEFAULT, DFX_PLAYER_TYPE_NATIVE_RENDER},
31 {PLAYER_TYPE_OH_AUDIO_RENDERER, DFX_PLAYER_TYPE_NATIVE_RENDER},
32 {PLAYER_TYPE_ARKTS_AUDIO_RENDERER, DFX_PLAYER_TYPE_TS_RENDER},
33 {PLAYER_TYPE_OPENSL_ES, DFX_PLAYER_TYPE_OPENSL_ES},
34 {PLAYER_TYPE_SOUND_POOL, DFX_PLAYER_TYPE_SOUNDPOOL},
35 {PLAYER_TYPE_AV_PLAYER, DFX_PLAYER_TYPE_AVPLAYER},
36 {PLAYER_TYPE_TONE_PLAYER, DFX_PLAYER_TYPE_TONEPLAYER},
37 };
38
FlushDfxMsg(uint32_t index,int32_t appUid)39 void AudioRenderDfxCollector::FlushDfxMsg(uint32_t index, int32_t appUid)
40 {
41 if (appUid == DFX_INVALID_APP_UID) {
42 AUDIO_INFO_LOG("flush failed index=%{public}d, appUid=%{public}d", index, appUid);
43 return;
44 }
45
46 for (auto &item : dfxInfos_) {
47 AUDIO_INFO_LOG("FlushDfxMsg..., index=%{public}u, appUid=%{public}d", item.first, appUid);
48 DfxMsgManager::GetInstance().Enqueue({.appUid = appUid, .renderInfo = item.second});
49 }
50
51 dfxInfos_.clear();
52 }
53
WriteActionMsg(uint32_t dfxIndex,RendererStage stage)54 RenderDfxBuilder& RenderDfxBuilder::WriteActionMsg(uint32_t dfxIndex, RendererStage stage)
55 {
56 dfxInfo_.rendererAction = {dfxIndex, 0, 0, stage};
57 return *this;
58 }
59
WriteInfoMsg(int64_t sourceDuration,const AudioRendererInfo & rendererInfo)60 RenderDfxBuilder& RenderDfxBuilder::WriteInfoMsg(int64_t sourceDuration, const AudioRendererInfo &rendererInfo)
61 {
62 std::chrono::milliseconds durationMs(sourceDuration);
63 auto durationSec = std::chrono::duration_cast<std::chrono::duration<int64_t, std::deci>>(durationMs).count();
64 auto dfxDurationSec = static_cast<uint16_t>(std::clamp(
65 durationSec, static_cast<int64_t>(MIN_DFX_NUMERIC_COUNT),
66 static_cast<int64_t>(std::numeric_limits<uint16_t>::max())));
67 AUDIO_INFO_LOG("[Start] duration=%{public}" PRId16, dfxDurationSec);
68
69 auto pos = DFX_PLAYER_TYPE_MAP.find(rendererInfo.playerType);
70 DfxPlayerType playerType = (pos == DFX_PLAYER_TYPE_MAP.end()) ? DFX_PLAYER_TYPE_NATIVE_RENDER : pos->second;
71
72 dfxInfo_.rendererInfo = {(dfxDurationSec >> 8) & 0xFF, dfxDurationSec & 0xFF,
73 playerType, rendererInfo.streamUsage};
74 return *this;
75 }
76
WriteStatMsg(const AudioRendererInfo & rendererInfo,const PlayStat & playStat)77 RenderDfxBuilder& RenderDfxBuilder::WriteStatMsg(const AudioRendererInfo &rendererInfo, const PlayStat &playStat)
78 {
79 auto writeFrame = playStat.frameCnt;
80 auto muteWriteFrame = playStat.muteFrameCnt;
81 auto lastPlayduration = playStat.playDuration;
82
83 uint16_t dfxZerodataPercent{0};
84 if (muteWriteFrame != 0) {
85 auto zerodataPercent = static_cast<int32_t>(
86 static_cast<double>(writeFrame) / (muteWriteFrame * MAX_DFX_NUMERIC_PERCENTAGE));
87 dfxZerodataPercent = std::clamp(zerodataPercent, MIN_DFX_NUMERIC_COUNT, MAX_DFX_NUMERIC_PERCENTAGE);
88 }
89 AUDIO_INFO_LOG("[WritePlayingAudioStatMsg] writeFrame=%{public}" PRId64 \
90 "muteWriteFrame=%{public}" PRId64 "zerodataPercent=%{public}" PRId32 \
91 "lastPlayduration=%{public}" PRId64,
92 writeFrame, muteWriteFrame, dfxZerodataPercent, lastPlayduration);
93
94 dfxInfo_.rendererStat = {rendererInfo.samplingRate, lastPlayduration, playStat.underFlowCnt,
95 rendererInfo.originalFlag, dfxZerodataPercent};
96 return *this;
97 }
98
GetResult()99 RenderDfxInfo RenderDfxBuilder::GetResult()
100 {
101 return dfxInfo_;
102 }
103 } // namespace AudioStandard
104 } // namespace OHOS
105