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 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 <mutex>
17 #include "media_log.h"
18 #include "media_errors.h"
19 #include "native_avscreen_capture_magic.h"
20 #include "surface_buffer_impl.h"
21 #include "native_avscreen_capture.h"
22
23 namespace {
24 constexpr OHOS::HiviewDFX::HiLogLabel LABEL = {LOG_CORE, LOG_DOMAIN, "NativeScreenCapture"};
25 }
26
27 using namespace OHOS::Media;
28 class NativeScreenCaptureCallback;
29
30 struct ScreenCaptureObject : public OH_AVScreenCapture {
ScreenCaptureObjectScreenCaptureObject31 explicit ScreenCaptureObject(const std::shared_ptr<ScreenCapture> &capture)
32 : screenCapture_(capture) {}
33 ~ScreenCaptureObject() = default;
34
35 const std::shared_ptr<ScreenCapture> screenCapture_ = nullptr;
36 std::shared_ptr<NativeScreenCaptureCallback> callback_ = nullptr;
37 };
38
39 class NativeScreenCaptureCallback : public ScreenCaptureCallBack {
40 public:
NativeScreenCaptureCallback(struct OH_AVScreenCapture * capture,struct OH_AVScreenCaptureCallback callback)41 NativeScreenCaptureCallback(struct OH_AVScreenCapture *capture, struct OH_AVScreenCaptureCallback callback)
42 : capture_(capture), callback_(callback) {}
43 virtual ~NativeScreenCaptureCallback() = default;
44
OnError(ScreenCaptureErrorType errorType,int32_t errorCode)45 void OnError(ScreenCaptureErrorType errorType, int32_t errorCode) override
46 {
47 MEDIA_LOGI("OnError() is called, errorType %{public}d, errorCode %{public}d", errorType, errorCode);
48 std::unique_lock<std::mutex> lock(mutex_);
49
50 if (capture_ != nullptr && callback_.onError != nullptr) {
51 callback_.onError(capture_, errorCode);
52 }
53 }
54
OnAudioBufferAvailable(bool isReady,AudioCaptureSourceType type)55 void OnAudioBufferAvailable(bool isReady, AudioCaptureSourceType type) override
56 {
57 MEDIA_LOGD("OnAudioBufferAvailable() is called, isReady:%{public}d", isReady);
58 std::unique_lock<std::mutex> lock(mutex_);
59 if (capture_ != nullptr && callback_.onAudioBufferAvailable != nullptr) {
60 callback_.onAudioBufferAvailable(capture_, isReady, static_cast<OH_AudioCaptureSourceType>(type));
61 }
62 }
63
OnVideoBufferAvailable(bool isReady)64 void OnVideoBufferAvailable(bool isReady) override
65 {
66 MEDIA_LOGD("OnVideoBufferAvailable() is called, isReady:%{public}d", isReady);
67 std::unique_lock<std::mutex> lock(mutex_);
68 if (capture_ != nullptr && callback_.onVideoBufferAvailable != nullptr) {
69 callback_.onVideoBufferAvailable(capture_, isReady);
70 }
71 }
72
StopCallback()73 void StopCallback()
74 {
75 std::unique_lock<std::mutex> lock(mutex_);
76 capture_ = nullptr;
77 }
78
79 private:
80 struct OH_AVScreenCapture *capture_;
81 struct OH_AVScreenCaptureCallback callback_;
82 std::mutex mutex_;
83 };
84
OH_AVScreenCapture_Create(void)85 struct OH_AVScreenCapture *OH_AVScreenCapture_Create(void)
86 {
87 std::shared_ptr<ScreenCapture> screenCapture = ScreenCaptureFactory::CreateScreenCapture();
88 CHECK_AND_RETURN_RET_LOG(screenCapture != nullptr, nullptr, "failed to ScreenCaptureFactory::CreateScreenCapture");
89
90 struct ScreenCaptureObject *object = new(std::nothrow) ScreenCaptureObject(screenCapture);
91 CHECK_AND_RETURN_RET_LOG(object != nullptr, nullptr, "failed to new ScreenCaptureObject");
92
93 return object;
94 }
95
OH_AVScreenCapture_Convert(OH_AVScreenCaptureConfig config)96 AVScreenCaptureConfig OH_AVScreenCapture_Convert(OH_AVScreenCaptureConfig config)
97 {
98 AVScreenCaptureConfig config_;
99 config_.captureMode = static_cast<CaptureMode>(config.captureMode);
100 config_.dataType = static_cast<DataType>(config.dataType);
101 config_.audioInfo.micCapInfo = {
102 .audioSampleRate = config.audioInfo.micCapInfo.audioSampleRate,
103 .audioChannels = config.audioInfo.micCapInfo.audioChannels,
104 .audioSource = static_cast<AudioCaptureSourceType>(config.audioInfo.micCapInfo.audioSource)
105 };
106 config_.audioInfo.innerCapInfo = {
107 .audioSampleRate = config.audioInfo.innerCapInfo.audioSampleRate,
108 .audioChannels = config.audioInfo.innerCapInfo.audioChannels,
109 .audioSource = static_cast<AudioCaptureSourceType>(config.audioInfo.innerCapInfo.audioSource)
110 };
111 config_.audioInfo.audioEncInfo.audioBitrate = config.audioInfo.audioEncInfo.audioBitrate;
112 config_.audioInfo.audioEncInfo.audioCodecformat =
113 static_cast<AudioCodecFormat>(config.audioInfo.audioEncInfo.audioCodecformat);
114 config_.videoInfo.videoCapInfo.displayId = config.videoInfo.videoCapInfo.displayId;
115 int32_t *taskIds = config.videoInfo.videoCapInfo.missionIDs;
116 int32_t size = config.videoInfo.videoCapInfo.missionIDsLen;
117 while (size > 0) {
118 if (taskIds == nullptr) {
119 break;
120 }
121 config_.videoInfo.videoCapInfo.taskIDs.push_back(*(taskIds));
122 taskIds++;
123 size--;
124 }
125 config_.videoInfo.videoCapInfo.videoFrameWidth = config.videoInfo.videoCapInfo.videoFrameWidth;
126 config_.videoInfo.videoCapInfo.videoFrameHeight = config.videoInfo.videoCapInfo.videoFrameHeight;
127 config_.videoInfo.videoCapInfo.videoSource =
128 static_cast<VideoSourceType>(config.videoInfo.videoCapInfo.videoSource);
129 config_.videoInfo.videoEncInfo = {
130 .videoCodec = static_cast<VideoCodecFormat>(config_.videoInfo.videoEncInfo.videoCodec),
131 .videoBitrate = config_.videoInfo.videoEncInfo. videoBitrate,
132 .videoFrameRate = config_.videoInfo.videoEncInfo.videoFrameRate
133 };
134 if (config.recorderInfo.url != nullptr) {
135 config_.recorderInfo.url = config.recorderInfo.url;
136 }
137 if (config.recorderInfo.fileFormat == CFT_MPEG_4A) {
138 config_.recorderInfo.fileFormat = ContainerFormatType::CFT_MPEG_4A;
139 } else if (config.recorderInfo.fileFormat == CFT_MPEG_4) {
140 config_.recorderInfo.fileFormat = ContainerFormatType::CFT_MPEG_4;
141 }
142 return config_;
143 }
144
OH_AVScreenCapture_Init(struct OH_AVScreenCapture * capture,OH_AVScreenCaptureConfig config)145 OH_AVSCREEN_CAPTURE_ErrCode OH_AVScreenCapture_Init(struct OH_AVScreenCapture *capture, OH_AVScreenCaptureConfig config)
146 {
147 CHECK_AND_RETURN_RET_LOG(capture != nullptr, AV_SCREEN_CAPTURE_ERR_INVALID_VAL, "input capture is nullptr!");
148
149 struct ScreenCaptureObject *screenCaptureObj = reinterpret_cast<ScreenCaptureObject *>(capture);
150 CHECK_AND_RETURN_RET_LOG(screenCaptureObj->screenCapture_ != nullptr,
151 AV_SCREEN_CAPTURE_ERR_INVALID_VAL, "screenCapture_ is null");
152
153 AVScreenCaptureConfig config_ = OH_AVScreenCapture_Convert(config);
154 int32_t ret = screenCaptureObj->screenCapture_->Init(config_);
155 CHECK_AND_RETURN_RET_LOG(ret == MSERR_OK, AV_SCREEN_CAPTURE_ERR_OPERATE_NOT_PERMIT, "screenCapture init failed!");
156
157 return AV_SCREEN_CAPTURE_ERR_OK;
158 }
159
OH_AVScreenCapture_StartScreenCapture(struct OH_AVScreenCapture * capture)160 OH_AVSCREEN_CAPTURE_ErrCode OH_AVScreenCapture_StartScreenCapture(struct OH_AVScreenCapture *capture)
161 {
162 CHECK_AND_RETURN_RET_LOG(capture != nullptr, AV_SCREEN_CAPTURE_ERR_INVALID_VAL, "input capture is nullptr!");
163
164 struct ScreenCaptureObject *screenCaptureObj = reinterpret_cast<ScreenCaptureObject *>(capture);
165 CHECK_AND_RETURN_RET_LOG(screenCaptureObj->screenCapture_ != nullptr,
166 AV_SCREEN_CAPTURE_ERR_INVALID_VAL, "screenCapture_ is null");
167
168 int32_t ret = screenCaptureObj->screenCapture_->StartScreenCapture();
169 CHECK_AND_RETURN_RET_LOG(ret == MSERR_OK, AV_SCREEN_CAPTURE_ERR_OPERATE_NOT_PERMIT, "StartScreenCapture failed!");
170
171 return AV_SCREEN_CAPTURE_ERR_OK;
172 }
173
OH_AVScreenCapture_StopScreenCapture(struct OH_AVScreenCapture * capture)174 OH_AVSCREEN_CAPTURE_ErrCode OH_AVScreenCapture_StopScreenCapture(struct OH_AVScreenCapture *capture)
175 {
176 CHECK_AND_RETURN_RET_LOG(capture != nullptr, AV_SCREEN_CAPTURE_ERR_INVALID_VAL, "input capture is nullptr!");
177
178 struct ScreenCaptureObject *screenCaptureObj = reinterpret_cast<ScreenCaptureObject *>(capture);
179 CHECK_AND_RETURN_RET_LOG(screenCaptureObj->screenCapture_ != nullptr,
180 AV_SCREEN_CAPTURE_ERR_INVALID_VAL, "screenCapture_ is null");
181
182 int32_t ret = screenCaptureObj->screenCapture_->StopScreenCapture();
183 CHECK_AND_RETURN_RET_LOG(ret == MSERR_OK, AV_SCREEN_CAPTURE_ERR_OPERATE_NOT_PERMIT, "StopScreenCapture failed!");
184
185 return AV_SCREEN_CAPTURE_ERR_OK;
186 }
187
OH_AVScreenCapture_AcquireAudioBuffer(struct OH_AVScreenCapture * capture,OH_AudioBuffer ** audiobuffer,OH_AudioCaptureSourceType type)188 OH_AVSCREEN_CAPTURE_ErrCode OH_AVScreenCapture_AcquireAudioBuffer(struct OH_AVScreenCapture *capture,
189 OH_AudioBuffer **audiobuffer, OH_AudioCaptureSourceType type)
190 {
191 CHECK_AND_RETURN_RET_LOG(capture != nullptr, AV_SCREEN_CAPTURE_ERR_INVALID_VAL, "input capture is nullptr!");
192
193 struct ScreenCaptureObject *screenCaptureObj = reinterpret_cast<ScreenCaptureObject *>(capture);
194 CHECK_AND_RETURN_RET_LOG(screenCaptureObj->screenCapture_ != nullptr,
195 AV_SCREEN_CAPTURE_ERR_INVALID_VAL, "screenCapture_ is null");
196
197 std::shared_ptr<AudioBuffer> aBuffer;
198 int32_t ret =
199 screenCaptureObj->screenCapture_->AcquireAudioBuffer(aBuffer, static_cast<AudioCaptureSourceType>(type));
200 CHECK_AND_RETURN_RET_LOG(ret == MSERR_OK, AV_SCREEN_CAPTURE_ERR_OPERATE_NOT_PERMIT, "AcquireAudioBuffer failed!");
201 if ((aBuffer == nullptr) || (audiobuffer == nullptr)) {
202 return AV_SCREEN_CAPTURE_ERR_NO_MEMORY;
203 }
204 if (aBuffer->buffer != nullptr) {
205 (*audiobuffer)->buf = std::move(aBuffer->buffer);
206 aBuffer->buffer = nullptr;
207 }
208 (*audiobuffer)->size = aBuffer->length;
209 (*audiobuffer)->timestamp = aBuffer->timestamp;
210 (*audiobuffer)->type = static_cast<OH_AudioCaptureSourceType>(aBuffer->sourcetype);
211 return AV_SCREEN_CAPTURE_ERR_OK;
212 }
213
OH_AVScreenCapture_AcquireVideoBuffer(struct OH_AVScreenCapture * capture,int32_t * fence,int64_t * timestamp,struct OH_Rect * region)214 OH_NativeBuffer* OH_AVScreenCapture_AcquireVideoBuffer(struct OH_AVScreenCapture *capture,
215 int32_t *fence, int64_t *timestamp, struct OH_Rect *region)
216 {
217 CHECK_AND_RETURN_RET_LOG(capture != nullptr, nullptr, "input capture is nullptr!");
218
219 struct ScreenCaptureObject *screenCaptureObj = reinterpret_cast<ScreenCaptureObject *>(capture);
220 CHECK_AND_RETURN_RET_LOG(screenCaptureObj->screenCapture_ != nullptr, nullptr, "screenCapture_ is null");
221
222 OHOS::Rect damage;
223 OHOS::sptr<OHOS::SurfaceBuffer> sufacebuffer =
224 screenCaptureObj->screenCapture_->AcquireVideoBuffer(*fence, *timestamp, damage);
225 region->x = damage.x;
226 region->y = damage.y;
227 region->width = damage.w;
228 region->height = damage.h;
229 CHECK_AND_RETURN_RET_LOG(sufacebuffer != nullptr, nullptr, "AcquireVideoBuffer failed!");
230
231 OH_NativeBuffer* nativebuffer = sufacebuffer->SurfaceBufferToNativeBuffer();
232 OH_NativeBuffer_Reference(nativebuffer);
233 return nativebuffer;
234 }
235
OH_AVScreenCapture_ReleaseVideoBuffer(struct OH_AVScreenCapture * capture)236 OH_AVSCREEN_CAPTURE_ErrCode OH_AVScreenCapture_ReleaseVideoBuffer(struct OH_AVScreenCapture *capture)
237 {
238 CHECK_AND_RETURN_RET_LOG(capture != nullptr, AV_SCREEN_CAPTURE_ERR_INVALID_VAL, "input capture is nullptr!");
239
240 struct ScreenCaptureObject *screenCaptureObj = reinterpret_cast<ScreenCaptureObject *>(capture);
241 CHECK_AND_RETURN_RET_LOG(screenCaptureObj->screenCapture_ != nullptr,
242 AV_SCREEN_CAPTURE_ERR_INVALID_VAL, "screenCapture_ is null");
243
244 int32_t ret = screenCaptureObj->screenCapture_->ReleaseVideoBuffer();
245 CHECK_AND_RETURN_RET_LOG(ret == MSERR_OK, AV_SCREEN_CAPTURE_ERR_OPERATE_NOT_PERMIT, "ReleaseVideoBuffer failed!");
246
247 return AV_SCREEN_CAPTURE_ERR_OK;
248 }
249
OH_AVScreenCapture_ReleaseAudioBuffer(struct OH_AVScreenCapture * capture,OH_AudioCaptureSourceType type)250 OH_AVSCREEN_CAPTURE_ErrCode OH_AVScreenCapture_ReleaseAudioBuffer(struct OH_AVScreenCapture *capture,
251 OH_AudioCaptureSourceType type)
252 {
253 CHECK_AND_RETURN_RET_LOG(capture != nullptr, AV_SCREEN_CAPTURE_ERR_INVALID_VAL, "input capture is nullptr!");
254
255 struct ScreenCaptureObject *screenCaptureObj = reinterpret_cast<ScreenCaptureObject *>(capture);
256 CHECK_AND_RETURN_RET_LOG(screenCaptureObj->screenCapture_ != nullptr,
257 AV_SCREEN_CAPTURE_ERR_INVALID_VAL, "screenCapture_ is null");
258
259 int32_t ret = screenCaptureObj->screenCapture_->ReleaseAudioBuffer(static_cast<AudioCaptureSourceType>(type));
260 CHECK_AND_RETURN_RET_LOG(ret == MSERR_OK, AV_SCREEN_CAPTURE_ERR_OPERATE_NOT_PERMIT, "ReleaseSurfaceBuffer failed!");
261
262 return AV_SCREEN_CAPTURE_ERR_OK;
263 }
264
OH_AVScreenCapture_SetCallback(struct OH_AVScreenCapture * capture,struct OH_AVScreenCaptureCallback callback)265 OH_AVSCREEN_CAPTURE_ErrCode OH_AVScreenCapture_SetCallback(struct OH_AVScreenCapture *capture,
266 struct OH_AVScreenCaptureCallback callback)
267 {
268 CHECK_AND_RETURN_RET_LOG(capture != nullptr, AV_SCREEN_CAPTURE_ERR_INVALID_VAL, "input capture is nullptr!");
269
270 struct ScreenCaptureObject *screenCaptureObj = reinterpret_cast<ScreenCaptureObject *>(capture);
271 CHECK_AND_RETURN_RET_LOG(screenCaptureObj->screenCapture_ != nullptr,
272 AV_SCREEN_CAPTURE_ERR_INVALID_VAL, "screenCapture_ is null");
273
274 screenCaptureObj->callback_ = std::make_shared<NativeScreenCaptureCallback>(capture, callback);
275 CHECK_AND_RETURN_RET_LOG(screenCaptureObj->callback_ != nullptr,
276 AV_SCREEN_CAPTURE_ERR_INVALID_VAL, "videoEncoder_ is nullptr!");
277
278 int32_t ret = screenCaptureObj->screenCapture_->SetScreenCaptureCallback(screenCaptureObj->callback_);
279 CHECK_AND_RETURN_RET_LOG(ret == MSERR_OK, AV_SCREEN_CAPTURE_ERR_OPERATE_NOT_PERMIT,
280 "SetScreenCaptureCallback failed!");
281
282 return AV_SCREEN_CAPTURE_ERR_OK;
283 }
284
OH_AVScreenCapture_Release(struct OH_AVScreenCapture * capture)285 OH_AVSCREEN_CAPTURE_ErrCode OH_AVScreenCapture_Release(struct OH_AVScreenCapture *capture)
286 {
287 CHECK_AND_RETURN_RET_LOG(capture != nullptr, AV_SCREEN_CAPTURE_ERR_INVALID_VAL, "input capture is nullptr!");
288
289 struct ScreenCaptureObject *screenCaptureObj = reinterpret_cast<ScreenCaptureObject *>(capture);
290
291 if (screenCaptureObj != nullptr && screenCaptureObj->screenCapture_ != nullptr) {
292 if (screenCaptureObj->callback_ != nullptr) {
293 screenCaptureObj->callback_->StopCallback();
294 }
295 int32_t ret = screenCaptureObj->screenCapture_->Release();
296 if (ret != MSERR_OK) {
297 MEDIA_LOGE("screen capture Release failed!");
298 capture = nullptr;
299 return AV_SCREEN_CAPTURE_ERR_OPERATE_NOT_PERMIT;
300 }
301 } else {
302 MEDIA_LOGD("screen capture is nullptr!");
303 }
304
305 delete capture;
306 return AV_SCREEN_CAPTURE_ERR_OK;
307 }
308
OH_AVScreenCapture_SetMicrophoneEnabled(struct OH_AVScreenCapture * capture,bool isMicrophone)309 OH_AVSCREEN_CAPTURE_ErrCode OH_AVScreenCapture_SetMicrophoneEnabled(struct OH_AVScreenCapture *capture,
310 bool isMicrophone)
311 {
312 CHECK_AND_RETURN_RET_LOG(capture != nullptr, AV_SCREEN_CAPTURE_ERR_INVALID_VAL, "input capture is nullptr!");
313
314 struct ScreenCaptureObject *screenCaptureObj = reinterpret_cast<ScreenCaptureObject *>(capture);
315 CHECK_AND_RETURN_RET_LOG(screenCaptureObj->screenCapture_ != nullptr,
316 AV_SCREEN_CAPTURE_ERR_INVALID_VAL, "screenCapture_ is null");
317
318 int32_t ret = screenCaptureObj->screenCapture_->SetMicrophoneEnabled(isMicrophone);
319 CHECK_AND_RETURN_RET_LOG(ret == MSERR_OK, AV_SCREEN_CAPTURE_ERR_OPERATE_NOT_PERMIT, "setMicrophoneEnable failed!");
320
321 return AV_SCREEN_CAPTURE_ERR_OK;
322 }