1 /*
2  * Copyright (c) 2020-2021 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 "camera_impl.h"
17 #include "media_log.h"
18 #include "camera_device_client.h"
19 #include <cstdio>
20 
21 using namespace std;
22 namespace OHOS {
23 namespace Media {
CameraImpl(const std::string & id,const CameraAbility * ability,const CameraInfo * info)24 CameraImpl::CameraImpl(const std::string &id, const CameraAbility *ability, const CameraInfo *info):id_(id)
25 {
26     ability_ = ability;
27     info_ = info;
28 }
29 
GetCameraId()30 string CameraImpl::GetCameraId()
31 {
32     return id_;
33 }
34 
GetCameraConfig() const35 const CameraConfig *CameraImpl::GetCameraConfig() const
36 {
37     return config_;
38 }
39 
GetFrameConfig(int32_t type)40 FrameConfig *CameraImpl::GetFrameConfig(int32_t type)
41 {
42     for (auto i : frameConfigs_) {
43         if (i->GetFrameConfigType() == type) {
44             return i;
45         }
46     }
47     return nullptr;
48 }
49 
Configure(CameraConfig & config)50 void CameraImpl::Configure(CameraConfig &config)
51 {
52     if (config_ != nullptr) {
53         return;
54     }
55 
56     if (config.GetFrameStateCb() == nullptr || config.GetEventHandler() == nullptr) {
57         return;
58     }
59 
60     if (deviceClient_ == nullptr) {
61         return;
62     }
63     int32_t ret = deviceClient_->SetCameraConfig(config);
64     if (ret != MEDIA_OK) {
65         MEDIA_ERR_LOG("Set camera config failed in cameraImpl.");
66         return;
67     }
68     config_ = &config;
69 }
70 
OnConfigured(int32_t ret,CameraConfig & config)71 void CameraImpl::OnConfigured(int32_t ret, CameraConfig &config)
72 {
73     if (ret != MEDIA_OK) {
74         handler_->Post([this, ret] { this->stateCb_->OnConfigureFailed(this->GetCameraId(), ret); });
75         return;
76     }
77     handler_->Post([this] { this->stateCb_->OnConfigured(*this); });
78 }
79 
Release()80 void CameraImpl::Release()
81 {
82     if (config_ != nullptr) {
83         delete config_;
84         config_ = nullptr;
85     }
86     if (deviceClient_ == nullptr) {
87         return;
88     }
89     deviceClient_->Release();
90     if (handler_ == nullptr) {
91         return;
92     }
93     handler_->Post([this] { this->stateCb_->OnReleased(*this); });
94 }
95 
TriggerLoopingCapture(FrameConfig & fc)96 int32_t CameraImpl::TriggerLoopingCapture(FrameConfig &fc)
97 {
98     if (config_ == nullptr) {
99         MEDIA_ERR_LOG("Cannot find available configuration, configure the camera first.");
100         return MEDIA_INVALID_PARAM;
101     }
102     int32_t type = fc.GetFrameConfigType();
103     if (type == FRAME_CONFIG_CAPTURE) {
104         MEDIA_ERR_LOG("looping capture not support FRAME_CONFIG_CAPTURE");
105         return MEDIA_ERR;
106     }
107     FrameConfig *curFc = GetFrameConfig(type);
108     if (curFc != nullptr) {
109         MEDIA_ERR_LOG("Frame config of the input type is already existed.");
110         return MEDIA_ERR;
111     }
112     if (deviceClient_ == nullptr) {
113         return MEDIA_ERR;
114     }
115     int32_t ret = deviceClient_->TriggerLoopingCapture(fc);
116     if (ret != MEDIA_OK) {
117         MEDIA_ERR_LOG("Camera device start looping capture failed.(ret=%d)", ret);
118         return MEDIA_ERR;
119     }
120     frameConfigs_.emplace_back(&fc);
121     return MEDIA_OK;
122 }
123 
StopLoopingCapture(int32_t type=-1)124 void CameraImpl::StopLoopingCapture(int32_t type = -1)
125 {
126     if (deviceClient_ == nullptr) {
127         return;
128     }
129     deviceClient_->StopLoopingCapture(type);
130     if (config_ == nullptr) {
131         return;
132     }
133     FrameStateCallback *fsc = config_->GetFrameStateCb();
134     if (fsc == nullptr) {
135         return;
136     }
137     EventHandler *eventhdl = config_->GetEventHandler();
138     if (eventhdl == nullptr) {
139         return;
140     }
141 
142     for (auto i : frameConfigs_) {
143         if (i->GetFrameConfigType() == type || type == -1) {
144             eventhdl->Post([fsc, this, i] {
145                 FrameResult frameResult;
146                 fsc->OnFrameFinished(*this, *i, frameResult);
147             });
148         }
149     }
150     /* clear all configs, if type == -1 */
151     if (type == -1) {
152         frameConfigs_.clear();
153     }
154 }
155 
TriggerSingleCapture(FrameConfig & fc)156 int32_t CameraImpl::TriggerSingleCapture(FrameConfig &fc)
157 {
158     if (config_ == nullptr) {
159         MEDIA_ERR_LOG("Cannot find available configuration, configure the camera first.");
160         return MEDIA_INVALID_PARAM;
161     }
162     if (deviceClient_ == nullptr) {
163         MEDIA_ERR_LOG("Cannot find available configuration, configure the camera first.");
164         return MEDIA_INVALID_PARAM;
165     }
166     if (fc.GetFrameConfigType() != FRAME_CONFIG_CAPTURE) {
167         MEDIA_ERR_LOG("single capture only support FRAME_CONFIG_CAPTURE");
168         return MEDIA_ERR;
169     }
170     int32_t ret = deviceClient_->TriggerSingleCapture(dynamic_cast<FrameConfig &>(fc));
171     if (ret != MEDIA_OK) {
172         return MEDIA_ERR;
173     }
174     return MEDIA_OK;
175 }
176 
GetAbility()177 const CameraAbility *CameraImpl::GetAbility()
178 {
179     return ability_;
180 }
181 
GetInfo()182 const CameraInfo *CameraImpl::GetInfo()
183 {
184     return info_;
185 }
186 
OnCreate(string cameraId)187 void CameraImpl::OnCreate(string cameraId)
188 {
189     deviceClient_ = CameraDeviceClient::GetInstance();
190     if (deviceClient_ == nullptr) {
191         return;
192     }
193     deviceClient_->SetCameraId(cameraId);
194     deviceClient_->SetCameraImpl(this);
195     deviceClient_->SetCameraCallback();
196     if (stateCb_ == nullptr || handler_ == nullptr) {
197         return;
198     }
199     handler_->Post([this] { this->stateCb_->OnCreated(*this); });
200 }
201 
OnFrameFinished(int32_t ret,FrameConfig & fc)202 void CameraImpl::OnFrameFinished(int32_t ret, FrameConfig &fc)
203 {
204     FrameStateCallback *fsc = config_->GetFrameStateCb();
205     if (fsc == nullptr) {
206         return;
207     }
208     EventHandler *eventhdl = config_->GetEventHandler();
209     if (eventhdl == nullptr) {
210         return;
211     }
212     if (ret != MEDIA_OK) {
213         eventhdl->Post([fsc, this, &fc] {
214             FrameResult frameResult;
215             fsc->OnFrameError(*this, fc, -1, frameResult);
216         });
217         return;
218     }
219     eventhdl->Post([fsc, this, &fc] {
220         FrameResult frameResult;
221         fsc->OnFrameFinished(*this, fc, frameResult);
222     });
223 }
224 
OnCreateFailed()225 void CameraImpl::OnCreateFailed()
226 {
227     if (stateCb_ == nullptr || handler_ == nullptr) {
228         return;
229     }
230     handler_->Post([this] { this->stateCb_->OnCreateFailed(id_, MEDIA_ERR); });
231 }
232 
RegistCb(CameraStateCallback & callback,EventHandler & handler)233 void CameraImpl::RegistCb(CameraStateCallback &callback, EventHandler &handler)
234 {
235     handler_ = &handler;
236     stateCb_ = &callback;
237 }
238 } // namespace Media
239 } // namespace OHOS