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