summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorwm4 <wm4@nowhere>2012-10-27 18:06:09 +0200
committerwm4 <wm4@nowhere>2012-11-01 02:07:45 +0100
commit9ba52ea6efd41db9dbd08311380f7fa633e22aa2 (patch)
tree698757630c88e96f323bc66461045234505ace91
parentd9839fe8623c855b6b335df3a5b9783e3ed22266 (diff)
downloadmpv-9ba52ea6efd41db9dbd08311380f7fa633e22aa2.tar.bz2
mpv-9ba52ea6efd41db9dbd08311380f7fa633e22aa2.tar.xz
screenshot, draw_bmp: use colorspace passed with mp_image
Remove the explicit struct mp_csp_details parameters from all related functions, and use mp_image.colorspace/levels instead.
-rw-r--r--image_writer.c32
-rw-r--r--libmpcodecs/sws_utils.c67
-rw-r--r--libmpcodecs/sws_utils.h4
-rw-r--r--libmpcodecs/vf_sub.c7
-rw-r--r--libvo/vo_lavc.c5
-rw-r--r--libvo/vo_x11.c4
-rw-r--r--libvo/vo_xv.c9
-rw-r--r--screenshot.c13
-rw-r--r--sub/draw_bmp.c73
-rw-r--r--sub/draw_bmp.h2
-rw-r--r--sub/sub.c9
-rw-r--r--sub/sub.h4
12 files changed, 137 insertions, 92 deletions
diff --git a/image_writer.c b/image_writer.c
index f4851a9176..82afeb0e48 100644
--- a/image_writer.c
+++ b/image_writer.c
@@ -39,8 +39,8 @@
#include "libmpcodecs/vf.h"
#include "fmt-conversion.h"
-//for sws_getContextFromCmdLine_hq and mp_sws_set_colorspace
#include "libmpcodecs/sws_utils.h"
+#include "libmpcodecs/vf.h"
#include "libvo/csputils.h"
#include "m_option.h"
@@ -284,28 +284,20 @@ 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
if (image->imgfmt != destfmt || is_anamorphic) {
+ struct mp_image hack = *image;
+ hack.w = hack.width;
+ hack.h = hack.height;
+
struct mp_image *dst = alloc_mpi(image->w, image->h, destfmt);
+ vf_clone_mpi_attributes(dst, image);
+
+ int flags = SWS_LANCZOS | SWS_FULL_CHR_H_INT | SWS_FULL_CHR_H_INP |
+ SWS_ACCURATE_RND | SWS_BITEXACT;
- struct SwsContext *sws = sws_getContextFromCmdLine_hq(image->width,
- image->height,
- image->imgfmt,
- dst->width,
- dst->height,
- dst->imgfmt);
-
- struct mp_csp_details colorspace = MP_CSP_DETAILS_DEFAULTS;
- if (csp)
- colorspace = *csp;
- // This is a property of the output device; images always use
- // full-range RGB.
- colorspace.levels_out = MP_CSP_LEVELS_PC;
- mp_sws_set_colorspace(sws, &colorspace);
-
- sws_scale(sws, (const uint8_t **)image->planes, image->stride, 0,
- image->height, dst->planes, dst->stride);
-
- sws_freeContext(sws);
+ mp_image_swscale(dst, &hack, flags);
allocated_image = dst;
image = dst;
diff --git a/libmpcodecs/sws_utils.c b/libmpcodecs/sws_utils.c
index d7500efe2e..4fc5639e55 100644
--- a/libmpcodecs/sws_utils.c
+++ b/libmpcodecs/sws_utils.c
@@ -18,6 +18,8 @@
#include <assert.h>
+#include <libavutil/opt.h>
+
#include "libmpcodecs/sws_utils.h"
#include "libmpcodecs/mp_image.h"
@@ -139,27 +141,58 @@ bool mp_sws_supported_format(int imgfmt)
&& sws_isSupportedOutput(av_format);
}
-void mp_image_swscale(struct mp_image *dst,
- const struct mp_image *src,
- struct mp_csp_details *csp,
+static int mp_csp_to_sws_colorspace(enum mp_csp csp)
+{
+ switch (csp) {
+ case MP_CSP_BT_601: return SWS_CS_ITU601;
+ case MP_CSP_BT_709: return SWS_CS_ITU709;
+ case MP_CSP_SMPTE_240M: return SWS_CS_SMPTE240M;
+ default: return SWS_CS_DEFAULT;
+ }
+}
+
+void mp_image_swscale(struct mp_image *dst, struct mp_image *src,
int my_sws_flags)
{
- enum PixelFormat dfmt, sfmt;
- dfmt = imgfmt2pixfmt(dst->imgfmt);
- sfmt = imgfmt2pixfmt(src->imgfmt);
+ enum PixelFormat s_fmt = imgfmt2pixfmt(src->imgfmt);
if (src->imgfmt == IMGFMT_RGB8 || src->imgfmt == IMGFMT_BGR8)
- sfmt = PIX_FMT_PAL8;
+ s_fmt = PIX_FMT_PAL8;
+ int s_csp = mp_csp_to_sws_colorspace(mp_image_csp(src));
+ int s_range = mp_image_levels(src) == MP_CSP_LEVELS_PC;
+
+ enum PixelFormat d_fmt = imgfmt2pixfmt(dst->imgfmt);
+ int d_csp = mp_csp_to_sws_colorspace(mp_image_csp(dst));
+ int d_range = mp_image_levels(dst) == MP_CSP_LEVELS_PC;
+
+ // Work around libswscale bug #1852 (fixed in ffmpeg commit 8edf9b1fa):
+ // setting range flags for RGB gives random bogus results.
+ // Newer libswscale always ignores range flags for RGB.
+ bool s_yuv = src->flags & MP_IMGFLAG_YUV;
+ bool d_yuv = dst->flags & MP_IMGFLAG_YUV;
+ s_range = s_range && s_yuv;
+ d_range = d_range && d_yuv;
+
+ struct SwsContext *sws = sws_alloc_context();
+
+ av_opt_set_int(sws, "sws_flags", my_sws_flags, 0);
+
+ av_opt_set_int(sws, "srcw", src->w, 0);
+ av_opt_set_int(sws, "srch", src->h, 0);
+ av_opt_set_int(sws, "src_format", s_fmt, 0);
+
+ av_opt_set_int(sws, "dstw", dst->w, 0);
+ av_opt_set_int(sws, "dsth", dst->h, 0);
+ av_opt_set_int(sws, "dst_format", d_fmt, 0);
+
+ sws_setColorspaceDetails(sws, sws_getCoefficients(s_csp), s_range,
+ sws_getCoefficients(d_csp), d_range,
+ 0, 1 << 16, 1 << 16);
+
+ int res = sws_init_context(sws, NULL, NULL);
+ assert(res >= 0);
- struct SwsContext *sws =
- sws_getContext(src->w, src->h, sfmt, dst->w, dst->h, dfmt,
- my_sws_flags, NULL, NULL, NULL);
- struct mp_csp_details mycsp = MP_CSP_DETAILS_DEFAULTS;
- if (csp)
- mycsp = *csp;
- mp_sws_set_colorspace(sws, &mycsp);
- sws_scale(sws, (const unsigned char *const *) src->planes, src->stride,
- 0, src->h,
- dst->planes, dst->stride);
+ sws_scale(sws, (const uint8_t *const *) src->planes, src->stride,
+ 0, src->h, dst->planes, dst->stride);
sws_freeContext(sws);
}
diff --git a/libmpcodecs/sws_utils.h b/libmpcodecs/sws_utils.h
index 70b7d0b7fb..a0cc47d850 100644
--- a/libmpcodecs/sws_utils.h
+++ b/libmpcodecs/sws_utils.h
@@ -25,9 +25,7 @@ int mp_sws_set_colorspace(struct SwsContext *sws, struct mp_csp_details *csp);
bool mp_sws_supported_format(int imgfmt);
-void mp_image_swscale(struct mp_image *dst,
- const struct mp_image *src,
- struct mp_csp_details *csp,
+void mp_image_swscale(struct mp_image *dst, struct mp_image *src,
int my_sws_flags);
#endif /* MP_SWS_UTILS_H */
diff --git a/libmpcodecs/vf_sub.c b/libmpcodecs/vf_sub.c
index 78f75221cb..2d5de3a7ba 100644
--- a/libmpcodecs/vf_sub.c
+++ b/libmpcodecs/vf_sub.c
@@ -221,11 +221,10 @@ static int put_image(struct vf_instance *vf, mp_image_t *mpi, double pts)
struct osd_state *osd = priv->osd;
prepare_image(vf, mpi);
+ mp_image_set_colorspace_details(mpi, &priv->csp);
- if (pts != MP_NOPTS_VALUE) {
- osd_draw_on_image(osd, priv->dim, pts, OSD_DRAW_SUB_FILTER, vf->dmpi,
- &priv->csp);
- }
+ if (pts != MP_NOPTS_VALUE)
+ osd_draw_on_image(osd, priv->dim, pts, OSD_DRAW_SUB_FILTER, vf->dmpi);
return vf_next_put_image(vf, vf->dmpi, pts);
}
diff --git a/libvo/vo_lavc.c b/libvo/vo_lavc.c
index 6c9a3906d0..96bf32521b 100644
--- a/libvo/vo_lavc.c
+++ b/libvo/vo_lavc.c
@@ -501,8 +501,9 @@ static void draw_osd(struct vo *vo, struct osd_state *osd)
.video_par = dar / sar,
};
- osd_draw_on_image(osd, dim, osd->vo_pts, OSD_DRAW_SUB_ONLY, vc->lastimg,
- &vc->colorspace);
+ mp_image_set_colorspace_details(vc->lastimg, &vc->colorspace);
+
+ osd_draw_on_image(osd, dim, osd->vo_pts, OSD_DRAW_SUB_ONLY, vc->lastimg);
}
}
diff --git a/libvo/vo_x11.c b/libvo/vo_x11.c
index 587730a89a..24bc98ba7d 100644
--- a/libvo/vo_x11.c
+++ b/libvo/vo_x11.c
@@ -440,8 +440,6 @@ static void draw_osd(struct vo *vo, struct osd_state *osd)
struct mp_image img = get_x_buffer(p);
- struct mp_csp_details csp = MP_CSP_DETAILS_DEFAULTS;
-
struct mp_osd_res res = {
.w = img.w,
.h = img.h,
@@ -449,7 +447,7 @@ static void draw_osd(struct vo *vo, struct osd_state *osd)
.video_par = vo->aspdat.par,
};
- osd_draw_on_image(osd, res, osd->vo_pts, 0, &img, &csp);
+ osd_draw_on_image(osd, res, osd->vo_pts, 0, &img);
}
static void flip_page(struct vo *vo)
diff --git a/libvo/vo_xv.c b/libvo/vo_xv.c
index 390c1753b6..82469e491f 100644
--- a/libvo/vo_xv.c
+++ b/libvo/vo_xv.c
@@ -309,6 +309,10 @@ static struct mp_image get_xv_buffer(struct vo *vo, int buf_index)
img.stride[n] = xv_image->pitches[sn];
}
+ struct mp_csp_details csp = {0};
+ vo_control(vo, VOCTRL_GET_YUV_COLORSPACE, &csp);
+ mp_image_set_colorspace_details(&img, &csp);
+
return img;
}
@@ -336,9 +340,6 @@ static void draw_osd(struct vo *vo, struct osd_state *osd)
struct mp_image img = get_xv_buffer(vo, ctx->current_buf);
- struct mp_csp_details csp = {0};
- vo_control(vo, VOCTRL_GET_YUV_COLORSPACE, &csp);
-
struct vo_rect *src = &ctx->src_rect;
struct vo_rect *dst = &ctx->dst_rect;
double xvpar = (double)dst->width / dst->height * src->height / src->width;
@@ -350,7 +351,7 @@ static void draw_osd(struct vo *vo, struct osd_state *osd)
.video_par = vo->aspdat.par,
};
- if (osd_draw_on_image(osd, res, osd->vo_pts, 0, &img, &csp))
+ if (osd_draw_on_image(osd, res, osd->vo_pts, 0, &img))
ctx->unchanged_image = false;
}
diff --git a/screenshot.c b/screenshot.c
index c1709fb9b5..e34fd6da15 100644
--- a/screenshot.c
+++ b/screenshot.c
@@ -235,13 +235,13 @@ static char *gen_fname(screenshot_ctx *ctx, const char *file_ext)
}
static struct mp_image *add_subs(struct MPContext *mpctx,
- struct mp_image *image,
- struct mp_csp_details *csp)
+ struct mp_image *image)
{
if (!(image->flags & MP_IMGFLAG_ALLOCATED)) {
struct mp_image *new_image = alloc_mpi(image->width, image->height,
image->imgfmt);
copy_mpi(new_image, image);
+ vf_clone_mpi_attributes(new_image, image);
new_image->w = image->w;
new_image->h = image->h;
image = new_image;
@@ -260,7 +260,7 @@ static struct mp_image *add_subs(struct MPContext *mpctx,
hack.w = hack.width;
hack.h = hack.height;
osd_draw_on_image(mpctx->osd, res, mpctx->osd->vo_pts,
- OSD_DRAW_SUB_ONLY, &hack, csp);
+ OSD_DRAW_SUB_ONLY, &hack);
return image;
}
@@ -272,12 +272,17 @@ static void screenshot_save(struct MPContext *mpctx, struct mp_image *image,
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;
if (with_subs)
- new_image = add_subs(mpctx, new_image, &colorspace);
+ new_image = add_subs(mpctx, new_image);
char *filename = gen_fname(ctx, image_writer_file_ext(opts));
if (filename) {
diff --git a/sub/draw_bmp.c b/sub/draw_bmp.c
index 5f68e17f1d..e693afe137 100644
--- a/sub/draw_bmp.c
+++ b/sub/draw_bmp.c
@@ -43,6 +43,9 @@ struct sub_cache {
struct part {
int bitmap_pos_id;
+ int imgfmt;
+ enum mp_csp colorspace;
+ enum mp_csp_levels levels;
int num_imgs;
struct sub_cache *imgs;
};
@@ -53,7 +56,7 @@ struct mp_draw_sub_cache
};
static struct part *get_cache(struct mp_draw_sub_cache **cache,
- struct sub_bitmaps *sbs);
+ struct sub_bitmaps *sbs, struct mp_image *format);
static bool get_sub_area(struct mp_rect bb, struct mp_image *temp,
struct sub_bitmap *sb, struct mp_image *out_area,
int *out_src_x, int *out_src_y);
@@ -206,22 +209,24 @@ static void unpremultiply_and_split_BGR32(struct mp_image *img,
}
}
-static void scale_sb_rgba(struct sub_bitmap *sb, struct mp_csp_details *csp,
- int imgfmt, struct mp_image **out_sbi,
- struct mp_image **out_sba)
+// dst_format merely contains the target colorspace/format information
+static void scale_sb_rgba(struct sub_bitmap *sb, struct mp_image *dst_format,
+ struct mp_image **out_sbi, struct mp_image **out_sba)
{
struct mp_image *sbisrc = new_mp_image(sb->w, sb->h);
mp_image_setfmt(sbisrc, IMGFMT_BGR32);
sbisrc->planes[0] = sb->bitmap;
sbisrc->stride[0] = sb->stride;
struct mp_image *sbisrc2 = alloc_mpi(sb->dw, sb->dh, IMGFMT_BGR32);
- mp_image_swscale(sbisrc2, sbisrc, csp, SWS_BILINEAR);
+ mp_image_swscale(sbisrc2, sbisrc, SWS_BILINEAR);
struct mp_image *sba = alloc_mpi(sb->dw, sb->dh, IMGFMT_Y8);
unpremultiply_and_split_BGR32(sbisrc2, sba);
- struct mp_image *sbi = alloc_mpi(sb->dw, sb->dh, imgfmt);
- mp_image_swscale(sbi, sbisrc2, csp, SWS_BILINEAR);
+ struct mp_image *sbi = alloc_mpi(sb->dw, sb->dh, dst_format->imgfmt);
+ sbi->colorspace = dst_format->colorspace;
+ sbi->levels = dst_format->levels;
+ mp_image_swscale(sbi, sbisrc2, SWS_BILINEAR);
free_mp_image(sbisrc);
free_mp_image(sbisrc2);
@@ -231,10 +236,10 @@ static void scale_sb_rgba(struct sub_bitmap *sb, struct mp_csp_details *csp,
}
static void draw_rgba(struct mp_draw_sub_cache **cache, struct mp_rect bb,
- struct mp_image *temp, int bits, struct mp_csp_details *csp,
+ struct mp_image *temp, int bits,
struct sub_bitmaps *sbs)
{
- struct part *part = get_cache(cache, sbs);
+ struct part *part = get_cache(cache, sbs, temp);
for (int i = 0; i < sbs->num_parts; ++i) {
struct sub_bitmap *sb = &sbs->parts[i];
@@ -257,7 +262,7 @@ static void draw_rgba(struct mp_draw_sub_cache **cache, struct mp_rect bb,
}
if (!(sbi && sba))
- scale_sb_rgba(sb, csp, temp->imgfmt, &sbi, &sba);
+ scale_sb_rgba(sb, temp, &sbi, &sba);
int bytes = (bits + 7) / 8;
uint8_t *alpha_p = sba->planes[0] + src_y * sba->stride[0] + src_x;
@@ -278,11 +283,12 @@ static void draw_rgba(struct mp_draw_sub_cache **cache, struct mp_rect bb,
}
static void draw_ass(struct mp_draw_sub_cache **cache, struct mp_rect bb,
- struct mp_image *temp, int bits, struct mp_csp_details *csp,
- struct sub_bitmaps *sbs)
+ struct mp_image *temp, int bits, struct sub_bitmaps *sbs)
{
struct mp_csp_params cspar = MP_CSP_PARAMS_DEFAULTS;
- cspar.colorspace = *csp;
+ cspar.colorspace.format = temp->colorspace;
+ cspar.colorspace.levels_in = temp->levels;
+ cspar.colorspace.levels_out = MP_CSP_LEVELS_PC; // RGB (libass.color)
cspar.int_bits_in = bits;
cspar.int_bits_out = 8;
@@ -416,7 +422,7 @@ static void get_closest_y444_format(int imgfmt, int *out_format, int *out_bits)
}
static struct part *get_cache(struct mp_draw_sub_cache **cache,
- struct sub_bitmaps *sbs)
+ struct sub_bitmaps *sbs, struct mp_image *format)
{
if (cache && !*cache)
*cache = talloc_zero(NULL, struct mp_draw_sub_cache);
@@ -426,14 +432,25 @@ static struct part *get_cache(struct mp_draw_sub_cache **cache,
bool use_cache = sbs->format == SUBBITMAP_RGBA;
if (cache && use_cache) {
part = (*cache)->parts[sbs->render_index];
- if (part && part->bitmap_pos_id != sbs->bitmap_pos_id) {
- talloc_free(part);
- part = NULL;
+ if (part) {
+ if (part->bitmap_pos_id != sbs->bitmap_pos_id
+ || part->imgfmt != format->imgfmt
+ || part->colorspace != format->colorspace
+ || part->levels != format->levels)
+ {
+ talloc_free(part);
+ part = NULL;
+ }
}
if (!part) {
- part = talloc_zero(*cache, struct part);
- part->bitmap_pos_id = sbs->bitmap_pos_id;
- part->num_imgs = sbs->num_parts;
+ part = talloc(*cache, struct part);
+ *part = (struct part) {
+ .bitmap_pos_id = sbs->bitmap_pos_id,
+ .num_imgs = sbs->num_parts,
+ .imgfmt = format->imgfmt,
+ .levels = format->levels,
+ .colorspace = format->colorspace,
+ };
part->imgs = talloc_zero_array(part, struct sub_cache,
part->num_imgs);
}
@@ -468,7 +485,7 @@ static bool get_sub_area(struct mp_rect bb, struct mp_image *temp,
// containing scaled versions of sbs contents - free the cache with
// talloc_free()
void mp_draw_sub_bitmaps(struct mp_draw_sub_cache **cache, struct mp_image *dst,
- struct sub_bitmaps *sbs, struct mp_csp_details *csp)
+ struct sub_bitmaps *sbs)
{
assert(mp_draw_sub_formats[sbs->format]);
if (!mp_sws_supported_format(dst->imgfmt))
@@ -491,17 +508,23 @@ void mp_draw_sub_bitmaps(struct mp_draw_sub_cache **cache, struct mp_image *dst,
temp = &dst_region;
} else {
temp = alloc_mpi(bb.x1 - bb.x0, bb.y1 - bb.y0, format);
- mp_image_swscale(temp, &dst_region, csp, SWS_POINT); // chroma up
+ // temp is always YUV, dst_region not
+ // reduce amount of conversions in YUV case (upsampling/shifting only)
+ if (dst_region.flags & MP_IMGFLAG_YUV) {
+ temp->colorspace = dst_region.colorspace;
+ temp->levels = dst_region.levels;
+ }
+ mp_image_swscale(temp, &dst_region, SWS_POINT); // chroma up
}
if (sbs->format == SUBBITMAP_RGBA) {
- draw_rgba(cache, bb, temp, bits, csp, sbs);
+ draw_rgba(cache, bb, temp, bits, sbs);
} else if (sbs->format == SUBBITMAP_LIBASS) {
- draw_ass(cache, bb, temp, bits, csp, sbs);
+ draw_ass(cache, bb, temp, bits, sbs);
}
if (temp != &dst_region) {
- mp_image_swscale(&dst_region, temp, csp, SWS_AREA); // chroma down
+ mp_image_swscale(&dst_region, temp, SWS_AREA); // chroma down
free_mp_image(temp);
}
}
diff --git a/sub/draw_bmp.h b/sub/draw_bmp.h
index b7ebcf5e8a..489e91f666 100644
--- a/sub/draw_bmp.h
+++ b/sub/draw_bmp.h
@@ -8,7 +8,7 @@ struct sub_bitmaps;
struct mp_csp_details;
struct mp_draw_sub_cache;
void mp_draw_sub_bitmaps(struct mp_draw_sub_cache **cache, struct mp_image *dst,
- struct sub_bitmaps *sbs, struct mp_csp_details *csp);
+ struct sub_bitmaps *sbs);
extern const bool mp_draw_sub_formats[SUBBITMAP_COUNT];
diff --git a/sub/sub.c b/sub/sub.c
index 7cea5a3cd1..517de35fc3 100644
--- a/sub/sub.c
+++ b/sub/sub.c
@@ -234,7 +234,6 @@ void osd_draw(struct osd_state *osd, struct mp_osd_res res,
struct draw_on_image_closure {
struct osd_state *osd;
struct mp_image *dest;
- struct mp_csp_details *dest_csp;
bool changed;
};
@@ -242,18 +241,16 @@ static void draw_on_image(void *ctx, struct sub_bitmaps *imgs)
{
struct draw_on_image_closure *closure = ctx;
struct osd_state *osd = closure->osd;
- mp_draw_sub_bitmaps(&osd->draw_cache, closure->dest, imgs,
- closure->dest_csp);
+ mp_draw_sub_bitmaps(&osd->draw_cache, closure->dest, imgs);
talloc_steal(osd, osd->draw_cache);
closure->changed = true;
}
// Returns whether anything was drawn.
bool osd_draw_on_image(struct osd_state *osd, struct mp_osd_res res,
- double video_pts, int draw_flags, struct mp_image *dest,
- struct mp_csp_details *dest_csp)
+ double video_pts, int draw_flags, struct mp_image *dest)
{
- struct draw_on_image_closure closure = {osd, dest, dest_csp};
+ struct draw_on_image_closure closure = {osd, dest};
osd_draw(osd, res, video_pts, draw_flags, mp_draw_sub_formats,
&draw_on_image, &closure);
return closure.changed;
diff --git a/sub/sub.h b/sub/sub.h
index 5013611e61..cdc094d290 100644
--- a/sub/sub.h
+++ b/sub/sub.h
@@ -205,10 +205,8 @@ void osd_draw(struct osd_state *osd, struct mp_osd_res res,
void (*cb)(void *ctx, struct sub_bitmaps *imgs), void *cb_ctx);
struct mp_image;
-struct mp_csp_details;
bool osd_draw_on_image(struct osd_state *osd, struct mp_osd_res res,
- double video_pts, int draw_flags, struct mp_image *dest,
- struct mp_csp_details *dest_csp);
+ double video_pts, int draw_flags, struct mp_image *dest);
struct mp_rect;
bool sub_bitmaps_bb(struct sub_bitmaps *imgs, struct mp_rect *out_bb);