Skip to content

Commit

Permalink
Decode embedded vobsub (dvbsub) using Showtime's own DVDSPU decoder
Browse files Browse the repository at this point in the history
Fixes #972
  • Loading branch information
andoma authored and Andreas Öman committed Jul 26, 2012
1 parent dbb52ce commit 49d46b6
Show file tree
Hide file tree
Showing 9 changed files with 241 additions and 135 deletions.
8 changes: 4 additions & 4 deletions configure.osx
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,10 @@ enable realpath
enable polarssl
enable librtmp
enable font_liberation
enable dvd
enable spotify
enable vda
enable fsevents

for opt do
optval="${opt#*=}"
Expand Down Expand Up @@ -82,10 +86,6 @@ setup_env "$@"
enable libpthread
enable zlib
enable posix_networking
enable dvd
enable spotify
enable vda
enable fsevents

#
# c compiler
Expand Down
3 changes: 1 addition & 2 deletions sources.mk
Original file line number Diff line number Diff line change
Expand Up @@ -188,8 +188,7 @@ SRCS += src/video/video_playback.c \
src/video/sub_ass.c \
src/video/ext_subtitles.c \
src/video/video_settings.c \

SRCS-$(CONFIG_DVD) += src/video/video_dvdspu.c
src/video/video_dvdspu.c \

SRCS-$(CONFIG_VDPAU) += src/video/vdpau.c

Expand Down
5 changes: 5 additions & 0 deletions src/media.c
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@
#include "i18n.h"
#include "video/ext_subtitles.h"
#include "video/video_settings.h"
#include "video/video_overlay.h"
#include "settings.h"

// -- Video accelerators ---------
Expand Down Expand Up @@ -1162,6 +1163,10 @@ media_codec_create(int codec_id, int parser,

} else
#endif
if(!video_overlay_codec_create(mc, codec_id, ctx, mp)) {

} else

