summaryrefslogtreecommitdiffstats
path: root/sub
diff options
context:
space:
mode:
authorwm4 <wm4@nowhere>2012-09-28 21:33:26 +0200
committerwm4 <wm4@nowhere>2012-10-16 07:26:30 +0200
commit2a5fcd2801ccaff48ad360613cef2d0edf80543c (patch)
treed6f8dc1d57e85788067d671b6875f6d62158b0f5 /sub
parent3c9c1790fee177cc9c9661475746a92ab6ce9bea (diff)
downloadmpv-2a5fcd2801ccaff48ad360613cef2d0edf80543c.tar.bz2
mpv-2a5fcd2801ccaff48ad360613cef2d0edf80543c.tar.xz
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.
Diffstat (limited to 'sub')
-rw-r--r--sub/sub.c73
-rw-r--r--sub/sub.h9
2 files changed, 82 insertions, 0 deletions
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 <stdio.h>
#include <stdlib.h>
#include <string.h>
+#include <assert.h>
#include <libavutil/mem.h>
#include <libavutil/common.h>
@@ -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);