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