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 #include <string>
16
17 #include "common/rs_common_def.h"
18 #include "display_engine/rs_vpe_manager.h"
19 #include "platform/common/rs_log.h"
20 #include "rs_trace.h"
21
22 using namespace OHOS::Media::VideoProcessingEngine;
23
OnOutputBufferAvailable(uint32_t index,VpeBufferFlag flag)24 void VpeVideoCallbackImpl::OnOutputBufferAvailable(uint32_t index, VpeBufferFlag flag)
25 {
26 if (videoFilter_.expired()) {
27 RS_LOGE("videoFilter_ is expired");
28 return;
29 }
30 std::shared_ptr<VpeVideo> video = videoFilter_.lock();
31 if (video == nullptr) {
32 RS_LOGE("video is nullptr");
33 return;
34 }
35 video->ReleaseOutputBuffer(index, true);
36 }
37 namespace OHOS {
38 namespace Rosen {
GetInstance()39 RSVpeManager& RSVpeManager::GetInstance()
40 {
41 static RSVpeManager instance{};
42 return instance;
43 }
44
ReleaseVpeVideo(uint64_t nodeId)45 void RSVpeManager::ReleaseVpeVideo(uint64_t nodeId)
46 {
47 std::lock_guard<std::mutex> lock(vpeVideoLock_);
48 auto it = allVpeVideo_.find(nodeId);
49 if (it == allVpeVideo_.end()) {
50 return;
51 }
52 std::shared_ptr<VpeVideo> vpeVideoImp = it->second;
53 if (vpeVideoImp != nullptr) {
54 int32_t ret = vpeVideoImp->Stop();
55 if (ret != 0) {
56 RS_LOGE("vpeVideo stop failed nodeId:%{public}" PRIu64 ", ret:%{public}d", nodeId, ret);
57 }
58 ret = vpeVideoImp->Release();
59 if (ret != 0) {
60 RS_LOGE("vpeVideo release failed nodeId:%{public}" PRIu64 ", ret:%{public}d", nodeId, ret);
61 }
62 }
63 allVpeVideo_.erase(nodeId);
64 return;
65 }
66
GetVpeVideo(uint32_t type,const RSSurfaceRenderNodeConfig & config)67 std::shared_ptr<VpeVideo> RSVpeManager::GetVpeVideo(uint32_t type, const RSSurfaceRenderNodeConfig& config)
68 {
69 ReleaseVpeVideo(config.id);
70 return VpeVideo::Create(type);
71 }
72
SetVpeVideoParameter(std::shared_ptr<VpeVideo> vpeVideo,uint32_t type,const RSSurfaceRenderNodeConfig & config)73 bool RSVpeManager::SetVpeVideoParameter(std::shared_ptr<VpeVideo> vpeVideo,
74 uint32_t type, const RSSurfaceRenderNodeConfig& config)
75 {
76 Media::Format param{};
77 if (type == VIDEO_TYPE_DETAIL_ENHANCER) {
78 param.PutIntValue(ParameterKey::DETAIL_ENHANCER_QUALITY_LEVEL, DETAIL_ENHANCER_LEVEL_HIGH);
79 if (vpeVideo->SetParameter(param) != 0) {
80 RS_LOGE("SetParameter level failed!");
81 return false;
82 }
83 }
84 param = Media::Format{};
85 param.PutLongValue(ParameterKey::DETAIL_ENHANCER_NODE_ID, config.id);
86 if (vpeVideo->SetParameter(param) != 0) {
87 RS_LOGE("SetParameter nodeId falied");
88 return false;
89 }
90 return true;
91 }
92
GetVpeVideoSurface(uint32_t type,const sptr<Surface> & RSSurface,const RSSurfaceRenderNodeConfig & config)93 sptr<Surface> RSVpeManager::GetVpeVideoSurface(uint32_t type, const sptr<Surface>& RSSurface,
94 const RSSurfaceRenderNodeConfig& config)
95 {
96 std::shared_ptr<VpeVideo> vpeVideo = GetVpeVideo(type, config);
97 if (vpeVideo == nullptr) {
98 RS_LOGE("GetVpeVideo failed");
99 return RSSurface;
100 }
101
102 std::shared_ptr<VpeVideoCallback> cb = std::make_shared<VpeVideoCallbackImpl>(vpeVideo);
103 int32_t ret = vpeVideo->RegisterCallback(cb);
104 if (ret != 0) {
105 RS_LOGE("RegisterCallback failed");
106 return RSSurface;
107 }
108
109 if (!SetVpeVideoParameter(vpeVideo, type, config)) {
110 return RSSurface;
111 }
112
113 ret = vpeVideo->SetOutputSurface(RSSurface);
114 if (ret != 0) {
115 RS_LOGE("SetOutputSurface failed");
116 return RSSurface;
117 }
118
119 sptr<Surface> vpeSurface = vpeVideo->GetInputSurface();
120 if (vpeSurface == nullptr) {
121 RS_LOGE("GetInputSurface failed");
122 return RSSurface;
123 }
124
125 ret = vpeVideo->Start();
126 if (ret != 0) {
127 RS_LOGE("start failed");
128 return RSSurface;
129 }
130 uint32_t mapSize = 0;
131 {
132 std::lock_guard<std::mutex> lock(vpeVideoLock_);
133 allVpeVideo_[config.id] = vpeVideo;
134 mapSize = allVpeVideo_.size();
135 }
136 RS_LOGD("type:%{public}u vepSF:%{public}" PRIu64 " RSSF:%{public}" PRIu64
137 " nodeId:%{public}" PRIu64 " mapSize:%{public}u",
138 type, vpeSurface->GetUniqueId(), RSSurface->GetUniqueId(), config.id, mapSize);
139 return vpeSurface;
140 }
141
CheckAndGetSurface(const sptr<Surface> & surface,const RSSurfaceRenderNodeConfig & config)142 sptr<Surface> RSVpeManager::CheckAndGetSurface(const sptr<Surface>& surface, const RSSurfaceRenderNodeConfig& config)
143 {
144 RS_TRACE_NAME_FMT("RSVpeManager::Creat name %{public}s nodeId:%{public}" PRIu64, config.name.c_str(), config.id);
145
146 if (config.nodeType != OHOS::Rosen::RSSurfaceNodeType::SELF_DRAWING_NODE) {
147 return surface;
148 }
149 if (!VpeVideo::IsSupported()) {
150 return surface;
151 }
152
153 Media::Format parameter{};
154 sptr<Surface> vpeSurface = surface;
155 std::vector<uint32_t> supportTypes = { VIDEO_TYPE_DETAIL_ENHANCER, VIDEO_TYPE_AIHDR_ENHANCER };
156 for (auto& type : supportTypes) {
157 if (VpeVideo::IsSupported(type, parameter)) {
158 vpeSurface = GetVpeVideoSurface(type, vpeSurface, config);
159 }
160 }
161 return vpeSurface;
162 }
163 } // namespace Rosen
164 } // namespace OHOS