/*****************************************************************************
* fbosd.c : framebuffer osd plugin for vlc
*****************************************************************************
- * Copyright (C) 2007, the VideoLAN team
+ * Copyright (C) 2007-2008, the VideoLAN team
* $Id$
*
* Authors: Jean-Paul Saman
# include "config.h"
#endif
-#include <vlc/vlc.h>
+#include <vlc_common.h>
+#include <vlc_plugin.h>
+#include <vlc_fs.h>
-#include <errno.h>
#include <stdlib.h> /* free() */
#include <string.h> /* strerror() */
#include <fcntl.h> /* open() */
#include <vlc_osd.h>
#include <vlc_strings.h>
-// #define FBOSD_BLENDING 1
+#undef FBOSD_BLENDING
+#undef FBOSD_DEBUG
/*****************************************************************************
* Local prototypes
static void CloseDisplay ( intf_thread_t * );
/* Load modules needed for rendering and blending */
-#ifdef FBOSD_BLENDING
+#if defined(FBOSD_BLENDING)
static int OpenBlending ( intf_thread_t * );
static void CloseBlending ( intf_thread_t * );
#endif
static int OpenTextRenderer ( intf_thread_t * );
static void CloseTextRenderer( intf_thread_t * );
-#if 0
-static int OpenScaling ( intf_thread_t * );
-static int CloseScaling ( intf_thread_t * );
-#endif
-
/* Manipulate the overlay buffer */
static int OverlayCallback( vlc_object_t *, char const *,
vlc_value_t, vlc_value_t, void * );
-static picture_t *AllocatePicture( vlc_object_t *,
- video_format_t * );
-static void DeAllocatePicture( vlc_object_t *, picture_t *,
- video_format_t * );
+static picture_t *AllocatePicture( video_format_t * );
+static void DeAllocatePicture( picture_t *, video_format_t * );
static void SetOverlayTransparency( intf_thread_t *,
bool );
static picture_t *LoadImage( intf_thread_t *, video_format_t *,
char * );
-#ifdef FBOSD_BLENDING
+#if defined(FBOSD_BLENDING)
static int BlendPicture( intf_thread_t *, video_format_t *,
video_format_t *, picture_t *, picture_t * );
#else
#define DISPLAY_LONGTEXT N_( "All rendered images and text will be " \
"displayed on the overlay framebuffer." )
-static int pi_pos_values[] = { 0, 1, 2, 4, 8, 5, 6, 9, 10 };
-static const char *ppsz_pos_descriptions[] =
+static const int pi_pos_values[] = { 0, 1, 2, 4, 8, 5, 6, 9, 10 };
+static const char *const ppsz_pos_descriptions[] =
{ N_("Center"), N_("Left"), N_("Right"), N_("Top"), N_("Bottom"),
N_("Top-Left"), N_("Top-Right"), N_("Bottom-Left"), N_("Bottom-Right") };
-static int pi_color_values[] = { 0xf0000000, 0x00000000, 0x00808080, 0x00C0C0C0,
+static const int pi_color_values[] = {
+ 0xf0000000, 0x00000000, 0x00808080, 0x00C0C0C0,
0x00FFFFFF, 0x00800000, 0x00FF0000, 0x00FF00FF, 0x00FFFF00,
0x00808000, 0x00008000, 0x00008080, 0x0000FF00, 0x00800080,
0x00000080, 0x000000FF, 0x0000FFFF};
-static const char *ppsz_color_descriptions[] = { N_("Default"), N_("Black"),
+static const char *const ppsz_color_descriptions[] = {
+ N_("Default"), N_("Black"),
N_("Gray"), N_("Silver"), N_("White"), N_("Maroon"), N_("Red"),
N_("Fuchsia"), N_("Yellow"), N_("Olive"), N_("Green"),
N_("Teal"), N_("Lime"), N_("Purple"), N_("Navy"), N_("Blue"),
N_("Aqua") };
-vlc_module_begin();
- set_shortname( "fbosd" );
- set_category( CAT_INTERFACE );
- set_subcategory( SUBCAT_INTERFACE_MAIN );
+vlc_module_begin ()
+ set_shortname( "fbosd" )
+ set_category( CAT_INTERFACE )
+ set_subcategory( SUBCAT_INTERFACE_MAIN )
- add_file( "fbosd-dev", "/dev/fb1", NULL, DEVICE_TEXT, DEVICE_LONGTEXT,
- false );
+ add_file( "fbosd-dev", "/dev/fb0", NULL, DEVICE_TEXT, DEVICE_LONGTEXT,
+ false )
add_string( "fbosd-aspect-ratio", "", NULL, ASPECT_RATIO_TEXT,
- ASPECT_RATIO_LONGTEXT, true );
+ ASPECT_RATIO_LONGTEXT, true )
add_string( "fbosd-image", NULL, NULL, FBOSD_IMAGE_TEXT,
- FBOSD_IMAGE_LONGTEXT, true );
+ FBOSD_IMAGE_LONGTEXT, true )
add_string( "fbosd-text", NULL, NULL, FBOSD_TEXT,
- FBOSD_LONGTEXT, true );
+ FBOSD_LONGTEXT, true )
-#ifdef FBOSD_BLENDING
add_integer_with_range( "fbosd-alpha", 255, 0, 255, NULL, ALPHA_TEXT,
- ALPHA_LONGTEXT, true );
-
-#endif
+ ALPHA_LONGTEXT, true )
- set_section( N_("Position"), NULL );
+ set_section( N_("Position"), NULL )
add_integer( "fbosd-x", 0, NULL, POSX_TEXT,
- POSX_LONGTEXT, false );
+ POSX_LONGTEXT, false )
add_integer( "fbosd-y", 0, NULL, POSY_TEXT,
- POSY_LONGTEXT, false );
- add_integer( "fbosd-position", 8, NULL, POS_TEXT, POS_LONGTEXT, true );
- change_integer_list( pi_pos_values, ppsz_pos_descriptions, 0 );
+ POSY_LONGTEXT, false )
+ add_integer( "fbosd-position", 8, NULL, POS_TEXT, POS_LONGTEXT, true )
+ change_integer_list( pi_pos_values, ppsz_pos_descriptions, NULL );
- set_section( N_("Font"), NULL );
+ set_section( N_("Font"), NULL )
add_integer_with_range( "fbosd-font-opacity", 255, 0, 255, NULL,
- OPACITY_TEXT, OPACITY_LONGTEXT, false );
+ OPACITY_TEXT, OPACITY_LONGTEXT, false )
add_integer( "fbosd-font-color", 0x00FFFFFF, NULL, COLOR_TEXT, COLOR_LONGTEXT,
- false );
- change_integer_list( pi_color_values, ppsz_color_descriptions, 0 );
+ false )
+ change_integer_list( pi_color_values, ppsz_color_descriptions, NULL );
add_integer( "fbosd-font-size", -1, NULL, SIZE_TEXT, SIZE_LONGTEXT,
- false );
+ false )
- set_section( N_("Commands"), NULL );
- add_bool( "fbosd-clear", false, NULL, CLEAR_TEXT, CLEAR_LONGTEXT, true );
- add_bool( "fbosd-render", false, NULL, RENDER_TEXT, RENDER_LONGTEXT, true );
- add_bool( "fbosd-display", false, NULL, DISPLAY_TEXT, DISPLAY_LONGTEXT, true );
+ set_section( N_("Commands"), NULL )
+ add_bool( "fbosd-clear", false, NULL, CLEAR_TEXT, CLEAR_LONGTEXT, true )
+ add_bool( "fbosd-render", false, NULL, RENDER_TEXT, RENDER_LONGTEXT, true )
+ add_bool( "fbosd-display", false, NULL, DISPLAY_TEXT, DISPLAY_LONGTEXT, true )
- set_description( _("GNU/Linux osd/overlay framebuffer interface") );
- set_capability( "interface", 10 );
- set_callbacks( Create, Destroy );
-vlc_module_end();
+ set_description( N_("GNU/Linux osd/overlay framebuffer interface") )
+ set_capability( "interface", 10 )
+ set_callbacks( Create, Destroy )
+vlc_module_end ()
/*****************************************************************************
* fbosd_render_t: render descriptor
int i_state;
/* Font style */
- text_style_t text_style; /* font control */
+ text_style_t* p_text_style; /* font control */
char *psz_string;
- /* Positon */
- bool b_absolute;
+ /* Position */
+ bool b_absolute;
int i_x;
int i_y;
int i_pos;
/* Image and Picture rendering */
image_handler_t *p_image;
-#ifdef FBOSD_BLENDING
+#if defined(FBOSD_BLENDING)
filter_t *p_blend; /* alpha blending module */
#endif
filter_t *p_text; /* text renderer module */
-#if 0
- filter_t *p_scale; /* scaling module */
-#endif
/* Render */
struct fbosd_render_t render[FBOSD_RENDER_MAX];
/* Font style */
text_style_t *p_style; /* font control */
- /* Positon */
+ /* Position */
bool b_absolute;
- int i_x;
- int i_y;
- int i_pos;
+ int i_x;
+ int i_y;
+ int i_pos;
- int i_alpha; /* transparency for images */
+ int i_alpha; /* transparency for images */
/* commands control */
bool b_need_update; /* update display with \overlay buffer */
char *psz_tmp;
int i;
-
/* Allocate instance and initialize some members */
- p_intf->p_sys = p_sys = malloc( sizeof( intf_sys_t ) );
+ p_intf->p_sys = p_sys = calloc( 1, sizeof( intf_sys_t ) );
if( !p_intf->p_sys )
- {
- msg_Err( p_intf, "out of memory" );
return VLC_ENOMEM;
- };
- memset( p_sys, 0, sizeof(intf_sys_t) );
- p_sys->p_style = malloc( sizeof( text_style_t ) );
+ p_sys->p_style = text_style_New();
if( !p_sys->p_style )
{
free( p_intf->p_sys );
- msg_Err( p_intf, "out of memory" );
return VLC_ENOMEM;
}
- p_intf->p_libvlc->pf_memcpy( p_sys->p_style, &default_text_style,
- sizeof( text_style_t ) );
p_intf->pf_run = Run;
p_sys->p_image = image_HandlerCreate( p_this );
if( !p_sys->p_image )
{
- free( p_intf->p_sys->p_style );
- free( p_intf->p_sys );
- msg_Err( p_intf, "out of memory" );
+ text_style_Delete( p_sys->p_style );
+ free( p_sys );
return VLC_ENOMEM;
}
-#ifdef FBOSD_BLENDING
p_sys->i_alpha = var_CreateGetIntegerCommand( p_intf, "fbosd-alpha" );
var_AddCallback( p_intf, "fbosd-alpha", OverlayCallback, NULL );
-#else
- p_sys->i_alpha = 255;
-#endif
+
+ /* Use PAL by default */
+ p_sys->i_width = p_sys->fmt_out.i_width = 704;
+ p_sys->i_height = p_sys->fmt_out.i_height = 576;
+
p_sys->i_aspect = -1;
psz_aspect =
var_CreateGetNonEmptyString( p_intf, "fbosd-aspect-ratio" );
*psz_parser++ = '\0';
p_sys->i_aspect = ( atoi( psz_aspect )
* VOUT_ASPECT_FACTOR ) / atoi( psz_parser );
- p_sys->fmt_out.i_aspect = p_sys->i_aspect;
+ p_sys->fmt_out.i_sar_num = p_sys->i_aspect * p_sys->i_height;
+ p_sys->fmt_out.i_sar_den = VOUT_ASPECT_FACTOR * p_sys->i_width;
}
msg_Dbg( p_intf, "using aspect ratio %d:%d",
atoi( psz_aspect ), atoi( psz_parser ) );
free( psz_aspect );
- psz_aspect = NULL;
}
- /* Use PAL by default */
- p_sys->i_width = p_sys->fmt_out.i_width = 704;
- p_sys->i_height = p_sys->fmt_out.i_height = 576;
-
psz_tmp = var_CreateGetNonEmptyStringCommand( p_intf, "fbosd-image" );
var_AddCallback( p_intf, "fbosd-image", OverlayCallback, NULL );
if( psz_tmp && *psz_tmp )
var_AddCallback( p_intf, "fbosd-font-opacity", OverlayCallback, NULL );
for( i = 0; i < FBOSD_RENDER_MAX; i++ )
- {
- p_intf->p_libvlc->pf_memcpy( &p_sys->render[i].text_style,
- &default_text_style,
- sizeof( text_style_t ) );
- }
+ p_sys->render[i].p_text_style = text_style_New();
p_sys->b_clear = var_CreateGetBoolCommand( p_intf, "fbosd-clear" );
p_sys->b_render = var_CreateGetBoolCommand( p_intf, "fbosd-render" );
Init( p_intf );
-#ifdef FBOSD_BLENDING
+#if defined(FBOSD_BLENDING)
/* Load the blending module */
if( OpenBlending( p_intf ) )
{
Destroy( VLC_OBJECT(p_intf) );
return VLC_EGENERIC;
}
-#if 0
- /* Load scaling module */
- if( OpenScaling( p_intf ) )
- {
- msg_Err( p_intf, "Unable to load image scaling module" );
- Destroy( VLC_OBJECT(p_intf) );
- return VLC_EGENERIC;
- }
-#endif
+
p_sys->b_render = true;
p_sys->b_need_update = true;
static void Destroy( vlc_object_t *p_this )
{
intf_thread_t *p_intf = (intf_thread_t *)p_this;
- intf_sys_t *p_sys = (intf_sys_t *) p_intf->p_sys;
+ intf_sys_t *p_sys = p_intf->p_sys;
int i;
+
p_sys->b_need_update = false;
p_sys->b_render = false;
p_sys->b_clear = false;
-#ifdef FBOSD_BLENDING
var_DelCallback( p_intf, "fbosd-alpha", OverlayCallback, NULL );
var_Destroy( p_intf, "fbosd-alpha" );
-#endif
var_DelCallback( p_intf, "fbosd-x", OverlayCallback, NULL );
var_DelCallback( p_intf, "fbosd-y", OverlayCallback, NULL );
{
free( p_sys->render[i].psz_string );
p_sys->render[i].i_state = FBOSD_STATE_FREE;
+ text_style_Delete( p_sys->render[i].p_text_style );
}
-#ifdef FBOSD_BLENDING
+#if defined(FBOSD_BLENDING)
if( p_sys->p_blend ) CloseBlending( p_intf );
#endif
if( p_sys->p_text ) CloseTextRenderer( p_intf );
-#if 0
- if( p_sys->p_scale ) CloseScaling( p_intf );
-#endif
+
if( p_sys->p_image )
image_HandlerDelete( p_sys->p_image );
if( p_sys->p_overlay )
- p_sys->p_overlay->pf_release( p_sys->p_overlay );
+ picture_Release( p_sys->p_overlay );
- free( p_sys->p_style );
+ text_style_Delete( p_sys->p_style );
free( p_sys );
}
-#ifdef FBOSD_BLENDING
+#if defined(FBOSD_BLENDING)
static int OpenBlending( intf_thread_t *p_intf )
{
if( p_intf->p_sys->p_blend ) return VLC_EGENERIC;
p_intf->p_sys->p_blend =
- vlc_object_create( p_intf, VLC_OBJECT_FILTER );
+ vlc_object_create( p_intf, sizeof(filter_t) );
vlc_object_attach( p_intf->p_sys->p_blend, p_intf );
p_intf->p_sys->p_blend->fmt_out.video.i_x_offset =
p_intf->p_sys->p_blend->fmt_out.video.i_y_offset = 0;
- p_intf->p_sys->p_blend->fmt_out.video.i_aspect =
- p_intf->p_sys->fmt_out.i_aspect;
+ p_intf->p_sys->p_blend->fmt_out.video.i_sar_num =
+ p_intf->p_sys->fmt_out.i_sar_num;
+ p_intf->p_sys->p_blend->fmt_out.video.i_sar_den =
+ p_intf->p_sys->fmt_out.i_sar_den;
p_intf->p_sys->p_blend->fmt_out.video.i_chroma =
p_intf->p_sys->fmt_out.i_chroma;
- if( config_GetInt( p_intf, "freetype-yuvp" ) )
+ if( var_InheritBool( p_intf, "freetype-yuvp" ) )
p_intf->p_sys->p_blend->fmt_in.video.i_chroma =
- VLC_FOURCC('Y','U','V','P');
+ VLC_CODEC_YUVP;
else
p_intf->p_sys->p_blend->fmt_in.video.i_chroma =
- VLC_FOURCC('Y','U','V','A');
+ VLC_CODEC_YUVA;
p_intf->p_sys->p_blend->p_module =
- module_Need( p_intf->p_sys->p_blend, "video blending", 0, 0 );
+ module_need( p_intf->p_sys->p_blend, "video blending", NULL, false );
if( !p_intf->p_sys->p_blend->p_module )
return VLC_EGENERIC;
if( p_intf->p_sys->p_blend )
{
if( p_intf->p_sys->p_blend->p_module )
- module_Unneed( p_intf->p_sys->p_blend,
+ module_unneed( p_intf->p_sys->p_blend,
p_intf->p_sys->p_blend->p_module );
- vlc_object_detach( p_intf->p_sys->p_blend );
vlc_object_release( p_intf->p_sys->p_blend );
}
}
if( p_intf->p_sys->p_text ) return VLC_EGENERIC;
p_intf->p_sys->p_text =
- vlc_object_create( p_intf, VLC_OBJECT_FILTER );
+ vlc_object_create( p_intf, sizeof(filter_t) );
vlc_object_attach( p_intf->p_sys->p_text, p_intf );
p_intf->p_sys->p_text->fmt_out.video.i_width =
if( psz_modulename && *psz_modulename )
{
p_intf->p_sys->p_text->p_module =
- module_Need( p_intf->p_sys->p_text, "text renderer",
+ module_need( p_intf->p_sys->p_text, "text renderer",
psz_modulename, true );
}
if( !p_intf->p_sys->p_text->p_module )
{
p_intf->p_sys->p_text->p_module =
- module_Need( p_intf->p_sys->p_text, "text renderer", 0, 0 );
+ module_need( p_intf->p_sys->p_text, "text renderer", NULL, false );
}
free( psz_modulename );
if( p_intf->p_sys->p_text )
{
if( p_intf->p_sys->p_text->p_module )
- module_Unneed( p_intf->p_sys->p_text,
+ module_unneed( p_intf->p_sys->p_text,
p_intf->p_sys->p_text->p_module );
- vlc_object_detach( p_intf->p_sys->p_text );
vlc_object_release( p_intf->p_sys->p_text );
}
}
-#if 0
-static int OpenScaling( intf_thread_t *p_intf )
-{
- if( p_intf->p_sys->p_scale ) return VLC_EGENERIC;
-
- p_intf->p_sys->p_scale =
- vlc_object_create( p_intf, VLC_OBJECT_FILTER );
- vlc_object_attach( p_intf->p_sys->p_scale, p_intf );
- p_intf->p_sys->p_scale->fmt_out.video.i_chroma =
- p_intf->p_sys->p_scale->fmt_in.video.i_chroma =
- p_intf->p_sys->fmt_out.i_chroma;
-
- /* XXX: We'll also be using it for YUVA and RGBA blending ... */
- p_intf->p_sys->p_scale->fmt_in.video.i_width =
- p_intf->p_sys->p_scale->fmt_in.video.i_height = 32;
- p_intf->p_sys->p_scale->fmt_out.video.i_width =
- p_intf->p_sys->p_scale->fmt_out.video.i_height = 16;
-
- p_intf->p_sys->p_scale->p_module =
- module_Need( p_intf->p_sys->p_scale, "video filter2", 0, 0 );
-
- if( !p_intf->p_sys->p_scale->p_module )
- return VLC_EGENERIC;
-
- return VLC_SUCCESS;
-}
-
-static int CloseScaling( intf_thread_t *p_intf )
-{
- if( p_intf->p_sys->p_scale )
- {
- if( p_intf->p_sys->p_scale->p_module )
- module_Unneed( p_intf->p_sys->p_scale,
- p_intf->p_sys->p_scale->p_module );
-
- vlc_object_detach( p_intf->p_sys->p_scale );
- vlc_object_release( p_intf->p_sys->p_scale );
- }
-}
-#endif
/*****************************************************************************
* AllocatePicture:
* allocate a picture buffer for use with the overlay fb.
*****************************************************************************/
-static picture_t *AllocatePicture( vlc_object_t *p_this,
- video_format_t *p_fmt )
+static picture_t *AllocatePicture( video_format_t *p_fmt )
{
- picture_t *p_pic = malloc( sizeof( picture_t ) );
- if( !p_pic ) return NULL;
+ picture_t *p_picture = picture_NewFromFormat( p_fmt );
+ if( !p_picture )
+ return NULL;
if( !p_fmt->p_palette &&
- ( p_fmt->i_chroma == VLC_FOURCC('Y','U','V','P') ) )
+ ( p_fmt->i_chroma == VLC_CODEC_YUVP ) )
{
p_fmt->p_palette = malloc( sizeof(video_palette_t) );
if( !p_fmt->p_palette )
{
- free( p_pic );
+ picture_Release( p_picture );
return NULL;
}
}
- else p_fmt->p_palette = NULL;
-
- p_pic->p_data_orig = NULL;
-
- vout_AllocatePicture( p_this, p_pic, p_fmt->i_chroma,
- p_fmt->i_width, p_fmt->i_height, p_fmt->i_aspect );
-
- if( !p_pic->i_planes )
+ else
{
- free( p_pic );
- free( p_fmt->p_palette );
- return NULL;
+ p_fmt->p_palette = NULL;
}
- return p_pic;
+
+ return p_picture;
}
/*****************************************************************************
* DeAllocatePicture:
* Deallocate a picture buffer and free all associated memory.
*****************************************************************************/
-static void DeAllocatePicture( vlc_object_t *p_this, picture_t *p_pic,
- video_format_t *p_fmt )
+static void DeAllocatePicture( picture_t *p_pic, video_format_t *p_fmt )
{
- VLC_UNUSED(p_this);
- if( p_pic )
- {
- free( p_pic->p_data_orig );
- if( p_pic->pf_release ) p_pic->pf_release( p_pic );
- }
if( p_fmt )
{
free( p_fmt->p_palette );
p_fmt->p_palette = NULL;
}
- p_pic = NULL;
+
+ if( p_pic )
+ picture_Release( p_pic );
}
/*****************************************************************************
static void SetOverlayTransparency( intf_thread_t *p_intf,
bool b_transparent )
{
- intf_sys_t *p_sys = (intf_sys_t *) p_intf->p_sys;
+ intf_sys_t *p_sys = p_intf->p_sys;
size_t i_size = p_sys->fmt_out.i_width * p_sys->fmt_out.i_height
* p_sys->i_bytes_per_pixel;
size_t i_page_size = (p_sys->i_page_size > i_size) ?
{
msg_Dbg( p_intf, "Make overlay %s",
b_transparent ? "transparent" : "opaque" );
- memset( p_sys->p_overlay->p[0].p_pixels, 0x00, i_page_size );
if( b_transparent )
memset( p_sys->p_overlay->p[0].p_pixels, 0xFF, i_page_size );
+ else
+ memset( p_sys->p_overlay->p[0].p_pixels, 0x00, i_page_size );
}
}
-#ifdef FBOSD_BLENDING
+#if defined(FBOSD_BLENDING)
/*****************************************************************************
* BlendPicture: Blend two pictures together..
*****************************************************************************/
video_format_t *p_fmt_dst, picture_t *p_pic_src,
picture_t *p_pic_dst )
{
- intf_sys_t *p_sys = (intf_sys_t *) p_intf->p_sys;
+ intf_sys_t *p_sys = p_intf->p_sys;
if( p_sys->p_blend && p_sys->p_blend->p_module )
{
int i_x_offset = p_sys->i_x;
int i_y_offset = p_sys->i_y;
memcpy( &p_sys->p_blend->fmt_in.video, p_fmt_src, sizeof( video_format_t ) );
-#if 0
- msg_Dbg( p_intf, "Blending pictures %p %4.4s (%dx%d) %d bits %d planes: 0=%p 1=%p 2=%p 3=%p",
- p_pic_src, (char*)&p_fmt_src->i_chroma,
- p_sys->p_blend->fmt_in.video.i_width, p_sys->p_blend->fmt_in.video.i_height,
- p_fmt_src->i_bits_per_pixel,
- p_pic_src->i_planes,
- p_pic_src->p[0].p_pixels, p_pic_src->p[1].p_pixels,
- p_pic_src->p[2].p_pixels, p_pic_src->p[3].p_pixels );
- msg_Dbg( p_intf, "Blending pictures %p %4.4s (%dx%d) %d bits %d planes: 0=%p 1=%p 2=%p 3=%p",
- p_pic_dst, (char*)&p_fmt_dst->i_chroma,
- p_fmt_dst->i_width, p_fmt_dst->i_height,
- p_fmt_dst->i_bits_per_pixel,
- p_pic_dst->i_planes,
- p_pic_dst->p[0].p_pixels, p_pic_dst->p[1].p_pixels,
- p_pic_dst->p[2].p_pixels, p_pic_dst->p[3].p_pixels );
-#endif
+
/* Update the output picture size */
p_sys->p_blend->fmt_out.video.i_width =
p_sys->p_blend->fmt_out.video.i_visible_width =
}
return VLC_EGENERIC;
}
+
+static int InvertAlpha( intf_thread_t *p_intf, picture_t **p_pic, video_format_t fmt )
+{
+ uint8_t *p_begin = NULL, *p_end = NULL;
+ uint8_t i_skip = 0;
+
+ if( *p_pic && ((*p_pic)->i_planes != 1) )
+ {
+ msg_Err( p_intf,
+ "cannot invert alpha channel too many planes %d (only 1 supported)",
+ (*p_pic)->i_planes );
+ return VLC_EGENERIC;
+ }
+
+ switch( fmt.i_chroma )
+ {
+ case VLC_CODEC_RGB24:
+ p_begin = (uint8_t *)(*p_pic)->p[Y_PLANE].p_pixels;
+ p_end = (uint8_t *)(*p_pic)->p[Y_PLANE].p_pixels +
+ ( fmt.i_height * (*p_pic)->p[Y_PLANE].i_pitch );
+ i_skip = 3;
+ break;
+ case VLC_CODEC_RGB32:
+ p_begin = (uint8_t *)(*p_pic)->p[Y_PLANE].p_pixels;
+ p_end = (uint8_t *)(*p_pic)->p[Y_PLANE].p_pixels +
+ ( fmt.i_height * (*p_pic)->p[Y_PLANE].i_pitch );
+ i_skip = 4;
+ break;
+ default:
+ msg_Err( p_intf, "cannot invert alpha channel chroma not supported %4.4s",
+ (char *)&fmt.i_chroma );
+ return VLC_EGENERIC;
+ }
+
+ for( ; p_begin < p_end; p_begin += i_skip )
+ {
+ uint8_t i_opacity = 0;
+
+ if( *p_begin != 0xFF )
+ i_opacity = 255 - *p_begin;
+ *p_begin = i_opacity;
+ }
+ /* end of kludge */
+ return VLC_SUCCESS;
+}
#endif
/*****************************************************************************
picture_t *p_src, picture_t *p_dest )
{
int i;
+ VLC_UNUSED( p_intf );
if( !p_dest && !p_src ) return VLC_EGENERIC;
if( p_src->p[i].i_pitch == p_dest->p[i].i_pitch )
{
/* There are margins, but with the same width : perfect ! */
- p_intf->p_libvlc->pf_memcpy(
- p_dest->p[i].p_pixels, p_src->p[i].p_pixels,
- p_src->p[i].i_pitch * p_src->p[i].i_visible_lines );
+ vlc_memcpy( p_dest->p[i].p_pixels, p_src->p[i].p_pixels,
+ p_src->p[i].i_pitch * p_src->p[i].i_visible_lines );
}
else
{
i_y_clip = ( i_y_offset + p_src->p[i].i_visible_lines ) - p_dest->p[i].i_visible_lines;
i_y_clip = ( i_y_clip > 0 ) ? i_y_clip : 0;
-#if 0
+#if defined(FBOSD_DEBUG)
msg_Dbg( p_intf, "i_pitch (%d,%d), (%d,%d)/(%d,%d)",
p_dest->p[i].i_visible_pitch, p_src->p[i].i_visible_pitch,
i_x_offset, i_y_offset, i_x, i_x_clip );
p_out += ( i_y_offset * p_dest->p[i].i_pitch );
for( i_line = 0; i_line < ( p_src->p[i].i_visible_lines - i_y_clip ); i_line++ )
{
- p_intf->p_libvlc->pf_memcpy( p_out + i_x, p_in,
- p_src->p[i].i_visible_pitch - i_x_clip );
+ vlc_memcpy( p_out + i_x, p_in,
+ p_src->p[i].i_visible_pitch - i_x_clip );
p_in += p_src->p[i].i_pitch;
p_out += p_dest->p[i].i_pitch;
}
static picture_t *RenderText( intf_thread_t *p_intf, const char *psz_string,
text_style_t *p_style, video_format_t *p_fmt )
{
- intf_sys_t *p_sys = (intf_sys_t *) p_intf->p_sys;
+ intf_sys_t *p_sys = p_intf->p_sys;
subpicture_region_t *p_region;
picture_t *p_dest = NULL;
if( p_sys->p_text && p_sys->p_text->p_module )
{
- p_region = (subpicture_region_t *) malloc( sizeof(subpicture_region_t) );
+ video_format_t fmt;
+
+ memset( &fmt, 0, sizeof(fmt) );
+ fmt.i_chroma = VLC_CODEC_TEXT;
+ fmt.i_width = fmt.i_visible_width = 0;
+ fmt.i_height = fmt.i_visible_height = 0;
+ fmt.i_x_offset = 0;
+ fmt.i_y_offset = 0;
+
+ p_region = subpicture_region_New( &fmt );
if( !p_region )
return p_dest;
- memset( p_region, 0, sizeof(subpicture_region_t) );
-
p_region->psz_text = strdup( psz_string );
- p_region->p_style = p_style;
-
- p_region->fmt.i_chroma = VLC_FOURCC('T','E','X','T');
- p_region->fmt.i_aspect = 0;
- p_region->fmt.i_width = p_region->fmt.i_visible_width = 0;
- p_region->fmt.i_height = p_region->fmt.i_visible_height = 0;
- p_region->fmt.i_x_offset = 0;
- p_region->fmt.i_y_offset = 0;
-
- p_region->i_align = OSD_ALIGN_LEFT | OSD_ALIGN_TOP;
+ if( !p_region->psz_text )
+ {
+ subpicture_region_Delete( p_region );
+ return NULL;
+ }
+ p_region->p_style = text_style_Duplicate( p_style );
+ p_region->i_align = SUBPICTURE_ALIGN_LEFT | SUBPICTURE_ALIGN_TOP;
if( p_sys->p_text->pf_render_text )
{
p_sys->p_text->pf_render_text( p_sys->p_text,
p_region, p_region );
-#ifndef FBOSD_BLENDING
- fmt_out.i_chroma = p_fmt->i_chroma;
- p_dest = ConvertImage( p_intf, &p_region->picture,
- &p_region->fmt, &fmt_out );
-#else
+#if defined(FBOSD_BLENDING)
fmt_out = p_region->fmt;
fmt_out.i_bits_per_pixel = 32;
- p_intf->p_libvlc->pf_memcpy( p_fmt, &fmt_out,
- sizeof(video_format_t) );
+ vlc_memcpy( p_fmt, &fmt_out, sizeof(video_format_t) );
+ /* FIXME not needed to copy the picture anymore no ? */
p_dest = AllocatePicture( VLC_OBJECT(p_intf), &fmt_out );
if( !p_dest )
{
- if( p_region->picture.pf_release )
- p_region->picture.pf_release( &p_region->picture );
- free( p_region->psz_text );
- free( p_region );
+ subpicture_region_Delete( p_region );
return NULL;
}
- vout_CopyPicture( VLC_OBJECT(p_intf), p_dest, &p_region->picture );
+ picture_Copy( p_dest, p_region->p_picture );
+#else
+ fmt_out.i_chroma = p_fmt->i_chroma;
+ p_dest = ConvertImage( p_intf, p_region->p_picture,
+ &p_region->fmt, &fmt_out );
#endif
- if( p_region->picture.pf_release )
- p_region->picture.pf_release( &p_region->picture );
- free( p_region->psz_text );
- free( p_region );
+ subpicture_region_Delete( p_region );
return p_dest;
}
- free( p_region->psz_text );
- free( p_region );
+ subpicture_region_Delete( p_region );
}
return p_dest;
}
return p_pic;
}
-#ifndef FBOSD_BLENDING
+#if ! defined(FBOSD_BLENDING)
/*****************************************************************************
* Convertmage: Convert image to another fourcc
*****************************************************************************/
static picture_t *ConvertImage( intf_thread_t *p_intf, picture_t *p_pic,
video_format_t *p_fmt_in, video_format_t *p_fmt_out )
{
- intf_sys_t *p_sys = (intf_sys_t *) p_intf->p_sys;
+ intf_sys_t *p_sys = p_intf->p_sys;
picture_t *p_old = NULL;
if( p_sys->p_image )
*****************************************************************************/
static int Init( intf_thread_t *p_intf )
{
- intf_sys_t *p_sys = (intf_sys_t *) p_intf->p_sys;
+ intf_sys_t *p_sys = p_intf->p_sys;
/* Initialize the output structure: RGB with square pixels, whatever
* the input format is, since it's the only format we know */
switch( p_sys->var_info.bits_per_pixel )
{
case 8: /* FIXME: set the palette */
- p_sys->fmt_out.i_chroma = VLC_FOURCC('R','G','B','2'); break;
+ p_sys->fmt_out.i_chroma = VLC_CODEC_RGB8; break;
case 15:
- p_sys->fmt_out.i_chroma = VLC_FOURCC('R','V','1','5'); break;
+ p_sys->fmt_out.i_chroma = VLC_CODEC_RGB15; break;
case 16:
- p_sys->fmt_out.i_chroma = VLC_FOURCC('R','V','1','6'); break;
+ p_sys->fmt_out.i_chroma = VLC_CODEC_RGB16; break;
case 24:
- p_sys->fmt_out.i_chroma = VLC_FOURCC('R','V','2','4'); break;
+ p_sys->fmt_out.i_chroma = VLC_CODEC_RGB24; break;
case 32:
- p_sys->fmt_out.i_chroma = VLC_FOURCC('R','V','3','2'); break;
+ p_sys->fmt_out.i_chroma = VLC_CODEC_RGB32; break;
default:
msg_Err( p_intf, "unknown screen depth %i",
p_sys->var_info.bits_per_pixel );
/* Assume we have square pixels */
if( p_sys->i_aspect < 0 )
{
- p_sys->fmt_out.i_aspect = ( p_sys->i_width
- * VOUT_ASPECT_FACTOR ) / p_sys->i_height;
+ p_sys->fmt_out.i_sar_num = 1;
+ p_sys->fmt_out.i_sar_den = 1;
+ }
+ else
+ {
+ p_sys->fmt_out.i_sar_num = p_sys->i_aspect * p_sys->i_height;
+ p_sys->fmt_out.i_sar_den = VOUT_ASPECT_FACTOR * p_sys->i_width;
}
- else p_sys->fmt_out.i_aspect = p_sys->i_aspect;
-
- p_sys->fmt_out.i_sar_num = p_sys->fmt_out.i_sar_den = 1;
/* Allocate overlay buffer */
- p_sys->p_overlay = AllocatePicture( VLC_OBJECT(p_intf),
- &p_sys->fmt_out );
+ p_sys->p_overlay = AllocatePicture( &p_sys->fmt_out );
if( !p_sys->p_overlay ) return VLC_EGENERIC;
SetOverlayTransparency( p_intf, true );
*****************************************************************************/
static void End( intf_thread_t *p_intf )
{
- intf_sys_t *p_sys = (intf_sys_t *) p_intf->p_sys;
+ intf_sys_t *p_sys = p_intf->p_sys;
/* CleanUp */
SetOverlayTransparency( p_intf, false );
if( p_sys->p_overlay )
{
int ret;
- ret = write( p_sys->i_fd, p_sys->p_overlay->p[0].p_pixels, p_sys->i_page_size );
+ ret = write( p_sys->i_fd, p_sys->p_overlay->p[0].p_pixels,
+ p_sys->i_page_size );
if( ret < 0 )
msg_Err( p_intf, "unable to clear overlay" );
}
- DeAllocatePicture( VLC_OBJECT(p_intf), p_intf->p_sys->p_overlay,
+ DeAllocatePicture( p_intf->p_sys->p_overlay,
&p_intf->p_sys->fmt_out );
p_intf->p_sys->p_overlay = NULL;
}
*****************************************************************************/
static int OpenDisplay( intf_thread_t *p_intf )
{
- intf_sys_t *p_sys = (intf_sys_t *) p_intf->p_sys;
+ intf_sys_t *p_sys = p_intf->p_sys;
char *psz_device; /* framebuffer device path */
struct fb_fix_screeninfo fix_info; /* framebuffer fix information */
/* Open framebuffer device */
- if( !(psz_device = config_GetPsz( p_intf, "fbosd-dev" )) )
+ if( !(psz_device = var_InheritString( p_intf, "fbosd-dev" )) )
{
msg_Err( p_intf, "don't know which fb osd/overlay device to open" );
return VLC_EGENERIC;
}
- p_sys->i_fd = open( psz_device, O_RDWR );
+ p_sys->i_fd = vlc_open( psz_device, O_RDWR );
if( p_sys->i_fd == -1 )
{
- msg_Err( p_intf, "cannot open %s (%s)", psz_device, strerror(errno) );
+ msg_Err( p_intf, "cannot open %s (%m)", psz_device );
free( psz_device );
return VLC_EGENERIC;
}
/* Get framebuffer device information */
if( ioctl( p_sys->i_fd, FBIOGET_VSCREENINFO, &p_sys->var_info ) )
{
- msg_Err( p_intf, "cannot get fb info (%s)", strerror(errno) );
+ msg_Err( p_intf, "cannot get fb info (%m)" );
close( p_sys->i_fd );
return VLC_EGENERIC;
}
p_sys->p_palette = malloc( 8 * 256 * sizeof( uint16_t ) );
if( !p_sys->p_palette )
{
- msg_Err( p_intf, "out of memory" );
close( p_sys->i_fd );
return VLC_ENOMEM;
}
*****************************************************************************/
static void CloseDisplay( intf_thread_t *p_intf )
{
- intf_sys_t *p_sys = (intf_sys_t *) p_intf;
+ intf_sys_t *p_sys = p_intf->p_sys;
/* Restore palette */
if( p_sys->var_info.bits_per_pixel == 8 )
static void Render( intf_thread_t *p_intf, struct fbosd_render_t *render )
{
- intf_sys_t *p_sys = (intf_sys_t*) p_intf->p_sys;
+ intf_sys_t *p_sys = p_intf->p_sys;
if( render->i_state != FBOSD_STATE_RENDER ) return;
if( !render->psz_string ) return;
{
RenderPicture( p_intf, render->i_x, render->i_y,
p_pic, p_sys->p_overlay );
- p_pic->pf_release( p_pic );
+ picture_Release( p_pic );
}
}
else if( render->i_type == FBOSD_RENDER_TEXT )
{
picture_t *p_text;
-#ifdef FBOSD_BLENDING
+#if defined(FBOSD_BLENDING)
video_format_t fmt_in;
memset( &fmt_in, 0, sizeof(video_format_t) );
- p_text = RenderText( p_intf, render->psz_string, &render->text_style,
+ p_text = RenderText( p_intf, render->psz_string, render->p_text_style,
&fmt_in );
if( p_text )
{
BlendPicture( p_intf, &fmt_in, &p_sys->fmt_out,
p_text, p_sys->p_overlay );
msg_Dbg( p_intf, "releasing picture" );
- DeAllocatePicture( VLC_OBJECT( p_intf ), p_text, &fmt_in );
+ DeAllocatePicture( p_text, &fmt_in );
}
#else
- p_text = RenderText( p_intf, render->psz_string, &render->text_style,
+ p_text = RenderText( p_intf, render->psz_string, render->p_text_style,
&p_sys->fmt_out );
if( p_text )
{
RenderPicture( p_intf, render->i_x, render->i_y,
p_text, p_sys->p_overlay );
- p_text->pf_release( p_text );
+ picture_Release( p_text );
}
#endif
}
static void RenderClear( intf_thread_t *p_intf, struct fbosd_render_t *render )
{
- intf_sys_t *p_sys = (intf_sys_t*) p_intf->p_sys;
+ intf_sys_t *p_sys = p_intf->p_sys;
- p_intf->p_libvlc->pf_memcpy( &render->text_style, &default_text_style,
- sizeof( text_style_t ) );
+ text_style_Delete( render->p_text_style );
+ render->p_text_style = text_style_New();
free( render->psz_string );
render->psz_string = NULL;
render->i_x = p_sys->i_x;
render->i_y = p_sys->i_y;
render->i_pos = p_sys->i_pos;
-#ifdef FBOSD_BLENDING
render->i_alpha = p_sys->i_alpha;
-#endif
render->b_absolute = p_sys->b_absolute;
render->i_state = FBOSD_STATE_FREE;
}
static bool isRendererReady( intf_thread_t *p_intf )
{
- intf_sys_t *p_sys = (intf_sys_t*) p_intf->p_sys;
+ intf_sys_t *p_sys = p_intf->p_sys;
int i;
/* Check if there are more items to render */
}
/*****************************************************************************
- * Run: rc thread
+ * Run: thread
*****************************************************************************
* This part of the interface is in a separate thread so that we can call
* exec() from within it without annoying the rest of the program.
*****************************************************************************/
static void Run( intf_thread_t *p_intf )
{
- intf_sys_t *p_sys = (intf_sys_t*) p_intf->p_sys;
+ intf_sys_t *p_sys = p_intf->p_sys;
+ int canc = vlc_savecancel();
- while( !intf_ShouldDie( p_intf ) )
+ while( vlc_object_alive( p_intf ) )
{
int i;
{
Render( p_intf, &p_sys->render[i] );
RenderClear( p_intf, &p_sys->render[i] );
- }
- }
+ }
+ }
if( p_sys->b_clear )
{
isRendererReady( p_intf ) )
{
int ret;
+#if defined(FBOSD_BLENDING)
+ /* Reverse alpha channel to work around FPGA bug */
+ InvertAlpha( p_intf, &p_sys->p_overlay, p_sys->fmt_out );
+#endif
ret = write( p_sys->i_fd, p_sys->p_overlay->p[0].p_pixels,
p_sys->i_page_size );
if( ret < 0 )
p_sys->b_need_update = false;
}
- if( vlc_CPU() & CPU_CAPABILITY_FPU )
- msleep( INTF_IDLE_SLEEP );
- else
- msleep( 500 );
+ msleep( INTF_IDLE_SLEEP );
}
End( p_intf );
+ vlc_restorecancel( canc );
}
static int OverlayCallback( vlc_object_t *p_this, char const *psz_cmd,
vlc_value_t oldval, vlc_value_t newval, void *p_data )
{
intf_thread_t *p_intf = (intf_thread_t *) p_this;
- intf_sys_t *p_sys = (intf_sys_t*) p_intf->p_sys;
+ intf_sys_t *p_sys = p_intf->p_sys;
VLC_UNUSED(oldval); VLC_UNUSED(p_data);
if( !strncmp( psz_cmd, "fbosd-display", 13 ) )
}
else if( !strncmp( psz_cmd, "fbosd-font-size", 15 ) )
{
- p_sys->render[i].text_style.i_font_size = newval.i_int;
+ p_sys->render[i].p_text_style->i_font_size = newval.i_int;
}
else if( !strncmp( psz_cmd, "fbosd-font-color", 16 ) )
{
- p_sys->render[i].text_style.i_font_color = newval.i_int;
+ p_sys->render[i].p_text_style->i_font_color = newval.i_int;
}
else if( !strncmp( psz_cmd, "fbosd-font-opacity", 18 ) )
{
- p_sys->render[i].text_style.i_font_alpha = 255 - newval.i_int;
+ p_sys->render[i].p_text_style->i_font_alpha = 255 - newval.i_int;
}
-#ifdef FBOSD_BLENDING
else if( !strncmp( psz_cmd, "fbosd-alpha", 11 ) )
{
p_sys->render[i].i_alpha = newval.i_int;
}
-#endif
}
return VLC_SUCCESS;
}