10a5c7a17Sopenharmony_ci/*
20a5c7a17Sopenharmony_ci * Copyright (c) 2020-2021 Huawei Device Co., Ltd.
30a5c7a17Sopenharmony_ci * Licensed under the Apache License, Version 2.0 (the "License");
40a5c7a17Sopenharmony_ci * you may not use this file except in compliance with the License.
50a5c7a17Sopenharmony_ci * You may obtain a copy of the License at
60a5c7a17Sopenharmony_ci *
70a5c7a17Sopenharmony_ci *     http://www.apache.org/licenses/LICENSE-2.0
80a5c7a17Sopenharmony_ci *
90a5c7a17Sopenharmony_ci * Unless required by applicable law or agreed to in writing, software
100a5c7a17Sopenharmony_ci * distributed under the License is distributed on an "AS IS" BASIS,
110a5c7a17Sopenharmony_ci * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
120a5c7a17Sopenharmony_ci * See the License for the specific language governing permissions and
130a5c7a17Sopenharmony_ci * limitations under the License.
140a5c7a17Sopenharmony_ci */
150a5c7a17Sopenharmony_ci
160a5c7a17Sopenharmony_ci#include "camera_impl.h"
170a5c7a17Sopenharmony_ci#include "media_log.h"
180a5c7a17Sopenharmony_ci#include "camera_device_client.h"
190a5c7a17Sopenharmony_ci#include <cstdio>
200a5c7a17Sopenharmony_ci
210a5c7a17Sopenharmony_ciusing namespace std;
220a5c7a17Sopenharmony_cinamespace OHOS {
230a5c7a17Sopenharmony_cinamespace Media {
240a5c7a17Sopenharmony_ciCameraImpl::CameraImpl(const std::string &id, const CameraAbility *ability, const CameraInfo *info):id_(id)
250a5c7a17Sopenharmony_ci{
260a5c7a17Sopenharmony_ci    ability_ = ability;
270a5c7a17Sopenharmony_ci    info_ = info;
280a5c7a17Sopenharmony_ci}
290a5c7a17Sopenharmony_ci
300a5c7a17Sopenharmony_cistring CameraImpl::GetCameraId()
310a5c7a17Sopenharmony_ci{
320a5c7a17Sopenharmony_ci    return id_;
330a5c7a17Sopenharmony_ci}
340a5c7a17Sopenharmony_ci
350a5c7a17Sopenharmony_ciconst CameraConfig *CameraImpl::GetCameraConfig() const
360a5c7a17Sopenharmony_ci{
370a5c7a17Sopenharmony_ci    return config_;
380a5c7a17Sopenharmony_ci}
390a5c7a17Sopenharmony_ci
400a5c7a17Sopenharmony_ciFrameConfig *CameraImpl::GetFrameConfig(int32_t type)
410a5c7a17Sopenharmony_ci{
420a5c7a17Sopenharmony_ci    for (auto i : frameConfigs_) {
430a5c7a17Sopenharmony_ci        if (i->GetFrameConfigType() == type) {
440a5c7a17Sopenharmony_ci            return i;
450a5c7a17Sopenharmony_ci        }
460a5c7a17Sopenharmony_ci    }
470a5c7a17Sopenharmony_ci    return nullptr;
480a5c7a17Sopenharmony_ci}
490a5c7a17Sopenharmony_ci
500a5c7a17Sopenharmony_civoid CameraImpl::Configure(CameraConfig &config)
510a5c7a17Sopenharmony_ci{
520a5c7a17Sopenharmony_ci    if (config_ != nullptr) {
530a5c7a17Sopenharmony_ci        return;
540a5c7a17Sopenharmony_ci    }
550a5c7a17Sopenharmony_ci
560a5c7a17Sopenharmony_ci    if (config.GetFrameStateCb() == nullptr || config.GetEventHandler() == nullptr) {
570a5c7a17Sopenharmony_ci        return;
580a5c7a17Sopenharmony_ci    }
590a5c7a17Sopenharmony_ci
600a5c7a17Sopenharmony_ci    if (deviceClient_ == nullptr) {
610a5c7a17Sopenharmony_ci        return;
620a5c7a17Sopenharmony_ci    }
630a5c7a17Sopenharmony_ci    int32_t ret = deviceClient_->SetCameraConfig(config);
640a5c7a17Sopenharmony_ci    if (ret != MEDIA_OK) {
650a5c7a17Sopenharmony_ci        MEDIA_ERR_LOG("Set camera config failed in cameraImpl.");
660a5c7a17Sopenharmony_ci        return;
670a5c7a17Sopenharmony_ci    }
680a5c7a17Sopenharmony_ci    config_ = &config;
690a5c7a17Sopenharmony_ci}
700a5c7a17Sopenharmony_ci
710a5c7a17Sopenharmony_civoid CameraImpl::OnConfigured(int32_t ret, CameraConfig &config)
720a5c7a17Sopenharmony_ci{
730a5c7a17Sopenharmony_ci    if (ret != MEDIA_OK) {
740a5c7a17Sopenharmony_ci        handler_->Post([this, ret] { this->stateCb_->OnConfigureFailed(this->GetCameraId(), ret); });
750a5c7a17Sopenharmony_ci        return;
760a5c7a17Sopenharmony_ci    }
770a5c7a17Sopenharmony_ci    handler_->Post([this] { this->stateCb_->OnConfigured(*this); });
780a5c7a17Sopenharmony_ci}
790a5c7a17Sopenharmony_ci
800a5c7a17Sopenharmony_civoid CameraImpl::Release()
810a5c7a17Sopenharmony_ci{
820a5c7a17Sopenharmony_ci    if (config_ != nullptr) {
830a5c7a17Sopenharmony_ci        delete config_;
840a5c7a17Sopenharmony_ci        config_ = nullptr;
850a5c7a17Sopenharmony_ci    }
860a5c7a17Sopenharmony_ci    if (deviceClient_ == nullptr) {
870a5c7a17Sopenharmony_ci        return;
880a5c7a17Sopenharmony_ci    }
890a5c7a17Sopenharmony_ci    deviceClient_->Release();
900a5c7a17Sopenharmony_ci    if (handler_ == nullptr) {
910a5c7a17Sopenharmony_ci        return;
920a5c7a17Sopenharmony_ci    }
930a5c7a17Sopenharmony_ci    handler_->Post([this] { this->stateCb_->OnReleased(*this); });
940a5c7a17Sopenharmony_ci}
950a5c7a17Sopenharmony_ci
960a5c7a17Sopenharmony_ciint32_t CameraImpl::TriggerLoopingCapture(FrameConfig &fc)
970a5c7a17Sopenharmony_ci{
980a5c7a17Sopenharmony_ci    if (config_ == nullptr) {
990a5c7a17Sopenharmony_ci        MEDIA_ERR_LOG("Cannot find available configuration, configure the camera first.");
1000a5c7a17Sopenharmony_ci        return MEDIA_INVALID_PARAM;
1010a5c7a17Sopenharmony_ci    }
1020a5c7a17Sopenharmony_ci    int32_t type = fc.GetFrameConfigType();
1030a5c7a17Sopenharmony_ci    if (type == FRAME_CONFIG_CAPTURE) {
1040a5c7a17Sopenharmony_ci        MEDIA_ERR_LOG("looping capture not support FRAME_CONFIG_CAPTURE");
1050a5c7a17Sopenharmony_ci        return MEDIA_ERR;
1060a5c7a17Sopenharmony_ci    }
1070a5c7a17Sopenharmony_ci    FrameConfig *curFc = GetFrameConfig(type);
1080a5c7a17Sopenharmony_ci    if (curFc != nullptr) {
1090a5c7a17Sopenharmony_ci        MEDIA_ERR_LOG("Frame config of the input type is already existed.");
1100a5c7a17Sopenharmony_ci        return MEDIA_ERR;
1110a5c7a17Sopenharmony_ci    }
1120a5c7a17Sopenharmony_ci    if (deviceClient_ == nullptr) {
1130a5c7a17Sopenharmony_ci        return MEDIA_ERR;
1140a5c7a17Sopenharmony_ci    }
1150a5c7a17Sopenharmony_ci    int32_t ret = deviceClient_->TriggerLoopingCapture(fc);
1160a5c7a17Sopenharmony_ci    if (ret != MEDIA_OK) {
1170a5c7a17Sopenharmony_ci        MEDIA_ERR_LOG("Camera device start looping capture failed.(ret=%d)", ret);
1180a5c7a17Sopenharmony_ci        return MEDIA_ERR;
1190a5c7a17Sopenharmony_ci    }
1200a5c7a17Sopenharmony_ci    frameConfigs_.emplace_back(&fc);
1210a5c7a17Sopenharmony_ci    return MEDIA_OK;
1220a5c7a17Sopenharmony_ci}
1230a5c7a17Sopenharmony_ci
1240a5c7a17Sopenharmony_civoid CameraImpl::StopLoopingCapture(int32_t type = -1)
1250a5c7a17Sopenharmony_ci{
1260a5c7a17Sopenharmony_ci    if (deviceClient_ == nullptr) {
1270a5c7a17Sopenharmony_ci        return;
1280a5c7a17Sopenharmony_ci    }
1290a5c7a17Sopenharmony_ci    deviceClient_->StopLoopingCapture(type);
1300a5c7a17Sopenharmony_ci    if (config_ == nullptr) {
1310a5c7a17Sopenharmony_ci        return;
1320a5c7a17Sopenharmony_ci    }
1330a5c7a17Sopenharmony_ci    FrameStateCallback *fsc = config_->GetFrameStateCb();
1340a5c7a17Sopenharmony_ci    if (fsc == nullptr) {
1350a5c7a17Sopenharmony_ci        return;
1360a5c7a17Sopenharmony_ci    }
1370a5c7a17Sopenharmony_ci    EventHandler *eventhdl = config_->GetEventHandler();
1380a5c7a17Sopenharmony_ci    if (eventhdl == nullptr) {
1390a5c7a17Sopenharmony_ci        return;
1400a5c7a17Sopenharmony_ci    }
1410a5c7a17Sopenharmony_ci
1420a5c7a17Sopenharmony_ci    for (auto i : frameConfigs_) {
1430a5c7a17Sopenharmony_ci        if (i->GetFrameConfigType() == type || type == -1) {
1440a5c7a17Sopenharmony_ci            eventhdl->Post([fsc, this, i] {
1450a5c7a17Sopenharmony_ci                FrameResult frameResult;
1460a5c7a17Sopenharmony_ci                fsc->OnFrameFinished(*this, *i, frameResult);
1470a5c7a17Sopenharmony_ci            });
1480a5c7a17Sopenharmony_ci        }
1490a5c7a17Sopenharmony_ci    }
1500a5c7a17Sopenharmony_ci    /* clear all configs, if type == -1 */
1510a5c7a17Sopenharmony_ci    if (type == -1) {
1520a5c7a17Sopenharmony_ci        frameConfigs_.clear();
1530a5c7a17Sopenharmony_ci    }
1540a5c7a17Sopenharmony_ci}
1550a5c7a17Sopenharmony_ci
1560a5c7a17Sopenharmony_ciint32_t CameraImpl::TriggerSingleCapture(FrameConfig &fc)
1570a5c7a17Sopenharmony_ci{
1580a5c7a17Sopenharmony_ci    if (config_ == nullptr) {
1590a5c7a17Sopenharmony_ci        MEDIA_ERR_LOG("Cannot find available configuration, configure the camera first.");
1600a5c7a17Sopenharmony_ci        return MEDIA_INVALID_PARAM;
1610a5c7a17Sopenharmony_ci    }
1620a5c7a17Sopenharmony_ci    if (deviceClient_ == nullptr) {
1630a5c7a17Sopenharmony_ci        MEDIA_ERR_LOG("Cannot find available configuration, configure the camera first.");
1640a5c7a17Sopenharmony_ci        return MEDIA_INVALID_PARAM;
1650a5c7a17Sopenharmony_ci    }
1660a5c7a17Sopenharmony_ci    if (fc.GetFrameConfigType() != FRAME_CONFIG_CAPTURE) {
1670a5c7a17Sopenharmony_ci        MEDIA_ERR_LOG("single capture only support FRAME_CONFIG_CAPTURE");
1680a5c7a17Sopenharmony_ci        return MEDIA_ERR;
1690a5c7a17Sopenharmony_ci    }
1700a5c7a17Sopenharmony_ci    int32_t ret = deviceClient_->TriggerSingleCapture(dynamic_cast<FrameConfig &>(fc));
1710a5c7a17Sopenharmony_ci    if (ret != MEDIA_OK) {
1720a5c7a17Sopenharmony_ci        return MEDIA_ERR;
1730a5c7a17Sopenharmony_ci    }
1740a5c7a17Sopenharmony_ci    return MEDIA_OK;
1750a5c7a17Sopenharmony_ci}
1760a5c7a17Sopenharmony_ci
1770a5c7a17Sopenharmony_ciconst CameraAbility *CameraImpl::GetAbility()
1780a5c7a17Sopenharmony_ci{
1790a5c7a17Sopenharmony_ci    return ability_;
1800a5c7a17Sopenharmony_ci}
1810a5c7a17Sopenharmony_ci
1820a5c7a17Sopenharmony_ciconst CameraInfo *CameraImpl::GetInfo()
1830a5c7a17Sopenharmony_ci{
1840a5c7a17Sopenharmony_ci    return info_;
1850a5c7a17Sopenharmony_ci}
1860a5c7a17Sopenharmony_ci
1870a5c7a17Sopenharmony_civoid CameraImpl::OnCreate(string cameraId)
1880a5c7a17Sopenharmony_ci{
1890a5c7a17Sopenharmony_ci    deviceClient_ = CameraDeviceClient::GetInstance();
1900a5c7a17Sopenharmony_ci    if (deviceClient_ == nullptr) {
1910a5c7a17Sopenharmony_ci        return;
1920a5c7a17Sopenharmony_ci    }
1930a5c7a17Sopenharmony_ci    deviceClient_->SetCameraId(cameraId);
1940a5c7a17Sopenharmony_ci    deviceClient_->SetCameraImpl(this);
1950a5c7a17Sopenharmony_ci    deviceClient_->SetCameraCallback();
1960a5c7a17Sopenharmony_ci    if (stateCb_ == nullptr || handler_ == nullptr) {
1970a5c7a17Sopenharmony_ci        return;
1980a5c7a17Sopenharmony_ci    }
1990a5c7a17Sopenharmony_ci    handler_->Post([this] { this->stateCb_->OnCreated(*this); });
2000a5c7a17Sopenharmony_ci}
2010a5c7a17Sopenharmony_ci
2020a5c7a17Sopenharmony_civoid CameraImpl::OnFrameFinished(int32_t ret, FrameConfig &fc)
2030a5c7a17Sopenharmony_ci{
2040a5c7a17Sopenharmony_ci    FrameStateCallback *fsc = config_->GetFrameStateCb();
2050a5c7a17Sopenharmony_ci    if (fsc == nullptr) {
2060a5c7a17Sopenharmony_ci        return;
2070a5c7a17Sopenharmony_ci    }
2080a5c7a17Sopenharmony_ci    EventHandler *eventhdl = config_->GetEventHandler();
2090a5c7a17Sopenharmony_ci    if (eventhdl == nullptr) {
2100a5c7a17Sopenharmony_ci        return;
2110a5c7a17Sopenharmony_ci    }
2120a5c7a17Sopenharmony_ci    if (ret != MEDIA_OK) {
2130a5c7a17Sopenharmony_ci        eventhdl->Post([fsc, this, &fc] {
2140a5c7a17Sopenharmony_ci            FrameResult frameResult;
2150a5c7a17Sopenharmony_ci            fsc->OnFrameError(*this, fc, -1, frameResult);
2160a5c7a17Sopenharmony_ci        });
2170a5c7a17Sopenharmony_ci        return;
2180a5c7a17Sopenharmony_ci    }
2190a5c7a17Sopenharmony_ci    eventhdl->Post([fsc, this, &fc] {
2200a5c7a17Sopenharmony_ci        FrameResult frameResult;
2210a5c7a17Sopenharmony_ci        fsc->OnFrameFinished(*this, fc, frameResult);
2220a5c7a17Sopenharmony_ci    });
2230a5c7a17Sopenharmony_ci}
2240a5c7a17Sopenharmony_ci
2250a5c7a17Sopenharmony_civoid CameraImpl::OnCreateFailed()
2260a5c7a17Sopenharmony_ci{
2270a5c7a17Sopenharmony_ci    if (stateCb_ == nullptr || handler_ == nullptr) {
2280a5c7a17Sopenharmony_ci        return;
2290a5c7a17Sopenharmony_ci    }
2300a5c7a17Sopenharmony_ci    handler_->Post([this] { this->stateCb_->OnCreateFailed(id_, MEDIA_ERR); });
2310a5c7a17Sopenharmony_ci}
2320a5c7a17Sopenharmony_ci
2330a5c7a17Sopenharmony_civoid CameraImpl::RegistCb(CameraStateCallback &callback, EventHandler &handler)
2340a5c7a17Sopenharmony_ci{
2350a5c7a17Sopenharmony_ci    handler_ = &handler;
2360a5c7a17Sopenharmony_ci    stateCb_ = &callback;
2370a5c7a17Sopenharmony_ci}
2380a5c7a17Sopenharmony_ci} // namespace Media
2390a5c7a17Sopenharmony_ci} // namespace OHOS