summaryrefslogtreecommitdiffstats
path: root/sub
diff options
context:
space:
mode:
authorwm4 <wm4@nowhere>2012-12-25 16:27:20 +0100
committerwm4 <wm4@nowhere>2013-01-13 20:04:14 +0100
commitfb23c3a8ee468a4eaa974440147b032a568f7d7b (patch)
tree510f713a02224dad79ef3734d7ccdb09271a28ed /sub
parent7d15bd1488b32be69aa21ed62749e610ac9d856a (diff)
downloadmpv-fb23c3a8ee468a4eaa974440147b032a568f7d7b.tar.bz2
mpv-fb23c3a8ee468a4eaa974440147b032a568f7d7b.tar.xz
draw_bmp: don't copy Y plane on up/down-sampling
Image areas with subtitles are upsampled to 4:4:4 in order to render the subtitles (makes blending easier). Try not to copy the Y plane on upsampling. The libswscale API requires this, but this commit works it around by scaling the chroma planes separately as AV_PIX_FMT_GRAY8. The Y plane is not touched at all. This is done for 420p8 only, which is the most commonly needed case. For other formats, the old way is used. Seems to make ASS rendering faster about 15% in the setup I tested.
Diffstat (limited to 'sub')
-rw-r--r--sub/draw_bmp.c51
1 files changed, 46 insertions, 5 deletions
diff --git a/sub/draw_bmp.c b/sub/draw_bmp.c
index 208b379168..4cf89349a0 100644
--- a/sub/draw_bmp.c
+++ b/sub/draw_bmp.c
@@ -464,23 +464,64 @@ static struct mp_image *chroma_up(struct mp_draw_sub_cache *cache, int imgfmt,
cache->upsample_temp = *cache->upsample_img;
struct mp_image *temp = &cache->upsample_temp;
mp_image_set_size(temp, src->w, src->h);
- // temp is always YUV, but src not necessarily
- // reduce amount of conversions in YUV case (upsampling/shifting only)
+
+ // The temp image is always YUV, but src not necessarily.
+ // Reduce amount of conversions in YUV case (upsampling/shifting only)
if (src->flags & MP_IMGFLAG_YUV) {
temp->colorspace = src->colorspace;
temp->levels = src->levels;
}
- mp_image_swscale(temp, src, SWS_POINT); // chroma up
+
+ if (src->imgfmt == IMGFMT_420P) {
+ assert(imgfmt == IMGFMT_444P);
+ // Faster upsampling: keep Y plane, upsample chroma planes only
+ // The whole point is not having swscale copy the Y plane
+ struct mp_image t_dst = *temp;
+ mp_image_setfmt(&t_dst, IMGFMT_Y8);
+ mp_image_set_size(&t_dst, temp->chroma_width, temp->chroma_height);
+ struct mp_image t_src = t_dst;
+ mp_image_set_size(&t_src, src->chroma_width, src->chroma_height);
+ for (int c = 0; c < 2; c++) {
+ t_dst.planes[0] = temp->planes[1 + c];
+ t_dst.stride[0] = temp->stride[1 + c];
+ t_src.planes[0] = src->planes[1 + c];
+ t_src.stride[0] = src->stride[1 + c];
+ mp_image_swscale(&t_dst, &t_src, SWS_POINT);
+ }
+ temp->planes[0] = src->planes[0];
+ temp->stride[0] = src->stride[0];
+ } else {
+ mp_image_swscale(temp, src, SWS_POINT);
+ }
return temp;
}
-// Undo chroma_up()
+// Undo chroma_up() (copy temp to old_src if needed)
static void chroma_down(struct mp_image *old_src, struct mp_image *temp)
{
assert(old_src->w == temp->w && old_src->h == temp->h);
if (temp != old_src) {
- mp_image_swscale(old_src, temp, SWS_AREA); // chroma down
+ if (old_src->imgfmt == IMGFMT_420P) {
+ // Downsampling, skipping the Y plane (see chroma_up())
+ assert(temp->imgfmt == IMGFMT_444P);
+ assert(temp->planes[0] == old_src->planes[0]);
+ struct mp_image t_dst = *temp;
+ mp_image_setfmt(&t_dst, IMGFMT_Y8);
+ mp_image_set_size(&t_dst, old_src->chroma_width,
+ old_src->chroma_height);
+ struct mp_image t_src = t_dst;
+ mp_image_set_size(&t_src, temp->chroma_width, temp->chroma_height);
+ for (int c = 0; c < 2; c++) {
+ t_dst.planes[0] = old_src->planes[1 + c];
+ t_dst.stride[0] = old_src->stride[1 + c];
+ t_src.planes[0] = temp->planes[1 + c];
+ t_src.stride[0] = temp->stride[1 + c];
+ mp_image_swscale(&t_dst, &t_src, SWS_AREA);
+ }
+ } else {
+ mp_image_swscale(old_src, temp, SWS_AREA); // chroma down
+ }
}
}