summaryrefslogtreecommitdiffstats
path: root/core
diff options
context:
space:
mode:
authorwm4 <wm4@nowhere>2012-11-04 18:39:32 +0100
committerwm4 <wm4@nowhere>2013-01-13 20:04:10 +0100
commit6e0b7300447c4f8f82bc5467870a00d7c4f2095f (patch)
tree30d8751dd4ff414214f08d8fee3e62af56923a9d /core
parentb7cacf9165290067b66b160b108790b89c080a3e (diff)
downloadmpv-6e0b7300447c4f8f82bc5467870a00d7c4f2095f.tar.bz2
mpv-6e0b7300447c4f8f82bc5467870a00d7c4f2095f.tar.xz
vf_screenshot: simplify
Instead of using a callback to "capture" the image next time the filter function is called, do it the other way around: on every filter invocation, create a reference to the image, and return it if a screenshot is requested. This also fixes the 1-frame delay when taking screenshots with the filter. This also allows simplifying screenshot.c.
Diffstat (limited to 'core')
-rw-r--r--core/screenshot.c71
1 files changed, 19 insertions, 52 deletions
diff --git a/core/screenshot.c b/core/screenshot.c
index 8e16771289..0f397f2dd7 100644
--- a/core/screenshot.c
+++ b/core/screenshot.c
@@ -48,7 +48,6 @@ typedef struct screenshot_ctx {
int mode;
int each_frame;
- int using_vf_screenshot;
int frameno;
} screenshot_ctx;
@@ -234,16 +233,9 @@ static char *gen_fname(screenshot_ctx *ctx, const char *file_ext)
}
}
-static struct mp_image *add_subs(struct MPContext *mpctx,
- struct mp_image *image)
+static void add_subs(struct MPContext *mpctx, struct mp_image *image)
{
- if (!(image->flags & MP_IMGFLAG_ALLOCATED)) {
- struct mp_image *new_image = alloc_mpi(image->w, image->h,
- image->imgfmt);
- copy_mpi(new_image, image);
- vf_clone_mpi_attributes(new_image, image);
- image = new_image;
- }
+ mp_image_make_writeable(image);
int d_w = image->display_w ? image->display_w : image->w;
int d_h = image->display_h ? image->display_h : image->h;
@@ -259,8 +251,6 @@ static struct mp_image *add_subs(struct MPContext *mpctx,
osd_draw_on_image(mpctx->osd, res, mpctx->osd->vo_pts,
OSD_DRAW_SUB_ONLY, image);
-
- return image;
}
static void screenshot_save(struct MPContext *mpctx, struct mp_image *image,
@@ -270,31 +260,18 @@ static void screenshot_save(struct MPContext *mpctx, struct mp_image *image,
struct image_writer_opts *opts = mpctx->opts.screenshot_image_opts;
- struct mp_image *new_image = image;
if (with_subs)
- new_image = add_subs(mpctx, new_image);
+ add_subs(mpctx, image);
char *filename = gen_fname(ctx, image_writer_file_ext(opts));
if (filename) {
mp_msg(MSGT_CPLAYER, MSGL_INFO, "*** screenshot '%s' ***\n", filename);
- if (!write_image(new_image, opts, filename))
+ if (!write_image(image, opts, filename))
mp_msg(MSGT_CPLAYER, MSGL_ERR, "\nError writing screenshot!\n");
talloc_free(filename);
}
- if (new_image != image)
- free_mp_image(new_image);
-}
-
-static void vf_screenshot_callback(void *pctx, struct mp_image *image)
-{
- struct MPContext *mpctx = (struct MPContext *)pctx;
- screenshot_ctx *ctx = mpctx->screenshot_ctx;
- screenshot_save(mpctx, image, ctx->mode == MODE_SUBTITLES);
- if (ctx->each_frame) {
- ctx->each_frame = false;
- screenshot_request(mpctx, ctx->mode, true);
- }
+ talloc_free(image);
}
static bool force_vf(struct MPContext *mpctx)
@@ -315,7 +292,6 @@ void screenshot_request(struct MPContext *mpctx, int mode, bool each_frame)
if (mpctx->video_out && mpctx->video_out->config_ok) {
screenshot_ctx *ctx = mpctx->screenshot_ctx;
- ctx->using_vf_screenshot = 0;
if (mode == MODE_SUBTITLES && mpctx->osd->render_subs_in_filter)
mode = 0;
@@ -332,26 +308,24 @@ void screenshot_request(struct MPContext *mpctx, int mode, bool each_frame)
struct voctrl_screenshot_args args =
{ .full_window = (mode == MODE_FULL_WINDOW) };
- if (!force_vf(mpctx)
- && vo_control(mpctx->video_out, VOCTRL_SCREENSHOT, &args) == true)
- {
+
+ if (!force_vf(mpctx))
+ vo_control(mpctx->video_out, VOCTRL_SCREENSHOT, &args);
+
+ if (!args.out_image) {
+ mp_msg(MSGT_CPLAYER, MSGL_INFO, "No VO support for taking"
+ " screenshots, trying VFCTRL_SCREENSHOT!\n");
+ struct vf_instance *vfilter = mpctx->sh_video->vfilter;
+ vfilter->control(vfilter, VFCTRL_SCREENSHOT, &args);
+ }
+
+ if (args.out_image) {
if (args.has_osd)
mode = 0;
screenshot_save(mpctx, args.out_image, mode == MODE_SUBTITLES);
- free_mp_image(args.out_image);
} else {
- mp_msg(MSGT_CPLAYER, MSGL_INFO, "No VO support for taking"
- " screenshots, trying VFCTRL_SCREENSHOT!\n");
- ctx->using_vf_screenshot = 1;
- struct vf_ctrl_screenshot cmd = {
- .image_callback = vf_screenshot_callback,
- .image_callback_ctx = mpctx,
- };
- struct vf_instance *vfilter = mpctx->sh_video->vfilter;
- if (vfilter->control(vfilter, VFCTRL_SCREENSHOT, &cmd) !=
- CONTROL_OK)
- mp_msg(MSGT_CPLAYER, MSGL_INFO,
- "...failed (need --vf=screenshot?)\n");
+ mp_msg(MSGT_CPLAYER, MSGL_INFO,
+ "...failed (need --vf=screenshot?)\n");
}
}
}
@@ -363,13 +337,6 @@ void screenshot_flip(struct MPContext *mpctx)
if (!ctx->each_frame)
return;
- // screenshot_flip is called when the VO presents a new frame. vf_screenshot
- // can behave completely different (consider filters inserted between
- // vf_screenshot and vf_vo, that add or remove frames), so handle this case
- // somewhere else.
- if (ctx->using_vf_screenshot)
- return;
-
ctx->each_frame = false;
screenshot_request(mpctx, ctx->mode, true);
}