From 2a5fcd2801ccaff48ad360613cef2d0edf80543c Mon Sep 17 00:00:00 2001 From: wm4 Date: Fri, 28 Sep 2012 21:33:26 +0200 Subject: sub: add preliminary emulation layer to draw OSD with EOSD This basically pushes the old OSD bitmaps via VOCTRL_DRAW_EOSD to the VO, instead of using the old callback-based interface. Future commits will change the code such that sub.c pushes images rendered by libass directly, rather than converting them to the old OSD format first. --- sub/sub.c | 73 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ sub/sub.h | 9 ++++++++ 2 files changed, 82 insertions(+) (limited to 'sub') diff --git a/sub/sub.c b/sub/sub.c index c527503ef1..8b89ca497c 100644 --- a/sub/sub.c +++ b/sub/sub.c @@ -19,6 +19,7 @@ #include #include #include +#include #include #include @@ -253,6 +254,7 @@ struct osd_state *osd_create(struct MPOpts *opts, struct ass_library *asslib) .ass_library = asslib, }; // temp hack, should be moved to mplayer later + new_osd_obj(OSDTYPE_ASS); new_osd_obj(OSDTYPE_OSD); new_osd_obj(OSDTYPE_SUBTITLE); new_osd_obj(OSDTYPE_PROGBAR); @@ -369,3 +371,74 @@ int vo_osd_check_range_update(int x1,int y1,int x2,int y2){ } return 0; } + +struct draw_osd_closure { + struct vo *vo; + struct osd_state *osd; + int render_index; +}; + +static void eosd_draw_osd_part(void *ctx, int x0, int y0, int w, int h, + unsigned char *src, unsigned char *srca, + int stride) +{ + struct draw_osd_closure *c = ctx; + + assert(c->render_index < MAX_OSD_PARTS); + assert(w > 0 && h > 0); + + size_t scratch_size = talloc_get_size(c->osd->scratch); + size_t new_size = stride * h * 2; + if (new_size > scratch_size) { + scratch_size = new_size; + c->osd->scratch = talloc_realloc(c->osd, c->osd->scratch, char *, + new_size); + } + + unsigned char *tmp = c->osd->scratch; + + for (int y = 0; y < h; y++) { + unsigned char *y_src = src + stride * y; + unsigned char *y_srca = srca + stride * y; + unsigned char *cur = tmp + y * w * 2; + for (int x = 0; x < w; x++) { + cur[x*2+0] = y_src[x]; + cur[x*2+1] = -y_srca[x]; + } + } + + struct sub_bitmaps *imgs = &c->osd->eosd[c->render_index]; + imgs->render_index = c->render_index; + imgs->format = SUBBITMAP_OLD; + imgs->bitmap_id++; + imgs->bitmap_pos_id++; + if (!imgs->num_parts) { + imgs->num_parts = 1; + imgs->parts = talloc_array(c->osd, struct sub_bitmap, imgs->num_parts); + } + + imgs->parts[0] = (struct sub_bitmap) { + .bitmap = tmp, + .stride = w * 2, + .x = x0, .y = y0, + .w = w, .h = h, + .dw = w, .dh = h, + }; + + vo_control(c->vo, VOCTRL_DRAW_EOSD, imgs); + + c->render_index++; +} + +// draw old-OSD using EOSD +void emulate_draw_osd(struct vo *vo, struct osd_state *osd) +{ + mp_eosd_res_t res = {0}; + if (vo_control(vo, VOCTRL_GET_EOSD_RES, &res) != VO_TRUE) + return; + + struct draw_osd_closure c = {vo, osd}; + c.render_index = 1; // 0 is the "normal" EOSD renderer for subtitles + osd_draw_text_ext(osd, res.w, res.h, res.ml, res.mt, res.mr, res.mb, 0, 0, + eosd_draw_osd_part, &c); +} diff --git a/sub/sub.h b/sub/sub.h index fc0047bba6..74d2b5a37a 100644 --- a/sub/sub.h +++ b/sub/sub.h @@ -24,10 +24,13 @@ #include "subreader.h" #include "dec_sub.h" +struct vo; + typedef struct mp_osd_bbox_s { int x1,y1,x2,y2; } mp_osd_bbox_t; +#define OSDTYPE_ASS 0 #define OSDTYPE_OSD 1 #define OSDTYPE_SUBTITLE 2 #define OSDTYPE_PROGBAR 3 @@ -78,6 +81,10 @@ struct osd_state { char *osd_text; int w, h; + struct sub_bitmaps eosd[MAX_OSD_PARTS]; + + void *scratch; + struct MPOpts *opts; }; @@ -153,6 +160,8 @@ void osd_draw_text_ext(struct osd_state *osd, int dxs, int dys, int stride), void *ctx); +void emulate_draw_osd(struct vo *vo, struct osd_state *osd); + struct osd_state *osd_create(struct MPOpts *opts, struct ass_library *asslib); void osd_set_text(struct osd_state *osd, const char *text); int osd_update(struct osd_state *osd, int dxs, int dys); -- cgit v1.2.3