summaryrefslogtreecommitdiffstats
path: root/player
diff options
context:
space:
mode:
authorwm4 <wm4@nowhere>2015-04-20 23:11:03 +0200
committerwm4 <wm4@nowhere>2015-04-20 23:11:03 +0200
commita3680d1b2d137461008d38486cdb2d5013291e61 (patch)
treee3bafaac8a13edf57ff3456333a26fd057ac0790 /player
parentccfe4d64184ae4c2983ae6b099c7c7ebb3770d0f (diff)
downloadmpv-a3680d1b2d137461008d38486cdb2d5013291e61.tar.bz2
mpv-a3680d1b2d137461008d38486cdb2d5013291e61.tar.xz
client API: add a screenshot_raw command
Requested. The wild code for setting up the mpv_node probably deserves to be cleaned up later. Fixes #1800.
Diffstat (limited to 'player')
-rw-r--r--player/command.c39
-rw-r--r--player/screenshot.c10
-rw-r--r--player/screenshot.h3
3 files changed, 52 insertions, 0 deletions
diff --git a/player/command.c b/player/command.c
index 376f2b6bed..d210398946 100644
--- a/player/command.c
+++ b/player/command.c
@@ -4040,6 +4040,22 @@ static bool check_property_autorepeat(char *property, struct MPContext *mpctx)
return true;
}
+static struct mpv_node *add_map_entry(struct mpv_node *dst, const char *key)
+{
+ struct mpv_node_list *list = dst->u.list;
+ assert(dst->format == MPV_FORMAT_NODE_MAP && dst->u.list);
+ MP_TARRAY_GROW(list, list->values, list->num);
+ MP_TARRAY_GROW(list, list->keys, list->num);
+ list->keys[list->num] = talloc_strdup(list, key);
+ return &list->values[list->num++];
+}
+
+#define ADD_MAP_INT(dst, name, i) (*add_map_entry(dst, name) = \
+ (struct mpv_node){ .format = MPV_FORMAT_INT64, .u.int64 = (i) });
+
+#define ADD_MAP_CSTR(dst, name, s) (*add_map_entry(dst, name) = \
+ (struct mpv_node){ .format = MPV_FORMAT_STRING, .u.string = (s) });
+
int run_command(struct MPContext *mpctx, struct mp_cmd *cmd, struct mpv_node *res)
{
struct command_ctx *cmdctx = mpctx->command_ctx;
@@ -4552,6 +4568,29 @@ int run_command(struct MPContext *mpctx, struct mp_cmd *cmd, struct mpv_node *re
screenshot_to_file(mpctx, cmd->args[0].v.s, cmd->args[1].v.i, msg_osd);
break;
+ case MP_CMD_SCREENSHOT_RAW: {
+ if (!res)
+ return -1;
+ struct mp_image *img = screenshot_get_rgb(mpctx, cmd->args[0].v.i);
+ if (!img)
+ return -1;
+ struct mpv_node_list *info = talloc_zero(NULL, struct mpv_node_list);
+ talloc_steal(info, img);
+ *res = (mpv_node){ .format = MPV_FORMAT_NODE_MAP, .u.list = info };
+ ADD_MAP_INT(res, "w", img->w);
+ ADD_MAP_INT(res, "h", img->h);
+ ADD_MAP_INT(res, "stride", img->stride[0]);
+ ADD_MAP_CSTR(res, "format", "bgr0");
+ struct mpv_byte_array *ba = talloc_ptrtype(info, ba);
+ *ba = (struct mpv_byte_array){
+ .data = img->planes[0],
+ .size = img->stride[0] * img->h,
+ };
+ *add_map_entry(res, "data") =
+ (struct mpv_node){.format = MPV_FORMAT_BYTE_ARRAY, .u.ba = ba,};
+ break;
+ }
+
case MP_CMD_RUN: {
char *args[MP_CMD_MAX_ARGS + 1] = {0};
for (int n = 0; n < cmd->nargs; n++)
diff --git a/player/screenshot.c b/player/screenshot.c
index f722b9561f..a47de292d5 100644
--- a/player/screenshot.c
+++ b/player/screenshot.c
@@ -357,6 +357,16 @@ static struct mp_image *screenshot_get(struct MPContext *mpctx, int mode)
return image;
}
+struct mp_image *screenshot_get_rgb(struct MPContext *mpctx, int mode)
+{
+ struct mp_image *mpi = screenshot_get(mpctx, mode);
+ if (!mpi)
+ return NULL;
+ struct mp_image *res = convert_image(mpi, IMGFMT_BGR0, mpctx->log);
+ talloc_free(mpi);
+ return res;
+}
+
void screenshot_to_file(struct MPContext *mpctx, const char *filename, int mode,
bool osd)
{
diff --git a/player/screenshot.h b/player/screenshot.h
index 84b7ef4f58..9ebe9ef76e 100644
--- a/player/screenshot.h
+++ b/player/screenshot.h
@@ -39,6 +39,9 @@ void screenshot_request(struct MPContext *mpctx, int mode, bool each_frame,
void screenshot_to_file(struct MPContext *mpctx, const char *filename, int mode,
bool osd);
+// mode is the same as in screenshot_request()
+struct mp_image *screenshot_get_rgb(struct MPContext *mpctx, int mode);
+
// Called by the playback core code when a new frame is displayed.
void screenshot_flip(struct MPContext *mpctx);