1 /*****************************************************************************
2 * audiobargraph_v.c : audiobargraph video plugin for vlc
3 *****************************************************************************
4 * Copyright (C) 2003-2006 the VideoLAN team
6 * Authors: Clement CHESNIN <clement.chesnin@gmail.com>
7 * Philippe COENT <philippe.coent@tdf.fr>
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License as published by
11 * the Free Software Foundation; either version 2 of the License, or
12 * (at your option) any later version.
14 * This program is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU General Public License for more details.
19 * You should have received a copy of the GNU General Public License
20 * along with this program; if not, write to the Free Software
21 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
22 *****************************************************************************/
24 /*****************************************************************************
26 *****************************************************************************/
34 #include <vlc_common.h>
35 #include <vlc_plugin.h>
36 #include <vlc_filter.h>
38 #include <vlc_image.h>
41 #include <vlc_memory.h>
47 /*****************************************************************************
49 *****************************************************************************/
51 #define I_VALUES_TEXT N_("Value of the audio channels levels")
52 #define I_VALUES_LONGTEXT N_("Value of the audio level of each channels between 0 and 1" \
53 "Each level should be separated with ':'.")
54 #define POSX_TEXT N_("X coordinate")
55 #define POSX_LONGTEXT N_("X coordinate of the bargraph." )
56 #define POSY_TEXT N_("Y coordinate")
57 #define POSY_LONGTEXT N_("Y coordinate of the bargraph." )
58 #define TRANS_TEXT N_("Transparency of the bargraph")
59 #define TRANS_LONGTEXT N_("Bargraph transparency value " \
60 "(from 0 for full transparency to 255 for full opacity)." )
61 #define POS_TEXT N_("Bargraph position")
62 #define POS_LONGTEXT N_( \
63 "Enforce the bargraph position on the video " \
64 "(0=center, 1=left, 2=right, 4=top, 8=bottom, you can " \
65 "also use combinations of these values, eg 6 = top-right).")
66 #define ALARM_TEXT N_("Alarm")
67 #define ALARM_LONGTEXT N_("Signals a silence and displays and alert " \
68 "(0=no alarm, 1=alarm).")
69 #define BARWIDTH_TEXT N_("Bar width in pixel (default : 10)")
70 #define BARWIDTH_LONGTEXT N_("Width in pixel of each bar in the BarGraph to be displayed " \
73 #define CFG_PREFIX "audiobargraph_v-"
75 static const int pi_pos_values[] = { 0, 1, 2, 4, 8, 5, 6, 9, 10 };
76 static const char *const ppsz_pos_descriptions[] =
77 { N_("Center"), N_("Left"), N_("Right"), N_("Top"), N_("Bottom"),
78 N_("Top-Left"), N_("Top-Right"), N_("Bottom-Left"), N_("Bottom-Right") };
80 static int OpenSub ( vlc_object_t * );
81 static int OpenVideo( vlc_object_t * );
82 static void Close ( vlc_object_t * );
86 set_category( CAT_VIDEO )
87 set_subcategory( SUBCAT_VIDEO_SUBPIC )
89 set_capability( "sub filter", 0 )
90 set_callbacks( OpenSub, Close )
91 set_description( N_("Audio Bar Graph Video sub filter") )
92 set_shortname( N_("Audio Bar Graph Video") )
93 add_shortcut( "audiobargraph_v" )
95 add_string( CFG_PREFIX "i_values", NULL, NULL, I_VALUES_TEXT, I_VALUES_LONGTEXT, false )
96 add_integer( CFG_PREFIX "x", 0, NULL, POSX_TEXT, POSX_LONGTEXT, true )
97 add_integer( CFG_PREFIX "y", 0, NULL, POSY_TEXT, POSY_LONGTEXT, true )
98 add_integer_with_range( CFG_PREFIX "transparency", 255, 0, 255, NULL,
99 TRANS_TEXT, TRANS_LONGTEXT, false )
100 add_integer( CFG_PREFIX "position", -1, NULL, POS_TEXT, POS_LONGTEXT, false )
101 change_integer_list( pi_pos_values, ppsz_pos_descriptions, NULL )
102 add_integer( CFG_PREFIX "alarm", 0, NULL, ALARM_TEXT, ALARM_LONGTEXT, true )
103 add_integer( CFG_PREFIX "barWidth", 10, NULL, BARWIDTH_TEXT, BARWIDTH_LONGTEXT, true )
105 /* video output filter submodule */
107 set_capability( "video filter2", 0 )
108 set_callbacks( OpenVideo, Close )
109 set_description( N_("Audio Bar Graph Video sub filter") )
110 add_shortcut( "audiobargraph_v" )
114 /*****************************************************************************
116 *****************************************************************************/
118 /*****************************************************************************
119 * Structure to hold the Bar Graph properties
120 ****************************************************************************/
123 int i_alpha; /* -1 means use default alpha */
135 * Private data holder
143 BarGraph_t p_BarGraph;
150 /* On the fly control variable */
154 static const char *const ppsz_filter_options[] = {
155 "i_values", "x", "y", "transparency", "position", "alarm", "barWidth", NULL
158 static const char *const ppsz_filter_callbacks[] = {
159 "audiobargraph_v-i_values",
162 "audiobargraph_v-transparency",
163 "audiobargraph_v-position",
164 "audiobargraph_v-alarm",
165 "audiobargraph_v-barWidth",
169 static int OpenCommon( vlc_object_t *, bool b_sub );
171 static subpicture_t *FilterSub( filter_t *, mtime_t );
172 static picture_t *FilterVideo( filter_t *, picture_t * );
174 static int BarGraphCallback( vlc_object_t *, char const *,
175 vlc_value_t, vlc_value_t, void * );
177 static void LoadBarGraph( vlc_object_t *, BarGraph_t *);
178 void parse_i_values( BarGraph_t *p_BarGraph, char *i_values);
181 * Open the sub filter
183 static int OpenSub( vlc_object_t *p_this )
185 return OpenCommon( p_this, true );
189 * Open the video filter
191 static int OpenVideo( vlc_object_t *p_this )
193 return OpenCommon( p_this, false );
197 * Common open function
199 static int OpenCommon( vlc_object_t *p_this, bool b_sub )
201 filter_t *p_filter = (filter_t *)p_this;
203 BarGraph_t *p_BarGraph;
204 char* i_values = NULL;
207 if( !b_sub && !es_format_IsSimilar( &p_filter->fmt_in, &p_filter->fmt_out ) )
209 msg_Err( p_filter, "Input and output format does not match" );
215 p_filter->p_sys = p_sys = malloc( sizeof( *p_sys ) );
218 p_BarGraph = &(p_sys->p_BarGraph);
221 p_sys->p_blend = NULL;
225 p_sys->p_blend = filter_NewBlend( VLC_OBJECT(p_filter),
226 &p_filter->fmt_in.video );
227 if( !p_sys->p_blend )
229 //free( p_BarGraph );
236 config_ChainParse( p_filter, CFG_PREFIX, ppsz_filter_options,
239 /* create and initialize variables */
240 p_sys->i_pos = var_CreateGetIntegerCommand( p_filter, "audiobargraph_v-position" );
241 p_sys->i_pos_x = var_CreateGetIntegerCommand( p_filter, "audiobargraph_v-x" );
242 p_sys->i_pos_y = var_CreateGetIntegerCommand( p_filter, "audiobargraph_v-y" );
243 p_BarGraph->i_alpha = var_CreateGetIntegerCommand( p_filter,
244 "audiobargraph_v-transparency" );
245 p_BarGraph->i_alpha = __MAX( __MIN( p_BarGraph->i_alpha, 255 ), 0 );
246 i_values = var_CreateGetStringCommand( p_filter, "audiobargraph_v-i_values" );
247 //p_BarGraph->nbChannels = 0;
248 //p_BarGraph->i_values = NULL;
249 parse_i_values(p_BarGraph, i_values);
250 p_BarGraph->alarm = var_CreateGetIntegerCommand( p_filter, "audiobargraph_v-alarm" );
251 p_BarGraph->barWidth = var_CreateGetIntegerCommand( p_filter, "audiobargraph_v-barWidth" );
252 p_BarGraph->scale = 400;
254 /* Ignore aligment if a position is given for video filter */
255 if( !b_sub && p_sys->i_pos_x >= 0 && p_sys->i_pos_y >= 0 )
258 vlc_mutex_init( &p_sys->lock );
259 LoadBarGraph( p_this, p_BarGraph );
260 p_sys->b_spu_update = true;
262 for( int i = 0; ppsz_filter_callbacks[i]; i++ )
263 var_AddCallback( p_filter, ppsz_filter_callbacks[i],
264 BarGraphCallback, p_sys );
269 p_filter->pf_sub_filter = FilterSub;
273 p_filter->pf_video_filter = FilterVideo;
281 * Common close function
283 static void Close( vlc_object_t *p_this )
285 filter_t *p_filter = (filter_t *)p_this;
286 filter_sys_t *p_sys = p_filter->p_sys;
287 BarGraph_t *p_BarGraph = &(p_sys->p_BarGraph);
289 for( int i = 0; ppsz_filter_callbacks[i]; i++ )
290 var_DelCallback( p_filter, ppsz_filter_callbacks[i],
291 BarGraphCallback, p_sys );
294 filter_DeleteBlend( p_sys->p_blend );
296 vlc_mutex_destroy( &p_sys->lock );
298 if( p_BarGraph->p_pic )
300 picture_Release( p_BarGraph->p_pic );
301 p_BarGraph->p_pic = NULL;
303 free( p_BarGraph->i_values );
311 static subpicture_t *FilterSub( filter_t *p_filter, mtime_t date )
313 filter_sys_t *p_sys = p_filter->p_sys;
314 BarGraph_t *p_BarGraph = &(p_sys->p_BarGraph);
317 subpicture_region_t *p_region;
321 vlc_mutex_lock( &p_sys->lock );
322 /* Basic test: b_spu_update occurs on a dynamic change */
323 if( !p_sys->b_spu_update )
325 vlc_mutex_unlock( &p_sys->lock );
329 p_pic = p_BarGraph->p_pic;
331 /* Allocate the subpicture internal data. */
332 p_spu = filter_NewSubpicture( p_filter );
336 p_spu->b_absolute = p_sys->b_absolute;
337 p_spu->i_start = date;
339 p_spu->b_ephemer = true;
341 /* Send an empty subpicture to clear the display when needed */
342 if( !p_pic || !p_BarGraph->i_alpha )
345 /* Create new SPU region */
346 memset( &fmt, 0, sizeof(video_format_t) );
347 fmt.i_chroma = VLC_CODEC_YUVA;
348 fmt.i_aspect = VOUT_ASPECT_FACTOR;
349 fmt.i_sar_num = fmt.i_sar_den = 1;
350 fmt.i_width = fmt.i_visible_width = p_pic->p[Y_PLANE].i_visible_pitch;
351 fmt.i_height = fmt.i_visible_height = p_pic->p[Y_PLANE].i_visible_lines;
352 fmt.i_x_offset = fmt.i_y_offset = 0;
353 p_region = subpicture_region_New( &fmt );
356 msg_Err( p_filter, "cannot allocate SPU region" );
357 p_filter->pf_sub_buffer_del( p_filter, p_spu );
363 picture_Copy( p_region->p_picture, p_pic );
365 /* where to locate the bar graph: */
366 if( p_sys->i_pos < 0 )
367 { /* set to an absolute xy */
368 p_region->i_align = OSD_ALIGN_RIGHT | OSD_ALIGN_TOP;
369 p_spu->b_absolute = true;
372 { /* set to one of the 9 relative locations */
373 p_region->i_align = p_sys->i_pos;
374 p_spu->b_absolute = false;
377 p_region->i_x = p_sys->i_pos_x;
378 p_region->i_y = p_sys->i_pos_y;
380 p_spu->p_region = p_region;
382 p_spu->i_alpha = p_BarGraph->i_alpha ;
385 vlc_mutex_unlock( &p_sys->lock );
393 static picture_t *FilterVideo( filter_t *p_filter, picture_t *p_src )
395 filter_sys_t *p_sys = p_filter->p_sys;
396 BarGraph_t *p_BarGraph = &(p_sys->p_BarGraph);
398 picture_t *p_dst = filter_NewPicture( p_filter );
402 picture_Copy( p_dst, p_src );
405 vlc_mutex_lock( &p_sys->lock );
408 const picture_t *p_pic = p_BarGraph->p_pic;
411 const video_format_t *p_fmt = &p_pic->format;
412 const int i_dst_w = p_filter->fmt_out.video.i_visible_width;
413 const int i_dst_h = p_filter->fmt_out.video.i_visible_height;
417 if( p_sys->i_pos & SUBPICTURE_ALIGN_BOTTOM )
419 p_sys->i_pos_y = i_dst_h - p_fmt->i_visible_height;
421 else if ( !(p_sys->i_pos & SUBPICTURE_ALIGN_TOP) )
423 p_sys->i_pos_y = ( i_dst_h - p_fmt->i_visible_height ) / 2;
430 if( p_sys->i_pos & SUBPICTURE_ALIGN_RIGHT )
432 p_sys->i_pos_x = i_dst_w - p_fmt->i_visible_width;
434 else if ( !(p_sys->i_pos & SUBPICTURE_ALIGN_LEFT) )
436 p_sys->i_pos_x = ( i_dst_w - p_fmt->i_visible_width ) / 2;
445 const int i_alpha = p_BarGraph->i_alpha;
446 if( filter_ConfigureBlend( p_sys->p_blend, i_dst_w, i_dst_h, p_fmt ) ||
447 filter_Blend( p_sys->p_blend, p_dst, p_sys->i_pos_x, p_sys->i_pos_y,
450 msg_Err( p_filter, "failed to blend a picture" );
453 vlc_mutex_unlock( &p_sys->lock );
456 picture_Release( p_src );
460 /*****************************************************************************
461 * Callback to update params on the fly
462 *****************************************************************************/
463 static int BarGraphCallback( vlc_object_t *p_this, char const *psz_var,
464 vlc_value_t oldval, vlc_value_t newval, void *p_data )
467 filter_sys_t *p_sys = (filter_sys_t *)p_data;
468 BarGraph_t *p_BarGraph = &(p_sys->p_BarGraph);
472 vlc_mutex_lock( &p_sys->lock );
473 if ( !strcmp( psz_var, "audiobargraph_v-x" ) )
475 p_sys->i_pos_x = newval.i_int;
477 else if ( !strcmp( psz_var, "audiobargraph_v-y" ) )
479 p_sys->i_pos_y = newval.i_int;
481 else if ( !strcmp( psz_var, "audiobargraph_v-position" ) )
483 p_sys->i_pos = newval.i_int;
485 else if ( !strcmp( psz_var, "audiobargraph_v-transparency" ) )
487 p_BarGraph->i_alpha = __MAX( __MIN( newval.i_int, 255 ), 0 );
489 else if ( !strcmp( psz_var, "audiobargraph_v-i_values" ) )
491 if( p_BarGraph->p_pic )
493 picture_Release( p_BarGraph->p_pic );
494 p_BarGraph->p_pic = NULL;
496 i_values = strdup( newval.psz_string );
497 free(p_BarGraph->i_values);
498 //p_BarGraph->i_values = NULL;
499 //p_BarGraph->nbChannels = 0;
500 // in case many answer are received at the same time, only keep one
501 res = strchr(i_values, '@');
504 parse_i_values( p_BarGraph, i_values);
505 LoadBarGraph(p_this,p_BarGraph);
507 else if ( !strcmp( psz_var, "audiobargraph_v-alarm" ) )
509 if( p_BarGraph->p_pic )
511 picture_Release( p_BarGraph->p_pic );
512 p_BarGraph->p_pic = NULL;
514 p_BarGraph->alarm = newval.i_int;
515 LoadBarGraph(p_this,p_BarGraph);
517 else if ( !strcmp( psz_var, "audiobargraph_v-barWidth" ) )
519 if( p_BarGraph->p_pic )
521 picture_Release( p_BarGraph->p_pic );
522 p_BarGraph->p_pic = NULL;
524 p_BarGraph->barWidth = newval.i_int;
525 LoadBarGraph(p_this,p_BarGraph);
527 p_sys->b_spu_update = true;
528 vlc_mutex_unlock( &p_sys->lock );
533 /*****************************************************************************
534 * LoadImage: creates and returns the bar graph image
535 *****************************************************************************/
536 static picture_t *LoadImage( vlc_object_t *p_this, int nbChannels, int* i_values, int scale, int alarm, int barWidth)
543 int moinsTrois, moinsCinq, moinsSept, moinsDix, moinsVingt;
545 if (nbChannels == 0) {
548 i_width = 2 * nbChannels * barWidth + 10;
551 moinsTrois = 0.71*scale + 20;
552 moinsCinq = 0.56*scale + 20;
553 moinsSept = 0.45*scale + 20;
554 moinsDix = 0.32*scale + 20;
555 moinsVingt = 0.1*scale + 20;
557 p_pic = picture_New(VLC_FOURCC('Y','U','V','A'), i_width+20, scale+30, VOUT_ASPECT_FACTOR * (i_width+20)/(scale+30));
559 // blacken the whole picture
560 for( i = 0 ; i < p_pic->i_planes ; i++ )
562 memset( p_pic->p[i].p_pixels, 0x00,
563 p_pic->p[i].i_visible_lines * p_pic->p[i].i_pitch );
567 for ( i_line = 20; i_line < scale+20; i_line++ ) {
569 #define DrawPointsBlack(a,b) {\
570 for (i=a; i<b; i++) {\
571 *(p_pic->p[0].p_pixels + (scale + 30 - i_line - 1) * p_pic->p[0].i_pitch + i ) = 0x00; \
572 *(p_pic->p[1].p_pixels + (scale + 30 - i_line - 1) * p_pic->p[1].i_pitch + i ) = 128; \
573 *(p_pic->p[2].p_pixels + (scale + 30 - i_line - 1) * p_pic->p[2].i_pitch + i ) = 128; \
574 *(p_pic->p[3].p_pixels + (scale + 30 - i_line - 1) * p_pic->p[3].i_pitch + i ) = 0xFF; \
577 #define DrawPointsWhite(a,b) {\
578 for (i=a; i<b; i++) {\
579 *(p_pic->p[0].p_pixels + (scale + 30 - i_line - 1) * p_pic->p[0].i_pitch + i ) = 0xFF;\
580 *(p_pic->p[1].p_pixels + (scale + 30 - i_line - 1) * p_pic->p[1].i_pitch + i ) = 128;\
581 *(p_pic->p[2].p_pixels + (scale + 30 - i_line - 1) * p_pic->p[2].i_pitch + i ) = 128;\
582 *(p_pic->p[3].p_pixels + (scale + 30 - i_line - 1) * p_pic->p[3].i_pitch + i ) = 0xFF; \
587 DrawPointsBlack(20,22);
588 DrawPointsWhite(22,24);
591 if (i_line == moinsTrois - 2) {
593 DrawPointsBlack(16,19);
595 if (i_line == moinsTrois - 1) {
597 DrawPointsBlack(18,19);
599 DrawPointsWhite(24,27);
601 if (i_line == moinsTrois) {
603 DrawPointsBlack(16,19);
605 DrawPointsBlack(24,27);
607 if (i_line == moinsTrois + 1) {
609 DrawPointsBlack(18,19);
611 DrawPointsBlack(24,27);
613 if (i_line == moinsTrois + 2) {
615 DrawPointsBlack(16,19);
619 if (i_line == moinsCinq - 2) {
621 DrawPointsBlack(16,19);
623 if (i_line == moinsCinq - 1) {
625 DrawPointsBlack(18,19);
627 DrawPointsWhite(24,27);
629 if (i_line == moinsCinq) {
631 DrawPointsBlack(16,19);
633 DrawPointsBlack(24,27);
635 if (i_line == moinsCinq + 1) {
637 DrawPointsBlack(16,17);
639 DrawPointsBlack(24,27);
641 if (i_line == moinsCinq + 2) {
643 DrawPointsBlack(16,19);
647 if (i_line == moinsSept - 2) {
649 DrawPointsBlack(18,19);
651 if (i_line == moinsSept - 1) {
653 DrawPointsBlack(18,19);
655 DrawPointsWhite(24,27);
657 if (i_line == moinsSept) {
659 DrawPointsBlack(18,19);
661 DrawPointsBlack(24,27);
663 if (i_line == moinsSept + 1) {
665 DrawPointsBlack(18,19);
667 DrawPointsBlack(24,27);
669 if (i_line == moinsSept + 2) {
671 DrawPointsBlack(16,19);
676 if (i_line == moinsDix - 2) {
678 DrawPointsBlack(14,15);
680 DrawPointsBlack(16,19);
682 if (i_line == moinsDix - 1) {
684 DrawPointsBlack(14,15);
686 DrawPointsBlack(16,17);
687 DrawPointsBlack(18,19);
689 DrawPointsWhite(24,27);
691 if (i_line == moinsDix) {
693 DrawPointsBlack(14,15);
695 DrawPointsBlack(16,17);
696 DrawPointsBlack(18,19);
698 DrawPointsBlack(24,27);
700 if (i_line == moinsDix + 1) {
702 DrawPointsBlack(14,15);
704 DrawPointsBlack(16,17);
705 DrawPointsBlack(18,19);
707 DrawPointsBlack(24,27);
709 if (i_line == moinsDix + 2) {
711 DrawPointsBlack(14,15);
713 DrawPointsBlack(16,19);
717 if (i_line == moinsVingt - 2) {
719 DrawPointsBlack(12,15);
721 DrawPointsBlack(16,19);
723 if (i_line == moinsVingt - 1) {
725 DrawPointsBlack(12,13);
727 DrawPointsBlack(16,17);
728 DrawPointsBlack(18,19);
730 DrawPointsWhite(24,27);
732 if (i_line == moinsVingt) {
734 DrawPointsBlack(12,15);
736 DrawPointsBlack(16,17);
737 DrawPointsBlack(18,19);
739 DrawPointsBlack(24,27);
741 if (i_line == moinsVingt + 1) {
743 DrawPointsBlack(14,15);
745 DrawPointsBlack(16,17);
746 DrawPointsBlack(18,19);
748 DrawPointsBlack(24,27);
750 if (i_line == moinsVingt + 2) {
752 DrawPointsBlack(12,15);
754 DrawPointsBlack(16,19);
760 // draw the bars and channel indicators
761 for (i=0; i<nbChannels; i++) {
762 for( j = barWidth+20 ; j < 2*barWidth+20; j++)
764 // channel indicators
765 for ( i_line = 12; i_line < 18; i_line++ ) {
767 *(p_pic->p[0].p_pixels +
768 (scale + 30 - i_line - 1) *
769 p_pic->p[0].i_pitch +
770 ( (2*i*barWidth)+j ) ) = 255;
771 *(p_pic->p[1].p_pixels +
772 (scale + 30 - i_line - 1) *
773 p_pic->p[1].i_pitch +
774 ( (2*i*barWidth)+j ) ) = 128;
775 *(p_pic->p[2].p_pixels +
776 (scale + 30 - i_line - 1) *
777 p_pic->p[2].i_pitch +
778 ( (2*i*barWidth)+j ) ) = 128;
779 *(p_pic->p[3].p_pixels +
780 (scale + 30 - i_line - 1) *
781 p_pic->p[3].i_pitch +
782 ( (2*i*barWidth)+j )) = 0xFF;
785 for( i_line = 20; i_line < i_values[i]+20; i_line++ )
787 if (i_line < moinsDix) { // green if < -10 dB
788 *(p_pic->p[0].p_pixels +
789 (scale + 30 - i_line - 1) *
790 p_pic->p[0].i_pitch +
791 ( (2*i*barWidth)+j ) ) = 150;
792 *(p_pic->p[1].p_pixels +
793 (scale + 30 - i_line - 1) *
794 p_pic->p[1].i_pitch +
795 ( (2*i*barWidth)+j ) ) = 44;
796 *(p_pic->p[2].p_pixels +
797 (scale + 30 - i_line - 1) *
798 p_pic->p[2].i_pitch +
799 ( (2*i*barWidth)+j ) ) = 21;
800 *(p_pic->p[3].p_pixels +
801 (scale + 30 - i_line - 1) *
802 p_pic->p[3].i_pitch +
803 ( (2*i*barWidth)+j )) = 0xFF;
804 } else if (i_line < moinsTrois) { // yellow if > -10dB and < -3dB
805 *(p_pic->p[0].p_pixels +
806 (scale + 30 - i_line - 1) *
807 p_pic->p[0].i_pitch +
808 ( (2*i*barWidth)+j ) ) = 226;
809 *(p_pic->p[1].p_pixels +
810 (scale + 30 - i_line - 1) *
811 p_pic->p[1].i_pitch +
812 ( (2*i*barWidth)+j ) ) = 1;
813 *(p_pic->p[2].p_pixels +
814 (scale + 30 - i_line - 1) *
815 p_pic->p[2].i_pitch +
816 ( (2*i*barWidth)+j ) ) = 148;
817 *(p_pic->p[3].p_pixels +
818 (scale + 30 - i_line - 1) *
819 p_pic->p[3].i_pitch +
820 ( (2*i*barWidth)+j )) = 0xFF;
821 } else { // red if > -3 dB
822 *(p_pic->p[0].p_pixels +
823 (scale + 30 - i_line - 1) *
824 p_pic->p[0].i_pitch +
825 ( (2*i*barWidth)+j ) ) = 76;
826 *(p_pic->p[1].p_pixels +
827 (scale + 30 - i_line - 1) *
828 p_pic->p[1].i_pitch +
829 ( (2*i*barWidth)+j ) ) = 85;
830 *(p_pic->p[2].p_pixels +
831 (scale + 30 - i_line - 1) *
832 p_pic->p[2].i_pitch +
833 ( (2*i*barWidth)+j ) ) = 0xFF;
834 *(p_pic->p[3].p_pixels +
835 (scale + 30 - i_line - 1) *
836 p_pic->p[3].i_pitch +
837 ( (2*i*barWidth)+j )) = 0xFF;
845 if (alarm) {// draw the alarm square
847 for ( i_line = 0; i_line < 10; i_line++ ) {
848 for (i=0; i<i_width+20; i++) {
849 *(p_pic->p[0].p_pixels +
850 (scale + 30 - i_line - 1) *
851 p_pic->p[0].i_pitch + i ) = 76;
852 *(p_pic->p[1].p_pixels +
853 (scale + 30 - i_line - 1) *
854 p_pic->p[1].i_pitch + i ) = 85;
855 *(p_pic->p[2].p_pixels +
856 (scale + 30 - i_line - 1) *
857 p_pic->p[2].i_pitch + i ) = 0xFF;
858 *(p_pic->p[3].p_pixels +
859 (scale + 30 - i_line - 1) *
860 p_pic->p[3].i_pitch + i ) = 0xFF;
864 for ( i_line = scale+21; i_line < scale+30; i_line++ ) {
865 for (i=0; i<i_width+20; i++) {
866 *(p_pic->p[0].p_pixels +
867 (scale + 30 - i_line - 1) *
868 p_pic->p[0].i_pitch + i ) = 76;
869 *(p_pic->p[1].p_pixels +
870 (scale + 30 - i_line - 1) *
871 p_pic->p[1].i_pitch + i ) = 85;
872 *(p_pic->p[2].p_pixels +
873 (scale + 30 - i_line - 1) *
874 p_pic->p[2].i_pitch + i ) = 0xFF;
875 *(p_pic->p[3].p_pixels +
876 (scale + 30 - i_line - 1) *
877 p_pic->p[3].i_pitch + i ) = 0xFF;
881 for ( i_line = 9; i_line < scale+21; i_line++ ) {
882 for (i=0; i<10; i++) {
883 *(p_pic->p[0].p_pixels +
884 (scale + 30 - i_line - 1) *
885 p_pic->p[0].i_pitch + i ) = 76;
886 *(p_pic->p[1].p_pixels +
887 (scale + 30 - i_line - 1) *
888 p_pic->p[1].i_pitch + i ) = 85;
889 *(p_pic->p[2].p_pixels +
890 (scale + 30 - i_line - 1) *
891 p_pic->p[2].i_pitch + i ) = 0xFF;
892 *(p_pic->p[3].p_pixels +
893 (scale + 30 - i_line - 1) *
894 p_pic->p[3].i_pitch + i ) = 0xFF;
896 for (i=i_width+11; i<i_width+20; i++) {
897 *(p_pic->p[0].p_pixels +
898 (scale + 30 - i_line - 1) *
899 p_pic->p[0].i_pitch + i ) = 76;
900 *(p_pic->p[1].p_pixels +
901 (scale + 30 - i_line - 1) *
902 p_pic->p[1].i_pitch + i ) = 85;
903 *(p_pic->p[2].p_pixels +
904 (scale + 30 - i_line - 1) *
905 p_pic->p[2].i_pitch + i ) = 0xFF;
906 *(p_pic->p[3].p_pixels +
907 (scale + 30 - i_line - 1) *
908 p_pic->p[3].i_pitch + i ) = 0xFF;
917 /*****************************************************************************
918 * LoadBarGraph: loads the BarGraph images into memory
919 *****************************************************************************/
920 static void LoadBarGraph( vlc_object_t *p_this, BarGraph_t *p_BarGraph )
923 p_BarGraph->p_pic = LoadImage( p_this, p_BarGraph->nbChannels, p_BarGraph->i_values, p_BarGraph->scale, p_BarGraph->alarm, p_BarGraph->barWidth);
924 if( !p_BarGraph->p_pic )
926 msg_Warn( p_this, "error while creating picture" );
931 /*****************************************************************************
932 * parse_i_values : parse i_values parameter and store the corresponding values
933 *****************************************************************************/
934 void parse_i_values( BarGraph_t *p_BarGraph, char *i_values)
940 p_BarGraph->nbChannels = 0;
941 p_BarGraph->i_values = NULL;
942 res = strtok_r(i_values, delim, &tok);
943 while (res != NULL) {
944 p_BarGraph->nbChannels++;
945 p_BarGraph->i_values = realloc_or_free(p_BarGraph->i_values,
946 p_BarGraph->nbChannels*sizeof(int));
947 assert(p_BarGraph->i_values);
948 p_BarGraph->i_values[p_BarGraph->nbChannels-1] = __MAX( __MIN( atof(res)*p_BarGraph->scale, p_BarGraph->scale ), 0 );
949 res = strtok_r(NULL, delim, &tok);