summaryrefslogtreecommitdiff
path: root/xine/vo_osdscaler.c
diff options
context:
space:
mode:
Diffstat (limited to 'xine/vo_osdscaler.c')
-rw-r--r--xine/vo_osdscaler.c439
1 files changed, 0 insertions, 439 deletions
diff --git a/xine/vo_osdscaler.c b/xine/vo_osdscaler.c
deleted file mode 100644
index d9562d9e..00000000
--- a/xine/vo_osdscaler.c
+++ /dev/null
@@ -1,439 +0,0 @@
-/*
- * vo_osdscaler.c: OSD scaling video-out post plugin
- *
- * See the main source file 'xineliboutput.c' for copyright information and
- * how to reach the author.
- *
- * $Id: vo_osdscaler.c,v 1.4 2009-05-27 08:37:06 phintuka Exp $
- *
- */
-
-#include <stdlib.h>
-
-#include <xine/video_out.h>
-#ifdef SWBLEND
-# include <xine/alphablend.h>
-#endif
-
-#define LOG_MODULENAME "[osdscaler] "
-#include "../logdefs.h"
-
-#include "vo_props.h"
-#include "vo_hook.h"
-
-/*#define LOGOSD(x...) LOGMSG(x)*/
-#define LOGOSD(x...)
-
-typedef rle_elem_t xine_rle_elem_t;
-
-#include "../tools/rle.h"
-
-
-/* Make sure our properties won't overlap with xine's properties */
-#if VO_NUM_PROPERTIES > VO_PROP_OSD_SCALING
-# error VO_NUM_PROPERTIES > VO_PROP_OSD_SCALING
-#endif
-
-#undef ABS
-#define ABS(x) ((x)<0?-(x):(x))
-
-
-/*
- * osd_data_t
- *
- * - cache scaled OSD data
- */
-
-typedef struct osd_data_s osd_data_t;
-
-struct osd_data_s {
- /* original source */
- vo_overlay_t *source;
-
- /* scaled overlay */
- uint8_t scaled : 1;
- vo_overlay_t ovl;
-
- /* for what output resolution overlay was scaled */
- uint16_t output_width;
- uint16_t output_height;
-
- /* linked list */
- osd_data_t *next;
-};
-
-/*
- * osd_data_dispose()
- *
- * - free() osd_data_t and all allocated memory
- */
-static void osd_data_dispose(osd_data_t *data)
-{
- if (data->scaled)
- free(data->ovl.rle);
- free(data);
-}
-
-/*
- * osd_data_clear()
- *
- * - free() whole linked list
- */
-static void osd_data_clear(osd_data_t *data)
-{
- if (data) {
- if (data->next)
- osd_data_clear(data->next);
- osd_data_dispose(data);
- }
-}
-
-/*
- * osd_data_remove()
- *
- * - remove (and free) specific osd_data_t item from linked list
- */
-static void osd_data_remove(osd_data_t **list, osd_data_t *data)
-{
- if (!list || !*list)
- return;
-
- /* special handling for list head */
- if (data == *list) {
- *list = data->next;
- free(data);
- return;
- }
-
- osd_data_t *it = *list;
- while (it) {
- if (data == it->next) {
- it->next = data->next;
- free(data);
- return;
- }
- it = it->next;
- }
-}
-
-/*
- * osd_data_init()
- *
- * - allocate and fill new osd_data_t
- *
- */
-static osd_data_t *osd_data_init(vo_overlay_t *ovl, osd_data_t *next,
- uint32_t factor_x, uint32_t factor_y)
-{
- osd_data_t *data = calloc(1, sizeof(osd_data_t));
-
- data->source = ovl;
- data->next = next;
-
- memcpy(&data->ovl, ovl, sizeof(vo_overlay_t));
-
- int num_rle = data->ovl.num_rle;
-
- /* new position and size */
- int x2 = ovl->x + ovl->width + 1;
- int y2 = ovl->y + ovl->height + 1;
- x2 = ((x2+1) * factor_x) >> 16;
- y2 = ((y2+1) * factor_y) >> 16;
- data->ovl.x = (ovl->x * factor_x) >> 16;
- data->ovl.y = (ovl->y * factor_y) >> 16;
- data->ovl.width = x2 - data->ovl.x - 1;
- data->ovl.height = y2 - data->ovl.y - 1;
-
- data->ovl.rle = (rle_elem_t*)
- rle_scale_nearest((struct xine_rle_elem_s*)ovl->rle, &num_rle,
- ovl->width, ovl->height,
- data->ovl.width, data->ovl.height);
- data->ovl.num_rle = num_rle;
- data->scaled = 1;
-
- LOGOSD("I: %d,%d %dx%d", ovl->x, ovl->y, ovl->width, ovl->height);
- LOGOSD("O: %d,%d %dx%d", data->ovl.x, data->ovl.y, data->ovl.width, data->ovl.height);
-
- return data;
-}
-
-/*
- * osdscaler_hook_t
- */
-typedef struct {
- vo_driver_hook_t h;
-
- /* configuration */
- uint8_t enable;
- uint8_t unscaled_supported;
- uint8_t custom_extent_supported;
- uint8_t argb_supported;
-
- /* current output */
- uint16_t output_width;
- uint16_t output_height;
- uint32_t factor_x; /* scaling factor << 16 */
- uint32_t factor_y;
- uint16_t x_move; /* OSD displacement */
- uint16_t y_move;
-
- /* currently showing OSDs - pre-scaled data */
- osd_data_t *active_osds;
-
-} osdscaler_hook_t;
-
-/*
- *
- */
-
-/*
- * override overlay_begin()
- */
-static void osdscaler_overlay_begin (vo_driver_t *self, vo_frame_t *frame, int changed)
-{
- osdscaler_hook_t *this = (osdscaler_hook_t*)self;
-
- /* assume we're wired when called */
- if (!this->h.orig_driver) {
- LOGMSG("osdscaler_overlay_begin: assertion this->h.orig_driver failed !");
- abort();
- }
-
- /* re-scale all if OSD changed */
- if (changed) {
- LOGOSD("osdscaler_overlay_begin: changed = 1");
- osd_data_clear(this->active_osds);
- this->active_osds = NULL;
- this->unscaled_supported = (vo_def_get_capabilities(self) & VO_CAP_UNSCALED_OVERLAY);
- /* VO_CAP_OSDSCALING == VO_CAP_CUSTOM_EXTENT_OVERLAY */
- this->custom_extent_supported = (vo_def_get_capabilities(self) & VO_CAP_OSDSCALING);
- /* VO_CAP_ARGB == VO_CAP_ARGB_LAYER_OVERLAY */
- this->argb_supported = (vo_def_get_capabilities(self) & VO_CAP_ARGB);
- }
-
- /* redirect */
- if (this->h.orig_driver->overlay_begin)
- this->h.orig_driver->overlay_begin(this->h.orig_driver, frame, changed);
-}
-
-static int check_for_scaling(osdscaler_hook_t *this, vo_frame_t *frame, vo_overlay_t *overlay)
-{
- this->x_move = this->y_move = 0;
-
- if (!this->enable)
- return 0;
-
- /* check for VDR OSD */
- if (overlay->hili_rgb_clut != VDR_OSD_MAGIC /* not from vdr */) {
- LOGOSD("overlay: source not VDR");
- return 0;
- }
-
- /* VDR input plugin stores some control data in hili clut area */
- vdr_osd_extradata_t *data = (vdr_osd_extradata_t *)overlay->hili_color;
- int extent_width = data->extent_width;
- int extent_height = data->extent_height;
-
- if (!data->scaling)
- return 0;
-
-#if 0
- if (this->custom_extent_supported) {
- /* let the "real" video driver do scaling */
- return 0;
- }
-#else
-# ifdef VO_CAP_CUSTOM_EXTENT_OVERLAY
- /* disable VDPAU HW scaler */
- overlay->extent_width = 0;
- overlay->extent_height = 0;
-# endif
-#endif
-
- /* detect output size */
- if (overlay->unscaled && this->unscaled_supported) {
- this->output_width = vo_def_get_property((vo_driver_t*)this, VO_PROP_WINDOW_WIDTH);
- this->output_height = vo_def_get_property((vo_driver_t*)this, VO_PROP_WINDOW_HEIGHT);
- } else {
- this->output_width = frame->width;
- this->output_height = frame->height;
- /* check cropping */
- if (frame->crop_top > 0) this->output_height -= frame->crop_top;
- if (frame->crop_bottom > 0) this->output_height -= frame->crop_bottom;
- if (frame->crop_left > 0) this->output_width -= frame->crop_left;
- if (frame->crop_right > 0) this->output_width -= frame->crop_right;
- }
-
- /* check if scaling should be done */
- if (ABS(this->output_width - extent_width) > extent_width /20 ||
- ABS(this->output_height - extent_height) > extent_height/20 ) {
- LOGOSD("scaling required");
- this->factor_x = 0x10000 * this->output_width / extent_width;
- this->factor_y = 0x10000 * this->output_height / extent_height;
- return 1;
- }
-
- /* if no scaling was required, we may still need to re-center OSD */
- if(this->output_width != extent_width)
- this->x_move = (this->output_width - extent_width)/2;
- if(this->output_height != extent_height)
- this->y_move = (this->output_height - extent_height)/2;
-
- return 0;
-}
-
-static vo_overlay_t *scale_overlay(osdscaler_hook_t *this, vo_frame_t *frame, vo_overlay_t *overlay)
-{
- if (check_for_scaling(this, frame, overlay)) {
-
- /* find old scaled OSD */
- osd_data_t *scaled = this->active_osds;
- while (scaled && scaled->source != overlay)
- scaled = scaled->next;
-
- /* output size changed since last scaling (need to re-scale) ? */
- if (scaled &&
- (scaled->output_width != this->output_width ||
- scaled->output_height != this->output_height)) {
-
- LOGOSD("re-scaling required: output size changed %dx%d -> %dx%d",
- scaled->output_width, scaled->output_height, this->output_width, this->output_height);
-
- osd_data_remove(&this->active_osds, scaled);
- scaled = NULL;
- }
-
- /* not scaled found ? */
- if (!scaled) {
- LOGOSD("scaling OSD");
- scaled = this->active_osds = osd_data_init(overlay, this->active_osds,
- this->factor_x, this->factor_y);
- scaled->output_width = this->output_width;
- scaled->output_height = this->output_height;
- }
-
- /* override */
- overlay = &scaled->ovl;
- }
-
- return overlay;
-}
-
-
-/*
- * interface
- */
-
-/*
- * override overlay_blend()
- */
-static void osdscaler_overlay_blend (vo_driver_t *self, vo_frame_t *frame, vo_overlay_t *overlay)
-{
- osdscaler_hook_t *this = (osdscaler_hook_t*)self;
-
- overlay = scale_overlay(this, frame, overlay);
-
- /* redirect */
- if (this->h.orig_driver->overlay_blend)
- this->h.orig_driver->overlay_blend(this->h.orig_driver, frame, overlay);
-}
-
-/*
- * override overlay_end()
- */
-static void osdscaler_overlay_end (vo_driver_t *self, vo_frame_t *vo_img)
-{
- osdscaler_hook_t *this = (osdscaler_hook_t*)self;
-
- /* redirect */
- if (this->h.orig_driver->overlay_end)
- this->h.orig_driver->overlay_end(this->h.orig_driver, vo_img);
-}
-
-
-/*
- * Management interface
- */
-
-/*
- * override get_capabilities()
- */
-static uint32_t osdscaler_get_capabilities(vo_driver_t *self)
-{
- return vo_def_get_capabilities(self) |
- VO_CAP_OSDSCALING;
-}
-
-/*
- * override get_property()
- */
-static int osdscaler_get_property(vo_driver_t *self, int prop)
-{
- osdscaler_hook_t *this = (osdscaler_hook_t*)self;
-
- switch (prop) {
- case VO_PROP_OSD_SCALING: return this->enable;
- default:;
- }
-
- return vo_def_get_property(self, prop);
-}
-
-/*
- * override set_property()
- */
-static int osdscaler_set_property(vo_driver_t *self, int prop, int val)
-{
- osdscaler_hook_t *this = (osdscaler_hook_t*)self;
-
- switch (prop) {
- case VO_PROP_OSD_SCALING:
- if (this->enable != val) {
- LOGOSD("osdscaler_set_property: enable %d->%d", this->enable, val);
- this->enable = val?1:0;
- }
- return this->enable;
- }
-
- return vo_def_set_property(self, prop, val);
-}
-
-
-/*
- * dispose()
- */
-static void osdscaler_dispose(vo_driver_t *self)
-{
- osdscaler_hook_t *this = (osdscaler_hook_t *) self;
-
- osd_data_clear(this->active_osds);
-
- vo_def_dispose(self);
-}
-
-
-/*
- * init()
- */
-vo_driver_t *osdscaler_init(void)
-{
- osdscaler_hook_t *this = calloc(1, sizeof(osdscaler_hook_t));
-
- /* OSD interface */
- this->h.vo.overlay_begin = osdscaler_overlay_begin;
- this->h.vo.overlay_blend = osdscaler_overlay_blend;
- this->h.vo.overlay_end = osdscaler_overlay_end;
-
- /* management interface */
- this->h.vo.get_capabilities = osdscaler_get_capabilities;
- this->h.vo.get_property = osdscaler_get_property;
- this->h.vo.set_property = osdscaler_set_property;
-
- this->h.vo.dispose = osdscaler_dispose;
-
- /* initialize data */
- this->enable = 0;
-
- return &this->h.vo;
-}
-