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.
This commit is contained in:
wm4 2012-09-28 21:33:26 +02:00
parent 3c9c1790fe
commit 2a5fcd2801
2 changed files with 82 additions and 0 deletions

View File

@ -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);
}

View File

@ -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);