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 #include "napi/native_api.h"
16 #include <js_native_api.h>
17 #include <cstring>
18 #include <iostream>
19 #include <multimedia/player_framework/native_avcapability.h>
20 #include <multimedia/player_framework/native_avcodec_videoencoder.h>
21 #include <unistd.h>
22 #include <cstdio>
23 #include <thread>
24 #include <native_buffer/native_buffer.h>
25 #include "hilog/log.h"
26 #include <fcntl.h>
27 #include <map>
28 #include "multimedia/player_framework/native_avscreen_capture.h"
29 #include "multimedia/player_framework/native_avscreen_capture_base.h"
30 #include "multimedia/player_framework/native_avscreen_capture_errors.h"
31 #include "multimedia/player_framework/native_avcapability.h"
32 #include "multimedia/player_framework/native_avcodec_base.h"
33 #include "multimedia/player_framework/native_avformat.h"
34 #include "multimedia/player_framework/native_avbuffer.h"
35 #include <fstream>
36 #include <memory>
37 #include <unistd.h>
38 #include <atomic>
39
40 using namespace std;
41 static int32_t g_recordTimeHalf = 500000;
42 static int32_t g_recordTimeOne = 1000000;
43 static uint64_t g_displaySelectedId = -1;
44
45 OH_AVCodec *g_videoEnc;
46 constexpr uint32_t DEFAULT_WIDTH = 720;
47 constexpr uint32_t DEFAULT_HEIGHT = 1280;
48 constexpr OH_AVPixelFormat DEFAULT_PIXELFORMAT = AV_PIXEL_FORMAT_NV12;
49 static int32_t g_aFlag = 0;
50 static int32_t g_vFlag = 0;
51 const int32_t TEST_PASS = 0;
52 const int32_t TEST_FAILED = 1;
53 static atomic<double> frameNum;
54 static OH_AVScreenCapture *screenCaptureNormal;
55 static struct OH_AVScreenCapture_ContentFilter *g_contentFilter;
56 static OH_AVScreenCapture *screenCaptureRecord;
57 static OH_AVScreenCapture *screenCaptureSurface;
58
SetConfig(OH_AVScreenCaptureConfig & config)59 void SetConfig(OH_AVScreenCaptureConfig &config)
60 {
61 int32_t width = 720;
62 int32_t height = 1280;
63 OH_AudioCaptureInfo micCapInfo = {.audioSampleRate = 48000, .audioChannels = 2, .audioSource = OH_MIC};
64 OH_AudioCaptureInfo innerCapInfo = {.audioSampleRate = 48000, .audioChannels = 2, .audioSource = OH_ALL_PLAYBACK};
65 OH_AudioEncInfo audioEncInfo = {.audioBitrate = 48000, .audioCodecformat = OH_AudioCodecFormat::OH_AAC_LC};
66 OH_AudioInfo audioInfo = {.micCapInfo = micCapInfo, .innerCapInfo = innerCapInfo, .audioEncInfo = audioEncInfo};
67
68 OH_VideoCaptureInfo videoCapInfo = {
69 .videoFrameWidth = width, .videoFrameHeight = height, .videoSource = OH_VIDEO_SOURCE_SURFACE_RGBA};
70 OH_VideoEncInfo videoEncInfo = {
71 .videoCodec = OH_VideoCodecFormat::OH_H264, .videoBitrate = 2000000, .videoFrameRate = 30};
72 OH_VideoInfo videoInfo = {.videoCapInfo = videoCapInfo, .videoEncInfo = videoEncInfo};
73
74 config = {
75 .captureMode = OH_CAPTURE_HOME_SCREEN,
76 .dataType = OH_ORIGINAL_STREAM,
77 .audioInfo = audioInfo,
78 .videoInfo = videoInfo,
79 };
80 }
81
OnError(OH_AVScreenCapture * capture,int32_t errorCode,void * userData)82 void OnError(OH_AVScreenCapture *capture, int32_t errorCode, void *userData)
83 {
84 (void)capture;
85 (void)errorCode;
86 (void)userData;
87 }
88
OnStateChange(struct OH_AVScreenCapture * capture,OH_AVScreenCaptureStateCode stateCode,void * userData)89 void OnStateChange(struct OH_AVScreenCapture *capture, OH_AVScreenCaptureStateCode stateCode, void *userData)
90 {
91 (void)capture;
92 (void)stateCode;
93 (void)userData;
94 }
95
OnDisplaySelected(struct OH_AVScreenCapture * capture,uint64_t displayId,void * userData)96 void OnDisplaySelected(struct OH_AVScreenCapture *capture, uint64_t displayId, void *userData)
97 {
98 (void)capture;
99 (void)displayId;
100 g_displaySelectedId = displayId;
101 (void)userData;
102 }
103
OnBufferAvailable(OH_AVScreenCapture * capture,OH_AVBuffer * buffer,OH_AVScreenCaptureBufferType bufferType,int64_t timestamp,void * userData)104 void OnBufferAvailable(OH_AVScreenCapture *capture, OH_AVBuffer *buffer, OH_AVScreenCaptureBufferType bufferType,
105 int64_t timestamp, void *userData)
106 {
107 if (bufferType == OH_AVScreenCaptureBufferType::OH_SCREEN_CAPTURE_BUFFERTYPE_VIDEO) {
108 frameNum.store(frameNum.load() + 1);
109 }
110 (void)capture;
111 (void)buffer;
112 (void)bufferType;
113 (void)timestamp;
114 (void)userData;
115 }
116
117 // SUB_MULTIMEDIA_SCREEN_CAPTURE_NORMAL_CONFIGURE_0100
NormalAVScreenCaptureTest(napi_env env,napi_callback_info info)118 static napi_value NormalAVScreenCaptureTest(napi_env env, napi_callback_info info)
119 {
120 screenCaptureNormal = OH_AVScreenCapture_Create();
121 OH_AVScreenCaptureConfig config_;
122 SetConfig(config_);
123
124 bool isMicrophone = false;
125 OH_AVScreenCapture_SetMicrophoneEnabled(screenCaptureNormal, isMicrophone);
126 bool isRotation = true;
127 OH_AVScreenCapture_SetCanvasRotation(screenCaptureNormal, isRotation);
128 OH_AVScreenCapture_SetErrorCallback(screenCaptureNormal, OnError, nullptr);
129 OH_AVScreenCapture_SetStateCallback(screenCaptureNormal, OnStateChange, nullptr);
130 OH_AVScreenCapture_SetDataCallback(screenCaptureNormal, OnBufferAvailable, nullptr);
131 vector<int> windowidsExclude = { -111 };
132 g_contentFilter = OH_AVScreenCapture_CreateContentFilter();
133 OH_AVScreenCapture_ContentFilter_AddAudioContent(g_contentFilter, OH_SCREEN_CAPTURE_NOTIFICATION_AUDIO);
134 OH_AVScreenCapture_ContentFilter_AddWindowContent(g_contentFilter,
135 &windowidsExclude[0], static_cast<int32_t>(windowidsExclude.size()));
136 OH_AVScreenCapture_ExcludeContent(screenCaptureNormal, g_contentFilter);
137 OH_AVScreenCapture_SkipPrivacyMode(screenCaptureNormal,
138 &windowidsExclude[0], static_cast<int32_t>(windowidsExclude.size()));
139 OH_AVSCREEN_CAPTURE_ErrCode result1 = OH_AVScreenCapture_Init(screenCaptureNormal, config_);
140 OH_AVSCREEN_CAPTURE_ErrCode result2 = OH_AVScreenCapture_StartScreenCapture(screenCaptureNormal);
141
142 OH_AVSCREEN_CAPTURE_ErrCode result = AV_SCREEN_CAPTURE_ERR_OK;
143 if (result2 == AV_SCREEN_CAPTURE_ERR_OK) {
144 result = AV_SCREEN_CAPTURE_ERR_OK;
145 } else {
146 result = AV_SCREEN_CAPTURE_ERR_OPERATE_NOT_PERMIT;
147 }
148 napi_value res;
149 napi_create_int32(env, result, &res);
150 return res;
151 }
152
153 // SUB_MULTIMEDIA_SCREEN_CAPTURE_NORMAL_CONFIGURE_0100
normalAVScreenCaptureTestStop(napi_env env,napi_callback_info info)154 static napi_value normalAVScreenCaptureTestStop(napi_env env, napi_callback_info info)
155 {
156 usleep(g_recordTimeHalf);
157 int32_t maxFrameRate = 20;
158 double exceedPercentage = 1.2;
159 int32_t width = 768;
160 int32_t height = 1280;
161 OH_AVScreenCapture_ResizeCanvas(screenCaptureNormal, width, height); // 768 width 1280 height
162 OH_AVSCREEN_CAPTURE_ErrCode result1 = OH_AVScreenCapture_SetMaxVideoFrameRate(screenCaptureNormal, maxFrameRate);
163 frameNum.store(0);
164 usleep(g_recordTimeOne);
165 int32_t totalFrameNum = frameNum.load();
166 double averageFrameNum = static_cast<double>(totalFrameNum / (g_recordTimeOne / g_recordTimeOne));
167 OH_AVSCREEN_CAPTURE_ErrCode result2 = OH_AVScreenCapture_StopScreenCapture(screenCaptureNormal);
168 OH_AVScreenCapture_ReleaseContentFilter(g_contentFilter);
169 OH_AVSCREEN_CAPTURE_ErrCode result3 = OH_AVScreenCapture_Release(screenCaptureNormal);
170 int32_t result = TEST_FAILED;
171 if (result3 == AV_SCREEN_CAPTURE_ERR_OK && ((result1 == AV_SCREEN_CAPTURE_ERR_OPERATE_NOT_PERMIT) ||
172 (result1 == AV_SCREEN_CAPTURE_ERR_OK && averageFrameNum < (maxFrameRate * exceedPercentage)))) {
173 result = TEST_PASS;
174 } else {
175 result = TEST_FAILED;
176 }
177 napi_value res;
178 napi_create_int32(env, result, &res);
179 return res;
180 }
181
182 // SUB_MULTIMEDIA_SCREEN_CAPTURE_NORMAL_CONFIGURE_0200
NormalAVScreenRecordTest(napi_env env,napi_callback_info info)183 static napi_value NormalAVScreenRecordTest(napi_env env, napi_callback_info info)
184 {
185 screenCaptureRecord = OH_AVScreenCapture_Create();
186 OH_AVScreenCaptureConfig config_;
187 OH_RecorderInfo recorderInfo;
188 const std::string screenCaptureRoot = "/data/storage/el2/base/files/";
189 int32_t outputFd = open((screenCaptureRoot + "screen01.mp4").c_str(), O_RDWR | O_CREAT, 0777);
190 std::string fileUrl = "fd://" + std::to_string(outputFd);
191 recorderInfo.url = const_cast<char *>(fileUrl.c_str());
192 recorderInfo.fileFormat = OH_ContainerFormatType::CFT_MPEG_4;
193 SetConfig(config_);
194 config_.dataType = OH_CAPTURE_FILE;
195 config_.recorderInfo = recorderInfo;
196
197 bool isMicrophone = false;
198 OH_AVScreenCapture_SetMicrophoneEnabled(screenCaptureRecord, isMicrophone);
199 OH_AVScreenCapture_SetErrorCallback(screenCaptureRecord, OnError, nullptr);
200 OH_AVScreenCapture_SetStateCallback(screenCaptureRecord, OnStateChange, nullptr);
201 OH_AVScreenCapture_SetDataCallback(screenCaptureRecord, OnBufferAvailable, nullptr);
202 OH_AVSCREEN_CAPTURE_ErrCode result1 = OH_AVScreenCapture_Init(screenCaptureRecord, config_);
203 OH_AVSCREEN_CAPTURE_ErrCode result2 = OH_AVScreenCapture_StartScreenRecording(screenCaptureRecord);
204
205 OH_AVSCREEN_CAPTURE_ErrCode result = AV_SCREEN_CAPTURE_ERR_OK;
206 if (result2 == AV_SCREEN_CAPTURE_ERR_OK) {
207 result = AV_SCREEN_CAPTURE_ERR_OK;
208 } else {
209 result = AV_SCREEN_CAPTURE_ERR_OPERATE_NOT_PERMIT;
210 }
211 napi_value res;
212 napi_create_int32(env, result, &res);
213 return res;
214 }
215
216 // SUB_MULTIMEDIA_SCREEN_CAPTURE_NORMAL_CONFIGURE_0200
normalAVScreenRecordTestStop(napi_env env,napi_callback_info info)217 static napi_value normalAVScreenRecordTestStop(napi_env env, napi_callback_info info)
218 {
219 usleep(g_recordTimeOne);
220 OH_AVSCREEN_CAPTURE_ErrCode result1 = OH_AVScreenCapture_StopScreenRecording(screenCaptureRecord);
221 OH_AVSCREEN_CAPTURE_ErrCode result2 = OH_AVScreenCapture_Release(screenCaptureRecord);
222
223 OH_AVSCREEN_CAPTURE_ErrCode result = AV_SCREEN_CAPTURE_ERR_OK;
224 if (result2 == AV_SCREEN_CAPTURE_ERR_OK) {
225 result = AV_SCREEN_CAPTURE_ERR_OK;
226 } else {
227 result = AV_SCREEN_CAPTURE_ERR_OPERATE_NOT_PERMIT;
228 }
229 napi_value res;
230 napi_create_int32(env, result, &res);
231 return res;
232 }
233
234 // SUB_MULTIMEDIA_SCREEN_CAPTURE_NORMAL_SetDisplayCallback_0100
normalAVScreenCaptureDisplayCallbackSuccess(napi_env env,napi_callback_info info)235 static napi_value normalAVScreenCaptureDisplayCallbackSuccess(napi_env env, napi_callback_info info)
236 {
237 g_displaySelectedId = -1;
238 screenCaptureNormal = OH_AVScreenCapture_Create();
239 OH_AVScreenCaptureConfig config_;
240 SetConfig(config_);
241
242 bool isMicrophone = false;
243 OH_AVScreenCapture_SetMicrophoneEnabled(screenCaptureNormal, isMicrophone);
244 bool isRotation = true;
245 OH_AVScreenCapture_SetCanvasRotation(screenCaptureNormal, isRotation);
246 OH_AVScreenCapture_SetErrorCallback(screenCaptureNormal, OnError, nullptr);
247 OH_AVScreenCapture_SetStateCallback(screenCaptureNormal, OnStateChange, nullptr);
248 OH_AVScreenCapture_SetDataCallback(screenCaptureNormal, OnBufferAvailable, nullptr);
249 OH_AVScreenCapture_SetDisplayCallback(screenCaptureNormal, OnDisplaySelected, nullptr);
250 vector<int> windowidsExclude = { -111 };
251 g_contentFilter = OH_AVScreenCapture_CreateContentFilter();
252 OH_AVScreenCapture_ContentFilter_AddAudioContent(g_contentFilter, OH_SCREEN_CAPTURE_NOTIFICATION_AUDIO);
253 OH_AVScreenCapture_ContentFilter_AddWindowContent(g_contentFilter,
254 &windowidsExclude[0], static_cast<int32_t>(windowidsExclude.size()));
255 OH_AVScreenCapture_ExcludeContent(screenCaptureNormal, g_contentFilter);
256 OH_AVScreenCapture_SkipPrivacyMode(screenCaptureNormal,
257 &windowidsExclude[0], static_cast<int32_t>(windowidsExclude.size()));
258 OH_AVSCREEN_CAPTURE_ErrCode result1 = OH_AVScreenCapture_Init(screenCaptureNormal, config_);
259 OH_AVSCREEN_CAPTURE_ErrCode result2 = OH_AVScreenCapture_StartScreenCapture(screenCaptureNormal);
260
261 int32_t result = TEST_FAILED;
262 if (result2 == AV_SCREEN_CAPTURE_ERR_OK) {
263 result = TEST_PASS;
264 }
265 if (result == TEST_PASS) {
266 result = g_displaySelectedId >= 0 ? TEST_PASS : TEST_FAILED;
267 }
268 napi_value res;
269 napi_create_int32(env, result, &res);
270 return res;
271 }
272
273 // SUB_MULTIMEDIA_SCREEN_CAPTURE_NORMAL_SetDisplayCallback_0200
normalAVScreenCaptureSetDisplayCallbackFail(napi_env env,napi_callback_info info)274 static napi_value normalAVScreenCaptureSetDisplayCallbackFail(napi_env env, napi_callback_info info)
275 {
276 g_displaySelectedId = -1;
277 screenCaptureNormal = OH_AVScreenCapture_Create();
278 OH_AVScreenCaptureConfig config_;
279 SetConfig(config_);
280
281 bool isMicrophone = false;
282 OH_AVScreenCapture_SetMicrophoneEnabled(screenCaptureNormal, isMicrophone);
283 bool isRotation = true;
284 OH_AVScreenCapture_SetCanvasRotation(screenCaptureNormal, isRotation);
285 OH_AVScreenCapture_SetErrorCallback(screenCaptureNormal, OnError, nullptr);
286 OH_AVScreenCapture_SetStateCallback(screenCaptureNormal, OnStateChange, nullptr);
287 OH_AVScreenCapture_SetDataCallback(screenCaptureNormal, OnBufferAvailable, nullptr);
288 vector<int> windowidsExclude = { -111 };
289 g_contentFilter = OH_AVScreenCapture_CreateContentFilter();
290 OH_AVScreenCapture_ContentFilter_AddAudioContent(g_contentFilter, OH_SCREEN_CAPTURE_NOTIFICATION_AUDIO);
291 OH_AVScreenCapture_ContentFilter_AddWindowContent(g_contentFilter,
292 &windowidsExclude[0], static_cast<int32_t>(windowidsExclude.size()));
293 OH_AVScreenCapture_ExcludeContent(screenCaptureNormal, g_contentFilter);
294 OH_AVScreenCapture_SkipPrivacyMode(screenCaptureNormal,
295 &windowidsExclude[0], static_cast<int32_t>(windowidsExclude.size()));
296 OH_AVSCREEN_CAPTURE_ErrCode result1 = OH_AVScreenCapture_Init(screenCaptureNormal, config_);
297 OH_AVSCREEN_CAPTURE_ErrCode result2 = OH_AVScreenCapture_StartScreenCapture(screenCaptureNormal);
298
299 OH_AVSCREEN_CAPTURE_ErrCode result = AV_SCREEN_CAPTURE_ERR_OK;
300 if (result2 == AV_SCREEN_CAPTURE_ERR_OK) {
301 result = OH_AVScreenCapture_SetDisplayCallback(screenCaptureNormal, OnDisplaySelected, nullptr);
302 } else {
303 result = AV_SCREEN_CAPTURE_ERR_OPERATE_NOT_PERMIT;
304 }
305 int32_t result3 = TEST_FAILED;
306 if (result == AV_SCREEN_CAPTURE_ERR_INVALID_STATE) {
307 result3 = TEST_PASS;
308 }
309 napi_value res;
310 napi_create_int32(env, result3, &res);
311 return res;
312 }
313
OnError(OH_AVCodec * codec,int32_t errorCode,void * userData)314 void OnError(OH_AVCodec *codec, int32_t errorCode, void *userData)
315 {
316 (void)codec;
317 (void)errorCode;
318 (void)userData;
319 }
320
OnStreamChanged(OH_AVCodec * codec,OH_AVFormat * format,void * userData)321 void OnStreamChanged(OH_AVCodec *codec, OH_AVFormat *format, void *userData)
322 {
323 (void)codec;
324 (void)format;
325 (void)userData;
326 }
327
OnNeedInputBuffer(OH_AVCodec * codec,uint32_t index,OH_AVBuffer * buffer,void * userData)328 void OnNeedInputBuffer(OH_AVCodec *codec, uint32_t index, OH_AVBuffer *buffer, void *userData)
329 {
330 (void)userData;
331 (void)index;
332 (void)buffer;
333 }
334
OnNewOutputBuffer(OH_AVCodec * codec,uint32_t index,OH_AVBuffer * buffer,void * userData)335 void OnNewOutputBuffer(OH_AVCodec *codec, uint32_t index, OH_AVBuffer *buffer, void *userData)
336 {
337 (void)codec;
338 OH_AVCodecBufferAttr info;
339 int32_t ret = OH_AVBuffer_GetBufferAttr(buffer, &info);
340 ret = OH_VideoEncoder_FreeOutputBuffer(codec, index);
341 }
342
343 // SUB_MULTIMEDIA_SCREEN_CAPTURE_NORMAL_CONFIGURE_0300
NormalAVScreenCaptureSurfaceTest(napi_env env,napi_callback_info info)344 static napi_value NormalAVScreenCaptureSurfaceTest(napi_env env, napi_callback_info info)
345 {
346 screenCaptureSurface = OH_AVScreenCapture_Create();
347 OH_AVScreenCaptureConfig config_;
348 SetConfig(config_);
349
350 bool isMicrophone = false;
351 OH_AVScreenCapture_SetMicrophoneEnabled(screenCaptureSurface, isMicrophone);
352 OH_AVScreenCapture_SetErrorCallback(screenCaptureSurface, OnError, nullptr);
353 OH_AVScreenCapture_SetStateCallback(screenCaptureSurface, OnStateChange, nullptr);
354 OH_AVScreenCapture_SetDataCallback(screenCaptureSurface, OnBufferAvailable, nullptr);
355 OH_AVSCREEN_CAPTURE_ErrCode result1 = OH_AVScreenCapture_Init(screenCaptureSurface, config_);
356
357
358 // 获取需要输入的Surface,以进行编码
359 OH_AVCapability *capability = OH_AVCodec_GetCapability(OH_AVCODEC_MIMETYPE_VIDEO_AVC, true);
360 const char *name = OH_AVCapability_GetName(capability);
361 g_videoEnc = OH_VideoEncoder_CreateByName(name);
362 // 配置异步回调,调用 OH_VideoEncoder_SetCallback 接口
363 int32_t ret =
364 OH_VideoEncoder_RegisterCallback(g_videoEnc,
365 {OnError, OnStreamChanged,
366 OnNeedInputBuffer, OnNewOutputBuffer},
367 nullptr);
368 // 配置视频帧速率
369 double frameRate = 30.0;
370 // 配置视频YUV值范围标志
371 bool rangeFlag = false;
372 // 配置视频原色
373 int32_t primary = static_cast<int32_t>(OH_ColorPrimary::COLOR_PRIMARY_BT709);
374 // 配置传输特性
375 int32_t transfer = static_cast<int32_t>(OH_TransferCharacteristic::TRANSFER_CHARACTERISTIC_BT709);
376 // 配置最大矩阵系数
377 int32_t matrix = static_cast<int32_t>(OH_MatrixCoefficient::MATRIX_COEFFICIENT_IDENTITY);
378 // 配置编码Profile
379 int32_t profile = static_cast<int32_t>(OH_AVCProfile::AVC_PROFILE_BASELINE);
380 // 配置编码比特率模式
381 int32_t rateMode = static_cast<int32_t>(OH_VideoEncodeBitrateMode::CBR);
382 // 配置关键帧的间隔,单位为毫秒
383 int32_t iFrameInterval = 23000;
384 // 配置所需的编码质量。只有在恒定质量模式下配置的编码器才支持此配置
385 int32_t quality = 0;
386 // 配置比特率
387 int64_t bitRate = 3000000;
388 OH_AVFormat *format = OH_AVFormat_Create();
389 OH_AVFormat_SetIntValue(format, OH_MD_KEY_WIDTH, DEFAULT_WIDTH);
390 OH_AVFormat_SetIntValue(format, OH_MD_KEY_HEIGHT, DEFAULT_HEIGHT);
391 OH_AVFormat_SetIntValue(format, OH_MD_KEY_PIXEL_FORMAT, DEFAULT_PIXELFORMAT);
392 OH_AVFormat_SetDoubleValue(format, OH_MD_KEY_FRAME_RATE, frameRate);
393 OH_AVFormat_SetIntValue(format, OH_MD_KEY_RANGE_FLAG, rangeFlag);
394 OH_AVFormat_SetIntValue(format, OH_MD_KEY_COLOR_PRIMARIES, primary);
395 OH_AVFormat_SetIntValue(format, OH_MD_KEY_TRANSFER_CHARACTERISTICS, transfer);
396 OH_AVFormat_SetIntValue(format, OH_MD_KEY_MATRIX_COEFFICIENTS, matrix);
397 OH_AVFormat_SetIntValue(format, OH_MD_KEY_I_FRAME_INTERVAL, iFrameInterval);
398 OH_AVFormat_SetIntValue(format, OH_MD_KEY_PROFILE, profile);
399 OH_AVFormat_SetIntValue(format, OH_MD_KEY_VIDEO_ENCODE_BITRATE_MODE, rateMode);
400 OH_AVFormat_SetLongValue(format, OH_MD_KEY_BITRATE, bitRate);
401 int result2 = OH_VideoEncoder_Configure(g_videoEnc, format);
402 OH_AVFormat_Destroy(format);
403
404 // 从视频编码器获取输入Surface
405 OHNativeWindow *nativeWindow;
406 int result3 = OH_VideoEncoder_GetSurface(g_videoEnc, &nativeWindow);
407 if (result3 != AV_ERR_OK) {
408 OH_LOG_INFO(LOG_APP, "==DEMO== ScreenCapture Started OH_VideoEncoder_GetSurface ret=%{public}d", result3);
409 }
410 int result4 = OH_VideoEncoder_Prepare(g_videoEnc);
411 std::string_view outputFilePath = "/data/storage/el2/base/files/DemoSurface.h264";
412 std::unique_ptr<std::ofstream> outputFile = std::make_unique<std::ofstream>();
413 outputFile->open(outputFilePath.data(), std::ios::out | std::ios::binary | std::ios::ate);
414
415 // 启动编码器
416 int32_t retEnc = OH_VideoEncoder_Start(g_videoEnc);
417 // 指定surface开始录屏
418 OH_AVSCREEN_CAPTURE_ErrCode result5 =
419 OH_AVScreenCapture_StartScreenCaptureWithSurface(screenCaptureSurface, nativeWindow);
420
421 OH_AVSCREEN_CAPTURE_ErrCode result = AV_SCREEN_CAPTURE_ERR_OK;
422 if (result5 == AV_SCREEN_CAPTURE_ERR_OK) {
423 result = AV_SCREEN_CAPTURE_ERR_OK;
424 } else {
425 result = AV_SCREEN_CAPTURE_ERR_OPERATE_NOT_PERMIT;
426 }
427 napi_value res;
428 napi_create_int32(env, result, &res);
429 return res;
430 }
431
432 // SUB_MULTIMEDIA_SCREEN_CAPTURE_NORMAL_CONFIGURE_0300
normalAVScreenCaptureSurfaceTestStop(napi_env env,napi_callback_info info)433 static napi_value normalAVScreenCaptureSurfaceTestStop(napi_env env, napi_callback_info info)
434 {
435 usleep(g_recordTimeOne);
436 OH_AVSCREEN_CAPTURE_ErrCode result1 = OH_AVScreenCapture_StopScreenCapture(screenCaptureSurface);
437 OH_AVSCREEN_CAPTURE_ErrCode result2 = OH_AVScreenCapture_Release(screenCaptureSurface);
438
439 OH_AVSCREEN_CAPTURE_ErrCode result = AV_SCREEN_CAPTURE_ERR_OK;
440 if (result2 == AV_SCREEN_CAPTURE_ERR_OK) {
441 result = AV_SCREEN_CAPTURE_ERR_OK;
442 } else {
443 result = AV_SCREEN_CAPTURE_ERR_OPERATE_NOT_PERMIT;
444 }
445 napi_value res;
446 napi_create_int32(env, result, &res);
447 return res;
448 }
449
450 class ScreenCaptureNdkCallBack {
451 public:
452 virtual ~ScreenCaptureNdkCallBack() = default;
453 virtual void OnError(int32_t errorCode) = 0;
454 virtual void OnAudioBufferAvailable(bool isReady, OH_AudioCaptureSourceType type) = 0;
455 virtual void OnVideoBufferAvailable(bool isReady) = 0;
456 };
457
458 class ScreenCaptureNdkTestCallback : public ScreenCaptureNdkCallBack {
459 public:
ScreenCaptureNdkTestCallback(OH_AVScreenCapture * ScreenCapture,FILE * audioFile,FILE * iFile,FILE * videoFile)460 ScreenCaptureNdkTestCallback(OH_AVScreenCapture *ScreenCapture, FILE *audioFile, FILE *iFile, FILE *videoFile)
461 : screenCapture_(ScreenCapture), aFile(audioFile), innerFile(iFile), vFile(videoFile) {}
462 ~ScreenCaptureNdkTestCallback() override;
463 void OnError(int32_t errorCode) override;
464 void OnAudioBufferAvailable(bool isReady, OH_AudioCaptureSourceType type) override;
465 void OnVideoBufferAvailable(bool isReady) override;
466
467 private:
468 OH_AVScreenCapture *screenCapture_;
469 FILE *aFile = nullptr;
470 FILE *innerFile = nullptr;
471 FILE *vFile = nullptr;
472 };
473
~ScreenCaptureNdkTestCallback()474 ScreenCaptureNdkTestCallback::~ScreenCaptureNdkTestCallback()
475 {
476 screenCapture_ = nullptr;
477 aFile = nullptr;
478 innerFile = nullptr;
479 vFile = nullptr;
480 }
481
OnError(int32_t errorCode)482 void ScreenCaptureNdkTestCallback::OnError(int32_t errorCode)
483 {
484 (void) errorCode;
485 }
486
OnAudioBufferAvailable(bool isReady,OH_AudioCaptureSourceType type)487 void ScreenCaptureNdkTestCallback::OnAudioBufferAvailable(bool isReady, OH_AudioCaptureSourceType type)
488 {
489 if (isReady == true) {
490 OH_AudioBuffer *audioBuffer = (OH_AudioBuffer *)malloc(sizeof(OH_AudioBuffer));
491 if (audioBuffer == nullptr) {
492 OH_LOG_INFO(LOG_APP, "audio buffer is nullptr");
493 return;
494 }
495 if (OH_AVScreenCapture_AcquireAudioBuffer(screenCapture_, &audioBuffer, type) == AV_SCREEN_CAPTURE_ERR_OK) {
496 if ((aFile != nullptr) && (audioBuffer->buf != nullptr) && (type == OH_MIC)) {
497 int32_t ret = fwrite(audioBuffer->buf, 1, audioBuffer->size, aFile);
498 free(audioBuffer->buf);
499 audioBuffer->buf = nullptr;
500 } else if ((innerFile != nullptr) && (audioBuffer->buf != nullptr) && (type == OH_ALL_PLAYBACK)) {
501 int32_t ret = fwrite(audioBuffer->buf, 1, audioBuffer->size, innerFile);
502 free(audioBuffer->buf);
503 audioBuffer->buf = nullptr;
504 }
505 free(audioBuffer);
506 audioBuffer = nullptr;
507 }
508 if (g_aFlag == 1) {
509 OH_AVScreenCapture_ReleaseAudioBuffer(screenCapture_, type);
510 }
511 } else {
512 OH_LOG_INFO(LOG_APP, "AcquireAudioBuffer failed");
513 }
514 }
515
OnVideoBufferAvailable(bool isReady)516 void ScreenCaptureNdkTestCallback::OnVideoBufferAvailable(bool isReady)
517 {
518 if (isReady == true) {
519 int32_t fence = 0;
520 int64_t timestamp = 0;
521 int32_t size = 4;
522 OH_Rect damage;
523 OH_NativeBuffer_Config config;
524 OH_NativeBuffer *nativeBuffer =
525 OH_AVScreenCapture_AcquireVideoBuffer(screenCapture_, &fence, ×tamp, &damage);
526 if (nativeBuffer != nullptr) {
527 OH_NativeBuffer_GetConfig(nativeBuffer, &config);
528 int32_t length = config.height * config.width * size;
529
530 OH_NativeBuffer_Unreference(nativeBuffer);
531 if (g_vFlag == 1) {
532 OH_AVScreenCapture_ReleaseVideoBuffer(screenCapture_);
533 }
534 } else {
535 OH_LOG_INFO(LOG_APP, "AcquireVideoBuffer failed");
536 }
537 }
538 }
539
540 std::shared_ptr<ScreenCaptureNdkTestCallback> screenCaptureCb = nullptr;
541 static char g_filename[100] = {0};
542 std::mutex mutex_;
543 std::map<OH_AVScreenCapture *, std::shared_ptr<ScreenCaptureNdkCallBack>> mockCbMap_;
544
OpenAFile(FILE * audioFile,string filename)545 FILE *OpenAFile(FILE *audioFile, string filename)
546 {
547 snprintf(g_filename, sizeof(g_filename), "data/storage/el2/base/files/%s.pcm", filename.c_str());
548 audioFile = fopen(g_filename, "w+");
549 return audioFile;
550 }
551
CloseFile(FILE * audioFile,FILE * videoFile)552 void CloseFile(FILE *audioFile, FILE *videoFile)
553 {
554 if (audioFile != nullptr) {
555 fclose(audioFile);
556 audioFile = nullptr;
557 }
558 if (videoFile != nullptr) {
559 fclose(videoFile);
560 videoFile = nullptr;
561 }
562 }
563
DelCallback(OH_AVScreenCapture * screenCapture)564 void DelCallback(OH_AVScreenCapture *screenCapture)
565 {
566 std::lock_guard<std::mutex> lock(mutex_);
567 if (mockCbMap_.empty()) {
568 return;
569 }
570 auto it = mockCbMap_.find(screenCapture);
571 if (it != mockCbMap_.end()) {
572 mockCbMap_.erase(it);
573 }
574 }
575
GetCallback(OH_AVScreenCapture * screenCapture)576 std::shared_ptr<ScreenCaptureNdkCallBack> GetCallback(OH_AVScreenCapture *screenCapture)
577 {
578 std::lock_guard<std::mutex> lock(mutex_);
579 if (mockCbMap_.empty()) {
580 return nullptr;
581 }
582 if (mockCbMap_.find(screenCapture) != mockCbMap_.end()) {
583 return mockCbMap_.at(screenCapture);
584 }
585 return nullptr;
586 }
587
OnError(OH_AVScreenCapture * screenCapture,int32_t errorCode)588 void OnError(OH_AVScreenCapture *screenCapture, int32_t errorCode)
589 {
590 std::shared_ptr<ScreenCaptureNdkCallBack> mockCb = GetCallback(screenCapture);
591 if (mockCb != nullptr) {
592 mockCb->OnError(errorCode);
593 }
594 }
595
OnAudioBufferAvailable(OH_AVScreenCapture * screenCapture,bool isReady,OH_AudioCaptureSourceType type)596 void OnAudioBufferAvailable(OH_AVScreenCapture *screenCapture, bool isReady, OH_AudioCaptureSourceType type)
597 {
598 std::shared_ptr<ScreenCaptureNdkCallBack> mockCb = GetCallback(screenCapture);
599 if (mockCb != nullptr) {
600 mockCb->OnAudioBufferAvailable(isReady, type);
601 }
602 }
603
OnVideoBufferAvailable(OH_AVScreenCapture * screenCapture,bool isReady)604 void OnVideoBufferAvailable(OH_AVScreenCapture *screenCapture, bool isReady)
605 {
606 std::shared_ptr<ScreenCaptureNdkCallBack> mockCb = GetCallback(screenCapture);
607 if (mockCb != nullptr) {
608 mockCb->OnVideoBufferAvailable(isReady);
609 }
610 }
611
SetScreenCaptureCallback(OH_AVScreenCapture * screenCapture,std::shared_ptr<ScreenCaptureNdkTestCallback> & cb)612 void SetScreenCaptureCallback(OH_AVScreenCapture *screenCapture, std::shared_ptr<ScreenCaptureNdkTestCallback> &cb)
613 {
614 if (cb != nullptr) {
615 std::lock_guard<std::mutex> lock(mutex_);
616 mockCbMap_[screenCapture] = cb;
617 struct OH_AVScreenCaptureCallback callback;
618 callback.onError = OnError;
619 callback.onAudioBufferAvailable = OnAudioBufferAvailable;
620 callback.onVideoBufferAvailable = OnVideoBufferAvailable;
621 OH_AVScreenCapture_SetCallback(screenCapture, callback);
622 }
623 }
624
625 // SUB_MULTIMEDIA_SCREEN_CAPTURE_NORMAL_CONFIGURE_0400
OriginAVScreenCaptureTest(napi_env env,napi_callback_info info)626 static napi_value OriginAVScreenCaptureTest(napi_env env, napi_callback_info info)
627 {
628 FILE *audioFile = nullptr;
629 OH_AVScreenCapture *screenCapture = OH_AVScreenCapture_Create();
630 OH_AVScreenCaptureConfig config_;
631 SetConfig(config_);
632 config_.videoInfo.videoCapInfo.videoSource = OH_VIDEO_SOURCE_SURFACE_RGBA;
633 audioFile = OpenAFile(audioFile, "SUB_MULTIMEDIA_SCREEN_CAPTURE_0004");
634 screenCaptureCb = std::make_shared<ScreenCaptureNdkTestCallback>(screenCapture, audioFile, nullptr, nullptr);
635
636 bool isMicrophone = true;
637 OH_AVScreenCapture_SetMicrophoneEnabled(screenCapture, isMicrophone);
638
639 SetScreenCaptureCallback(screenCapture, screenCaptureCb);
640 OH_AVSCREEN_CAPTURE_ErrCode result1 = OH_AVScreenCapture_Init(screenCapture, config_);
641 OH_AVSCREEN_CAPTURE_ErrCode result2 = OH_AVScreenCapture_StartScreenCapture(screenCapture);
642 OH_AVScreenCapture_StopScreenCapture(screenCapture);
643 DelCallback(screenCapture);
644 OH_AVScreenCapture_Release(screenCapture);
645 CloseFile(audioFile, nullptr);
646 screenCaptureCb = nullptr;
647 napi_value res;
648 OH_AVSCREEN_CAPTURE_ErrCode result;
649 if (result1 == AV_SCREEN_CAPTURE_ERR_OK) {
650 result = AV_SCREEN_CAPTURE_ERR_OK;
651 } else {
652 OH_LOG_INFO(LOG_APP, "init/start/stop failed, init: %d, start: %d", result1, result2);
653 result = AV_SCREEN_CAPTURE_ERR_OPERATE_NOT_PERMIT;
654 }
655 napi_create_int32(env, result, &res);
656 return res;
657 }
658
normalAVScreenCaptureShowCursorTest(napi_env env,napi_callback_info info)659 static napi_value normalAVScreenCaptureShowCursorTest(napi_env env, napi_callback_info info)
660 {
661 screenCaptureNormal = OH_AVScreenCapture_Create();
662 OH_AVScreenCaptureConfig config_;
663 SetConfig(config_);
664
665 bool isMicrophone = false;
666 OH_AVScreenCapture_SetMicrophoneEnabled(screenCaptureNormal, isMicrophone);
667 OH_AVScreenCapture_SetErrorCallback(screenCaptureNormal, OnError, nullptr);
668 OH_AVScreenCapture_SetStateCallback(screenCaptureNormal, OnStateChange, nullptr);
669 OH_AVScreenCapture_SetDataCallback(screenCaptureNormal, OnBufferAvailable, nullptr);
670
671 OH_AVScreenCapture_ShowCursor(screenCaptureNormal, false);
672
673 OH_AVSCREEN_CAPTURE_ErrCode result1 = OH_AVScreenCapture_Init(screenCaptureNormal, config_);
674 OH_AVSCREEN_CAPTURE_ErrCode result2 = OH_AVScreenCapture_StartScreenCapture(screenCaptureNormal);
675
676 OH_AVSCREEN_CAPTURE_ErrCode result = AV_SCREEN_CAPTURE_ERR_OK;
677 if (result2 == AV_SCREEN_CAPTURE_ERR_OK) {
678 result = AV_SCREEN_CAPTURE_ERR_OK;
679 } else {
680 result = AV_SCREEN_CAPTURE_ERR_OPERATE_NOT_PERMIT;
681 }
682 napi_value res;
683 napi_create_int32(env, result, &res);
684 return res;
685 }
686
normalAVScreenCaptureShowCursorTestStop(napi_env env,napi_callback_info info)687 static napi_value normalAVScreenCaptureShowCursorTestStop(napi_env env, napi_callback_info info)
688 {
689 usleep(g_recordTimeOne);
690 OH_AVSCREEN_CAPTURE_ErrCode result1 = OH_AVScreenCapture_StopScreenCapture(screenCaptureNormal);
691 OH_AVSCREEN_CAPTURE_ErrCode result2 = OH_AVScreenCapture_Release(screenCaptureNormal);
692
693 OH_AVSCREEN_CAPTURE_ErrCode result = AV_SCREEN_CAPTURE_ERR_OK;
694 if (result1 == AV_SCREEN_CAPTURE_ERR_OK && result2 == AV_SCREEN_CAPTURE_ERR_OK) {
695 result = AV_SCREEN_CAPTURE_ERR_OK;
696 } else {
697 result = AV_SCREEN_CAPTURE_ERR_OPERATE_NOT_PERMIT;
698 }
699 napi_value res;
700 napi_create_int32(env, result, &res);
701 return res;
702 }
703
normalAVScreenCaptureShowCursorBeforeTestStop(napi_env env,napi_callback_info info)704 static napi_value normalAVScreenCaptureShowCursorBeforeTestStop(napi_env env, napi_callback_info info)
705 {
706 usleep(g_recordTimeOne);
707 OH_AVScreenCapture_ShowCursor(screenCaptureNormal, true);
708 usleep(g_recordTimeOne);
709 OH_AVScreenCapture_ShowCursor(screenCaptureNormal, false);
710
711 OH_AVSCREEN_CAPTURE_ErrCode result1 = OH_AVScreenCapture_StopScreenCapture(screenCaptureNormal);
712 OH_AVSCREEN_CAPTURE_ErrCode result2 = OH_AVScreenCapture_Release(screenCaptureNormal);
713
714 OH_AVSCREEN_CAPTURE_ErrCode result = AV_SCREEN_CAPTURE_ERR_OK;
715 if (result1 == AV_SCREEN_CAPTURE_ERR_OK && result2 == AV_SCREEN_CAPTURE_ERR_OK) {
716 result = AV_SCREEN_CAPTURE_ERR_OK;
717 } else {
718 result = AV_SCREEN_CAPTURE_ERR_OPERATE_NOT_PERMIT;
719 }
720 napi_value res;
721 napi_create_int32(env, result, &res);
722 return res;
723 }
normalAVScreenCaptureShowCursorWithParaNullFalse(napi_env env,napi_callback_info info)724 static napi_value normalAVScreenCaptureShowCursorWithParaNullFalse(napi_env env, napi_callback_info info)
725 {
726 bool isMicrophone = false;
727 screenCaptureNormal = OH_AVScreenCapture_Create();
728 OH_AVSCREEN_CAPTURE_ErrCode result = OH_AVScreenCapture_ShowCursor(nullptr, false);
729 int resCapture = TEST_FAILED;
730 if (result == AV_SCREEN_CAPTURE_ERR_INVALID_VAL) {
731 resCapture = TEST_PASS;
732 }
733 napi_value res;
734 napi_create_int32(env, resCapture, &res);
735 return res;
736 }
737
738
normalAVScreenCaptureShowCursorWithParaNullTrue(napi_env env,napi_callback_info info)739 static napi_value normalAVScreenCaptureShowCursorWithParaNullTrue(napi_env env, napi_callback_info info)
740 {
741 bool isMicrophone = false;
742 screenCaptureNormal = OH_AVScreenCapture_Create();
743 OH_AVSCREEN_CAPTURE_ErrCode result = OH_AVScreenCapture_ShowCursor(nullptr, true);
744 int resCapture = TEST_FAILED;
745 if (result == AV_SCREEN_CAPTURE_ERR_INVALID_VAL) {
746 resCapture = TEST_PASS;
747 }
748 napi_value res;
749 napi_create_int32(env, resCapture, &res);
750 return res;
751 }
752
753 EXTERN_C_START
Init(napi_env env,napi_value exports)754 static napi_value Init(napi_env env, napi_value exports)
755 {
756 napi_property_descriptor desc[] = {
757 {"normalAVScreenCaptureTest", nullptr, NormalAVScreenCaptureTest, nullptr, nullptr, nullptr, napi_default,
758 nullptr},
759 {"normalAVScreenRecordTest", nullptr, NormalAVScreenRecordTest, nullptr, nullptr, nullptr, napi_default,
760 nullptr},
761 {"normalAVScreenCaptureSurfaceTest", nullptr, NormalAVScreenCaptureSurfaceTest, nullptr, nullptr, nullptr,
762 napi_default, nullptr},
763 {"originAVScreenCaptureTest", nullptr, OriginAVScreenCaptureTest, nullptr, nullptr, nullptr,
764 napi_default, nullptr},
765 {"normalAVScreenCaptureTestStop", nullptr, normalAVScreenCaptureTestStop, nullptr, nullptr, nullptr,
766 napi_default, nullptr},
767 {"normalAVScreenRecordTestStop", nullptr, normalAVScreenRecordTestStop, nullptr, nullptr, nullptr,
768 napi_default, nullptr},
769 {"normalAVScreenCaptureSurfaceTestStop", nullptr, normalAVScreenCaptureSurfaceTestStop, nullptr, nullptr,
770 nullptr, napi_default, nullptr},
771 {"normalAVScreenCaptureShowCursorTest", nullptr, normalAVScreenCaptureShowCursorTest, nullptr, nullptr,
772 nullptr, napi_default, nullptr},
773 {"normalAVScreenCaptureShowCursorTestStop", nullptr, normalAVScreenCaptureShowCursorTestStop, nullptr, nullptr,
774 nullptr, napi_default, nullptr},
775 {"normalAVScreenCaptureShowCursorWithParaNullTrue", nullptr, normalAVScreenCaptureShowCursorWithParaNullTrue,
776 nullptr, nullptr, nullptr, napi_default, nullptr},
777 {"normalAVScreenCaptureShowCursorWithParaNullFalse", nullptr, normalAVScreenCaptureShowCursorWithParaNullFalse,
778 nullptr, nullptr, nullptr, napi_default, nullptr},
779 {"normalAVScreenCaptureShowCursorBeforeTestStop", nullptr, normalAVScreenCaptureShowCursorBeforeTestStop,
780 nullptr, nullptr, nullptr, napi_default, nullptr},
781 {"normalAVScreenCaptureSetDisplayCallbackFail", nullptr, normalAVScreenCaptureSetDisplayCallbackFail,
782 nullptr, nullptr, nullptr, napi_default, nullptr},
783 {"normalAVScreenCaptureDisplayCallbackSuccess", nullptr, normalAVScreenCaptureDisplayCallbackSuccess,
784 nullptr, nullptr, nullptr, napi_default, nullptr},
785 };
786 napi_define_properties(env, exports, sizeof(desc) / sizeof(desc[0]), desc);
787 return exports;
788 }
789
790 EXTERN_C_END
791
792 static napi_module demoModule = {
793 .nm_version = 1,
794 .nm_flags = 0,
795 .nm_filename = nullptr,
796 .nm_register_func = Init,
797 .nm_modname = "nativeAVScreenCapturendk",
798 .nm_priv = ((void *)0),
799 .reserved = {0},
800 };
801
RegisterEntryModule(void)802 extern "C" __attribute__((constructor)) void RegisterEntryModule(void) { napi_module_register(&demoModule); }
803