summaryrefslogtreecommitdiffstats
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
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.
-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);