172 lines
6.1 KiB
C++
172 lines
6.1 KiB
C++
#define LOG_NDEBUG 0
|
|
#define LOG_TAG "ScreenCaptureTest"
|
|
#include "Log.h"
|
|
#include "ScreenCapture.h"
|
|
#define DUMP_BASEDIR "/data"
|
|
#define PORTTYPE_VALUE_VIDEO_ONLY_main_screen 0x11000000 //main screen
|
|
#define PORTTYPE_VALUE_VIDEO_OSD_main_screen 0x11000001 //main screen
|
|
#define PORTTYPE_VALUE_VIDEO_ONLY_second_screen 0x11000002 //second screen
|
|
#define PORTTYPE_VALUE_VIDEO_OSD_second_screen 0x11000003 //second screen
|
|
|
|
|
|
static int saveBufferAsFile(void *buffer, size_t size, char *file)
|
|
{
|
|
int fd = open(file, O_CREAT|O_RDWR, 0666);
|
|
int wrSize = 0;
|
|
int ret = 0;
|
|
|
|
if (fd < 0) {
|
|
return fd;
|
|
}
|
|
|
|
do {
|
|
int ret = write (fd, (char *)buffer + wrSize, size - wrSize);
|
|
if (ret > 0) {
|
|
wrSize += ret;
|
|
} else {
|
|
break;
|
|
}
|
|
} while (wrSize < size);
|
|
close(fd);
|
|
return ret;
|
|
}
|
|
|
|
|
|
static void checkAndSaveBufferToFile(const char *baseFile, char *filename, void *buffer, size_t size)
|
|
{
|
|
if (0 == access(baseFile, F_OK)) {
|
|
if (saveBufferAsFile(buffer, size, filename) >= 0) {
|
|
printf("Save file ok: %s", filename);
|
|
} else {
|
|
printf("Save file fail: %s!", filename);
|
|
}
|
|
}
|
|
}
|
|
|
|
static void print_usage(void)
|
|
{
|
|
printf ("Usage: screenrecorder\n");
|
|
printf ("Options:\n\n");
|
|
printf ("--help : display this help and exit\n");
|
|
printf ("--width : you can set 3840 or 1920\n");
|
|
printf ("--height : you can set 2160 or 1080\n");
|
|
printf ("--framerate : you can set 30 or less than 30\n");
|
|
printf ("--format : you can set 1:nv21 2:nv12 \n");
|
|
printf ("--layer : you can set 0:main screen video only 1:main screen video+osd 2:second screen video only 3:second screen video+osd\n");
|
|
printf ("command sample: ./screenrecoder --width 1920 --height 1080 --framerate 30 --format 2 --layer 1\n");
|
|
printf ("\n");
|
|
}
|
|
|
|
static ScreenCapture_Params* parse_command_line(int argc, char *argv[], ScreenCapture_Params *params)
|
|
{
|
|
int i;
|
|
|
|
/* Set the default parameters */
|
|
params->width = 1920;
|
|
params->height = 1080;
|
|
params->framerate = 30;
|
|
params->data_type = SCREENCONTROL_FMT_NV12;
|
|
params->port_type = PORTTYPE_VALUE_VIDEO_ONLY_main_screen;
|
|
|
|
/* Parse command line */
|
|
for (i = 1; i < argc; i++) {
|
|
if (strncmp (argv[i], "--", 2) == 0) {
|
|
if (strcmp (argv[i] + 2, "help") == 0) {
|
|
print_usage();
|
|
return nullptr;
|
|
}
|
|
else if (strcmp (argv[i] + 2, "width") == 0 && ++i < argc) {
|
|
if (sscanf (argv[i], "%d", ¶ms->width) != 1 || (params->width != 1920 && params->width != 3840)) {
|
|
printf("Invalid width: %d. Allowed values are 1920 or 3840.\n", params->width);
|
|
return nullptr;
|
|
}
|
|
}
|
|
else if (strcmp (argv[i] + 2, "height") == 0 && ++i < argc) {
|
|
if (sscanf (argv[i], "%d", ¶ms->height) != 1 || (params->height != 1080 && params->height != 2160)) {
|
|
printf("Invalid height: %d. Allowed values are 1080 or 2160.\n", params->height);
|
|
return nullptr;
|
|
}
|
|
}
|
|
else if (strcmp (argv[i] + 2, "framerate") == 0 && ++i < argc) {
|
|
if (sscanf (argv[i], "%d", ¶ms->framerate) != 1 || params->framerate > 30 || params->framerate <= 0) {
|
|
printf("Invalid framerate: %d. Framerate must be 30 or less.\n", params->framerate);
|
|
return nullptr;
|
|
}
|
|
}
|
|
else if (strcmp (argv[i] + 2, "format") == 0 && ++i < argc) {
|
|
if (sscanf (argv[i], "%d", ¶ms->data_type) != 1 || (params->data_type != 1 && params->data_type != 2)) {
|
|
printf("Invalid format: %d. Allowed values are 1 (nv21) or 2 (nv12).\n", params->data_type);
|
|
return nullptr;
|
|
}
|
|
}
|
|
else if (strcmp (argv[i] + 2, "layer") == 0 && ++i < argc) {
|
|
if (sscanf (argv[i], "%d", ¶ms->port_type) != 1 || params->port_type < 0 || params->port_type > 3) {
|
|
printf("Invalid layer: %d. Allowed values are 0, 1, 2, or 3.\n", params->port_type);
|
|
return nullptr;
|
|
}
|
|
switch (params->port_type) {
|
|
case 0:
|
|
params->port_type = PORTTYPE_VALUE_VIDEO_ONLY_main_screen;
|
|
break;
|
|
case 1:
|
|
params->port_type = PORTTYPE_VALUE_VIDEO_OSD_main_screen;
|
|
break;
|
|
case 2:
|
|
params->port_type = PORTTYPE_VALUE_VIDEO_ONLY_second_screen;
|
|
break;
|
|
case 3:
|
|
params->port_type = PORTTYPE_VALUE_VIDEO_OSD_second_screen;
|
|
break;
|
|
}
|
|
} else {
|
|
printf("Unknown option: %s\n", argv[i]);
|
|
print_usage();
|
|
return nullptr;
|
|
}
|
|
}
|
|
}
|
|
|
|
return params;
|
|
}
|
|
|
|
int main(int argc, char **argv) {
|
|
int count = 0;
|
|
ScreenCapture_Params params = {0};
|
|
if (parse_command_line(argc, argv, ¶ms) == nullptr) {
|
|
printf ("parse_command_line fail\n");
|
|
return 0;
|
|
}
|
|
int size = params.width * params.height * 3/2;
|
|
auto capture = std::make_unique<ScreenCapture>();
|
|
bool ret = capture->init(¶ms);
|
|
if (!ret) {
|
|
printf ("capture->init() fail\n");
|
|
return 0;
|
|
}
|
|
ret = capture->start();
|
|
if (!ret) {
|
|
printf ("capture->start() fail\n");
|
|
return 0;
|
|
}
|
|
char *buffer = (char *)malloc(size);
|
|
while (1) {
|
|
memset(buffer,0,size);
|
|
ret = capture->readBuffer(buffer);
|
|
if (!ret) {
|
|
usleep(100);
|
|
continue;
|
|
}
|
|
count++;
|
|
char filename[64] = {0};
|
|
const char *dump_path = DUMP_BASEDIR;
|
|
snprintf(filename, 64, "%s/screen-capture-%d.yuv", dump_path, count);
|
|
checkAndSaveBufferToFile(dump_path, filename, buffer, size);
|
|
if (count >= 5)
|
|
break;
|
|
}
|
|
free(buffer);
|
|
capture->stop();
|
|
return 0;
|
|
}
|
|
|