xref: /test/xts/hats/hdf/camera/cameraMg/v1_0/src/common.cpp (revision 9762338d)
1/*
2 * Copyright (c) 2023-2024 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 "common.h"
17#include "camera.h"
18#include "video_key_info.h"
19
20namespace OHOS::Camera {
21Test::ResultCallback Test::resultCallback_ = 0;
22
23uint64_t Test::GetCurrentLocalTimeStamp()
24{
25    std::chrono::time_point<std::chrono::system_clock, std::chrono::milliseconds> tp =
26        std::chrono::time_point_cast<std::chrono::milliseconds>(std::chrono::system_clock::now());
27    auto tmp = std::chrono::duration_cast<std::chrono::milliseconds>(tp.time_since_epoch());
28    return static_cast<uint64_t>(tmp.count());
29}
30
31int32_t Test::DumpImageFile(int streamId, std::string suffix, const void* buffer, int32_t size)
32{
33    if (imageDataSaveSwitch == SWITCH_OFF) {
34        return 0;
35    }
36    if (streamId < 0) {
37        CAMERA_LOGE("ivalid stream id: %{public}d", streamId);
38        return -1;
39    }
40    char mkdirCmd[PATH_MAX] = {0};
41    char path[PATH_MAX] = {0};
42    int ret = sprintf_s(mkdirCmd, sizeof(mkdirCmd) / sizeof(mkdirCmd[0]),
43        "mkdir -p /data/stream-%d", streamId);
44    if (ret < 0) {
45        return -1;
46    }
47    system(mkdirCmd);
48    ret = sprintf_s(path, sizeof(path) / sizeof(path[0]), "data/stream-%d/%lld.%s",
49        streamId, GetCurrentLocalTimeStamp(), suffix.c_str());
50    if (ret < 0) {
51        return -1;
52    }
53
54    int imgFd = open(path, O_RDWR | O_CREAT, 00766);
55    if (imgFd == -1) {
56        CAMERA_LOGE("open file failed, errno: %{public}s", strerror(errno));
57        return -1;
58    }
59
60    ret = write(imgFd, buffer, size);
61    if (ret == -1) {
62        CAMERA_LOGE("write file failed, error: %{public}s", strerror(errno));
63        close(imgFd);
64        return -1;
65    }
66    close(imgFd);
67    return 0;
68}
69
70void Test::Init()
71{
72    if (service == nullptr) {
73        service = ICameraHost::Get("camera_service", false);
74        if (service == nullptr) {
75            CAMERA_LOGI("ICameraHost get failed");
76        } else {
77            CAMERA_LOGE("ICameraHost get success");
78        }
79        ASSERT_TRUE(service != nullptr);
80    }
81    hostCallback = new TestCameraHostCallback();
82    service->SetCallback(hostCallback);
83    service->GetCameraIds(cameraIds);
84    if (cameraIds.size() == 0) {
85        CAMERA_LOGE("camera device list empty");
86        GTEST_SKIP() << "No Camera Available" << std::endl;
87        return;
88    }
89}
90
91void Test::GetCameraMetadata()
92{
93    rc = service->GetCameraAbility(cameraIds.front(), abilityVec);
94    if (rc != HDI::Camera::V1_0::NO_ERROR) {
95        CAMERA_LOGE("GetCameraAbility failed, rc = %{public}d", rc);
96    }
97    MetadataUtils::ConvertVecToMetadata(abilityVec, ability);
98
99    common_metadata_header_t* data = ability->get();
100    camera_metadata_item_t entry;
101    int ret = FindCameraMetadataItem(data, OHOS_CONTROL_AE_AVAILABLE_MODES, &entry);
102    if (ret == 0) {
103        CAMERA_LOGI("get OHOS_CONTROL_AE_AVAILABLE_MODES success");
104    }
105    camera_metadata_item_t connectEntry;
106    ret = FindCameraMetadataItem(data, OHOS_ABILITY_CAMERA_CONNECTION_TYPE, &connectEntry);
107    if (ret == HDI::Camera::V1_0::NO_ERROR && connectEntry.data.u8 != nullptr && connectEntry.count > 0) {
108        uint8_t cameraConnectionType = *(connectEntry.data.u8);
109        if (static_cast<int>(cameraConnectionType) == OHOS_CAMERA_CONNECTION_TYPE_USB_PLUGIN) {
110            CAMERA_LOGI("get OHOS_ABILITY_CAMERA_CONNECTION_TYPE success, this camera is usb camera.");
111            previewWidth = usbCamera_previewWidth;
112            previewHeight = usbCamera_previewHeight;
113            videoWidth = usbCamera_videoWidth;
114            videoHeight = usbCamera_videoHeight;
115            captureWidth = usbCamera_captureWidth;
116            captureHeight = usbCamera_captureHeight;
117            analyzeWidth = usbCamera_analyzeWidth;
118            analyzeHeight = usbCamera_analyzeHeight;
119            previewFormat = usbCamera_previewFormat;
120            videoFormat = usbCamera_videoFormat;
121            snapshotFormat = usbCamera_snapshotFormat;
122            analyzeFormat = usbCamera_analyzeFormat;
123            videoEncodeType = usbCamera_videoEncodeType;
124        }
125    }
126}
127
128void Test::Open()
129{
130    if (cameraDevice == nullptr) {
131        if (cameraIds.size() == 0) {
132            CAMERA_LOGE("camera device list empty");
133            return;
134        }
135        GetCameraMetadata();
136        deviceCallback = new OHOS::Camera::Test::DemoCameraDeviceCallback();
137        rc = service->OpenCamera(cameraIds.front(), deviceCallback, cameraDevice);
138        if (rc != HDI::Camera::V1_0::NO_ERROR || cameraDevice == nullptr) {
139            CAMERA_LOGE("openCamera failed, rc = %{public}d", rc);
140            return;
141        }
142        CAMERA_LOGI("OpenCamera success");
143    }
144}
145
146void Test::Close()
147{
148    if (cameraDevice != nullptr) {
149        cameraDevice->Close();
150        cameraDevice = nullptr;
151    }
152}
153
154void Test::StartStream(std::vector<StreamIntent> intents)
155{
156    streamOperatorCallback = new TestStreamOperatorCallback();
157    rc = cameraDevice->GetStreamOperator(streamOperatorCallback, streamOperator);
158    if (rc == HDI::Camera::V1_0::NO_ERROR) {
159        CAMERA_LOGI("GetStreamOperator success");
160    } else {
161        CAMERA_LOGE("GetStreamOperator fail, rc = %{public}d", rc);
162    }
163    streamInfoPre = std::make_shared<StreamInfo>();
164    streamInfoVideo = std::make_shared<StreamInfo>();
165    streamInfoCapture = std::make_shared<StreamInfo>();
166    streamInfoAnalyze = std::make_shared<StreamInfo>();
167    for (auto& intent : intents) {
168        if (intent == StreamIntent::PREVIEW) {
169            streamInfoPre->streamId_ = streamIdPreview;
170            streamInfoPre->width_ = previewWidth;
171            streamInfoPre->height_ = previewHeight;
172            streamInfoPre->format_ = previewFormat;
173            streamInfoPre->dataspace_ = UT_DATA_SIZE;
174            streamInfoPre->intent_ = intent;
175            streamInfoPre->tunneledMode_ = UT_TUNNEL_MODE;
176            std::shared_ptr<StreamConsumer> consumer_pre = std::make_shared<StreamConsumer>();
177            streamInfoPre->bufferQueue_ = consumer_pre->CreateProducerSeq([this](void* addr, uint32_t size) {
178                DumpImageFile(streamIdPreview, "yuv", addr, size);
179            });
180            streamInfoPre->bufferQueue_->producer_->SetQueueSize(UT_DATA_SIZE);
181            consumerMap_[intent] = consumer_pre;
182            streamInfos.push_back(*streamInfoPre);
183        } else if (intent == StreamIntent::VIDEO) {
184            streamInfoVideo->streamId_ = streamIdVideo;
185            streamInfoVideo->width_ = videoWidth;
186            streamInfoVideo->height_ = videoHeight;
187            streamInfoVideo->format_ = videoFormat;
188            streamInfoVideo->dataspace_ = UT_DATA_SIZE;
189            streamInfoVideo->intent_ = intent;
190            streamInfoVideo->encodeType_ = ENCODE_TYPE_H265;
191            streamInfoVideo->tunneledMode_ = UT_TUNNEL_MODE;
192            std::shared_ptr<StreamConsumer> consumer_video = std::make_shared<StreamConsumer>();
193            streamInfoVideo->bufferQueue_ = consumer_video->CreateProducerSeq([this](void* addr, uint32_t size) {
194                DumpImageFile(streamIdPreview, "yuv", addr, size);
195            });
196            streamInfoVideo->bufferQueue_->producer_->SetQueueSize(UT_DATA_SIZE);
197            consumerMap_[intent] = consumer_video;
198            streamInfos.push_back(*streamInfoVideo);
199        } else if (intent == StreamIntent::ANALYZE) {
200            streamInfoAnalyze->streamId_ = streamIdAnalyze;
201            streamInfoAnalyze->width_ = analyzeWidth;
202            streamInfoAnalyze->height_ = analyzeHeight;
203            streamInfoAnalyze->format_ = analyzeFormat;
204            streamInfoAnalyze->dataspace_ = UT_DATA_SIZE;
205            streamInfoAnalyze->intent_ = intent;
206            streamInfoAnalyze->tunneledMode_ = UT_TUNNEL_MODE;
207
208            std::shared_ptr<StreamConsumer> consumer_analyze = std::make_shared<StreamConsumer>();
209            streamInfoAnalyze->bufferQueue_ = consumer_analyze->CreateProducerSeq([this](void* addr, uint32_t size) {
210                common_metadata_header_t *data = static_cast<common_metadata_header_t *>(addr);
211                camera_metadata_item_t entry = {};
212
213                int ret = FindCameraMetadataItem(data, OHOS_STATISTICS_FACE_IDS, &entry);
214                if (ret == 0) {
215                    for (size_t i = 0; i < entry.count; i++) {
216                        int id = entry.data.i32[i];
217                        CAMERA_LOGI("Face ids : %{public}d", id);
218                    }
219                }
220
221                ret = FindCameraMetadataItem(data, OHOS_STATISTICS_FACE_RECTANGLES, &entry);
222                if (ret == 0) {
223                    for (size_t i = 0; i < entry.count; i++) {
224                        int id = entry.data.i32[i];
225                        CAMERA_LOGI("Face rectangles : %{public}d", id);
226                    }
227                }
228            });
229            streamInfoAnalyze->bufferQueue_->producer_->SetQueueSize(UT_DATA_SIZE);
230            consumerMap_[intent] = consumer_analyze;
231            streamInfos.push_back(*streamInfoAnalyze);
232        } else {
233            streamInfoCapture->streamId_ = streamIdAnalyze;
234            streamInfoCapture->width_ = analyzeWidth;
235            streamInfoCapture->height_ = analyzeHeight;
236            streamInfoCapture->format_ = analyzeFormat;
237            streamInfoCapture->dataspace_ = UT_DATA_SIZE;
238            streamInfoCapture->intent_ = intent;
239            streamInfoCapture->tunneledMode_ = UT_TUNNEL_MODE;
240            std::shared_ptr<StreamConsumer> consumer_capture = std::make_shared<StreamConsumer>();
241            streamInfoCapture->bufferQueue_ = consumer_capture->CreateProducerSeq([this](void* addr, uint32_t size) {
242                DumpImageFile(streamIdPreview, "yuv", addr, size);
243            });
244            streamInfoCapture->bufferQueue_->producer_->SetQueueSize(UT_DATA_SIZE);
245            consumerMap_[intent] = consumer_capture;
246            streamInfos.push_back(*streamInfoCapture);
247        }
248    }
249
250    rc = streamOperator->CreateStreams(streamInfos);
251    EXPECT_EQ(false, rc != HDI::Camera::V1_0::NO_ERROR);
252    rc = streamOperator->CommitStreams(OperationMode::NORMAL, abilityVec);
253    EXPECT_EQ(false, rc != HDI::Camera::V1_0::NO_ERROR);
254    sleep(1);
255    std::vector<StreamInfo>().swap(streamInfos);
256}
257
258void Test::StartCapture(int streamId, int captureId, bool shutterCallback, bool isStreaming)
259{
260    captureInfo = std::make_shared<CaptureInfo>();
261    captureInfo->streamIds_ = {streamId};
262    captureInfo->captureSetting_ = abilityVec;
263    captureInfo->enableShutterCallback_ = shutterCallback;
264    rc = (CamRetCode)streamOperator->Capture(captureId, *captureInfo, isStreaming);
265    EXPECT_EQ(true, rc == HDI::Camera::V1_0::NO_ERROR);
266    if (rc == HDI::Camera::V1_0::NO_ERROR) {
267        CAMERA_LOGI("check Capture: Capture success, %{public}d", captureId);
268    } else {
269        std::cout << "rc = " << rc << std::endl;
270        CAMERA_LOGE("check Capture: Capture fail, rc = %{public}d", rc);
271    }
272    sleep(UT_SLEEP_TIME);
273}
274
275void Test::StopStream(std::vector<int>& captureIds, std::vector<int>& streamIds)
276{
277    if (sizeof(captureIds) > 0) {
278        for (auto &captureId : captureIds) {
279            rc = streamOperator->CancelCapture(captureId);
280            EXPECT_EQ(true, rc == HDI::Camera::V1_0::NO_ERROR);
281            if (rc == HDI::Camera::V1_0::NO_ERROR) {
282                CAMERA_LOGI("check Capture: CancelCapture success, %{public}d", captureId);
283            } else {
284                CAMERA_LOGE("check Capture: CancelCapture fail, rc = %{public}d, captureId = %{public}d",
285                    rc, captureId);
286            }
287        }
288    }
289    if (sizeof(streamIds) > 0) {
290        rc = streamOperator->ReleaseStreams(streamIds);
291        EXPECT_EQ(true, rc == HDI::Camera::V1_0::NO_ERROR);
292        if (rc == HDI::Camera::V1_0::NO_ERROR) {
293            CAMERA_LOGI("check Capture: ReleaseStream success");
294        } else {
295            CAMERA_LOGE("check Capture: ReleaseStreams fail, rc = %{public}d", rc);
296        }
297    }
298}
299
300void Test::StreamConsumer::CalculateFps(int64_t timestamp, int32_t streamId)
301{
302    if (isFirstCalculateFps_) {
303        if ((timestamp - intervalTimestamp_) >= interval_) {
304            int64_t timeInterval = timestamp - intervalTimestamp_;
305            if (timeInterval != 0) {
306                float fps = (int64_t)(100000000000 * timestampCount_ / timeInterval) / 100.0;
307                CAMERA_LOGI("Calculate FPS success, streamId: %{public}d, Fps:%{public}f", streamId, fps);
308                interval_ = ONESECOND_OF_MICROSECOND_UNIT;
309            } else {
310                CAMERA_LOGE("Calculate FPS error timeInerval is 0");
311            }
312        }
313    } else {
314        intervalTimestamp_ = timestamp;
315        isFirstCalculateFps_ = true;
316    }
317    if ((timestamp - intervalTimestamp_) >= ONESECOND_OF_MICROSECOND_UNIT * UT_SECOND_TIMES) {
318        intervalTimestamp_ = timestamp;
319        timestampCount_ = 0;
320        interval_ = ONESECOND_OF_MICROSECOND_UNIT;
321    }
322    timestampCount_++;
323}
324
325OHOS::sptr<OHOS::IBufferProducer> Test::StreamConsumer::CreateProducer(std::function<void(void*, uint32_t)> callback)
326{
327    consumer_ = OHOS::IConsumerSurface::Create();
328    if (consumer_ == nullptr) {
329        return nullptr;
330    }
331    sptr<IBufferConsumerListener> listener = new TestBufferConsumerListener();
332    consumer_->RegisterConsumerListener(listener);
333    auto producer = consumer_->GetProducer();
334    if (producer == nullptr) {
335        return nullptr;
336    }
337
338    callback_ = callback;
339    consumerThread_ = new std::thread([this, listener] {
340        int32_t flushFence = 0;
341        int64_t timestamp = 0;
342        OHOS::Rect damage;
343        TestBufferConsumerListener* checker = static_cast<TestBufferConsumerListener*>(listener.GetRefPtr());
344        while (running_ == true) {
345            OHOS::sptr<OHOS::SurfaceBuffer> buffer = nullptr;
346            if (checker->checkBufferAvailable()) {
347                consumer_->AcquireBuffer(buffer, flushFence, timestamp, damage);
348                if (buffer != nullptr) {
349                    void* addr = buffer->GetVirAddr();
350                    uint32_t size = buffer->GetSize();
351
352                    int32_t gotSize = 0;
353                    int32_t isKey = 0;
354                    int32_t streamId = 0;
355                    int32_t captureId = 0;
356                    buffer->GetExtraData()->ExtraGet(OHOS::Camera::dataSize, gotSize);
357                    buffer->GetExtraData()->ExtraGet(OHOS::Camera::isKeyFrame, isKey);
358                    buffer->GetExtraData()->ExtraGet(OHOS::Camera::timeStamp, timestamp);
359                    buffer->GetExtraData()->ExtraGet(OHOS::Camera::streamId, streamId);
360                    buffer->GetExtraData()->ExtraGet(OHOS::Camera::captureId, captureId);
361                    if (gotSize) {
362                        CalculateFps(timestamp, streamId);
363                        callback_(addr, gotSize);
364                    } else {
365                        callback_(addr, size);
366                    }
367
368                    consumer_->ReleaseBuffer(buffer, -1);
369                    shotCount_--;
370                    if (shotCount_ == 0) {
371                        std::unique_lock<std::mutex> l(l_);
372                        cv_.notify_one();
373                    }
374                }
375            }
376            if (running_ == false) {
377                break;
378            }
379            usleep(1);
380        }
381    });
382
383    return producer;
384}
385
386OHOS::sptr<BufferProducerSequenceable> Test::StreamConsumer::CreateProducerSeq(
387    std::function<void(void*, uint32_t)> callback)
388{
389    OHOS::sptr<OHOS::IBufferProducer> producer = CreateProducer(callback);
390    if (producer == nullptr) {
391        return nullptr;
392    }
393
394    return new BufferProducerSequenceable(producer);
395}
396
397int32_t Test::TestStreamOperatorCallback::OnCaptureStarted(int32_t captureId, const std::vector<int32_t> &streamId)
398{
399    for (auto it : streamId) {
400        CAMERA_LOGE("captureId: %{public}d, streamId: %{public}d", captureId, it);
401    }
402    return HDI::Camera::V1_0::NO_ERROR;
403}
404
405int32_t Test::TestStreamOperatorCallback::OnCaptureEnded(int32_t captureId, const std::vector<CaptureEndedInfo> &infos)
406{
407    for (auto it : infos) {
408        CAMERA_LOGE("captureId: %{public}d, streamId: %{public}d, count: %{public}d", captureId, it.streamId_,
409            it.frameCount_);
410    }
411    return HDI::Camera::V1_0::NO_ERROR;
412}
413
414int32_t Test::TestStreamOperatorCallback::OnCaptureError(int32_t captureId, const std::vector<CaptureErrorInfo> &infos)
415{
416    for (auto it : infos) {
417        CAMERA_LOGE("captureId: %{public}d, streamId: %{public}d, error: %{public}d", captureId, it.streamId_,
418            it.error_);
419    }
420    return HDI::Camera::V1_0::NO_ERROR;
421}
422
423int32_t Test::TestStreamOperatorCallback::OnFrameShutter(int32_t captureId,
424    const std::vector<int32_t> &streamIds, uint64_t timestamp)
425{
426    (void)timestamp;
427    for (auto it : streamIds) {
428        CAMERA_LOGE("captureId: %{public}d, streamId: %{public}d", captureId, it);
429    }
430    return HDI::Camera::V1_0::NO_ERROR;
431}
432
433int32_t Test::DemoCameraDeviceCallback::OnError(ErrorType type, int32_t errorMsg)
434{
435    CAMERA_LOGE("type: %{public}d, errorMsg: %{public}d", type, errorMsg);
436    return HDI::Camera::V1_0::NO_ERROR;
437}
438
439int32_t Test::DemoCameraDeviceCallback::OnResult(uint64_t timestamp, const std::vector<uint8_t> &result)
440{
441    if (Test::resultCallback_) {
442        std::shared_ptr<CameraMetadata> resultMeta;
443        MetadataUtils::ConvertVecToMetadata(result, resultMeta);
444        Test::resultCallback_(timestamp, resultMeta);
445    }
446    return HDI::Camera::V1_0::NO_ERROR;
447}
448
449int32_t Test::TestCameraHostCallback::OnCameraStatus(const std::string& cameraId, CameraStatus status)
450{
451    CAMERA_LOGE("cameraId: %{public}s, status: %{public}d", cameraId.c_str(), status);
452    return HDI::Camera::V1_0::NO_ERROR;
453}
454
455int32_t Test::TestCameraHostCallback::OnFlashlightStatus(const std::string& cameraId, FlashlightStatus status)
456{
457    CAMERA_LOGE("cameraId: %{public}s, status: %{public}d", cameraId.c_str(), status);
458    return HDI::Camera::V1_0::NO_ERROR;
459}
460
461int32_t Test::TestCameraHostCallback::OnCameraEvent(const std::string& cameraId, CameraEvent event)
462{
463    CAMERA_LOGE("cameraId: %{public}s, status: %{public}d", cameraId.c_str(), event);
464    return HDI::Camera::V1_0::NO_ERROR;
465}
466
467}