From 738aeb1c60c6ffe95e915e443598f8a51081bdfb Mon Sep 17 00:00:00 2001 From: wm4 Date: Fri, 26 Oct 2012 19:29:47 +0200 Subject: screenshot: let VOs pass colorspace information via mp_image This removes the hack that screenshot_save() got the colorspace information from the decoder. Instead, require the VOs to set the colorspace information on the mp_images used to pass around the screenshot data. This is more correct, as the image may have been converted/modified in the video filter chain, although there's nothing yet in the video filter chain which does this correctly. --- image_writer.c | 6 +++--- image_writer.h | 4 ++-- libmpcodecs/vf_screenshot.c | 1 + libvo/vo_corevideo.m | 2 ++ libvo/vo_direct3d.c | 2 ++ libvo/vo_image.c | 3 ++- libvo/vo_opengl.c | 2 ++ libvo/vo_opengl_old.c | 2 ++ libvo/vo_vdpau.c | 2 ++ screenshot.c | 10 +--------- 10 files changed, 19 insertions(+), 15 deletions(-) diff --git a/image_writer.c b/image_writer.c index 82afeb0e48..f449b5c617 100644 --- a/image_writer.c +++ b/image_writer.c @@ -41,7 +41,6 @@ #include "libmpcodecs/sws_utils.h" #include "libmpcodecs/vf.h" -#include "libvo/csputils.h" #include "m_option.h" @@ -260,8 +259,8 @@ const char *image_writer_file_ext(const struct image_writer_opts *opts) return get_writer(opts)->file_ext; } -int write_image(struct mp_image *image, const struct mp_csp_details *csp, - const struct image_writer_opts *opts, const char *filename) +int write_image(struct mp_image *image, const struct image_writer_opts *opts, + const char *filename) { struct mp_image *allocated_image = NULL; struct image_writer_opts defs = image_writer_opts_defaults; @@ -286,6 +285,7 @@ int write_image(struct mp_image *image, const struct mp_csp_details *csp, // Caveat: - no colorspace/levels conversion done if pixel formats equal // - RGB->YUV assumes BT.601 + // - color levels broken in various ways thanks to libswscale if (image->imgfmt != destfmt || is_anamorphic) { struct mp_image hack = *image; hack.w = hack.width; diff --git a/image_writer.h b/image_writer.h index 9df1d88583..f92c2f800d 100644 --- a/image_writer.h +++ b/image_writer.h @@ -46,5 +46,5 @@ const char *image_writer_file_ext(const struct image_writer_opts *opts); * accordingly. Setting w and width or h and height to different values * can be used to store snapshots of anamorphic video. */ -int write_image(struct mp_image *image, const struct mp_csp_details *csp, - const struct image_writer_opts *opts, const char *filename); +int write_image(struct mp_image *image, const struct image_writer_opts *opts, + const char *filename); diff --git a/libmpcodecs/vf_screenshot.c b/libmpcodecs/vf_screenshot.c index 013525694a..604aab7835 100644 --- a/libmpcodecs/vf_screenshot.c +++ b/libmpcodecs/vf_screenshot.c @@ -143,6 +143,7 @@ static int put_image(struct vf_instance *vf, mp_image_t *mpi, double pts) image = *vf->priv->image; image.w = vf->priv->image->w; image.h = vf->priv->image->h; + vf_clone_mpi_attributes(&image, mpi); vf->priv->image_callback(vf->priv->image_callback_ctx, &image); vf->priv->store_slices = 0; } diff --git a/libvo/vo_corevideo.m b/libvo/vo_corevideo.m index c05863145c..0fd8510f39 100644 --- a/libvo/vo_corevideo.m +++ b/libvo/vo_corevideo.m @@ -381,6 +381,8 @@ static mp_image_t *get_screenshot(struct vo *vo) image->w = vo->aspdat.prew; image->h = vo->aspdat.preh; + mp_image_set_colorspace_details(image, &p->colorspace); + return image; } diff --git a/libvo/vo_direct3d.c b/libvo/vo_direct3d.c index 2fa71d0d70..773cd5fb76 100644 --- a/libvo/vo_direct3d.c +++ b/libvo/vo_direct3d.c @@ -1804,6 +1804,8 @@ static mp_image_t *get_screenshot(d3d_priv *priv) image->w = priv->vo->aspdat.prew; image->h = priv->vo->aspdat.preh; + mp_image_set_colorspace_details(image, &priv->colorspace); + return image; } diff --git a/libvo/vo_image.c b/libvo/vo_image.c index b00ee1af8f..7f80a16f35 100644 --- a/libvo/vo_image.c +++ b/libvo/vo_image.c @@ -104,6 +104,7 @@ static uint32_t draw_image(struct vo *vo, mp_image_t *mpi) mp_image_t img = *mpi; img.width = p->d_width; img.height = p->d_height; + mp_image_set_colorspace_details(&img, &p->colorspace); void *t = talloc_new(NULL); char *filename = talloc_asprintf(t, "%08d.%s", p->frame, @@ -113,7 +114,7 @@ static uint32_t draw_image(struct vo *vo, mp_image_t *mpi) filename = mp_path_join(t, bstr0(p->outdir), bstr0(filename)); mp_msg(MSGT_VO, MSGL_STATUS, "\nSaving %s\n", filename); - write_image(&img, &p->colorspace, p->opts, filename); + write_image(&img, p->opts, filename); talloc_free(t); diff --git a/libvo/vo_opengl.c b/libvo/vo_opengl.c index 92a280f49b..cc7b7bde40 100644 --- a/libvo/vo_opengl.c +++ b/libvo/vo_opengl.c @@ -1400,6 +1400,8 @@ static mp_image_t *get_screenshot(struct gl_priv *p) image->w = p->vo->aspdat.prew; image->h = p->vo->aspdat.preh; + mp_image_set_colorspace_details(image, &p->colorspace); + return image; } diff --git a/libvo/vo_opengl_old.c b/libvo/vo_opengl_old.c index f9262e417d..4823576290 100644 --- a/libvo/vo_opengl_old.c +++ b/libvo/vo_opengl_old.c @@ -828,6 +828,8 @@ static mp_image_t *get_screenshot(struct vo *vo) image->w = vo->aspdat.prew; image->h = vo->aspdat.preh; + mp_image_set_colorspace_details(image, &p->colorspace); + return image; } diff --git a/libvo/vo_vdpau.c b/libvo/vo_vdpau.c index ba0e0993a2..3f5b7bc660 100644 --- a/libvo/vo_vdpau.c +++ b/libvo/vo_vdpau.c @@ -1365,6 +1365,8 @@ static struct mp_image *read_output_surface(struct vdpctx *vc, VdpStatus vdp_st; struct vdp_functions *vdp = vc->vdp; struct mp_image *image = alloc_mpi(width, height, IMGFMT_BGR32); + image->colorspace = MP_CSP_RGB; + image->levels = vc->colorspace.levels_out; // hardcoded with conv. matrix void *dst_planes[] = { image->planes[0] }; uint32_t dst_pitches[] = { image->stride[0] }; diff --git a/screenshot.c b/screenshot.c index e34fd6da15..f69bba9b76 100644 --- a/screenshot.c +++ b/screenshot.c @@ -270,14 +270,6 @@ static void screenshot_save(struct MPContext *mpctx, struct mp_image *image, { screenshot_ctx *ctx = mpctx->screenshot_ctx; - struct mp_csp_details colorspace; - get_detected_video_colorspace(mpctx->sh_video, &colorspace); - // This is a property of the output device; images always use - // full-range RGB. - colorspace.levels_out = MP_CSP_LEVELS_PC; - // This is a bad hack, until the VOs set image->colorspace correctly - mp_image_set_colorspace_details(image, &colorspace); - struct image_writer_opts *opts = mpctx->opts.screenshot_image_opts; struct mp_image *new_image = image; @@ -287,7 +279,7 @@ static void screenshot_save(struct MPContext *mpctx, struct mp_image *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, &colorspace, opts, filename)) + if (!write_image(new_image, opts, filename)) mp_msg(MSGT_CPLAYER, MSGL_ERR, "\nError writing screenshot!\n"); talloc_free(filename); } -- cgit v1.2.3