• 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 #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, &timestamp, &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