1 /*
2 * Copyright (c) 2023 Huawei Device Co., Ltd.
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file expected 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 "hdi_common_v1_1.h"
17 #include "camera.h"
18 #include "video_key_info.h"
19
20 namespace OHOS::Camera {
21 int64_t OHOS::Camera::HdiCommonV1_1::StreamConsumer::g_timestamp[2] = {0};
22
Init()23 void HdiCommonV1_1::Init()
24 {
25 uint32_t mainVer;
26 uint32_t minVer;
27 int32_t ret;
28 if (serviceV1_1 == nullptr) {
29 serviceV1_1 = OHOS::HDI::Camera::V1_1::ICameraHost::Get("camera_service", false);
30 if (serviceV1_1 == nullptr) {
31 printf("Init ICameraHost get failed serviceV1_1 nullptr\n");
32 CAMERA_LOGE("Init ICameraHost get failed serviceV1_1 nullptr");
33 return;
34 }
35 CAMERA_LOGI("V1_1::ICameraHost get success");
36 ret = serviceV1_1->GetVersion(mainVer, minVer);
37 if (ret != 0) {
38 printf("Init GetVersion failed, ret = %d\n", ret);
39 CAMERA_LOGE("Init GetVersion failed, ret = %{public}d", ret);
40 return;
41 }
42 CAMERA_LOGI("V1_1::ICameraHost get version success, %{public}d, %{public}d", mainVer, minVer);
43 service = static_cast<OHOS::HDI::Camera::V1_0::ICameraHost *>(serviceV1_1.GetRefPtr());
44 }
45
46 hostCallback = new TestCameraHostCallback();
47 ret = service->SetCallback(hostCallback);
48 if (ret != 0) {
49 printf("Init SetCallback failed, ret = %d\n", ret);
50 CAMERA_LOGE("Init SetCallback failed, ret = %{public}d", ret);
51 }
52 }
53
Open(int cameraId)54 void HdiCommonV1_1::Open(int cameraId)
55 {
56 if (cameraDevice == nullptr) {
57 if (serviceV1_1 == nullptr) {
58 printf("Open ICameraHost failed\n");
59 CAMERA_LOGE("Open ICameraHost failed");
60 return;
61 }
62 service->GetCameraIds(cameraIds);
63 if (cameraIds.size() == 0) {
64 printf("Open GetCameraIds failed\n");
65 CAMERA_LOGE("Open GetCameraIds failed");
66 return;
67 }
68 GetCameraMetadata(cameraId);
69 deviceCallback = new OHOS::Camera::HdiCommon::DemoCameraDeviceCallback();
70 if (DEVICE_1 == cameraId) {
71 rc = serviceV1_1->OpenCamera_V1_1(cameraIds[1], deviceCallback, cameraDeviceV1_1); // front camera
72 } else {
73 rc = serviceV1_1->OpenCamera_V1_1(cameraIds[0], deviceCallback, cameraDeviceV1_1); // rear camera
74 }
75 if (rc != HDI::Camera::V1_0::NO_ERROR || cameraDeviceV1_1 == nullptr) {
76 printf("Open OpenCamera_V1_1 failed, rc = %d\n", rc);
77 CAMERA_LOGE("Open OpenCamera_V1_1 failed, rc = %{public}d", rc);
78 return;
79 }
80 cameraDevice = static_cast<OHOS::HDI::Camera::V1_0::ICameraDevice *>(cameraDeviceV1_1.GetRefPtr());
81 CAMERA_LOGI("OpenCamera V1_1 success");
82 }
83 }
84
GetCameraMetadata(int cameraId)85 void HdiCommonV1_1::GetCameraMetadata(int cameraId)
86 {
87 if (DEVICE_1 == cameraId) {
88 rc = service->GetCameraAbility(cameraIds[1], abilityVec); // front camera
89 } else {
90 rc = service->GetCameraAbility(cameraIds[0], abilityVec); // rear camera
91 }
92 if (rc != HDI::Camera::V1_0::NO_ERROR) {
93 printf("GetCameraAbility failed, rc = %d\n", rc);
94 CAMERA_LOGE("GetCameraAbility failed, rc = %{public}d", rc);
95 return;
96 }
97 MetadataUtils::ConvertVecToMetadata(abilityVec, ability);
98 }
99
DefaultPreview(std::shared_ptr<StreamInfo_V1_1> &infos)100 void HdiCommonV1_1::DefaultPreview(std::shared_ptr<StreamInfo_V1_1> &infos)
101 {
102 infos->v1_0.streamId_ = streamIdPreview;
103 infos->v1_0.width_ = previewWidth;
104 infos->v1_0.height_ = previewHeight;
105 infos->v1_0.format_ = previewFormat;
106 infos->v1_0.dataspace_ = UT_DATA_SIZE;
107 infos->v1_0.intent_ = StreamIntent::PREVIEW;
108 infos->v1_0.tunneledMode_ = UT_TUNNEL_MODE;
109 }
110
DefaultCapture(std::shared_ptr<StreamInfo_V1_1> &infos)111 void HdiCommonV1_1::DefaultCapture(std::shared_ptr<StreamInfo_V1_1> &infos)
112 {
113 infos->v1_0.streamId_ = streamIdCapture;
114 infos->v1_0.width_ = captureWidth;
115 infos->v1_0.height_ = captureHeight;
116 infos->v1_0.format_ = snapshotFormat;
117 infos->v1_0.dataspace_ = UT_DATA_SIZE;
118 infos->v1_0.intent_ = StreamIntent::STILL_CAPTURE;
119 infos->v1_0.tunneledMode_ = UT_TUNNEL_MODE;
120 }
121
DefaultInfosPreview(std::shared_ptr<StreamInfo_V1_1> &infos)122 void HdiCommonV1_1::DefaultInfosPreview(std::shared_ptr<StreamInfo_V1_1> &infos)
123 {
124 DefaultPreview(infos);
125 std::shared_ptr<StreamConsumer> consumer_pre = std::make_shared<StreamConsumer>();
126 infos->v1_0.bufferQueue_ = consumer_pre->CreateProducerSeq([this](void* addr, uint32_t size) {
127 DumpImageFile(streamIdPreview, "yuv", addr, size);
128 });
129 infos->v1_0.bufferQueue_->producer_->SetQueueSize(UT_DATA_SIZE);
130 consumerMap_[StreamIntent::PREVIEW] = consumer_pre;
131 }
132
DefaultInfosCapture(std::shared_ptr<StreamInfo_V1_1> &infos)133 void HdiCommonV1_1::DefaultInfosCapture(std::shared_ptr<StreamInfo_V1_1> &infos)
134 {
135 DefaultCapture(infos);
136 std::shared_ptr<StreamConsumer> consumer_capture = std::make_shared<StreamConsumer>();
137 infos->v1_0.bufferQueue_ = consumer_capture->CreateProducerSeq([this](void* addr, uint32_t size) {
138 DumpImageFile(streamIdCapture, "jpeg", addr, size);
139 });
140 infos->v1_0.bufferQueue_->producer_->SetQueueSize(UT_DATA_SIZE);
141 consumerMap_[StreamIntent::STILL_CAPTURE] = consumer_capture;
142 }
143
DefaultInfosVideo(std::shared_ptr<StreamInfo_V1_1> &infos)144 void HdiCommonV1_1::DefaultInfosVideo(std::shared_ptr<StreamInfo_V1_1> &infos)
145 {
146 infos->v1_0.streamId_ = streamIdVideo;
147 infos->v1_0.width_ = videoWidth;
148 infos->v1_0.height_ = videoHeight;
149 infos->v1_0.format_ = videoFormat;
150 infos->v1_0.dataspace_ = UT_DATA_SIZE;
151 infos->v1_0.intent_ = StreamIntent::VIDEO;
152 infos->v1_0.encodeType_ = ENCODE_TYPE_H265;
153 infos->v1_0.tunneledMode_ = UT_TUNNEL_MODE;
154 std::shared_ptr<StreamConsumer> consumer_video = std::make_shared<StreamConsumer>();
155 infos->v1_0.bufferQueue_ = consumer_video->CreateProducerSeq([this](void* addr, uint32_t size) {
156 DumpImageFile(streamIdVideo, "yuv", addr, size);
157 });
158 infos->v1_0.bufferQueue_->producer_->SetQueueSize(UT_DATA_SIZE);
159 consumerMap_[StreamIntent::VIDEO] = consumer_video;
160 }
161
DefaultInfosAnalyze(std::shared_ptr<StreamInfo_V1_1> &infos)162 void HdiCommonV1_1::DefaultInfosAnalyze(std::shared_ptr<StreamInfo_V1_1> &infos)
163 {
164 infos->v1_0.streamId_ = streamIdAnalyze;
165 infos->v1_0.width_ = analyzeWidth;
166 infos->v1_0.height_ = analyzeHeight;
167 infos->v1_0.format_ = analyzeFormat;
168 infos->v1_0.dataspace_ = UT_DATA_SIZE;
169 infos->v1_0.intent_ = StreamIntent::ANALYZE;
170 infos->v1_0.tunneledMode_ = UT_TUNNEL_MODE;
171
172 std::shared_ptr<StreamConsumer> consumer_analyze = std::make_shared<StreamConsumer>();
173 infos->v1_0.bufferQueue_ = consumer_analyze->CreateProducerSeq([this](void* addr, uint32_t size) {
174 common_metadata_header_t *data = static_cast<common_metadata_header_t *>(addr);
175 camera_metadata_item_t entry = {};
176
177 int ret = FindCameraMetadataItem(data, OHOS_STATISTICS_FACE_IDS, &entry);
178 if (ret == HDI::Camera::V1_0::NO_ERROR && entry.data.i32 != nullptr && entry.count > 0) {
179 for (size_t i = 0; i < entry.count; i++) {
180 int id = entry.data.i32[i];
181 CAMERA_LOGI("Face ids : %{public}d", id);
182 }
183 }
184
185 ret = FindCameraMetadataItem(data, OHOS_STATISTICS_FACE_RECTANGLES, &entry);
186 if (ret == HDI::Camera::V1_0::NO_ERROR && entry.data.i32 != nullptr && entry.count > 0) {
187 for (size_t i = 0; i < entry.count; i++) {
188 int id = entry.data.i32[i];
189 CAMERA_LOGI("Face rectangles : %{public}d", id);
190 }
191 }
192 });
193 infos->v1_0.bufferQueue_->producer_->SetQueueSize(UT_DATA_SIZE);
194 consumerMap_[StreamIntent::ANALYZE] = consumer_analyze;
195 }
196
StartStream(std::vector<StreamIntent> intents)197 void HdiCommonV1_1::StartStream(std::vector<StreamIntent> intents)
198 {
199 StartStream(intents, OHOS::HDI::Camera::V1_1::NORMAL);
200 }
201
StartStream(std::vector<StreamIntent> intents, OperationMode_V1_1 mode)202 void HdiCommonV1_1::StartStream(std::vector<StreamIntent> intents, OperationMode_V1_1 mode)
203 {
204 streamOperatorCallback = new TestStreamOperatorCallback();
205 uint32_t mainVersion = 1;
206 uint32_t minVersion = 0;
207 rc = cameraDeviceV1_1->GetStreamOperator_V1_1(streamOperatorCallback, streamOperator_V1_1);
208 if (rc == HDI::Camera::V1_0::NO_ERROR) {
209 rc = streamOperator_V1_1->GetVersion(mainVersion, minVersion);
210 streamOperator = static_cast<OHOS::HDI::Camera::V1_0::IStreamOperator *>(streamOperator_V1_1.GetRefPtr());
211 if (rc != HDI::Camera::V1_0::NO_ERROR) {
212 printf("StreamOperator V1_1 get version failed, rc = %d\n", rc);
213 CAMERA_LOGE("StreamOperator V1_1 get version failed, rc = %{public}d", rc);
214 }
215 CAMERA_LOGI("GetStreamOperator success");
216 } else {
217 printf("GetStreamOperator fail, rc = %d\n", rc);
218 CAMERA_LOGE("GetStreamOperator fail, rc = %{public}d", rc);
219 }
220 streamInfoPre = std::make_shared<StreamInfo_V1_1>();
221 streamInfoVideo = std::make_shared<StreamInfo_V1_1>();
222 streamInfoCapture = std::make_shared<StreamInfo_V1_1>();
223 streamInfoAnalyze = std::make_shared<StreamInfo_V1_1>();
224 for (auto& intent : intents) {
225 if (intent == StreamIntent::PREVIEW) {
226 DefaultInfosPreview(streamInfoPre);
227 streamInfos.push_back(*streamInfoPre);
228 } else if (intent == StreamIntent::VIDEO) {
229 DefaultInfosVideo(streamInfoVideo);
230 streamInfos.push_back(*streamInfoVideo);
231 } else if (intent == StreamIntent::ANALYZE) {
232 DefaultInfosAnalyze(streamInfoAnalyze);
233 streamInfos.push_back(*streamInfoAnalyze);
234 } else {
235 DefaultInfosCapture(streamInfoCapture);
236 streamInfos.push_back(*streamInfoCapture);
237 }
238 }
239 rc = streamOperator_V1_1->CreateStreams_V1_1(streamInfos);
240 if (rc != HDI::Camera::V1_0::NO_ERROR) {
241 printf("check StartStream: CreateStreams_V1_1 fail, rc = %d\n", rc);
242 CAMERA_LOGE("check StartStream: CreateStreams_V1_1 fail, rc = %{public}d", rc);
243 }
244 rc = streamOperator_V1_1->CommitStreams_V1_1(mode, abilityVec);
245 if (rc != HDI::Camera::V1_0::NO_ERROR) {
246 printf("check StartStream: CommitStreams_V1_1 fail, rc = %d\n", rc);
247 CAMERA_LOGE("check StartStream: CommitStreams_V1_1 fail, rc = %{public}d", rc);
248 }
249 sleep(1);
250 std::vector<StreamInfo_V1_1>().swap(streamInfos);
251 }
252
StartCapture(int streamId, int captureId, bool shutterCallback, bool isStreaming)253 void HdiCommonV1_1::StartCapture(int streamId, int captureId, bool shutterCallback, bool isStreaming)
254 {
255 captureInfo = std::make_shared<CaptureInfo>();
256 captureInfo->streamIds_ = {streamId};
257 captureInfo->captureSetting_ = abilityVec;
258 captureInfo->enableShutterCallback_ = shutterCallback;
259 if (streamOperator_V1_1 != nullptr) {
260 rc = (CamRetCode)streamOperator_V1_1->Capture(captureId, *captureInfo, isStreaming);
261 } else {
262 rc = (CamRetCode)streamOperator->Capture(captureId, *captureInfo, isStreaming);
263 }
264
265 if (rc != HDI::Camera::V1_0::NO_ERROR) {
266 printf("check Capture: Capture fail, rc = %d\n", rc);
267 CAMERA_LOGE("check Capture: Capture fail, rc = %{public}d", rc);
268 }
269 sleep(UT_SLEEP_TIME);
270 }
271
StopStream(std::vector<int>& captureIds, std::vector<int>& streamIds)272 void HdiCommonV1_1::StopStream(std::vector<int>& captureIds, std::vector<int>& streamIds)
273 {
274 if (captureIds.size() > 0) {
275 for (auto &captureId : captureIds) {
276 if (streamOperator_V1_1 != nullptr) {
277 rc = streamOperator_V1_1->CancelCapture(captureId);
278 } else {
279 rc = streamOperator->CancelCapture(captureId);
280 }
281 if (rc != HDI::Camera::V1_0::NO_ERROR) {
282 printf("CancelCapture fail, rc = %d, captureId = %d\n", rc, captureId);
283 CAMERA_LOGE("CancelCapture fail, rc = %{public}d, captureId = %{public}d", rc, captureId);
284 }
285 }
286 }
287 if (streamIds.size() > 0) {
288 if (streamOperator_V1_1 != nullptr) {
289 rc = streamOperator_V1_1->ReleaseStreams(streamIds);
290 } else {
291 rc = streamOperator->ReleaseStreams(streamIds);
292 }
293 if (rc != HDI::Camera::V1_0::NO_ERROR) {
294 printf("check Capture: ReleaseStreams fail, rc = %d\n", rc);
295 CAMERA_LOGE("check Capture: ReleaseStreams fail, rc = %{public}d", rc);
296 }
297 }
298 }
299
GetTimeStamp( int64_t *g_timestamp, uint32_t lenght, int64_t timestamp, int32_t gotSize)300 void HdiCommonV1_1::StreamConsumer::GetTimeStamp(
301 int64_t *g_timestamp, uint32_t lenght, int64_t timestamp, int32_t gotSize)
302 {
303 if (gotSize != UT_PREVIEW_SIZE) {
304 if (g_timestamp[0] == 0) {
305 g_timestamp[0] = timestamp;
306 } else {
307 g_timestamp[1] = timestamp;
308 }
309 }
310 }
311
CreateProducer( std::function<void(void*, uint32_t)> callback)312 OHOS::sptr<OHOS::IBufferProducer> HdiCommonV1_1::StreamConsumer::CreateProducer(
313 std::function<void(void*, uint32_t)> callback)
314 {
315 consumer_ = OHOS::IConsumerSurface::Create();
316 if (consumer_ == nullptr) {
317 return nullptr;
318 }
319 sptr<IBufferConsumerListener> listener = new TestBufferConsumerListener();
320 consumer_->RegisterConsumerListener(listener);
321 auto producer = consumer_->GetProducer();
322 if (producer == nullptr) {
323 return nullptr;
324 }
325
326 callback_ = callback;
327 consumerThread_ = new std::thread([this, listener] {
328 int32_t flushFence = 0;
329 int64_t timestamp = 0;
330 OHOS::Rect damage;
331 TestBufferConsumerListener* checker = static_cast<TestBufferConsumerListener*>(listener.GetRefPtr());
332 while (running_ == true) {
333 OHOS::sptr<OHOS::SurfaceBuffer> buffer = nullptr;
334 if (checker->checkBufferAvailable()) {
335 consumer_->AcquireBuffer(buffer, flushFence, timestamp, damage);
336 if (buffer != nullptr) {
337 void* addr = buffer->GetVirAddr();
338 uint32_t size = buffer->GetSize();
339
340 int32_t gotSize = 0;
341 int32_t isKey = 0;
342 int32_t streamId = 0;
343 int32_t captureId = 0;
344 buffer->GetExtraData()->ExtraGet(OHOS::Camera::dataSize, gotSize);
345 buffer->GetExtraData()->ExtraGet(OHOS::Camera::isKeyFrame, isKey);
346 buffer->GetExtraData()->ExtraGet(OHOS::Camera::timeStamp, timestamp);
347 buffer->GetExtraData()->ExtraGet(OHOS::Camera::streamId, streamId);
348 buffer->GetExtraData()->ExtraGet(OHOS::Camera::captureId, captureId);
349 GetTimeStamp(g_timestamp, sizeof(g_timestamp) / sizeof(g_timestamp[0]), timestamp, gotSize);
350 if (gotSize) {
351 CalculateFps(timestamp, streamId);
352 callback_(addr, gotSize);
353 } else {
354 callback_(addr, size);
355 }
356
357 consumer_->ReleaseBuffer(buffer, -1);
358 shotCount_--;
359 if (shotCount_ == 0) {
360 std::unique_lock<std::mutex> l(l_);
361 cv_.notify_one();
362 }
363 }
364 }
365 if (running_ == false) {
366 break;
367 }
368 usleep(1);
369 }
370 });
371
372 return producer;
373 }
374
CreateProducerSeq( std::function<void(void*, uint32_t)> callback)375 OHOS::sptr<BufferProducerSequenceable> HdiCommonV1_1::StreamConsumer::CreateProducerSeq(
376 std::function<void(void*, uint32_t)> callback)
377 {
378 OHOS::sptr<OHOS::IBufferProducer> producer = CreateProducer(callback);
379 if (producer == nullptr) {
380 return nullptr;
381 }
382
383 return new BufferProducerSequenceable(producer);
384 }
385 }
386