1 /*
2 * Copyright (c) 2024 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
16 #include <chrono>
17
18 #include "rs_video_frame_rate_vote.h"
19 #include "ffrt_inner.h"
20 #include "platform/common/rs_log.h"
21
22 namespace OHOS {
23 namespace Rosen {
24 namespace {
25 const static uint32_t NORMAL_RATE_MIN = 1;
26 const static uint32_t NORMAL_RATE_MAX = 144;
27 constexpr int32_t DELAY_TIME = 1000 * 1000;
28 }
29
RSVideoFrameRateVote(uint64_t surfaceNodeId,const std::function<void (uint64_t)> & releaseCallback,const std::function<void (uint64_t,uint32_t)> & voteCallback)30 RSVideoFrameRateVote::RSVideoFrameRateVote(uint64_t surfaceNodeId,
31 const std::function<void(uint64_t)>& releaseCallback,
32 const std::function<void(uint64_t, uint32_t)>& voteCallback)
33 : surfaceNodeId_(surfaceNodeId), releaseCallback_(releaseCallback), voteCallback_(voteCallback)
34 {
35 std::string queueName = "video_frame_rate_vote_queue_" + std::to_string(surfaceNodeId);
36 ffrtQueue_ = std::make_shared<ffrt::queue>(queueName.c_str());
37 }
38
~RSVideoFrameRateVote()39 RSVideoFrameRateVote::~RSVideoFrameRateVote()
40 {
41 voteCallback_ = nullptr;
42 releaseCallback_ = nullptr;
43 taskHandler_ = nullptr;
44 ffrtQueue_ = nullptr;
45 }
46
StartVideoFrameRateVote(double videoRate)47 void RSVideoFrameRateVote::StartVideoFrameRateVote(double videoRate)
48 {
49 CancelDelayTask();
50 VoteVideoFrameRate(videoRate);
51 SendDelayTask();
52 }
53
VoteVideoFrameRate(double videoRate)54 void RSVideoFrameRateVote::VoteVideoFrameRate(double videoRate)
55 {
56 int32_t intRate = static_cast<int32_t>(videoRate);
57 uint32_t rate = static_cast<uint32_t>(intRate);
58 if (rate < NORMAL_RATE_MIN || rate > NORMAL_RATE_MAX) {
59 return;
60 }
61 if (rate == lastRate_) {
62 return;
63 }
64 RS_LOGI("video vote surfaceNodeId(%{public}s) rate(%{public}u)", std::to_string(surfaceNodeId_).c_str(), rate);
65 DoVoteCallback(rate);
66 lastRate_ = rate;
67 }
68
SendDelayTask()69 void RSVideoFrameRateVote::SendDelayTask()
70 {
71 std::lock_guard<ffrt::mutex> autoLock(ffrtMutex_);
72 auto initTask = [this]() {
73 DoReleaseCallback();
74 };
75 ffrt::task_attr taskAttr;
76 taskAttr.delay(DELAY_TIME);
77 if (ffrtQueue_) {
78 taskHandler_ = ffrtQueue_->submit_h(initTask, taskAttr);
79 }
80 }
81
CancelDelayTask()82 void RSVideoFrameRateVote::CancelDelayTask()
83 {
84 std::lock_guard<ffrt::mutex> autoLock(ffrtMutex_);
85 if (taskHandler_) {
86 ffrtQueue_->cancel(taskHandler_);
87 taskHandler_ = nullptr;
88 }
89 }
90
DoVoteCallback(uint32_t rate)91 void RSVideoFrameRateVote::DoVoteCallback(uint32_t rate)
92 {
93 if (voteCallback_ == nullptr) {
94 return;
95 }
96 voteCallback_(surfaceNodeId_, rate);
97 }
98
DoReleaseCallback()99 void RSVideoFrameRateVote::DoReleaseCallback()
100 {
101 if (releaseCallback_ == nullptr) {
102 return;
103 }
104 releaseCallback_(surfaceNodeId_);
105 }
106 } // namespace Rosen
107 } // namespace OHOS