if(media_codec_create_lavc(mc, codec_id, ctx, mcp)) {
free(mc);
return NULL;
Expand Down
66 changes: 36 additions & 30 deletions src/ui/glw/glw_video_overlay.c
Original file line number Diff line number Diff line change
Expand Up @@ -262,7 +262,7 @@ glw_video_overlay_render(glw_video_t *gv, glw_rctx_t *frc, glw_rctx_t *vrc)
{
glw_video_overlay_t *gvo;
glw_root_t *gr = gv->w.glw_root;
int show_dvd_overlays = 0;
int show_dvd_overlays = 1;
glw_rctx_t rc0;

#if ENABLE_DVD
Expand All @@ -271,7 +271,7 @@ glw_video_overlay_render(glw_video_t *gv, glw_rctx_t *frc, glw_rctx_t *vrc)
(glw_is_focused(&gv->w) || !vd->vd_pci.hli.hl_gi.hli_ss))
show_dvd_overlays = 1;
#endif

LIST_FOREACH(gvo, &gv->gv_overlays, gvo_link) {

if(gv->gv_vo_on_video || gvo->gvo_videoframe_align)
Expand Down Expand Up @@ -358,16 +358,19 @@ glw_video_overlay_render(glw_video_t *gv, glw_rctx_t *frc, glw_rctx_t *vrc)
glw_renderer_vtx_pos(&gvo->gvo_renderer, 3, x1, y2, 0.0);

} else {
float ys = gv->gv_cfg_cur.gvc_flags & GVC_YHALF ? 2 : 1;
glw_Scalef(&rc0,
2.0f / gv->gv_cfg_cur.gvc_width[0],
-2.0f / (ys * gv->gv_cfg_cur.gvc_height[0]),
0.0f);
float w,h;

if(gvo->gvo_canvas_width && gvo->gvo_canvas_height) {
w = gvo->gvo_canvas_width;
h = gvo->gvo_canvas_height;
} else {
float ys = gv->gv_cfg_cur.gvc_flags & GVC_YHALF ? 2 : 1;
w = gv->gv_cfg_cur.gvc_width[0];
h = gv->gv_cfg_cur.gvc_height[0] * ys;
}

glw_Translatef(&rc0,
-gv->gv_cfg_cur.gvc_width[0] / 2,
(ys * -gv->gv_cfg_cur.gvc_height[0]) / 2,
0.0f);
glw_Scalef(&rc0, 2 / w, -2 / h, 1.0f);
glw_Translatef(&rc0, -w / 2, -h / 2, 0.0f);
}

glw_renderer_draw(&gvo->gvo_renderer, gr, &rc0,
Expand Down Expand Up @@ -454,28 +457,25 @@ glw_video_overlay_pointer_event(video_decoder_t *vd, int width, int height,
}


#if ENABLE_DVD
/**
*
*/
static void
spu_repaint(glw_video_t *gv, dvdspu_t *d)
{
video_decoder_t *vd = gv->gv_vd;
int width = d->d_x2 - d->d_x1;
int height = d->d_y2 - d->d_y1;
int outsize = width * height * 4;
uint32_t *tmp, *t0;
int x, y, i;
uint8_t *buf = d->d_bitmap;
pci_t *pci = &vd->vd_pci;
dvdnav_highlight_area_t ha;

#if ENABLE_DVD
video_decoder_t *vd = gv->gv_vd;
int hi_palette[4];
int hi_alpha[4];

if(vd->vd_spu_clut == NULL)
return;

dvdnav_highlight_area_t ha;
pci_t *pci = &vd->vd_pci;
vd->vd_spu_in_menu = pci->hli.hl_gi.hli_ss;

if(pci->hli.hl_gi.hli_ss &&
Expand All @@ -493,32 +493,34 @@ spu_repaint(glw_video_t *gv, dvdspu_t *d)
hi_palette[3] = (ha.palette >> 28) & 0xf;
}

t0 = tmp = malloc(outsize);


ha.sx -= d->d_x1;
ha.ex -= d->d_x1;

ha.sy -= d->d_y1;
ha.ey -= d->d_y1;
#endif

t0 = tmp = malloc(outsize);

/* XXX: this can be optimized in many ways */

for(y = 0; y < height; y++) {
for(x = 0; x < width; x++) {
i = buf[0];

#if ENABLE_DVD
if(pci->hli.hl_gi.hli_ss &&
x >= ha.sx && y >= ha.sy && x <= ha.ex && y <= ha.ey) {

if(hi_alpha[i] == 0) {
*tmp = 0;
} else {
*tmp = vd->vd_spu_clut[hi_palette[i] & 0xf] |
*tmp = d->d_clut[hi_palette[i] & 0xf] |
((hi_alpha[i] * 0x11) << 24);
}

} else {
} else
#endif
{

if(d->d_alpha[i] == 0) {

Expand All @@ -527,7 +529,7 @@ spu_repaint(glw_video_t *gv, dvdspu_t *d)

*tmp = 0;
} else {
*tmp = vd->vd_spu_clut[d->d_palette[i] & 0xf] |
*tmp = d->d_clut[d->d_palette[i] & 0xf] |
((d->d_alpha[i] * 0x11) << 24);
}
}
Expand All @@ -541,6 +543,10 @@ spu_repaint(glw_video_t *gv, dvdspu_t *d)


glw_video_overlay_t *gvo = gvo_create(AV_NOPTS_VALUE, GVO_DVDSPU);

gvo->gvo_canvas_width = d->d_canvas_width;
gvo->gvo_canvas_height = d->d_canvas_height;

LIST_INSERT_HEAD(&gv->gv_overlays, gvo, gvo_link);
glw_root_t *gr = gv->w.glw_root;
gvo->gvo_videoframe_align = 1;
Expand Down Expand Up @@ -616,7 +622,6 @@ glw_video_overlay_spu_layout(glw_video_t *gv, int64_t pts)
}
hts_mutex_unlock(&vd->vd_spu_mutex);
}
#endif


/**
Expand All @@ -638,6 +643,8 @@ gvo_create_from_vo_bitmap(glw_video_t *gv, video_overlay_t *vo)
gvo->gvo_stop = vo->vo_stop;
gvo->gvo_fadein = vo->vo_fadein;
gvo->gvo_fadeout = vo->vo_fadeout;
gvo->gvo_canvas_width = vo->vo_canvas_width;
gvo->gvo_canvas_height = vo->vo_canvas_height;

glw_renderer_init_quad(&gvo->gvo_renderer);

Expand Down Expand Up @@ -816,10 +823,8 @@ glw_video_overlay_set_pts(glw_video_t *gv, int64_t pts)
{
const video_decoder_t *vd = gv->gv_vd;
int want_focus = 0;

#if ENABLE_DVD
printf("Video overlay PTS = %lld\n", pts);
glw_video_overlay_spu_layout(gv, pts);
#endif
pts -= vd->vd_mp->mp_svdelta;
pts -= vd->vd_mp->mp_pts_delta_for_subs;

Expand All @@ -830,6 +835,7 @@ glw_video_overlay_set_pts(glw_video_t *gv, int64_t pts)
if(vd->vd_pci.hli.hl_gi.hli_ss)
want_focus = 1;
#endif

glw_set_focus_weight(&gv->w, want_focus ? 1.0 : 0.0);
}

Expand Down
44 changes: 34 additions & 10 deletions src/video/video_decoder.c
Original file line number Diff line number Diff line change
Expand Up @@ -359,13 +359,34 @@ vd_thread(void *aux)
reinit = 1;
break;

#ifdef CONFIG_DVD
case MB_DVD_HILITE:
#if ENABLE_DVD
case MB_DVD_RESET_SPU:
vd->vd_spu_curbut = 1;
dvdspu_flush(vd);
break;

case MB_DVD_CLUT:
case MB_DVD_PCI:
printf("CLUT updated\n");
dvdspu_decode_clut(vd->vd_dvd_clut, mb->mb_data);
break;

case MB_DVD_SPU:
dvdspu_decoder_dispatch(vd, mb, mp);
printf("SPU updated\n");
dvdspu_enqueue(vd, mb, vd->vd_dvd_clut, 0, 0);
break;

case MB_DVD_HILITE:
vd->vd_spu_curbut = mb->mb_data32;
vd->vd_spu_repaint = 1;
break;

case MB_DVD_PCI:
memcpy(&vd->vd_pci, mb->mb_data, sizeof(pci_t));
vd->vd_spu_repaint = 1;
event_t *e = event_create(EVENT_DVD_PCI, sizeof(event_t) + sizeof(pci_t));
memcpy(e->e_payload, mb->mb_data, sizeof(pci_t));
mp_enqueue_event(mp, e);
event_release(e);
break;
#endif

Expand Down Expand Up @@ -431,9 +452,8 @@ video_decoder_create(media_pipe_t *mp, vd_frame_deliver_t *frame_delivery,

vd_init_timings(vd);

#ifdef CONFIG_DVD
dvdspu_decoder_init(vd);
#endif
TAILQ_INIT(&vd->vd_spu_queue);
hts_mutex_init(&vd->vd_spu_mutex);

TAILQ_INIT(&vd->vd_overlay_queue);
hts_mutex_init(&vd->vd_overlay_mutex);
Expand Down Expand Up @@ -468,9 +488,13 @@ video_decoder_stop(video_decoder_t *vd)
void
video_decoder_destroy(video_decoder_t *vd)
{
#ifdef CONFIG_DVD
dvdspu_decoder_deinit(vd);
#endif
dvdspu_t *d;

while((d = TAILQ_FIRST(&vd->vd_spu_queue)) != NULL)
dvdspu_destroy(vd, d);

hts_mutex_destroy(&vd->vd_spu_mutex);

video_overlay_flush(vd, 0);

hts_mutex_destroy(&vd->vd_overlay_mutex);
Expand Down
26 changes: 19 additions & 7 deletions src/video/video_decoder.h
Original file line number Diff line number Diff line change
Expand Up @@ -26,10 +26,10 @@
#include "misc/kalman.h"

#if ENABLE_DVD
TAILQ_HEAD(dvdspu_queue, dvdspu);
#include <dvdnav/dvdnav.h>
#endif

TAILQ_HEAD(dvdspu_queue, dvdspu);
TAILQ_HEAD(video_overlay_queue, video_overlay);

#define VIDEO_DECODER_REORDER_SIZE 16
Expand Down Expand Up @@ -130,19 +130,18 @@ typedef struct video_decoder {
/**
* DVD / SPU related members
*/
#ifdef CONFIG_DVD
struct dvdspu_queue vd_spu_queue;

uint32_t *vd_spu_clut;

hts_mutex_t vd_spu_mutex;

#ifdef CONFIG_DVD
uint32_t vd_dvd_clut[16];
pci_t vd_pci;
#endif

int vd_spu_curbut;
int vd_spu_repaint;

#endif
int vd_spu_in_menu;

/**
Expand Down Expand Up @@ -201,7 +200,6 @@ void video_decoder_scan_ext_sub(video_decoder_t *vd, int64_t pts);
*
* This include both subtitling and menus on DVDs
*/
#if ENABLE_DVD

typedef struct dvdspu {

Expand All @@ -223,6 +221,11 @@ typedef struct dvdspu {

int d_destroyme;

uint32_t d_clut[16];

int d_canvas_width;
int d_canvas_height;

} dvdspu_t;

void dvdspu_decoder_init(video_decoder_t *vd);
Expand All @@ -236,7 +239,16 @@ void dvdspu_decoder_dispatch(video_decoder_t *vd, media_buf_t *mb,

int dvdspu_decode(dvdspu_t *d, int64_t pts);

#endif
void dvdspu_decode_clut(uint32_t *dst, const uint32_t *src);

void dvdspu_enqueue(video_decoder_t *vd, media_buf_t *mb, const uint32_t *clut,
int w, int h);

void dvdspu_flush(video_decoder_t *vd);

int dvdspu_codec_create(media_codec_t *mc, enum CodecID id,
AVCodecContext *ctx, media_pipe_t *mp);


#endif /* VIDEO_DECODER_H */

Loading

0 comments on commit 49d46b6

Please sign in to comment.