+++ /dev/null
-#include <unistd.h>
-#include <Eina.h>
-#include <Ecore.h>
-#include <streamrecorder.h>
-#include <wayland-client.h>
-#include "e_info_client_screen_recorder.h"
-
-int _log_dom = -1;
-
-#define CRT(...) EINA_LOG_DOM_CRIT(_log_dom, __VA_ARGS__)
-#define ERR(...) EINA_LOG_DOM_ERR(_log_dom, __VA_ARGS__)
-#define WRN(...) EINA_LOG_DOM_WARN(_log_dom, __VA_ARGS__)
-#define INF(...) EINA_LOG_DOM_INFO(_log_dom, __VA_ARGS__)
-#define DBG(...) EINA_LOG_DOM_DBG(_log_dom, __VA_ARGS__)
-
-typedef struct
-{
- int w, h;
-} Screen_Recorder_Size;
-
-typedef struct
-{
- char filename[PATH_MAX];
- int framerate;
- Screen_Recorder_Size resolution;
-} Screen_Recorder_Args;
-
-streamrecorder_h _stream_recorder;
-
-static Eina_Bool _screen_recorder_efl_init(void);
-static void _screen_recorder_efl_shutdown(void);
-static Eina_Bool _screen_recorder_output_size_get(Screen_Recorder_Size *out);
-static Eina_Bool _screen_recorder_parse_args(int argc, char **argv, Screen_Recorder_Args *args);
-static Eina_Bool _stream_recorder_run(const char *filename, int framerate, int w, int h);
-
-static void
-_usage(void)
-{
- fprintf(stderr, SCREEN_RECORDER_USAGE);
-}
-
-static Eina_Bool
-_screen_recorder_cb_handle_stdin(void *data, Ecore_Fd_Handler *handler EINA_UNUSED)
-{
- Screen_Recorder_Args *args = data;
- char c;
- int ret;
-
- ret = scanf("%c", &c);
- if (ret < 1)
- return ECORE_CALLBACK_RENEW;
-
- streamrecorder_commit(_stream_recorder);
- streamrecorder_destroy(_stream_recorder);
- _stream_recorder = NULL;
-
- fprintf(stdout, "Finish recording screen: %s\n", args->filename);
-
- ecore_main_loop_quit();
-
- return ECORE_CALLBACK_RENEW;
-}
-
-int
-e_info_client_screen_recorder_run(int argc, char **argv)
-{
- Screen_Recorder_Args args =
- { {0, }, /* filename */
- 60, /* framerate */
- {360, 360} /* widthxheight resolution */
- };
- Eina_Bool res;
- char *val;
-
- EINA_SAFETY_ON_FALSE_RETURN_VAL(_screen_recorder_efl_init(), -1);
-
- val = getenv("XDG_RUNTIME_DIR");
- if (!val)
- {
- WRN("Not found \"XDG_RUNTIME_DIR\", Set \"/run\" on its value "
- "for run screen recording anyway.");
- setenv("XDG_RUNTIME_DIR", "/run", 1);
- }
-
- if (!_screen_recorder_output_size_get(&args.resolution))
- {
- WRN("failed to get output size, use default size (%dx%d)",
- args.resolution.w, args.resolution.h);
- }
-
- res = _screen_recorder_parse_args(argc, argv, &args);
- if (!res)
- {
- _usage();
- goto end;
- }
-
- res = _stream_recorder_run(args.filename,
- args.framerate,
- args.resolution.w,
- args.resolution.h);
- if (!res)
- {
- ERR("Could not initialize the streamrecorder");
- goto end;
- }
-
- fprintf(stdout, "Press any key to finish recording");
- fflush(stdout);
-
- ecore_main_fd_handler_add(STDIN_FILENO, ECORE_FD_READ,
- _screen_recorder_cb_handle_stdin,
- &args, NULL, NULL);
-
- ecore_main_loop_begin();
-
-end:
- _screen_recorder_efl_shutdown();
-
- return (res == EINA_TRUE) ? 0 : -1;
-}
-
-static Eina_Bool
-_screen_recorder_efl_init(void)
-{
- EINA_SAFETY_ON_FALSE_RETURN_VAL(eina_init(), EINA_FALSE);
-
- _log_dom = eina_log_domain_register("screen_recorder", NULL);
- if (_log_dom < 0)
- {
- EINA_LOG_CRIT("Could not create logging domain '%s'.", "screen_recorder");
- goto fail_log_dom;
- }
-
- EINA_SAFETY_ON_FALSE_GOTO(ecore_init(), fail_ecore);
-
- DBG("Done efl init");
-
- return EINA_TRUE;
-
-fail_ecore:
- eina_log_domain_unregister(_log_dom);
- _log_dom = -1;
-fail_log_dom:
- eina_shutdown();
-
- return EINA_FALSE;
-}
-
-static void
-_screen_recorder_efl_shutdown(void)
-{
- ecore_shutdown();
- eina_log_domain_unregister(_log_dom);
- _log_dom = -1;
- eina_shutdown();
-}
-
-static Eina_Bool
-_screen_recorder_fullpath_make_with_ext(char out[PATH_MAX], const char *filename)
-{
- char fullname[PATH_MAX] = {0,};
- char *dot;
- const char *ext = ".mp4";
- const char *prefix = "e-screen-record";
- const char *default_path = "/tmp";
- int len_l, len;
-
- len_l = PATH_MAX;
- if (filename)
- {
- if (filename[0] != '/')
- len = snprintf(fullname, len_l, "%s/%s", default_path, filename);
- else
- len = snprintf(fullname, len_l, "%s", filename);
-
- len_l -= len;
- if (len_l <= 0)
- {
- ERR("file name is too long");
- return EINA_FALSE;
- }
-
- dot = strrchr(fullname, '.');
- len = strlen(ext);
- if ((!dot) ||
- (strlen(dot) != len) ||
- (strncmp(dot, ext, len) != 0))
- {
- /* concatenate file extention. */
- if (len_l < (len + 1))
- {
- ERR("file name is too long");
- return EINA_FALSE;
- }
-
- strncat(fullname, ext, len);
- }
-
- strncpy(out, fullname, PATH_MAX);
- }
- else
- {
- time_t timer;
- struct tm *t, buf;
-
- timer = time(NULL);
- t = localtime_r(&timer, &buf);
- if (!t)
- return EINA_FALSE;
-
- len = snprintf(fullname, len_l, "%s/%s-%04d%02d%02d.%02d%02d%02d",
- default_path, prefix,
- t->tm_year+1900, t->tm_mon+1, t->tm_mday, t->tm_hour,
- t->tm_min, t->tm_sec);
- len_l -= len;
-
- len = strlen(ext);
- if ((len + 1) > len_l)
- fullname[PATH_MAX - (len + 1)] = '\0';
-
- strncat(fullname, ext, len);
- strncpy(out, fullname, PATH_MAX);
- }
-
- return EINA_TRUE;
-}
-
-static Eina_Bool
-_screen_recorder_parse_args(int argc, char **argv, Screen_Recorder_Args *args)
-{
- char *filename = NULL;
- int i;
- Eina_Bool res;
-
- DBG("Begin Parse Arguments");
-
- for (i = 0; i < argc; i++)
- {
- if (strcmp(argv[i], "-dump_video") == 0)
- continue;
- else if ((strcmp(argv[i], "--help") == 0) || (strcmp(argv[i], "-h") == 0))
- return EINA_FALSE;
- else if (sscanf(argv[i], "--rate=%d", &args->framerate) == 1)
- {
- if (args->framerate < 1)
- {
- fprintf(stderr, "ERROR: invalid framerate, "
- "it should be greater than 0: %d\n",
- args->framerate);
- return EINA_FALSE;
- }
- }
- else if (sscanf(argv[i], "--resolution=%dx%d", &args->resolution.w, &args->resolution.h) == 2)
- {
- if ((args->resolution.w < 1) || (args->resolution.h < 1))
- {
- fprintf(stderr, "ERROR: invalid resolution, "
- "resolution value should be greater than 0: %dx%d\n",
- args->resolution.w, args->resolution.h);
- return EINA_FALSE;
- }
- }
- else if ((strcmp(argv[i], "--") == 0) || (argv[i][0] == '-'))
- {
- fprintf(stderr, "ERROR: unkown parameter, %s\n", argv[i]);
- return EINA_FALSE;
- }
- else if (i == (argc - 1))
- filename = argv[i];
- }
-
- res = _screen_recorder_fullpath_make_with_ext(args->filename, filename);
- if (!res)
- {
- ERR("invalid file path: %s", args->filename);
- return EINA_FALSE;
- }
-
- DBG("Done Parse Arguments");
- INF("Arguments: framerate(%d) resolution(%dx%d) filename(%s)",
- args->framerate, args->resolution.w, args->resolution.h, args->filename);
-
- return EINA_TRUE;
-}
-
-static void
-_cb_stream_recorder_status(unsigned long long elapsed_time, unsigned long long file_size, void *user_data)
-{
- DBG("Recording Status: time(%.5f s) size(%lld KB)",
- (double)elapsed_time / (double)1000, file_size);
-}
-
-static Eina_Bool
-_stream_recorder_run(const char *filename, int framerate, int w, int h)
-{
- streamrecorder_state_e state;
- int err;
-
- DBG("Begin Initializing Streamrecorder");
-
- err = streamrecorder_create(&_stream_recorder);
- if (err != STREAMRECORDER_ERROR_NONE)
- {
- ERR("failed to create streamrecorder: %d", err);
- return EINA_FALSE;
- }
-
- err = streamrecorder_get_state(_stream_recorder, &state);
- if (err == STREAMRECORDER_ERROR_NONE)
- {
- if (state == STREAMRECORDER_STATE_CREATED)
- INF("StreamRecorder State: 'Created'");
- else
- INF("StreamRecorder State: %d", state);
- }
-
- err = streamrecorder_set_video_resolution(_stream_recorder, w, h);
- if (err != STREAMRECORDER_ERROR_NONE)
- {
- ERR("failed to set video resolution: %dx%d", w, h);
- goto fail;
- }
-
- err = streamrecorder_set_video_framerate(_stream_recorder, framerate);
- if (err != STREAMRECORDER_ERROR_NONE)
- {
- ERR("failed to set video framerate: %d", 30);
- goto fail;
- }
-
- err = streamrecorder_set_filename(_stream_recorder, filename);
- if (err != STREAMRECORDER_ERROR_NONE)
- {
- ERR("failed to set filename for streamrecorder: %s", filename);
- goto fail;
- }
-
- err = streamrecorder_set_mode(_stream_recorder,
- STREAMRECORDER_MODE_DEVICE_LOOPBACK);
- if (err != STREAMRECORDER_ERROR_NONE)
- {
- ERR("failed to set mode of streamrecorder: %d", err);
- goto fail;
- }
-
- err = streamrecorder_set_recording_status_cb(_stream_recorder,
- _cb_stream_recorder_status,
- NULL);
- if (err != STREAMRECORDER_ERROR_NONE)
- {
- ERR("failed to set callback for recording status");
- goto fail;
- }
-
- err = streamrecorder_prepare(_stream_recorder);
- if (err != STREAMRECORDER_ERROR_NONE)
- {
- ERR("failed to prepare streamrecorder: %d", err);
- goto fail;
- }
-
- err = streamrecorder_start(_stream_recorder);
- if (err != STREAMRECORDER_ERROR_NONE)
- {
- ERR("failed to start streamrecorder");
- goto fail;
- }
-
- DBG("Done Initializing Streamrecorder");
-
- return EINA_TRUE;
-fail:
- streamrecorder_destroy(_stream_recorder);
- _stream_recorder = NULL;
-
- return EINA_FALSE;
-}
-
-static void
-_screen_recorder_cb_wl_registry_global(void *data, struct wl_registry *registry, uint32_t id, const char *interface, uint32_t version)
-{
- struct wl_output **output;
-
- if (strcmp(interface, "wl_output") != 0)
- return;
-
-
- output = (struct wl_output **)data;
- *output = wl_registry_bind(registry, id, &wl_output_interface, version);
-}
-
-static void
-_screen_recorder_cb_wl_registry_global_remove(void *data EINA_UNUSED, struct wl_registry *registry EINA_UNUSED, uint32_t name EINA_UNUSED)
-{
-}
-
-static const struct wl_registry_listener _registry_listener =
-{
- _screen_recorder_cb_wl_registry_global,
- _screen_recorder_cb_wl_registry_global_remove,
-};
-
-static void
-_screen_recorder_cb_wl_output_geometry(void *data EINA_UNUSED, struct wl_output *output EINA_UNUSED, int32_t x EINA_UNUSED, int32_t y EINA_UNUSED, int32_t pw EINA_UNUSED, int32_t ph EINA_UNUSED, int32_t subpixel EINA_UNUSED, const char *make EINA_UNUSED, const char *model EINA_UNUSED, int32_t transform EINA_UNUSED)
-{
-}
-
-static void
-_screen_recorder_cb_wl_output_mode(void *data, struct wl_output *output EINA_UNUSED, unsigned int flags, int w, int h, int refresh EINA_UNUSED)
-{
- Screen_Recorder_Size *size;
-
- if (!(flags & WL_OUTPUT_MODE_CURRENT))
- return;
-
- INF("wl_output.mode: (%dx%d)", w, h);
- size = data;
- size->w = w;
- size->h = h;
-}
-
-static void
-_screen_recorder_cb_wl_output_done(void *data EINA_UNUSED, struct wl_output *output EINA_UNUSED)
-{
-}
-
-static void
-_screen_recorder_cb_wl_output_scale(void *data EINA_UNUSED, struct wl_output *output EINA_UNUSED, int32_t factor EINA_UNUSED)
-{
-}
-
-static const struct wl_output_listener _output_listener =
-{
- _screen_recorder_cb_wl_output_geometry,
- _screen_recorder_cb_wl_output_mode,
- _screen_recorder_cb_wl_output_done,
- _screen_recorder_cb_wl_output_scale,
-};
-
-static Eina_Bool
-_screen_recorder_output_size_get(Screen_Recorder_Size *out)
-{
- struct wl_display *display;
- struct wl_registry *registry;
- struct wl_output *output = NULL;
- Screen_Recorder_Size size = {0, };
- Eina_Bool ret = EINA_FALSE;
-
- display = wl_display_connect(NULL);
- if (!display)
- {
- ERR("failed to connect wl_display");
- return ret;
- }
-
- registry = wl_display_get_registry(display);
- if (!registry)
- {
- ERR("failed to get wl_registry");
- goto err_reg;
- }
-
- wl_registry_add_listener(registry, &_registry_listener, &output);
- wl_display_roundtrip(display);
-
- if (!output)
- {
- ERR("failed to bind wl_output");
- goto err_output;
- }
-
- wl_output_add_listener(output, &_output_listener, &size);
- wl_display_roundtrip(display);
-
- ret = (size.w != 0);
- if (ret)
- {
- out->w = size.w;
- out->h = size.h;
- }
-
- wl_output_destroy(output);
-err_output:
- wl_registry_destroy(registry);
-err_reg:
- wl_display_disconnect(display);
-
- return ret;
-}