X-Git-Url: https://git.sesse.net/?a=blobdiff_plain;f=modules%2Fcodec%2Fzvbi.c;h=a5e5df666ed37a0632ac3146e6be61974ed67510;hb=07461467f965bf926c14f2d4a4096b84db7fe44e;hp=50c4edf7d26437f7c574e9829e37b0db50e237f1;hpb=d466fd4185ffd791413658e948205e2676d2f470;p=vlc diff --git a/modules/codec/zvbi.c b/modules/codec/zvbi.c index 50c4edf7d2..a5e5df666e 100644 --- a/modules/codec/zvbi.c +++ b/modules/codec/zvbi.c @@ -7,20 +7,21 @@ * Authors: Derk-Jan Hartman * Jean-Paul Saman * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation; either version 2.1 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA. + * You should have received a copy of the GNU Lesser General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA. *****************************************************************************/ + /***************************************************************************** * * information on teletext format can be found here : @@ -41,13 +42,15 @@ # include "config.h" #endif +#include + #include #include #include #include #include -#include +#include "substext.h" /***************************************************************************** * Module descriptor. @@ -59,9 +62,9 @@ static void Close( vlc_object_t * ); #define PAGE_LONGTEXT N_("Open the indicated Teletext page." \ "Default page is index 100") -#define OPAQUE_TEXT N_("Text is always opaque") -#define OPAQUE_LONGTEXT N_("Setting vbi-opaque to false " \ - "makes the boxed text transparent." ) +#define OPAQUE_TEXT N_("Teletext transparency") +#define OPAQUE_LONGTEXT N_("Setting vbi-opaque to true " \ + "makes the text to be boxed and maybe easier to read." ) #define POS_TEXT N_("Teletext alignment") #define POS_LONGTEXT N_( \ @@ -86,13 +89,13 @@ vlc_module_begin () set_subcategory( SUBCAT_INPUT_SCODEC ) set_callbacks( Open, Close ) - add_integer( "vbi-page", 100, NULL, + add_integer( "vbi-page", 100, PAGE_TEXT, PAGE_LONGTEXT, false ) - add_bool( "vbi-opaque", true, NULL, + add_bool( "vbi-opaque", false, OPAQUE_TEXT, OPAQUE_LONGTEXT, false ) - add_integer( "vbi-position", 4, NULL, POS_TEXT, POS_LONGTEXT, false ) - change_integer_list( pi_pos_values, ppsz_pos_descriptions, NULL ); - add_bool( "vbi-text", false, NULL, + add_integer( "vbi-position", 8, POS_TEXT, POS_LONGTEXT, false ) + change_integer_list( pi_pos_values, ppsz_pos_descriptions ); + add_bool( "vbi-text", false, TELX_TEXT, TELX_LONGTEXT, false ) vlc_module_end () @@ -104,18 +107,20 @@ vlc_module_end () //Guessing table for missing "default region triplet" static const int pi_default_triplet[] = { - 0, 0, // slo cze + 0, 0, 0, 0, // slo slk cze ces 8, // pol - 24,24,24,24, //ssc scr slv rum + 24,24,24,24,24, //scc scr srp hrv slv + 24,24, //rum ron 32,32,32,32,32, //est lit rus bul ukr 48,48, //gre ell 64, //ara 88, //heb 16 }; //default static const char *const ppsz_default_triplet[] = { - "slo", "cze", + "slo", "slk", "cze", "ces", "pol", - "ssc", "scr", "slv", "rum", + "scc", "scr", "srp", "hrv", "slv", + "rum", "ron", "est", "lit", "rus", "bul", "ukr", "gre", "ell", "ara", @@ -131,27 +136,12 @@ typedef enum { ZVBI_KEY_INDEX = 'i' << 16, } ttxt_key_id; -typedef enum { - DATA_UNIT_EBU_TELETEXT_NON_SUBTITLE = 0x02, - DATA_UNIT_EBU_TELETEXT_SUBTITLE = 0x03, - DATA_UNIT_EBU_TELETEXT_INVERTED = 0x0C, - - DATA_UNIT_ZVBI_WSS_CPR1204 = 0xB4, - DATA_UNIT_ZVBI_CLOSED_CAPTION_525 = 0xB5, - DATA_UNIT_ZVBI_MONOCHROME_SAMPLES_525 = 0xB6, - - DATA_UNIT_VPS = 0xC3, - DATA_UNIT_WSS = 0xC4, - DATA_UNIT_CLOSED_CAPTION = 0xC5, - DATA_UNIT_MONOCHROME_SAMPLES = 0xC6, - - DATA_UNIT_STUFFING = 0xFF, -} data_unit_id; +#define MAX_SLICES 32 struct decoder_sys_t { vbi_decoder * p_vbi_dec; - vbi_dvb_demux * p_dvb_demux; + vbi_sliced p_vbi_sliced[MAX_SLICES]; unsigned int i_last_page; bool b_update; bool b_text; /* Subtitles as text */ @@ -178,8 +168,10 @@ static subpicture_t *Subpicture( decoder_t *p_dec, video_format_t *p_fmt, int i_align, mtime_t i_pts ); static void EventHandler( vbi_event *ev, void *user_data ); -static int OpaquePage( picture_t *p_src, const vbi_page p_page, - const video_format_t fmt, bool b_opaque ); +static int OpaquePage( picture_t *p_src, const vbi_page *p_page, + const video_format_t fmt, bool b_opaque, const int text_offset ); +static int get_first_visible_row( vbi_char *p_text, int rows, int columns); +static int get_last_visible_row( vbi_char *p_text, int rows, int columns); /* Properties callbacks */ static int RequestPage( vlc_object_t *p_this, char const *psz_cmd, @@ -205,21 +197,18 @@ static int Open( vlc_object_t *p_this ) if( p_dec->fmt_in.i_codec != VLC_CODEC_TELETEXT ) return VLC_EGENERIC; - p_dec->pf_decode_sub = Decode; - p_sys = p_dec->p_sys = malloc( sizeof(decoder_sys_t) ); + p_sys = p_dec->p_sys = calloc( 1, sizeof(decoder_sys_t) ); if( p_sys == NULL ) return VLC_ENOMEM; - memset( p_sys, 0, sizeof(decoder_sys_t) ); p_sys->i_key[0] = p_sys->i_key[1] = p_sys->i_key[2] = '*' - '0'; p_sys->b_update = false; p_sys->p_vbi_dec = vbi_decoder_new(); - p_sys->p_dvb_demux = vbi_dvb_pes_demux_new( NULL, NULL ); vlc_mutex_init( &p_sys->lock ); - if( (p_sys->p_vbi_dec == NULL) || (p_sys->p_dvb_demux == NULL) ) + if( p_sys->p_vbi_dec == NULL ) { - msg_Err( p_dec, "VBI decoder/demux could not be created." ); + msg_Err( p_dec, "VBI decoder could not be created." ); Close( p_this ); return VLC_ENOMEM; } @@ -246,8 +235,7 @@ static int Open( vlc_object_t *p_this ) /* Create the var on vlc_global. */ p_sys->i_wanted_page = var_CreateGetInteger( p_dec, "vbi-page" ); - var_AddCallback( p_dec, "vbi-page", - RequestPage, p_sys ); + var_AddCallback( p_dec, "vbi-page", RequestPage, p_sys ); /* Check if the Teletext track has a known "initial page". */ if( p_sys->i_wanted_page == 100 && p_dec->fmt_in.subs.teletext.i_magazine != -1 ) @@ -275,6 +263,8 @@ static int Open( vlc_object_t *p_this ) p_dec->fmt_out.video.i_chroma = VLC_CODEC_TEXT; else p_dec->fmt_out.video.i_chroma = VLC_CODEC_RGBA; + + p_dec->pf_decode_sub = Decode; return VLC_SUCCESS; } @@ -295,20 +285,15 @@ static void Close( vlc_object_t *p_this ) if( p_sys->p_vbi_dec ) vbi_decoder_delete( p_sys->p_vbi_dec ); - if( p_sys->p_dvb_demux ) - vbi_dvb_demux_delete( p_sys->p_dvb_demux ); free( p_sys ); } -#define MAX_SLICES 32 - #ifdef WORDS_BIGENDIAN # define ZVBI_PIXFMT_RGBA32 VBI_PIXFMT_RGBA32_BE #else # define ZVBI_PIXFMT_RGBA32 VBI_PIXFMT_RGBA32_LE #endif - /***************************************************************************** * Decode: *****************************************************************************/ @@ -320,8 +305,6 @@ static subpicture_t *Decode( decoder_t *p_dec, block_t **pp_block ) video_format_t fmt; bool b_cached = false; vbi_page p_page; - const uint8_t *p_pos; - unsigned int i_left; if( (pp_block == NULL) || (*pp_block == NULL) ) return NULL; @@ -329,20 +312,44 @@ static subpicture_t *Decode( decoder_t *p_dec, block_t **pp_block ) p_block = *pp_block; *pp_block = NULL; - p_pos = p_block->p_buffer; - i_left = p_block->i_buffer; - - while( i_left > 0 ) + if( p_block->i_buffer > 0 && + ( ( p_block->p_buffer[0] >= 0x10 && p_block->p_buffer[0] <= 0x1f ) || + ( p_block->p_buffer[0] >= 0x99 && p_block->p_buffer[0] <= 0x9b ) ) ) { - vbi_sliced p_sliced[MAX_SLICES]; - unsigned int i_lines = 0; - int64_t i_pts; + vbi_sliced *p_sliced = p_sys->p_vbi_sliced; + unsigned int i_lines = 0; - i_lines = vbi_dvb_demux_cor( p_sys->p_dvb_demux, p_sliced, - MAX_SLICES, &i_pts, &p_pos, &i_left ); + p_block->i_buffer--; + p_block->p_buffer++; + while( p_block->i_buffer >= 2 ) + { + int i_id = p_block->p_buffer[0]; + unsigned i_size = p_block->p_buffer[1]; + + if( 2 + i_size > p_block->i_buffer ) + break; + + if( ( i_id == 0x02 || i_id == 0x03 ) && i_size >= 44 && i_lines < MAX_SLICES ) + { + unsigned line_offset = p_block->p_buffer[2] & 0x1f; + unsigned field_parity = p_block->p_buffer[2] & 0x20; + + p_sliced[i_lines].id = VBI_SLICED_TELETEXT_B; + if( line_offset > 0 ) + p_sliced[i_lines].line = line_offset + (field_parity ? 0 : 313); + else + p_sliced[i_lines].line = 0; + for( int i = 0; i < 42; i++ ) + p_sliced[i_lines].data[i] = vbi_rev8( p_block->p_buffer[4 + i] ); + i_lines++; + } + + p_block->i_buffer -= 2 + i_size; + p_block->p_buffer += 2 + i_size; + } if( i_lines > 0 ) - vbi_decode( p_sys->p_vbi_dec, p_sliced, i_lines, i_pts / 90000.0 ); + vbi_decode( p_sys->p_vbi_dec, p_sliced, i_lines, 0 ); } /* */ @@ -365,7 +372,7 @@ static subpicture_t *Decode( decoder_t *p_dec, block_t **pp_block ) if( !b_cached ) { - if( p_sys->i_last_page != i_wanted_page ) + if( p_sys->b_text && p_sys->i_last_page != i_wanted_page ) { /* We need to reset the subtitle */ p_spu = Subpicture( p_dec, &fmt, true, @@ -373,7 +380,8 @@ static subpicture_t *Decode( decoder_t *p_dec, block_t **pp_block ) i_align, p_block->i_pts ); if( !p_spu ) goto error; - p_spu->p_region->psz_text = strdup(""); + subpicture_updater_sys_t *p_spu_sys = p_spu->updater.p_sys; + p_spu_sys->text = strdup(""); p_sys->b_update = true; p_sys->i_last_page = i_wanted_page; @@ -388,10 +396,25 @@ static subpicture_t *Decode( decoder_t *p_dec, block_t **pp_block ) msg_Dbg( p_dec, "we now have page: %d ready for display", i_wanted_page ); #endif + + /* Ignore transparent rows at the beginning and end */ + int i_first_row = get_first_visible_row( p_page.text, p_page.rows, p_page.columns ); + int i_num_rows; + if ( i_first_row < 0 ) { + i_first_row = p_page.rows - 1; + i_num_rows = 0; + } else { + i_num_rows = get_last_visible_row( p_page.text, p_page.rows, p_page.columns ) - i_first_row + 1; + } +#ifdef ZVBI_DEBUG + msg_Dbg( p_dec, "After top and tail of page we have rows %i-%i of %i", + i_first_row + 1, i_first_row + i_num_rows, p_page.rows ); +#endif + /* If there is a page or sub to render, then we do that here */ /* Create the subpicture unit */ p_spu = Subpicture( p_dec, &fmt, p_sys->b_text, - p_page.columns, p_page.rows, + p_page.columns, i_num_rows, i_align, p_block->i_pts ); if( !p_spu ) goto error; @@ -399,19 +422,30 @@ static subpicture_t *Decode( decoder_t *p_dec, block_t **pp_block ) if( p_sys->b_text ) { unsigned int i_textsize = 7000; - int i_total; + int i_total,offset; char p_text[i_textsize+1]; i_total = vbi_print_page_region( &p_page, p_text, i_textsize, - "UTF-8", 0, 0, 0, 0, p_page.columns, p_page.rows ); - p_text[i_total] = '\0'; - /* Strip off the pagenumber */ - if( i_total <= 40 ) - goto error; - p_spu->p_region->psz_text = strdup( &p_text[8] ); + "UTF-8", 0, 0, 0, i_first_row, p_page.columns, i_num_rows ); + + for( offset=1; offsetupdater.p_sys; + p_spu_sys->text = strdup( &p_text[offset] ); + + p_spu_sys->align = i_align; + p_spu_sys->i_font_height_percent = 5; + p_spu_sys->renderbg = b_opaque; #ifdef ZVBI_DEBUG - msg_Info( p_dec, "page %x-%x(%d)\n%s", p_page.pgno, p_page.subno, i_total, p_text ); + msg_Info( p_dec, "page %x-%x(%d)\n\"%s\"", p_page.pgno, p_page.subno, i_total, &p_text[offset] ); #endif } else @@ -420,14 +454,22 @@ static subpicture_t *Decode( decoder_t *p_dec, block_t **pp_block ) /* ZVBI is stupid enough to assume pitch == width */ p_pic->p->i_pitch = 4 * fmt.i_width; - vbi_draw_vt_page( &p_page, ZVBI_PIXFMT_RGBA32, - p_spu->p_region->p_picture->p->p_pixels, 1, 1 ); + + /* Maintain subtitle postion */ + p_spu->p_region->i_y = i_first_row*10; + p_spu->i_original_picture_width = p_page.columns*12; + p_spu->i_original_picture_height = p_page.rows*10; + + vbi_draw_vt_page_region( &p_page, ZVBI_PIXFMT_RGBA32, + p_spu->p_region->p_picture->p->p_pixels, -1, + 0, i_first_row, p_page.columns, i_num_rows, + 1, 1); vlc_mutex_lock( &p_sys->lock ); memcpy( p_sys->nav_link, &p_page.nav_link, sizeof( p_sys->nav_link )) ; vlc_mutex_unlock( &p_sys->lock ); - OpaquePage( p_pic, p_page, fmt, b_opaque ); + OpaquePage( p_pic, &p_page, fmt, b_opaque, i_first_row * p_page.columns ); } exit: @@ -437,12 +479,6 @@ exit: error: vbi_unref_page( &p_page ); - if( p_spu != NULL ) - { - decoder_DeleteSubpicture( p_dec, p_spu ); - p_spu = NULL; - } - block_Release( p_block ); return NULL; } @@ -453,33 +489,31 @@ static subpicture_t *Subpicture( decoder_t *p_dec, video_format_t *p_fmt, mtime_t i_pts ) { video_format_t fmt; - subpicture_t *p_spu; + subpicture_t *p_spu=NULL; /* If there is a page or sub to render, then we do that here */ /* Create the subpicture unit */ - p_spu = decoder_NewSubpicture( p_dec ); + if( b_text ) + p_spu = decoder_NewSubpictureText( p_dec ); + else + p_spu = decoder_NewSubpicture( p_dec, NULL ); if( !p_spu ) { msg_Warn( p_dec, "can't get spu buffer" ); return NULL; } - memset( &fmt, 0, sizeof(video_format_t) ); - fmt.i_chroma = b_text ? VLC_CODEC_TEXT : - VLC_CODEC_RGBA; + video_format_Init(&fmt, b_text ? VLC_CODEC_TEXT : VLC_CODEC_RGBA); if( b_text ) { fmt.i_bits_per_pixel = 0; - fmt.i_sar_num = 0; - fmt.i_sar_den = 0; } else { - fmt.i_sar_num = 1; - fmt.i_sar_den = 1; fmt.i_width = fmt.i_visible_width = i_columns * 12; fmt.i_height = fmt.i_visible_height = i_rows * 10; fmt.i_bits_per_pixel = 32; + fmt.i_sar_num = fmt.i_sar_den = 0; /* let the vout set the correct AR */ } fmt.i_x_offset = fmt.i_y_offset = 0; @@ -487,24 +521,22 @@ static subpicture_t *Subpicture( decoder_t *p_dec, video_format_t *p_fmt, if( p_spu->p_region == NULL ) { msg_Err( p_dec, "cannot allocate SPU region" ); - decoder_DeleteSubpicture( p_dec, p_spu ); + subpicture_Delete( p_spu ); return NULL; } p_spu->p_region->i_x = 0; p_spu->p_region->i_y = 0; - p_spu->p_region->i_align = i_align; p_spu->i_start = i_pts; - p_spu->i_stop = 0; + p_spu->i_stop = b_text ? i_pts + (10*CLOCK_FREQ): 0; p_spu->b_ephemer = true; - p_spu->b_absolute = false; + p_spu->b_absolute = b_text ? false : true; if( !b_text ) - { - p_spu->i_original_picture_width = fmt.i_width; - p_spu->i_original_picture_height = fmt.i_height; - } + p_spu->p_region->i_align = i_align; + p_spu->i_original_picture_width = fmt.i_width; + p_spu->i_original_picture_height = fmt.i_height; /* */ *p_fmt = fmt; @@ -552,8 +584,34 @@ static void EventHandler( vbi_event *ev, void *user_data ) msg_Dbg( p_dec, "Network ID changed" ); } -static int OpaquePage( picture_t *p_src, const vbi_page p_page, - const video_format_t fmt, bool b_opaque ) +static int get_first_visible_row( vbi_char *p_text, int rows, int columns) +{ + for ( int i = 0; i < rows * columns; i++ ) + { + if ( p_text[i].opacity != VBI_TRANSPARENT_SPACE ) + { + return i / columns; + } + } + + return -1; +} + +static int get_last_visible_row( vbi_char *p_text, int rows, int columns) +{ + for ( int i = rows * columns - 1; i >= 0; i-- ) + { + if (p_text[i].opacity != VBI_TRANSPARENT_SPACE) + { + return i / columns; + } + } + + return -1; +} + +static int OpaquePage( picture_t *p_src, const vbi_page *p_page, + const video_format_t fmt, bool b_opaque, const int text_offset ) { unsigned int x, y; @@ -564,8 +622,8 @@ static int OpaquePage( picture_t *p_src, const vbi_page p_page, { for( x = 0; x < fmt.i_width; x++ ) { - const vbi_opacity opacity = p_page.text[ y/10 * p_page.columns + x/12 ].opacity; - const int background = p_page.text[ y/10 * p_page.columns + x/12 ].background; + const vbi_opacity opacity = p_page->text[ text_offset + y/10 * p_page->columns + x/12 ].opacity; + const int background = p_page->text[ text_offset + y/10 * p_page->columns + x/12 ].background; uint32_t *p_pixel = (uint32_t*)&p_src->p->p_pixels[y * p_src->p->i_pitch + 4*x]; switch( opacity ) @@ -585,7 +643,7 @@ static int OpaquePage( picture_t *p_src, const vbi_page p_page, break; /* Full text transparency. only foreground color is show */ case VBI_TRANSPARENT_FULL: - if( (*p_pixel) == (0xff000000 | p_page.color_map[background] ) ) + if( (*p_pixel) == (0xff000000 | p_page->color_map[background] ) ) *p_pixel = 0; break; } @@ -601,32 +659,37 @@ static int RequestPage( vlc_object_t *p_this, char const *psz_cmd, { decoder_sys_t *p_sys = p_data; VLC_UNUSED(p_this); VLC_UNUSED(psz_cmd); VLC_UNUSED(oldval); + int want_navlink = -1; vlc_mutex_lock( &p_sys->lock ); switch( newval.i_int ) { case ZVBI_KEY_RED: - p_sys->i_wanted_page = vbi_bcd2dec( p_sys->nav_link[0].pgno ); - p_sys->i_wanted_subpage = p_sys->nav_link[0].subno; + want_navlink = 0; break; case ZVBI_KEY_GREEN: - p_sys->i_wanted_page = vbi_bcd2dec( p_sys->nav_link[1].pgno ); - p_sys->i_wanted_subpage = p_sys->nav_link[1].subno; + want_navlink = 1; break; case ZVBI_KEY_YELLOW: - p_sys->i_wanted_page = vbi_bcd2dec( p_sys->nav_link[2].pgno ); - p_sys->i_wanted_subpage = p_sys->nav_link[2].subno; + want_navlink = 2; break; case ZVBI_KEY_BLUE: - p_sys->i_wanted_page = vbi_bcd2dec( p_sys->nav_link[3].pgno ); - p_sys->i_wanted_subpage = p_sys->nav_link[3].subno; + want_navlink = 3; break; case ZVBI_KEY_INDEX: - p_sys->i_wanted_page = vbi_bcd2dec( p_sys->nav_link[5].pgno ); /* #4 is SKIPPED */ - p_sys->i_wanted_subpage = p_sys->nav_link[5].subno; + want_navlink = 5; /* #4 is SKIPPED */ break; } - if( newval.i_int > 0 && newval.i_int < 999 ) + + if (want_navlink > -1) + { + int page = vbi_bcd2dec( p_sys->nav_link[want_navlink].pgno ); + if (page > 0 && page < 999) { + p_sys->i_wanted_page = page; + p_sys->i_wanted_subpage = p_sys->nav_link[want_navlink].subno; + } + } + else if( newval.i_int > 0 && newval.i_int < 999 ) { p_sys->i_wanted_page = newval.i_int; p_sys->i_wanted_subpage = VBI_ANY_SUBNO; @@ -669,7 +732,7 @@ static int EventKey( vlc_object_t *p_this, char const *psz_cmd, decoder_t *p_dec = p_data; decoder_sys_t *p_sys = p_dec->p_sys; - VLC_UNUSED(psz_cmd); VLC_UNUSED(oldval); + VLC_UNUSED(psz_cmd); VLC_UNUSED(oldval); VLC_UNUSED( p_this ); /* FIXME: Capture + and - key for subpage browsing */ if( newval.i_int == '-' || newval.i_int == '+' ) @@ -685,7 +748,8 @@ static int EventKey( vlc_object_t *p_this, char const *psz_cmd, if ( !vbi_bcd_digits_greater( p_sys->i_wanted_subpage, 0x00 ) || vbi_bcd_digits_greater( p_sys->i_wanted_subpage, 0x99 ) ) p_sys->i_wanted_subpage = VBI_ANY_SUBNO; else - vout_OSDMessage( p_this, DEFAULT_CHAN, "%s: %d", _("Subpage"), vbi_bcd2dec( p_sys->i_wanted_subpage) ); + msg_Info( p_dec, "subpage: %d", + vbi_bcd2dec( p_sys->i_wanted_subpage) ); p_sys->b_update = true; vlc_mutex_unlock( &p_sys->lock ); @@ -699,7 +763,8 @@ static int EventKey( vlc_object_t *p_this, char const *psz_cmd, p_sys->i_key[0] = p_sys->i_key[1]; p_sys->i_key[1] = p_sys->i_key[2]; p_sys->i_key[2] = (int)(newval.i_int - '0'); - vout_OSDMessage( p_this, DEFAULT_CHAN, "%s: %c%c%c", _("Page"), (char)(p_sys->i_key[0]+'0'), (char)(p_sys->i_key[1]+'0'), (char)(p_sys->i_key[2]+'0') ); + msg_Info( p_dec, "page: %c%c%c", (char)(p_sys->i_key[0]+'0'), + (char)(p_sys->i_key[1]+'0'), (char)(p_sys->i_key[2]+'0') ); int i_new_page = 0;