1 /*
2 * Copyright (c) 2021-2022 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 "hstream_repeat.h"
17
18 #include "camera_util.h"
19 #include "metadata_utils.h"
20 #include "display.h"
21 #include "display_manager.h"
22 #include "camera_log.h"
23
24 namespace OHOS {
25 namespace CameraStandard {
26 static const int32_t STREAM_ROTATE_90 = 90;
27 static const int32_t STREAM_ROTATE_180 = 180;
28 static const int32_t STREAM_ROTATE_270 = 270;
29 static const int32_t STREAM_ROTATE_360 = 360;
30
HStreamRepeat(sptr<OHOS::IBufferProducer> producer,int32_t format,int32_t width,int32_t height,bool isVideo)31 HStreamRepeat::HStreamRepeat(
32 sptr<OHOS::IBufferProducer> producer, int32_t format, int32_t width, int32_t height, bool isVideo)
33 : HStreamCommon(StreamType::REPEAT, producer, format, width, height)
34 {
35 isVideo_ = isVideo;
36 }
37
~HStreamRepeat()38 HStreamRepeat::~HStreamRepeat()
39 {}
40
LinkInput(sptr<OHOS::HDI::Camera::V1_1::IStreamOperator> streamOperator,std::shared_ptr<OHOS::Camera::CameraMetadata> cameraAbility,int32_t streamId)41 int32_t HStreamRepeat::LinkInput(sptr<OHOS::HDI::Camera::V1_1::IStreamOperator> streamOperator,
42 std::shared_ptr<OHOS::Camera::CameraMetadata> cameraAbility, int32_t streamId)
43 {
44 int32_t ret = HStreamCommon::LinkInput(streamOperator, cameraAbility, streamId);
45 if (ret != CAMERA_OK) {
46 return ret;
47 }
48 if (!isVideo_) {
49 SetStreamTransform();
50 }
51 return CAMERA_OK;
52 }
53
SetStreamInfo(StreamInfo_V1_1 & streamInfo)54 void HStreamRepeat::SetStreamInfo(StreamInfo_V1_1 &streamInfo)
55 {
56 HStreamCommon::SetStreamInfo(streamInfo);
57 if (isVideo_) {
58 streamInfo.v1_0.intent_ = VIDEO;
59 streamInfo.v1_0.encodeType_ = ENCODE_TYPE_H264;
60 } else {
61 streamInfo.v1_0.intent_ = PREVIEW;
62 streamInfo.v1_0.encodeType_ = ENCODE_TYPE_NULL;
63 }
64 }
65
Start()66 int32_t HStreamRepeat::Start()
67 {
68 CAMERA_SYNC_TRACE;
69 {
70 std::lock_guard<std::mutex> lock(streamOperatorLock_);
71 if (streamOperator_ == nullptr) {
72 return CAMERA_INVALID_STATE;
73 }
74 }
75 if (curCaptureID_ != 0) {
76 MEDIA_ERR_LOG("HStreamRepeat::Start, Already started with captureID: %{public}d", curCaptureID_);
77 return CAMERA_INVALID_STATE;
78 }
79 int32_t ret = AllocateCaptureId(curCaptureID_);
80 if (ret != CAMERA_OK) {
81 MEDIA_ERR_LOG("HStreamRepeat::Start Failed to allocate a captureId");
82 return ret;
83 }
84 std::vector<uint8_t> ability;
85 {
86 std::lock_guard<std::mutex> lock(cameraAbilityLock_);
87 OHOS::Camera::MetadataUtils::ConvertMetadataToVec(cameraAbility_, ability);
88 }
89 CaptureInfo captureInfo;
90 captureInfo.streamIds_ = {streamId_};
91 captureInfo.captureSetting_ = ability;
92 captureInfo.enableShutterCallback_ = false;
93 MEDIA_INFO_LOG("HStreamRepeat::Start Starting with capture ID: %{public}d", curCaptureID_);
94 CamRetCode rc;
95 {
96 std::lock_guard<std::mutex> lock(streamOperatorLock_);
97 rc = (CamRetCode)(streamOperator_->Capture(curCaptureID_, captureInfo, true));
98 }
99 if (rc != HDI::Camera::V1_0::NO_ERROR) {
100 ReleaseCaptureId(curCaptureID_);
101 curCaptureID_ = 0;
102 MEDIA_ERR_LOG("HStreamRepeat::Start Failed with error Code:%{public}d", rc);
103 ret = HdiToServiceError(rc);
104 }
105 return ret;
106 }
107
Stop()108 int32_t HStreamRepeat::Stop()
109 {
110 CAMERA_SYNC_TRACE;
111
112 {
113 std::lock_guard<std::mutex> lock(streamOperatorLock_);
114 if (streamOperator_ == nullptr) {
115 return CAMERA_INVALID_STATE;
116 }
117 }
118 if (curCaptureID_ == 0) {
119 MEDIA_ERR_LOG("HStreamRepeat::Stop, Stream not started yet");
120 return CAMERA_INVALID_STATE;
121 }
122 int32_t ret = CAMERA_OK;
123 CamRetCode rc;
124 {
125 std::lock_guard<std::mutex> lock(streamOperatorLock_);
126 rc = (CamRetCode)(streamOperator_->CancelCapture(curCaptureID_));
127 }
128 if (rc != HDI::Camera::V1_0::NO_ERROR) {
129 MEDIA_ERR_LOG("HStreamRepeat::Stop Failed with errorCode:%{public}d, curCaptureID_: %{public}d",
130 rc, curCaptureID_);
131 ret = HdiToServiceError(rc);
132 }
133 ReleaseCaptureId(curCaptureID_);
134 curCaptureID_ = 0;
135 return ret;
136 }
137
Release()138 int32_t HStreamRepeat::Release()
139 {
140 if (curCaptureID_) {
141 ReleaseCaptureId(curCaptureID_);
142 }
143 {
144 std::lock_guard<std::mutex> lock(callbackLock_);
145 streamRepeatCallback_ = nullptr;
146 }
147 return HStreamCommon::Release();
148 }
149
IsVideo()150 bool HStreamRepeat::IsVideo()
151 {
152 return isVideo_;
153 }
154
SetCallback(sptr<IStreamRepeatCallback> & callback)155 int32_t HStreamRepeat::SetCallback(sptr<IStreamRepeatCallback> &callback)
156 {
157 if (callback == nullptr) {
158 MEDIA_ERR_LOG("HStreamRepeat::SetCallback callback is null");
159 return CAMERA_INVALID_ARG;
160 }
161 std::lock_guard<std::mutex> lock(callbackLock_);
162 streamRepeatCallback_ = callback;
163 return CAMERA_OK;
164 }
165
OnFrameStarted()166 int32_t HStreamRepeat::OnFrameStarted()
167 {
168 CAMERA_SYNC_TRACE;
169 std::lock_guard<std::mutex> lock(callbackLock_);
170 if (streamRepeatCallback_ != nullptr) {
171 streamRepeatCallback_->OnFrameStarted();
172 }
173 return CAMERA_OK;
174 }
175
OnFrameEnded(int32_t frameCount)176 int32_t HStreamRepeat::OnFrameEnded(int32_t frameCount)
177 {
178 CAMERA_SYNC_TRACE;
179 std::lock_guard<std::mutex> lock(callbackLock_);
180 if (streamRepeatCallback_ != nullptr) {
181 streamRepeatCallback_->OnFrameEnded(frameCount);
182 }
183 return CAMERA_OK;
184 }
185
OnFrameError(int32_t errorType)186 int32_t HStreamRepeat::OnFrameError(int32_t errorType)
187 {
188 std::lock_guard<std::mutex> lock(callbackLock_);
189 if (streamRepeatCallback_ != nullptr) {
190 int32_t repeatErrorCode;
191 if (errorType == BUFFER_LOST) {
192 repeatErrorCode = CAMERA_STREAM_BUFFER_LOST;
193 } else {
194 repeatErrorCode = CAMERA_UNKNOWN_ERROR;
195 }
196 CAMERA_SYSEVENT_FAULT(CreateMsg("Preview OnFrameError! errorCode:%d", repeatErrorCode));
197 streamRepeatCallback_->OnFrameError(repeatErrorCode);
198 }
199 return CAMERA_OK;
200 }
201
AddDeferredSurface(const sptr<OHOS::IBufferProducer> & producer)202 int32_t HStreamRepeat::AddDeferredSurface(const sptr<OHOS::IBufferProducer> &producer)
203 {
204 MEDIA_INFO_LOG("HStreamRepeat::AddDeferredSurface called");
205 {
206 std::lock_guard<std::mutex> lock(producerLock_);
207 if (producer == nullptr) {
208 MEDIA_ERR_LOG("HStreamRepeat::AddDeferredSurface producer is null");
209 return CAMERA_INVALID_ARG;
210 }
211 producer_ = producer;
212 }
213 SetStreamTransform();
214 {
215 std::lock_guard<std::mutex> lock(streamOperatorLock_);
216 if (streamOperator_ == nullptr) {
217 MEDIA_ERR_LOG("HStreamRepeat::CreateAndHandleDeferredStreams(), streamOperator_ == null");
218 return CAMERA_INVALID_STATE;
219 }
220 }
221 MEDIA_INFO_LOG("HStreamRepeat::AttachBufferQueue start");
222 sptr<BufferProducerSequenceable> bufferProducerSequenceable;
223 CamRetCode rc;
224 {
225 std::lock_guard<std::mutex> lock(producerLock_);
226 bufferProducerSequenceable = new BufferProducerSequenceable(producer_);
227 }
228 {
229 std::lock_guard<std::mutex> lock(streamOperatorLock_);
230 rc = (CamRetCode)(streamOperator_->AttachBufferQueue(streamId_, bufferProducerSequenceable));
231 }
232 if (rc != HDI::Camera::V1_0::NO_ERROR) {
233 MEDIA_ERR_LOG("HStreamRepeat::AttachBufferQueue(), Failed to AttachBufferQueue %{public}d", rc);
234 }
235 MEDIA_INFO_LOG("HStreamRepeat::AddDeferredSurface end %{public}d", rc);
236 return CAMERA_OK;
237 }
238
DumpStreamInfo(std::string & dumpString)239 void HStreamRepeat::DumpStreamInfo(std::string& dumpString)
240 {
241 dumpString += "repeat stream:\n";
242 HStreamCommon::DumpStreamInfo(dumpString);
243 }
244
SetStreamTransform()245 void HStreamRepeat::SetStreamTransform()
246 {
247 camera_metadata_item_t item;
248 int ret;
249 int32_t sensorOrientation;
250 camera_position_enum_t cameraPosition = OHOS_CAMERA_POSITION_BACK;
251 {
252 std::lock_guard<std::mutex> lock(cameraAbilityLock_);
253 if (cameraAbility_ == nullptr) {
254 return;
255 }
256 ret = OHOS::Camera::FindCameraMetadataItem(cameraAbility_->get(), OHOS_SENSOR_ORIENTATION, &item);
257 if (ret != CAM_META_SUCCESS) {
258 MEDIA_ERR_LOG("HStreamRepeat::SetStreamTransform get sensor orientation failed");
259 return;
260 }
261 sensorOrientation = item.data.i32[0];
262 MEDIA_INFO_LOG("HStreamRepeat::SetStreamTransform sensor orientation %{public}d", sensorOrientation);
263
264 ret = OHOS::Camera::FindCameraMetadataItem(cameraAbility_->get(), OHOS_ABILITY_CAMERA_POSITION, &item);
265 if (ret != CAM_META_SUCCESS) {
266 MEDIA_ERR_LOG("HStreamRepeat::SetStreamTransform get camera position failed");
267 return;
268 }
269 cameraPosition = static_cast<camera_position_enum_t>(item.data.u8[0]);
270 MEDIA_INFO_LOG("HStreamRepeat::SetStreamTransform camera position %{public}d", cameraPosition);
271 }
272
273 std::lock_guard<std::mutex> lock(producerLock_);
274 if (producer_ == nullptr) {
275 MEDIA_ERR_LOG("HStreamRepeat::SetStreamTransform failed because producer is null");
276 return;
277 }
278 auto display = OHOS::Rosen::DisplayManager::GetInstance().GetDefaultDisplay();
279 if (display == nullptr) {
280 MEDIA_INFO_LOG("GetDefaultDisplay failed");
281 return;
282 }
283 if (display->GetWidth() < display->GetHeight()) {
284 ret = SurfaceError::SURFACE_ERROR_OK;
285 int32_t streamRotation = sensorOrientation;
286 if (cameraPosition == OHOS_CAMERA_POSITION_FRONT) {
287 switch (streamRotation) {
288 case STREAM_ROTATE_90: {
289 ret = producer_->SetTransform(GRAPHIC_FLIP_H_ROT90);
290 break;
291 }
292 case STREAM_ROTATE_180: {
293 ret = producer_->SetTransform(GRAPHIC_FLIP_H_ROT180);
294 break;
295 }
296 case STREAM_ROTATE_270: {
297 ret = producer_->SetTransform(GRAPHIC_FLIP_H_ROT270);
298 break;
299 }
300 default: {
301 break;
302 }
303 }
304 MEDIA_INFO_LOG("HStreamRepeat::SetStreamTransform filp rotate %{public}d", streamRotation);
305 } else {
306 streamRotation = STREAM_ROTATE_360 - sensorOrientation;
307 switch (streamRotation) {
308 case STREAM_ROTATE_90: {
309 ret = producer_->SetTransform(GRAPHIC_ROTATE_90);
310 break;
311 }
312 case STREAM_ROTATE_180: {
313 ret = producer_->SetTransform(GRAPHIC_ROTATE_180);
314 break;
315 }
316 case STREAM_ROTATE_270: {
317 ret = producer_->SetTransform(GRAPHIC_ROTATE_270);
318 break;
319 }
320 default: {
321 break;
322 }
323 }
324 MEDIA_INFO_LOG("HStreamRepeat::SetStreamTransform not flip rotate %{public}d", streamRotation);
325 }
326 if (ret != SurfaceError::SURFACE_ERROR_OK) {
327 MEDIA_ERR_LOG("HStreamRepeat::SetStreamTransform failed %{public}d", ret);
328 }
329 } else {
330 ret = SurfaceError::SURFACE_ERROR_OK;
331 if (cameraPosition == OHOS_CAMERA_POSITION_FRONT) {
332 ret = producer_->SetTransform(GRAPHIC_FLIP_H);
333 MEDIA_INFO_LOG("HStreamRepeat::SetStreamTransform filp for wide side devices");
334 } else {
335 ret = producer_->SetTransform(GRAPHIC_ROTATE_NONE);
336 MEDIA_INFO_LOG("HStreamRepeat::SetStreamTransform none rotate");
337 }
338 }
339 }
340 } // namespace Standard
341 } // namespace OHOS
342