1 /*
2  * Copyright (c) 2023-2023 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 "video_output_impl.h"
17 #include "camera_log.h"
18 #include "camera_util.h"
19 
20 using namespace std;
21 using namespace OHOS;
22 using namespace OHOS::CameraStandard;
23 const std::unordered_map<CameraFormat, Camera_Format> g_fwToNdkCameraFormat = {
24     {CameraFormat::CAMERA_FORMAT_RGBA_8888, Camera_Format::CAMERA_FORMAT_RGBA_8888},
25     {CameraFormat::CAMERA_FORMAT_YUV_420_SP, Camera_Format::CAMERA_FORMAT_YUV_420_SP},
26     {CameraFormat::CAMERA_FORMAT_JPEG, Camera_Format::CAMERA_FORMAT_JPEG},
27     {CameraFormat::CAMERA_FORMAT_YCBCR_P010, Camera_Format::CAMERA_FORMAT_YCBCR_P010},
28     {CameraFormat::CAMERA_FORMAT_YCRCB_P010, Camera_Format::CAMERA_FORMAT_YCRCB_P010}
29 };
30 
31 class InnerVideoOutputCallback : public VideoStateCallback {
32 public:
InnerVideoOutputCallback(Camera_VideoOutput * videoOutput,VideoOutput_Callbacks * callback)33     InnerVideoOutputCallback(Camera_VideoOutput* videoOutput, VideoOutput_Callbacks* callback)
34         : videoOutput_(videoOutput), callback_(*callback) {}
35     ~InnerVideoOutputCallback() = default;
36 
OnFrameStarted() const37     void OnFrameStarted() const override
38     {
39         MEDIA_DEBUG_LOG("OnFrameStarted is called!");
40         if (videoOutput_ != nullptr && callback_.onFrameStart != nullptr) {
41             callback_.onFrameStart(videoOutput_);
42         }
43     }
44 
OnFrameEnded(const int32_t frameCount) const45     void OnFrameEnded(const int32_t frameCount) const override
46     {
47         MEDIA_DEBUG_LOG("OnFrameEnded is called! frame count: %{public}d", frameCount);
48         if (videoOutput_ != nullptr && callback_.onFrameEnd != nullptr) {
49             callback_.onFrameEnd(videoOutput_, frameCount);
50         }
51     }
52 
OnError(const int32_t errorCode) const53     void OnError(const int32_t errorCode) const override
54     {
55         MEDIA_DEBUG_LOG("OnError is called!, errorCode: %{public}d", errorCode);
56         if (videoOutput_ != nullptr && callback_.onError != nullptr) {
57             callback_.onError(videoOutput_, FrameworkToNdkCameraError(errorCode));
58         }
59     }
60 
OnDeferredVideoEnhancementInfo(const CaptureEndedInfoExt info) const61     void OnDeferredVideoEnhancementInfo(const CaptureEndedInfoExt info) const override
62     {
63         // empty impl
64         MEDIA_DEBUG_LOG("OnDeferredVideoEnhancementInfo is called!");
65     }
66 
67 private:
68     Camera_VideoOutput* videoOutput_;
69     VideoOutput_Callbacks callback_;
70 };
71 
Camera_VideoOutput(sptr<VideoOutput> & innerVideoOutput)72 Camera_VideoOutput::Camera_VideoOutput(sptr<VideoOutput> &innerVideoOutput) : innerVideoOutput_(innerVideoOutput)
73 {
74     MEDIA_DEBUG_LOG("Camera_VideoOutput Constructor is called");
75 }
76 
~Camera_VideoOutput()77 Camera_VideoOutput::~Camera_VideoOutput()
78 {
79     MEDIA_DEBUG_LOG("~Camera_VideoOutput is called");
80     if (innerVideoOutput_) {
81         innerVideoOutput_ = nullptr;
82     }
83 }
84 
RegisterCallback(VideoOutput_Callbacks * callback)85 Camera_ErrorCode Camera_VideoOutput::RegisterCallback(VideoOutput_Callbacks* callback)
86 {
87     shared_ptr<InnerVideoOutputCallback> innerCallback =
88                 make_shared<InnerVideoOutputCallback>(this, callback);
89     innerVideoOutput_->SetCallback(innerCallback);
90     return CAMERA_OK;
91 }
92 
UnregisterCallback(VideoOutput_Callbacks * callback)93 Camera_ErrorCode Camera_VideoOutput::UnregisterCallback(VideoOutput_Callbacks* callback)
94 {
95     innerVideoOutput_->SetCallback(nullptr);
96     return CAMERA_OK;
97 }
98 
Start()99 Camera_ErrorCode Camera_VideoOutput::Start()
100 {
101     int32_t ret = innerVideoOutput_->Start();
102     return FrameworkToNdkCameraError(ret);
103 }
104 
Stop()105 Camera_ErrorCode Camera_VideoOutput::Stop()
106 {
107     int32_t ret = innerVideoOutput_->Stop();
108     return FrameworkToNdkCameraError(ret);
109 }
110 
Release()111 Camera_ErrorCode Camera_VideoOutput::Release()
112 {
113     int32_t ret = innerVideoOutput_->Release();
114     return FrameworkToNdkCameraError(ret);
115 }
116 
GetInnerVideoOutput()117 sptr<VideoOutput> Camera_VideoOutput::GetInnerVideoOutput()
118 {
119     return innerVideoOutput_;
120 }
121 
GetVideoProfile(Camera_VideoProfile ** profile)122 Camera_ErrorCode Camera_VideoOutput::GetVideoProfile(Camera_VideoProfile** profile)
123 {
124     auto videoOutputProfile = innerVideoOutput_->GetVideoProfile();
125     CHECK_AND_RETURN_RET_LOG(videoOutputProfile != nullptr, CAMERA_SERVICE_FATAL_ERROR,
126         "Camera_VideoOutput::GetVideoProfile failed to get video profile!");
127 
128     CameraFormat cameraFormat = videoOutputProfile->GetCameraFormat();
129     auto itr = g_fwToNdkCameraFormat.find(cameraFormat);
130     CHECK_AND_RETURN_RET_LOG(itr != g_fwToNdkCameraFormat.end(), CAMERA_SERVICE_FATAL_ERROR,
131         "Camera_VideoOutput::GetVideoProfile unsupported camera format %{public}d", cameraFormat);
132 
133     auto frames = videoOutputProfile->GetFrameRates();
134     CHECK_AND_RETURN_RET_LOG(frames.size() > 1, CAMERA_SERVICE_FATAL_ERROR,
135         "Camera_VideoOutput::GetVideoProfile the current video profile is not configured correctly!");
136 
137     Camera_VideoProfile* newProfile = new Camera_VideoProfile;
138     CHECK_AND_RETURN_RET_LOG(newProfile != nullptr, CAMERA_SERVICE_FATAL_ERROR,
139         "Camera_VideoOutput::GetVideoProfile failed to allocate memory for video profile!");
140 
141     newProfile->format = itr->second;
142     newProfile->range.min = static_cast<uint32_t>(frames[0]);
143     newProfile->range.max = static_cast<uint32_t>(frames[1]);
144     newProfile->size.width = videoOutputProfile->GetSize().width;
145     newProfile->size.height = videoOutputProfile->GetSize().height;
146 
147     *profile = newProfile;
148     return CAMERA_OK;
149 }
150 
GetSupportedFrameRates(Camera_FrameRateRange ** frameRateRange,uint32_t * size)151 Camera_ErrorCode Camera_VideoOutput::GetSupportedFrameRates(Camera_FrameRateRange** frameRateRange, uint32_t* size)
152 {
153     std::vector<std::vector<int32_t>> frameRate = innerVideoOutput_->GetSupportedFrameRates();
154     if (frameRate.size() == 0) {
155         *size = 0;
156         return CAMERA_OK;
157     }
158 
159     Camera_FrameRateRange* newframeRateRange =  new Camera_FrameRateRange[frameRate.size()];
160     CHECK_AND_RETURN_RET_LOG(newframeRateRange != nullptr, CAMERA_SERVICE_FATAL_ERROR,
161         "Failed to allocate memory for Camera_FrameRateRange!");
162 
163     for (size_t index = 0; index < frameRate.size(); ++index) {
164         if (frameRate[index].size() <= 1) {
165             MEDIA_ERR_LOG("invalid frameRate size!");
166             delete[] newframeRateRange;
167             newframeRateRange = nullptr;
168             return CAMERA_SERVICE_FATAL_ERROR;
169         }
170         newframeRateRange[index].min = static_cast<uint32_t>(frameRate[index][0]);
171         newframeRateRange[index].max = static_cast<uint32_t>(frameRate[index][1]);
172     }
173 
174     *frameRateRange = newframeRateRange;
175     *size = frameRate.size();
176     return CAMERA_OK;
177 }
178 
DeleteFrameRates(Camera_FrameRateRange * frameRateRange)179 Camera_ErrorCode Camera_VideoOutput::DeleteFrameRates(Camera_FrameRateRange* frameRateRange)
180 {
181     if (frameRateRange != nullptr) {
182         delete[] frameRateRange;
183         frameRateRange = nullptr;
184     }
185 
186     return CAMERA_OK;
187 }
188 
SetFrameRate(int32_t minFps,int32_t maxFps)189 Camera_ErrorCode Camera_VideoOutput::SetFrameRate(int32_t minFps, int32_t maxFps)
190 {
191     int32_t ret = innerVideoOutput_->SetFrameRate(minFps, maxFps);
192     return FrameworkToNdkCameraError(ret);
193 }
194 
GetActiveFrameRate(Camera_FrameRateRange * frameRateRange)195 Camera_ErrorCode Camera_VideoOutput::GetActiveFrameRate(Camera_FrameRateRange* frameRateRange)
196 {
197     std::vector<int32_t> activeFrameRate = innerVideoOutput_->GetFrameRateRange();
198     CHECK_AND_RETURN_RET_LOG(activeFrameRate.size() > 1, CAMERA_SERVICE_FATAL_ERROR,
199         "invalid activeFrameRate size!");
200 
201     frameRateRange->min = static_cast<uint32_t>(activeFrameRate[0]);
202     frameRateRange->max = static_cast<uint32_t>(activeFrameRate[1]);
203 
204     return CAMERA_OK;
205 }
GetVideoRotation(int32_t imageRotation,Camera_ImageRotation * cameraImageRotation)206 Camera_ErrorCode Camera_VideoOutput::GetVideoRotation(int32_t imageRotation, Camera_ImageRotation* cameraImageRotation)
207 {
208     CHECK_AND_RETURN_RET_LOG(cameraImageRotation != nullptr, CAMERA_SERVICE_FATAL_ERROR,
209         "GetCameraImageRotation failed");
210     CHECK_AND_RETURN_RET_LOG(innerVideoOutput_ != nullptr, CAMERA_SERVICE_FATAL_ERROR,
211         "innerVideoOutput_ is nullptr");
212     int32_t cameraOutputRotation = innerVideoOutput_->GetVideoRotation(imageRotation);
213     CHECK_AND_RETURN_RET_LOG(cameraOutputRotation != CAMERA_SERVICE_FATAL_ERROR, CAMERA_SERVICE_FATAL_ERROR,
214         "Camera_VideoOutput::GetVideoRotation camera service fatal error! ret: %{public}d", cameraOutputRotation);
215     *cameraImageRotation = static_cast<Camera_ImageRotation>(cameraOutputRotation);
216     return CAMERA_OK;
217 }