1 /*
2 * Copyright (c) 2021-2022 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 "output/video_output.h"
17 #include "camera_util.h"
18 #include "hstream_repeat_callback_stub.h"
19 #include "input/camera_device.h"
20 #include "input/camera_input.h"
21 #include "camera_log.h"
22
23 namespace OHOS {
24 namespace CameraStandard {
VideoOutput(sptr<IStreamRepeat> & streamRepeat)25 VideoOutput::VideoOutput(sptr<IStreamRepeat> &streamRepeat)
26 : CaptureOutput(CAPTURE_OUTPUT_TYPE_VIDEO, StreamType::REPEAT, streamRepeat) {
27 }
28
~VideoOutput()29 VideoOutput::~VideoOutput()
30 {
31 svcCallback_ = nullptr;
32 appCallback_ = nullptr;
33 }
34
35 class HStreamRepeatCallbackImpl : public HStreamRepeatCallbackStub {
36 public:
37 sptr<VideoOutput> videoOutput_ = nullptr;
HStreamRepeatCallbackImpl()38 HStreamRepeatCallbackImpl() : videoOutput_(nullptr) {
39 }
40
HStreamRepeatCallbackImpl(const sptr<VideoOutput> & videoOutput)41 explicit HStreamRepeatCallbackImpl(const sptr<VideoOutput>& videoOutput) : videoOutput_(videoOutput) {
42 }
43
~HStreamRepeatCallbackImpl()44 ~HStreamRepeatCallbackImpl()
45 {
46 videoOutput_ = nullptr;
47 }
48
OnFrameStarted()49 int32_t OnFrameStarted() override
50 {
51 CAMERA_SYNC_TRACE;
52 if (videoOutput_ != nullptr && videoOutput_->GetApplicationCallback() != nullptr) {
53 videoOutput_->GetApplicationCallback()->OnFrameStarted();
54 } else {
55 MEDIA_INFO_LOG("Discarding HStreamRepeatCallbackImpl::OnFrameStarted callback in video");
56 }
57 return CAMERA_OK;
58 }
59
OnFrameEnded(const int32_t frameCount)60 int32_t OnFrameEnded(const int32_t frameCount) override
61 {
62 CAMERA_SYNC_TRACE;
63 if (videoOutput_ != nullptr && videoOutput_->GetApplicationCallback() != nullptr) {
64 videoOutput_->GetApplicationCallback()->OnFrameEnded(frameCount);
65 } else {
66 MEDIA_INFO_LOG("Discarding HStreamRepeatCallbackImpl::OnFrameEnded callback in video");
67 }
68 return CAMERA_OK;
69 }
70
OnFrameError(const int32_t errorCode)71 int32_t OnFrameError(const int32_t errorCode) override
72 {
73 if (videoOutput_ != nullptr && videoOutput_->GetApplicationCallback() != nullptr) {
74 videoOutput_->GetApplicationCallback()->OnError(errorCode);
75 } else {
76 MEDIA_INFO_LOG("Discarding HStreamRepeatCallbackImpl::OnFrameError callback in video");
77 }
78 return CAMERA_OK;
79 }
80 };
81
SetCallback(std::shared_ptr<VideoStateCallback> callback)82 void VideoOutput::SetCallback(std::shared_ptr<VideoStateCallback> callback)
83 {
84 appCallback_ = callback;
85 if (appCallback_ != nullptr) {
86 if (svcCallback_ == nullptr) {
87 svcCallback_ = new(std::nothrow) HStreamRepeatCallbackImpl(this);
88 if (svcCallback_ == nullptr) {
89 MEDIA_ERR_LOG("VideoOutput::SetCallback: new HStreamRepeatCallbackImpl Failed to register callback");
90 appCallback_ = nullptr;
91 return;
92 }
93 }
94 if (GetStream() == nullptr) {
95 MEDIA_ERR_LOG("VideoOutput Failed to SetCallback!, GetStream is nullptr");
96 return;
97 }
98 int32_t errorCode = CAMERA_OK;
99 auto itemStream = static_cast<IStreamRepeat *>(GetStream().GetRefPtr());
100 if (itemStream) {
101 errorCode = itemStream->SetCallback(svcCallback_);
102 } else {
103 MEDIA_ERR_LOG("VideoOutput::SetCallback itemStream is nullptr");
104 }
105
106 if (errorCode != CAMERA_OK) {
107 MEDIA_ERR_LOG("VideoOutput::SetCallback: Failed to register callback, errorCode: %{public}d", errorCode);
108 svcCallback_ = nullptr;
109 appCallback_ = nullptr;
110 }
111 }
112 }
113
Start()114 int32_t VideoOutput::Start()
115 {
116 std::lock_guard<std::mutex> lock(asyncOpMutex_);
117 CaptureSession* captureSession = GetSession();
118 if (captureSession == nullptr || !captureSession->IsSessionCommited()) {
119 MEDIA_ERR_LOG("VideoOutput Failed to Start!, session not config");
120 return CameraErrorCode::SESSION_NOT_CONFIG;
121 }
122 if (GetStream() == nullptr) {
123 MEDIA_ERR_LOG("VideoOutput Failed to Start!, GetStream is nullptr");
124 return CameraErrorCode::SERVICE_FATL_ERROR;
125 }
126 auto itemStream = static_cast<IStreamRepeat *>(GetStream().GetRefPtr());
127 int32_t errCode = CAMERA_UNKNOWN_ERROR;
128 if (itemStream) {
129 errCode = itemStream->Start();
130 if (errCode != CAMERA_OK) {
131 MEDIA_ERR_LOG("VideoOutput Failed to Start!, errCode: %{public}d", errCode);
132 }
133 } else {
134 MEDIA_ERR_LOG("VideoOutput::Start() itemStream is nullptr");
135 }
136 return ServiceToCameraError(errCode);
137 }
138
Stop()139 int32_t VideoOutput::Stop()
140 {
141 std::lock_guard<std::mutex> lock(asyncOpMutex_);
142 if (GetStream() == nullptr) {
143 MEDIA_ERR_LOG("VideoOutput Failed to Stop!, GetStream is nullptr");
144 return CameraErrorCode::SERVICE_FATL_ERROR;
145 }
146 auto itemStream = static_cast<IStreamRepeat *>(GetStream().GetRefPtr());
147 int32_t errCode = CAMERA_UNKNOWN_ERROR;
148 if (itemStream) {
149 errCode = itemStream->Stop();
150 if (errCode != CAMERA_OK) {
151 MEDIA_ERR_LOG("VideoOutput Failed to Stop!, errCode: %{public}d", errCode);
152 }
153 } else {
154 MEDIA_ERR_LOG("VideoOutput::Stop() itemStream is nullptr");
155 }
156 return ServiceToCameraError(errCode);
157 }
158
Resume()159 int32_t VideoOutput::Resume()
160 {
161 std::lock_guard<std::mutex> lock(asyncOpMutex_);
162 if (GetStream() == nullptr) {
163 MEDIA_ERR_LOG("VideoOutput Failed to Resume!, GetStream is nullptr");
164 return CameraErrorCode::SERVICE_FATL_ERROR;
165 }
166 auto itemStream = static_cast<IStreamRepeat *>(GetStream().GetRefPtr());
167 int32_t errCode = CAMERA_UNKNOWN_ERROR;
168 if (itemStream) {
169 errCode = itemStream->Start();
170 } else {
171 MEDIA_ERR_LOG("VideoOutput::Resume() itemStream is nullptr");
172 }
173 return ServiceToCameraError(errCode);
174 }
175
Pause()176 int32_t VideoOutput::Pause()
177 {
178 std::lock_guard<std::mutex> lock(asyncOpMutex_);
179 if (GetStream() == nullptr) {
180 MEDIA_ERR_LOG("VideoOutput Failed to Pause!, GetStream is nullptr");
181 return CameraErrorCode::SERVICE_FATL_ERROR;
182 }
183 auto itemStream = static_cast<IStreamRepeat *>(GetStream().GetRefPtr());
184 int32_t errCode = CAMERA_UNKNOWN_ERROR;
185 if (itemStream) {
186 errCode = itemStream->Stop();
187 } else {
188 MEDIA_ERR_LOG("VideoOutput::Pause() itemStream is nullptr");
189 }
190 return errCode;
191 }
192
Release()193 int32_t VideoOutput::Release()
194 {
195 std::lock_guard<std::mutex> lock(asyncOpMutex_);
196 if (GetStream() == nullptr) {
197 MEDIA_ERR_LOG("VideoOutput Failed to Release!, GetStream is nullptr");
198 return CameraErrorCode::SERVICE_FATL_ERROR;
199 }
200 auto itemStream = static_cast<IStreamRepeat *>(GetStream().GetRefPtr());
201 int32_t errCode = CAMERA_UNKNOWN_ERROR;
202 if (itemStream) {
203 errCode = itemStream->Release();
204 } else {
205 MEDIA_ERR_LOG("VideoOutput::Release() itemStream is nullptr");
206 }
207 if (errCode != CAMERA_OK) {
208 MEDIA_ERR_LOG("Failed to release VideoOutput!, errCode: %{public}d", errCode);
209 }
210 svcCallback_ = nullptr;
211 appCallback_ = nullptr;
212 CaptureOutput::Release();
213 return ServiceToCameraError(errCode);
214 }
215
GetApplicationCallback()216 std::shared_ptr<VideoStateCallback> VideoOutput::GetApplicationCallback()
217 {
218 return appCallback_;
219 }
220
GetFrameRateRange()221 const std::vector<int32_t>& VideoOutput::GetFrameRateRange()
222 {
223 return videoFrameRateRange_;
224 }
225
SetFrameRateRange(int32_t minFrameRate,int32_t maxFrameRate)226 void VideoOutput::SetFrameRateRange(int32_t minFrameRate, int32_t maxFrameRate)
227 {
228 MEDIA_DEBUG_LOG("VideoOutput::SetFrameRateRange min = %{public}d and max = %{public}d",
229 minFrameRate, maxFrameRate);
230
231 videoFrameRateRange_ = {minFrameRate, maxFrameRate};
232 }
233 } // CameraStandard
234 } // OHOS
235