blob: 6fed9e3c9c54661bd0b227b4984bcfb1eec1ff7f (
plain)
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
|
/*
* 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: vo_osdreorder.c,v 1.1 2009-03-17 12:14:41 phintuka Exp $
*
*/
#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));
/* OSD interface */
this->h.vo.overlay_blend = osdreorder_overlay_blend;
this->h.vo.overlay_end = osdreorder_overlay_end;
return &this->h.vo;
}
|