1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106
|
/*
* vo_osdreorder.c: OSD re-ordering video-out post plugin
*
* See the main source file 'xineliboutput.c' for copyright information and
* how to reach the author.
*
* $Id$
*
*/
#include "vo_osdreorder.h"
#include <stdlib.h>
#include <xine/video_out.h>
#include "vo_props.h"
#include "vo_hook.h"
/*
* osdreorder_hook_t
*/
typedef struct {
vo_driver_hook_t h;
/* currently showing OSDs in new drawing order */
vo_overlay_t *overlay[50];
} osdreorder_hook_t;
/*
*
*/
static int osd_level(vo_overlay_t *overlay)
{
if (overlay->hili_rgb_clut != VDR_OSD_MAGIC /* not from vdr */) {
return 9999;
}
/* VDR input plugin stores some control data in hili clut area */
vdr_osd_extradata_t *data = (vdr_osd_extradata_t *)overlay->hili_color;
return data->layer;
}
/*
* interface
*/
/*
* override overlay_blend()
*/
static void osdreorder_overlay_blend (vo_driver_t *self, vo_frame_t *frame, vo_overlay_t *overlay)
{
osdreorder_hook_t *this = (osdreorder_hook_t*)self;
int my_level = osd_level(overlay);
int i;
/* search position */
for (i = 0; this->overlay[i] && osd_level(this->overlay[i]) >= my_level; i++)
;
/* make room */
if (this->overlay[i])
memmove(&this->overlay[i+1], &this->overlay[i], (49-i)*sizeof(vo_overlay_t*));
this->overlay[i] = overlay;
return;
}
/*
* override overlay_end()
*/
static void osdreorder_overlay_end (vo_driver_t *self, vo_frame_t *vo_img)
{
osdreorder_hook_t *this = (osdreorder_hook_t*)self;
int i;
for (i = 0; this->overlay[i]; i++) {
this->h.orig_driver->overlay_blend(this->h.orig_driver, vo_img, this->overlay[i]);
this->overlay[i] = NULL;
}
/* redirect */
if (this->h.orig_driver->overlay_end)
this->h.orig_driver->overlay_end(this->h.orig_driver, vo_img);
}
/*
* init()
*/
vo_driver_t *osd_reorder_init(void)
{
osdreorder_hook_t *this = calloc(1, sizeof(osdreorder_hook_t));
if (!this)
return NULL;
/* OSD interface */
this->h.vo.overlay_blend = osdreorder_overlay_blend;
this->h.vo.overlay_end = osdreorder_overlay_end;
this->h.vo.dispose = vo_def_dispose;
return &this->h.vo;
}
|