#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(); 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; }