mirror of
https://github.com/mpv-player/mpv
synced 2025-03-31 07:51:55 +00:00
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.
This commit is contained in:
parent
9ba52ea6ef
commit
738aeb1c60
@ -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;
|
||||
|
@ -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);
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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);
|
||||
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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] };
|
||||
|
10
screenshot.c
10
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);
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user