summaryrefslogtreecommitdiffstats
path: root/sub
diff options
context:
space:
mode:
authorwm4 <wm4@nowhere>2012-12-22 17:17:43 +0100
committerwm4 <wm4@nowhere>2013-01-13 20:04:12 +0100
commit1c65428d6f70f05333ecc8284e3f235c679fff26 (patch)
tree6939a94a824aba4a8929136dc906cdc1d5b5de6b /sub
parent233cc15be99a94891bfc62bbb79af38ee192d9ff (diff)
downloadmpv-1c65428d6f70f05333ecc8284e3f235c679fff26.tar.bz2
mpv-1c65428d6f70f05333ecc8284e3f235c679fff26.tar.xz
sub: do not copy the target image if there is no OSD/subs
It's not easy to tell whether the OSD/subs are empty, or if something is drawn. In general you have to use osd_draw() with a custom callback. If nothing is visible, the callback is never invoked. (The actual reason why this is so "hard" is the implementation of osd_libass.c, which doesn't allow separating rendering and drawing of OSD elements, because all OSD elements share the same ASS_Renderer.) To simplify avoiding copies, make osd_draw_on_image() instead of the caller use mp_image_make_writeable(). Introduce osd_draw_on_image_p(), which works like osd_draw_on_image(), but gets the new image allocation from an image pool. This is supposed to be an optimization, because it reduces the frequency of large allocations/deallocations for image data. The result of this is that the frequency of copies needed in conjunction with vf_sub, screenshots, and vo_lavc (encoding) should be reduced. vf_sub now always does true pass-through if no subs are shown. Drop the pts check from vf_sub. This didn't make much sense.
Diffstat (limited to 'sub')
-rw-r--r--sub/sub.c21
-rw-r--r--sub/sub.h5
2 files changed, 26 insertions, 0 deletions
diff --git a/sub/sub.c b/sub/sub.c
index 1365d3c844..4baf4f1487 100644
--- a/sub/sub.c
+++ b/sub/sub.c
@@ -39,6 +39,8 @@
#include "draw_bmp.h"
#include "spudec.h"
#include "subreader.h"
+#include "video/mp_image.h"
+#include "video/mp_image_pool.h"
char * const sub_osd_names[]={
@@ -274,6 +276,7 @@ struct draw_on_image_closure {
struct osd_state *osd;
struct mp_image *dest;
struct mp_draw_sub_backup *bk;
+ struct mp_image_pool *pool;
bool changed;
};
@@ -283,11 +286,17 @@ static void draw_on_image(void *ctx, struct sub_bitmaps *imgs)
struct osd_state *osd = closure->osd;
if (closure->bk)
mp_draw_sub_backup_add(closure->bk, closure->dest, imgs);
+ if (closure->pool) {
+ mp_image_pool_make_writeable(closure->pool, closure->dest);
+ } else {
+ mp_image_make_writeable(closure->dest);
+ }
mp_draw_sub_bitmaps(&osd->draw_cache, closure->dest, imgs);
talloc_steal(osd, osd->draw_cache);
closure->changed = true;
}
+// Calls mp_image_make_writeable() on the dest image if something is drawn.
// 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)
@@ -298,6 +307,18 @@ bool osd_draw_on_image(struct osd_state *osd, struct mp_osd_res res,
return closure.changed;
}
+// Like osd_draw_on_image(), but if dest needs to be copied to make it
+// writeable, allocate images from the given pool. (This is a minor
+// optimization to reduce "real" image sized memory allocations.)
+void osd_draw_on_image_p(struct osd_state *osd, struct mp_osd_res res,
+ double video_pts, int draw_flags,
+ struct mp_image_pool *pool, struct mp_image *dest)
+{
+ struct draw_on_image_closure closure = {osd, dest, .pool = pool};
+ osd_draw(osd, res, video_pts, draw_flags, mp_draw_sub_formats,
+ &draw_on_image, &closure);
+}
+
void osd_draw_on_image_bk(struct osd_state *osd, struct mp_osd_res res,
double video_pts, int draw_flags,
struct mp_draw_sub_backup *bk, struct mp_image *dest)
diff --git a/sub/sub.h b/sub/sub.h
index ed4401cacf..38b7b29f34 100644
--- a/sub/sub.h
+++ b/sub/sub.h
@@ -222,6 +222,11 @@ struct mp_image;
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_image_pool;
+void osd_draw_on_image_p(struct osd_state *osd, struct mp_osd_res res,
+ double video_pts, int draw_flags,
+ struct mp_image_pool *pool, struct mp_image *dest);
+
struct mp_draw_sub_backup;
void osd_draw_on_image_bk(struct osd_state *osd, struct mp_osd_res res,
double video_pts, int draw_flags,