• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 }