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 "screen_capture_adapter_impl.h"
17
18 #include "foundation/multimedia/player_framework/interfaces/inner_api/native/media_errors.h"
19 #include "nweb_log.h"
20 #include "surface_adapter_impl.h"
21
22 namespace OHOS::NWeb {
23 namespace {
GetOHCaptureMode(const CaptureModeAdapter & mode)24 OHOS::Media::CaptureMode GetOHCaptureMode(const CaptureModeAdapter& mode)
25 {
26 switch (mode) {
27 case CaptureModeAdapter::CAPTURE_HOME_SCREEN:
28 return OHOS::Media::CaptureMode::CAPTURE_HOME_SCREEN;
29 case CaptureModeAdapter::CAPTURE_SPECIFIED_SCREEN:
30 return OHOS::Media::CaptureMode::CAPTURE_SPECIFIED_SCREEN;
31 case CaptureModeAdapter::CAPTURE_SPECIFIED_WINDOW:
32 return OHOS::Media::CaptureMode::CAPTURE_SPECIFIED_WINDOW;
33 default:
34 return OHOS::Media::CaptureMode::CAPTURE_INVAILD;
35 }
36 return OHOS::Media::CaptureMode::CAPTURE_INVAILD;
37 }
38
GetOHDataType(const DataTypeAdapter & type)39 OHOS::Media::DataType GetOHDataType(const DataTypeAdapter& type)
40 {
41 switch (type) {
42 case DataTypeAdapter::ORIGINAL_STREAM_DATA_TYPE:
43 return OHOS::Media::DataType::ORIGINAL_STREAM;
44 case DataTypeAdapter::ENCODED_STREAM_DATA_TYPE:
45 return OHOS::Media::DataType::ENCODED_STREAM;
46 case DataTypeAdapter::CAPTURE_FILE_DATA_TYPE:
47 return OHOS::Media::DataType::CAPTURE_FILE;
48 default:
49 return OHOS::Media::DataType::INVAILD;
50 }
51 return OHOS::Media::DataType::INVAILD;
52 }
53
GetOHAudioCaptureSourceType(const AudioCaptureSourceTypeAdapter & type)54 OHOS::Media::AudioCaptureSourceType GetOHAudioCaptureSourceType(const AudioCaptureSourceTypeAdapter& type)
55 {
56 switch (type) {
57 case AudioCaptureSourceTypeAdapter::SOURCE_DEFAULT:
58 return OHOS::Media::AudioCaptureSourceType::SOURCE_DEFAULT;
59 case AudioCaptureSourceTypeAdapter::MIC:
60 return OHOS::Media::AudioCaptureSourceType::MIC;
61 case AudioCaptureSourceTypeAdapter::ALL_PLAYBACK:
62 return OHOS::Media::AudioCaptureSourceType::ALL_PLAYBACK;
63 case AudioCaptureSourceTypeAdapter::APP_PLAYBACK:
64 return OHOS::Media::AudioCaptureSourceType::APP_PLAYBACK;
65 default:
66 return OHOS::Media::AudioCaptureSourceType::SOURCE_INVALID;
67 }
68 return OHOS::Media::AudioCaptureSourceType::SOURCE_INVALID;
69 }
70
GetAudioCaptureSourceTypeAdapter(const OHOS::Media::AudioCaptureSourceType & type)71 AudioCaptureSourceTypeAdapter GetAudioCaptureSourceTypeAdapter(const OHOS::Media::AudioCaptureSourceType& type)
72 {
73 switch (type) {
74 case OHOS::Media::AudioCaptureSourceType::SOURCE_DEFAULT:
75 return AudioCaptureSourceTypeAdapter::SOURCE_DEFAULT;
76 case OHOS::Media::AudioCaptureSourceType::MIC:
77 return AudioCaptureSourceTypeAdapter::MIC;
78 case OHOS::Media::AudioCaptureSourceType::ALL_PLAYBACK:
79 return AudioCaptureSourceTypeAdapter::ALL_PLAYBACK;
80 case OHOS::Media::AudioCaptureSourceType::APP_PLAYBACK:
81 return AudioCaptureSourceTypeAdapter::APP_PLAYBACK;
82 default:
83 return AudioCaptureSourceTypeAdapter::SOURCE_INVALID;
84 }
85 return AudioCaptureSourceTypeAdapter::SOURCE_INVALID;
86 }
87
GetOHAudioCodecFormat(const AudioCodecFormatAdapter & format)88 OHOS::Media::AudioCodecFormat GetOHAudioCodecFormat(const AudioCodecFormatAdapter& format)
89 {
90 switch (format) {
91 case AudioCodecFormatAdapter::AUDIO_DEFAULT:
92 return OHOS::Media::AudioCodecFormat::AUDIO_DEFAULT;
93 case AudioCodecFormatAdapter::AAC_LC:
94 return OHOS::Media::AudioCodecFormat::AAC_LC;
95 default:
96 return OHOS::Media::AudioCodecFormat::AUDIO_CODEC_FORMAT_BUTT;
97 }
98 return OHOS::Media::AudioCodecFormat::AUDIO_CODEC_FORMAT_BUTT;
99 }
100
GetOHVideoSourceType(const VideoSourceTypeAdapter & type)101 OHOS::Media::VideoSourceType GetOHVideoSourceType(const VideoSourceTypeAdapter& type)
102 {
103 switch (type) {
104 case VideoSourceTypeAdapter::VIDEO_SOURCE_SURFACE_YUV:
105 return OHOS::Media::VideoSourceType::VIDEO_SOURCE_SURFACE_YUV;
106 case VideoSourceTypeAdapter::VIDEO_SOURCE_SURFACE_ES:
107 return OHOS::Media::VideoSourceType::VIDEO_SOURCE_SURFACE_ES;
108 case VideoSourceTypeAdapter::VIDEO_SOURCE_SURFACE_RGBA:
109 return OHOS::Media::VideoSourceType::VIDEO_SOURCE_SURFACE_RGBA;
110 default:
111 return OHOS::Media::VideoSourceType::VIDEO_SOURCE_BUTT;
112 }
113 return OHOS::Media::VideoSourceType::VIDEO_SOURCE_BUTT;
114 }
115
GetOHVideoCodecFormat(const VideoCodecFormatAdapter & format)116 OHOS::Media::VideoCodecFormat GetOHVideoCodecFormat(const VideoCodecFormatAdapter& format)
117 {
118 switch (format) {
119 case VideoCodecFormatAdapter::VIDEO_DEFAULT:
120 return OHOS::Media::VideoCodecFormat::VIDEO_DEFAULT;
121 case VideoCodecFormatAdapter::H264:
122 return OHOS::Media::VideoCodecFormat::H264;
123 case VideoCodecFormatAdapter::MPEG4:
124 return OHOS::Media::VideoCodecFormat::MPEG4;
125 default:
126 return OHOS::Media::VideoCodecFormat::VIDEO_CODEC_FORMAT_BUTT;
127 }
128 return OHOS::Media::VideoCodecFormat::VIDEO_CODEC_FORMAT_BUTT;
129 }
130
GetOHContainerFormatType(const ContainerFormatTypeAdapter & type)131 std::string GetOHContainerFormatType(const ContainerFormatTypeAdapter& type)
132 {
133 switch (type) {
134 case ContainerFormatTypeAdapter::CFT_MPEG_4A_TYPE:
135 return std::string(OHOS::Media::ContainerFormatType::CFT_MPEG_4A);
136 default:
137 return std::string(OHOS::Media::ContainerFormatType::CFT_MPEG_4);
138 }
139 return std::string(OHOS::Media::ContainerFormatType::CFT_MPEG_4);
140 }
141
ConvertScreenCaptureConfig(const std::shared_ptr<ScreenCaptureConfigAdapter> config)142 OHOS::Media::AVScreenCaptureConfig ConvertScreenCaptureConfig(const std::shared_ptr<ScreenCaptureConfigAdapter> config)
143 {
144 OHOS::Media::AVScreenCaptureConfig avConfig;
145
146 if (!config) {
147 WVLOG_I("ConvertScreenCaptureConfig config is null");
148 return avConfig;
149 }
150
151 avConfig.captureMode = GetOHCaptureMode(config->GetCaptureMode());
152 avConfig.dataType = GetOHDataType(config->GetDataType());
153
154 if (config->GetAudioInfo() && config->GetAudioInfo()->GetMicCapInfo()) {
155 avConfig.audioInfo.micCapInfo.audioSampleRate = config->GetAudioInfo()->GetMicCapInfo()->GetAudioSampleRate();
156 avConfig.audioInfo.micCapInfo.audioChannels = config->GetAudioInfo()->GetMicCapInfo()->GetAudioChannels();
157 avConfig.audioInfo.micCapInfo.audioSource =
158 GetOHAudioCaptureSourceType(config->GetAudioInfo()->GetMicCapInfo()->GetAudioSource());
159 }
160
161 if (config->GetAudioInfo() && config->GetAudioInfo()->GetInnerCapInfo()) {
162 avConfig.audioInfo.innerCapInfo.audioSampleRate =
163 config->GetAudioInfo()->GetInnerCapInfo()->GetAudioSampleRate();
164 avConfig.audioInfo.innerCapInfo.audioChannels = config->GetAudioInfo()->GetInnerCapInfo()->GetAudioChannels();
165 avConfig.audioInfo.innerCapInfo.audioSource =
166 GetOHAudioCaptureSourceType(config->GetAudioInfo()->GetInnerCapInfo()->GetAudioSource());
167 }
168
169 if (config->GetAudioInfo() && config->GetAudioInfo()->GetAudioEncInfo()) {
170 avConfig.audioInfo.audioEncInfo.audioBitrate = config->GetAudioInfo()->GetAudioEncInfo()->GetAudioBitrate();
171 avConfig.audioInfo.audioEncInfo.audioCodecformat =
172 GetOHAudioCodecFormat(config->GetAudioInfo()->GetAudioEncInfo()->GetAudioCodecformat());
173 }
174
175 if (config->GetVideoInfo() && config->GetVideoInfo()->GetVideoCapInfo()) {
176 avConfig.videoInfo.videoCapInfo.displayId = config->GetVideoInfo()->GetVideoCapInfo()->GetDisplayId();
177 avConfig.videoInfo.videoCapInfo.taskIDs = config->GetVideoInfo()->GetVideoCapInfo()->GetTaskIDs();
178 avConfig.videoInfo.videoCapInfo.videoFrameWidth =
179 config->GetVideoInfo()->GetVideoCapInfo()->GetVideoFrameWidth();
180 avConfig.videoInfo.videoCapInfo.videoFrameHeight =
181 config->GetVideoInfo()->GetVideoCapInfo()->GetVideoFrameHeight();
182 avConfig.videoInfo.videoCapInfo.videoSource =
183 GetOHVideoSourceType(config->GetVideoInfo()->GetVideoCapInfo()->GetVideoSourceType());
184 }
185
186 if (config->GetVideoInfo() && config->GetVideoInfo()->GetVideoEncInfo()) {
187 avConfig.videoInfo.videoEncInfo.videoCodec =
188 GetOHVideoCodecFormat(config->GetVideoInfo()->GetVideoEncInfo()->GetVideoCodecFormat());
189 avConfig.videoInfo.videoEncInfo.videoBitrate = config->GetVideoInfo()->GetVideoEncInfo()->GetVideoBitrate();
190 avConfig.videoInfo.videoEncInfo.videoFrameRate = config->GetVideoInfo()->GetVideoEncInfo()->GetVideoFrameRate();
191 }
192
193 if (config->GetDataType() == DataTypeAdapter::CAPTURE_FILE_DATA_TYPE && config->GetRecorderInfo()) {
194 avConfig.recorderInfo.url = config->GetRecorderInfo()->GetUrl();
195 avConfig.recorderInfo.fileFormat = GetOHContainerFormatType(config->GetRecorderInfo()->GetFileFormat());
196 }
197
198 return avConfig;
199 }
200
GetScreenCaptureStateCodeAdapter(const OHOS::Media::AVScreenCaptureStateCode & stateCode)201 ScreenCaptureStateCodeAdapter GetScreenCaptureStateCodeAdapter(const OHOS::Media::AVScreenCaptureStateCode& stateCode)
202 {
203 switch (stateCode) {
204 case OHOS::Media::AVScreenCaptureStateCode::SCREEN_CAPTURE_STATE_STARTED:
205 return ScreenCaptureStateCodeAdapter::SCREEN_CAPTURE_STATE_STARTED;
206 case OHOS::Media::AVScreenCaptureStateCode::SCREEN_CAPTURE_STATE_CANCELED:
207 return ScreenCaptureStateCodeAdapter::SCREEN_CAPTURE_STATE_CANCELED;
208 case OHOS::Media::AVScreenCaptureStateCode::SCREEN_CAPTURE_STATE_STOPPED_BY_USER:
209 return ScreenCaptureStateCodeAdapter::SCREEN_CAPTURE_STATE_STOPPED_BY_USER;
210 case OHOS::Media::AVScreenCaptureStateCode::SCREEN_CAPTURE_STATE_INTERRUPTED_BY_OTHER:
211 return ScreenCaptureStateCodeAdapter::SCREEN_CAPTURE_STATE_INTERRUPTED_BY_OTHER;
212 case OHOS::Media::AVScreenCaptureStateCode::SCREEN_CAPTURE_STATE_STOPPED_BY_CALL:
213 return ScreenCaptureStateCodeAdapter::SCREEN_CAPTURE_STATE_STOPPED_BY_CALL;
214 case OHOS::Media::AVScreenCaptureStateCode::SCREEN_CAPTURE_STATE_MIC_UNAVAILABLE:
215 return ScreenCaptureStateCodeAdapter::SCREEN_CAPTURE_STATE_MIC_UNAVAILABLE;
216 case OHOS::Media::AVScreenCaptureStateCode::SCREEN_CAPTURE_STATE_MIC_MUTED_BY_USER:
217 return ScreenCaptureStateCodeAdapter::SCREEN_CAPTURE_STATE_MIC_MUTED_BY_USER;
218 case OHOS::Media::AVScreenCaptureStateCode::SCREEN_CAPTURE_STATE_MIC_UNMUTED_BY_USER:
219 return ScreenCaptureStateCodeAdapter::SCREEN_CAPTURE_STATE_MIC_UNMUTED_BY_USER;
220 case OHOS::Media::AVScreenCaptureStateCode::SCREEN_CAPTURE_STATE_ENTER_PRIVATE_SCENE:
221 return ScreenCaptureStateCodeAdapter::SCREEN_CAPTURE_STATE_ENTER_PRIVATE_SCENE;
222 case OHOS::Media::AVScreenCaptureStateCode::SCREEN_CAPTURE_STATE_EXIT_PRIVATE_SCENE:
223 return ScreenCaptureStateCodeAdapter::SCREEN_CAPTURE_STATE_EXIT_PRIVATE_SCENE;
224 default:
225 return ScreenCaptureStateCodeAdapter::SCREEN_CAPTURE_STATE_INVLID;
226 }
227 return ScreenCaptureStateCodeAdapter::SCREEN_CAPTURE_STATE_INVLID;
228 }
229 } // namespace
230
OnError(OHOS::Media::ScreenCaptureErrorType errorType,int32_t errorCode)231 void OHScreenCaptureCallback::OnError(OHOS::Media::ScreenCaptureErrorType errorType, int32_t errorCode)
232 {
233 WVLOG_I("OnError() is called, errorType %{public}d, errorCode %{public}d", errorType, errorCode);
234 if (callback_) {
235 callback_->OnError(errorCode);
236 }
237 }
238
OnAudioBufferAvailable(bool isReady,OHOS::Media::AudioCaptureSourceType type)239 void OHScreenCaptureCallback::OnAudioBufferAvailable(bool isReady, OHOS::Media::AudioCaptureSourceType type)
240 {
241 if (callback_) {
242 callback_->OnAudioBufferAvailable(isReady, GetAudioCaptureSourceTypeAdapter(type));
243 }
244 }
245
OnVideoBufferAvailable(bool isReady)246 void OHScreenCaptureCallback::OnVideoBufferAvailable(bool isReady)
247 {
248 if (callback_) {
249 callback_->OnVideoBufferAvailable(isReady);
250 }
251 }
252
OnStateChange(OHOS::Media::AVScreenCaptureStateCode stateCode)253 void OHScreenCaptureCallback::OnStateChange(OHOS::Media::AVScreenCaptureStateCode stateCode)
254 {
255 WVLOG_I("OnStateChange() is called, stateCode %{public}d", stateCode);
256 if (callback_) {
257 callback_->OnStateChange(GetScreenCaptureStateCodeAdapter(stateCode));
258 }
259 }
260
~ScreenCaptureAdapterImpl()261 ScreenCaptureAdapterImpl::~ScreenCaptureAdapterImpl()
262 {
263 Release();
264 }
265
Init(const std::shared_ptr<ScreenCaptureConfigAdapter> config)266 int32_t ScreenCaptureAdapterImpl::Init(const std::shared_ptr<ScreenCaptureConfigAdapter> config)
267 {
268 if (screenCapture_) {
269 return 0;
270 }
271 screenCapture_ = OHOS::Media::ScreenCaptureFactory::CreateScreenCapture();
272 if (!screenCapture_) {
273 WVLOG_E("CreateScreenCapture create failed");
274 return -1;
275 }
276
277 if (!config) {
278 WVLOG_E("config is null");
279 return -1;
280 }
281
282 int32_t ret = screenCapture_->Init(ConvertScreenCaptureConfig(config));
283 if (ret != Media::MSERR_OK) {
284 WVLOG_E("OH_AVScreenCapture init failed, ret = %{public}d", ret);
285 Release();
286 return -1;
287 }
288 return 0;
289 }
290
Release()291 void ScreenCaptureAdapterImpl::Release()
292 {
293 if (!screenCapture_) {
294 return;
295 }
296 screenCaptureCallback_ = nullptr;
297 int32_t ret = screenCapture_->Release();
298 if (ret != Media::MSERR_OK) {
299 WVLOG_E("OH_AVScreenCapture release failed, ret = %{public}d", ret);
300 }
301 screenCapture_ = nullptr;
302 }
303
SetMicrophoneEnable(bool enable)304 int32_t ScreenCaptureAdapterImpl::SetMicrophoneEnable(bool enable)
305 {
306 if (!screenCapture_) {
307 WVLOG_E("not init");
308 return -1;
309 }
310 int32_t ret = screenCapture_->SetMicrophoneEnabled(enable);
311 if (ret != Media::MSERR_OK) {
312 WVLOG_E("set microphone enabled failed, ret = %{public}d", ret);
313 return -1;
314 }
315 return 0;
316 }
317
StartCapture()318 int32_t ScreenCaptureAdapterImpl::StartCapture()
319 {
320 if (!screenCapture_) {
321 WVLOG_E("not init");
322 return -1;
323 }
324 int32_t ret = screenCapture_->SetPrivacyAuthorityEnabled();
325 if (ret != Media::MSERR_OK) {
326 WVLOG_E("start capture SetPrivacyAuthorityEnabled failed, ret = %{public}d", ret);
327 return -1;
328 }
329 ret = screenCapture_->SetCanvasRotation(true);
330 if (ret != Media::MSERR_OK) {
331 WVLOG_E("start capture SetCanvasRotation failed, ret = %{public}d", ret);
332 }
333 ret = screenCapture_->StartScreenCapture();
334 if (ret != Media::MSERR_OK) {
335 WVLOG_E("start capture failed, ret = %{public}d", ret);
336 return -1;
337 }
338 return 0;
339 }
340
StopCapture()341 int32_t ScreenCaptureAdapterImpl::StopCapture()
342 {
343 if (!screenCapture_) {
344 WVLOG_E("not init");
345 return -1;
346 }
347 int32_t ret = screenCapture_->StopScreenCapture();
348 if (ret != Media::MSERR_OK) {
349 WVLOG_E("stop capture failed, ret = %{public}d", ret);
350 return -1;
351 }
352 return 0;
353 }
354
SetCaptureCallback(const std::shared_ptr<ScreenCaptureCallbackAdapter> callback)355 int32_t ScreenCaptureAdapterImpl::SetCaptureCallback(const std::shared_ptr<ScreenCaptureCallbackAdapter> callback)
356 {
357 if (!screenCapture_ || !callback || screenCaptureCallback_) {
358 WVLOG_E("not init or param error");
359 return -1;
360 }
361 screenCaptureCallback_ = std::make_shared<OHScreenCaptureCallback>(callback);
362 if (!screenCaptureCallback_) {
363 WVLOG_E("make_shared failed");
364 return -1;
365 }
366 int32_t ret = screenCapture_->SetScreenCaptureCallback(screenCaptureCallback_);
367 if (ret != Media::MSERR_OK) {
368 WVLOG_E("set callback failed, ret = %{public}d", ret);
369 screenCaptureCallback_ = nullptr;
370 return -1;
371 }
372 return 0;
373 }
374
AcquireVideoBuffer()375 std::shared_ptr<SurfaceBufferAdapter> ScreenCaptureAdapterImpl::AcquireVideoBuffer()
376 {
377 if (!screenCapture_) {
378 WVLOG_E("not init");
379 return nullptr;
380 }
381 int32_t fence;
382 int64_t timestamp;
383 OHOS::Rect region;
384 sptr<OHOS::SurfaceBuffer> surfaceBuffer = screenCapture_->AcquireVideoBuffer(fence, timestamp, region);
385 if (surfaceBuffer == nullptr) {
386 WVLOG_E("acquire video buffer failed");
387 return nullptr;
388 }
389 auto surfaceBufferImpl = std::make_shared<SurfaceBufferAdapterImpl>(surfaceBuffer);
390 if (!surfaceBufferImpl) {
391 WVLOG_E("make_unique failed");
392 (void)ReleaseVideoBuffer();
393 return nullptr;
394 }
395 return std::move(surfaceBufferImpl);
396 }
397
ReleaseVideoBuffer()398 int32_t ScreenCaptureAdapterImpl::ReleaseVideoBuffer()
399 {
400 if (!screenCapture_) {
401 WVLOG_E("not init");
402 return -1;
403 }
404 int32_t ret = screenCapture_->ReleaseVideoBuffer();
405 if (ret != Media::MSERR_OK) {
406 WVLOG_E("release video buffer failed, ret = %{public}d", ret);
407 return -1;
408 }
409 return 0;
410 }
411 } // namespace OHOS::NWeb
412