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 *****************************************************************************/
33 #include <vlc_common.h>
34 #include <vlc_plugin.h>
35 #include <vlc_filter.h>
37 #include <vlc_image.h>
43 /*****************************************************************************
45 *****************************************************************************/
47 #define I_VALUES_TEXT N_("Value of the audio channels levels")
48 #define I_VALUES_LONGTEXT N_("Value of the audio level of each channels between 0 and 1" \
49 "Each level should be separated with ':'.")
50 #define POSX_TEXT N_("X coordinate")
51 #define POSX_LONGTEXT N_("X coordinate of the bargraph." )
52 #define POSY_TEXT N_("Y coordinate")
53 #define POSY_LONGTEXT N_("Y coordinate of the bargraph." )
54 #define TRANS_TEXT N_("Transparency of the bargraph")
55 #define TRANS_LONGTEXT N_("Bargraph transparency value " \
56 "(from 0 for full transparency to 255 for full opacity)." )
57 #define POS_TEXT N_("Bargraph position")
58 #define POS_LONGTEXT N_( \
59 "Enforce the bargraph position on the video " \
60 "(0=center, 1=left, 2=right, 4=top, 8=bottom, you can " \
61 "also use combinations of these values, eg 6 = top-right).")
62 #define ALARM_TEXT N_("Alarm")
63 #define ALARM_LONGTEXT N_("Signals a silence and displays and alert " \
64 "(0=no alarm, 1=alarm).")
65 #define BARWIDTH_TEXT N_("Bar width in pixel (default : 10)")
66 #define BARWIDTH_LONGTEXT N_("Width in pixel of each bar in the BarGraph to be displayed " \
69 #define CFG_PREFIX "audiobargraph_v-"
71 static const int pi_pos_values[] = { 0, 1, 2, 4, 8, 5, 6, 9, 10 };
72 static const char *const ppsz_pos_descriptions[] =
73 { N_("Center"), N_("Left"), N_("Right"), N_("Top"), N_("Bottom"),
74 N_("Top-Left"), N_("Top-Right"), N_("Bottom-Left"), N_("Bottom-Right") };
76 static int OpenSub ( vlc_object_t * );
77 static int OpenVideo( vlc_object_t * );
78 static void Close ( vlc_object_t * );
82 set_category( CAT_VIDEO )
83 set_subcategory( SUBCAT_VIDEO_SUBPIC )
85 set_capability( "sub filter", 0 )
86 set_callbacks( OpenSub, Close )
87 set_description( N_("Audio Bar Graph Video sub filter") )
88 set_shortname( N_("Audio Bar Graph Video") )
89 add_shortcut( "audiobargraph_v" )
91 add_string( CFG_PREFIX "i_values", NULL, NULL, I_VALUES_TEXT, I_VALUES_LONGTEXT, false )
92 add_integer( CFG_PREFIX "x", 0, NULL, POSX_TEXT, POSX_LONGTEXT, true )
93 add_integer( CFG_PREFIX "y", 0, NULL, POSY_TEXT, POSY_LONGTEXT, true )
94 add_integer_with_range( CFG_PREFIX "transparency", 255, 0, 255, NULL,
95 TRANS_TEXT, TRANS_LONGTEXT, false )
96 add_integer( CFG_PREFIX "position", -1, NULL, POS_TEXT, POS_LONGTEXT, false )
97 change_integer_list( pi_pos_values, ppsz_pos_descriptions, NULL )
98 add_integer( CFG_PREFIX "alarm", 0, NULL, ALARM_TEXT, ALARM_LONGTEXT, true )
99 add_integer( CFG_PREFIX "barWidth", 10, NULL, BARWIDTH_TEXT, BARWIDTH_LONGTEXT, true )
101 /* video output filter submodule */
103 set_capability( "video filter2", 0 )
104 set_callbacks( OpenVideo, Close )
105 set_description( N_("Audio Bar Graph Video sub filter") )
106 add_shortcut( "audiobargraph_v" )
110 /*****************************************************************************
112 *****************************************************************************/
114 /*****************************************************************************
115 * Structure to hold the Bar Graph properties
116 ****************************************************************************/
119 int i_alpha; /* -1 means use default alpha */
131 * Private data holder
139 BarGraph_t p_BarGraph;
146 /* On the fly control variable */
150 static const char *const ppsz_filter_options[] = {
151 "i_values", "x", "y", "transparency", "position", "alarm", "barWidth", NULL
154 static const char *const ppsz_filter_callbacks[] = {
155 "audiobargraph_v-i_values",
158 "audiobargraph_v-transparency",
159 "audiobargraph_v-position",
160 "audiobargraph_v-alarm",
161 "audiobargraph_v-barWidth",
165 static int OpenCommon( vlc_object_t *, bool b_sub );
167 static subpicture_t *FilterSub( filter_t *, mtime_t );
168 static picture_t *FilterVideo( filter_t *, picture_t * );
170 static int BarGraphCallback( vlc_object_t *, char const *,
171 vlc_value_t, vlc_value_t, void * );
173 static void LoadBarGraph( vlc_object_t *, BarGraph_t *);
174 void parse_i_values( BarGraph_t *p_BarGraph, char *i_values);
177 * Open the sub filter
179 static int OpenSub( vlc_object_t *p_this )
181 return OpenCommon( p_this, true );
185 * Open the video filter
187 static int OpenVideo( vlc_object_t *p_this )
189 return OpenCommon( p_this, false );
193 * Common open function
195 static int OpenCommon( vlc_object_t *p_this, bool b_sub )
197 filter_t *p_filter = (filter_t *)p_this;
199 BarGraph_t *p_BarGraph;
200 char* i_values = NULL;
203 if( !b_sub && !es_format_IsSimilar( &p_filter->fmt_in, &p_filter->fmt_out ) )
205 msg_Err( p_filter, "Input and output format does not match" );
211 p_filter->p_sys = p_sys = malloc( sizeof( *p_sys ) );
214 p_BarGraph = &(p_sys->p_BarGraph);
217 p_sys->p_blend = NULL;
221 p_sys->p_blend = filter_NewBlend( VLC_OBJECT(p_filter),
222 &p_filter->fmt_in.video );
223 if( !p_sys->p_blend )
225 //free( p_BarGraph );
232 config_ChainParse( p_filter, CFG_PREFIX, ppsz_filter_options,
235 /* create and initialize variables */
236 p_sys->i_pos = var_CreateGetIntegerCommand( p_filter, "audiobargraph_v-position" );
237 p_sys->i_pos_x = var_CreateGetIntegerCommand( p_filter, "audiobargraph_v-x" );
238 p_sys->i_pos_y = var_CreateGetIntegerCommand( p_filter, "audiobargraph_v-y" );
239 p_BarGraph->i_alpha = var_CreateGetIntegerCommand( p_filter,
240 "audiobargraph_v-transparency" );
241 p_BarGraph->i_alpha = __MAX( __MIN( p_BarGraph->i_alpha, 255 ), 0 );
242 i_values = var_CreateGetStringCommand( p_filter, "audiobargraph_v-i_values" );
243 //p_BarGraph->nbChannels = 0;
244 //p_BarGraph->i_values = NULL;
245 parse_i_values(p_BarGraph, i_values);
246 p_BarGraph->alarm = var_CreateGetIntegerCommand( p_filter, "audiobargraph_v-alarm" );
247 p_BarGraph->barWidth = var_CreateGetIntegerCommand( p_filter, "audiobargraph_v-barWidth" );
248 p_BarGraph->scale = 400;
250 /* Ignore aligment if a position is given for video filter */
251 if( !b_sub && p_sys->i_pos_x >= 0 && p_sys->i_pos_y >= 0 )
254 vlc_mutex_init( &p_sys->lock );
255 LoadBarGraph( p_this, p_BarGraph );
256 p_sys->b_spu_update = true;
258 for( int i = 0; ppsz_filter_callbacks[i]; i++ )
259 var_AddCallback( p_filter, ppsz_filter_callbacks[i],
260 BarGraphCallback, p_sys );
265 p_filter->pf_sub_filter = FilterSub;
269 p_filter->pf_video_filter = FilterVideo;
277 * Common close function
279 static void Close( vlc_object_t *p_this )
281 filter_t *p_filter = (filter_t *)p_this;
282 filter_sys_t *p_sys = p_filter->p_sys;
283 BarGraph_t *p_BarGraph = &(p_sys->p_BarGraph);
285 for( int i = 0; ppsz_filter_callbacks[i]; i++ )
286 var_DelCallback( p_filter, ppsz_filter_callbacks[i],
287 BarGraphCallback, p_sys );
290 filter_DeleteBlend( p_sys->p_blend );
292 vlc_mutex_destroy( &p_sys->lock );
294 if( p_BarGraph->p_pic )
296 picture_Release( p_BarGraph->p_pic );
297 p_BarGraph->p_pic = NULL;
299 free( p_BarGraph->i_values );
307 static subpicture_t *FilterSub( filter_t *p_filter, mtime_t date )
309 filter_sys_t *p_sys = p_filter->p_sys;
310 BarGraph_t *p_BarGraph = &(p_sys->p_BarGraph);
313 subpicture_region_t *p_region;
317 vlc_mutex_lock( &p_sys->lock );
318 /* Basic test: b_spu_update occurs on a dynamic change */
319 if( !p_sys->b_spu_update )
321 vlc_mutex_unlock( &p_sys->lock );
325 p_pic = p_BarGraph->p_pic;
327 /* Allocate the subpicture internal data. */
328 p_spu = filter_NewSubpicture( p_filter );
332 p_spu->b_absolute = p_sys->b_absolute;
333 p_spu->i_start = date;
335 p_spu->b_ephemer = true;
337 /* Send an empty subpicture to clear the display when needed */
338 if( !p_pic || !p_BarGraph->i_alpha )
341 /* Create new SPU region */
342 memset( &fmt, 0, sizeof(video_format_t) );
343 fmt.i_chroma = VLC_CODEC_YUVA;
344 fmt.i_sar_num = fmt.i_sar_den = 1;
345 fmt.i_width = fmt.i_visible_width = p_pic->p[Y_PLANE].i_visible_pitch;
346 fmt.i_height = fmt.i_visible_height = p_pic->p[Y_PLANE].i_visible_lines;
347 fmt.i_x_offset = fmt.i_y_offset = 0;
348 p_region = subpicture_region_New( &fmt );
351 msg_Err( p_filter, "cannot allocate SPU region" );
352 p_filter->pf_sub_buffer_del( p_filter, p_spu );
358 picture_Copy( p_region->p_picture, p_pic );
360 /* where to locate the bar graph: */
361 if( p_sys->i_pos < 0 )
362 { /* set to an absolute xy */
363 p_region->i_align = SUBPICTURE_ALIGN_RIGHT | SUBPICTURE_ALIGN_TOP;
364 p_spu->b_absolute = true;
367 { /* set to one of the 9 relative locations */
368 p_region->i_align = p_sys->i_pos;
369 p_spu->b_absolute = false;
372 p_region->i_x = p_sys->i_pos_x;
373 p_region->i_y = p_sys->i_pos_y;
375 p_spu->p_region = p_region;
377 p_spu->i_alpha = p_BarGraph->i_alpha ;
380 vlc_mutex_unlock( &p_sys->lock );
388 static picture_t *FilterVideo( filter_t *p_filter, picture_t *p_src )
390 filter_sys_t *p_sys = p_filter->p_sys;
391 BarGraph_t *p_BarGraph = &(p_sys->p_BarGraph);
393 picture_t *p_dst = filter_NewPicture( p_filter );
397 picture_Copy( p_dst, p_src );
400 vlc_mutex_lock( &p_sys->lock );
403 const picture_t *p_pic = p_BarGraph->p_pic;
406 const video_format_t *p_fmt = &p_pic->format;
407 const int i_dst_w = p_filter->fmt_out.video.i_visible_width;
408 const int i_dst_h = p_filter->fmt_out.video.i_visible_height;
412 if( p_sys->i_pos & SUBPICTURE_ALIGN_BOTTOM )
414 p_sys->i_pos_y = i_dst_h - p_fmt->i_visible_height;
416 else if ( !(p_sys->i_pos & SUBPICTURE_ALIGN_TOP) )
418 p_sys->i_pos_y = ( i_dst_h - p_fmt->i_visible_height ) / 2;
425 if( p_sys->i_pos & SUBPICTURE_ALIGN_RIGHT )
427 p_sys->i_pos_x = i_dst_w - p_fmt->i_visible_width;
429 else if ( !(p_sys->i_pos & SUBPICTURE_ALIGN_LEFT) )
431 p_sys->i_pos_x = ( i_dst_w - p_fmt->i_visible_width ) / 2;
440 const int i_alpha = p_BarGraph->i_alpha;
441 if( filter_ConfigureBlend( p_sys->p_blend, i_dst_w, i_dst_h, p_fmt ) ||
442 filter_Blend( p_sys->p_blend, p_dst, p_sys->i_pos_x, p_sys->i_pos_y,
445 msg_Err( p_filter, "failed to blend a picture" );
448 vlc_mutex_unlock( &p_sys->lock );
451 picture_Release( p_src );
455 /*****************************************************************************
456 * Callback to update params on the fly
457 *****************************************************************************/
458 static int BarGraphCallback( vlc_object_t *p_this, char const *psz_var,
459 vlc_value_t oldval, vlc_value_t newval, void *p_data )
462 filter_sys_t *p_sys = (filter_sys_t *)p_data;
463 BarGraph_t *p_BarGraph = &(p_sys->p_BarGraph);
467 vlc_mutex_lock( &p_sys->lock );
468 if ( !strcmp( psz_var, "audiobargraph_v-x" ) )
470 p_sys->i_pos_x = newval.i_int;
472 else if ( !strcmp( psz_var, "audiobargraph_v-y" ) )
474 p_sys->i_pos_y = newval.i_int;
476 else if ( !strcmp( psz_var, "audiobargraph_v-position" ) )
478 p_sys->i_pos = newval.i_int;
480 else if ( !strcmp( psz_var, "audiobargraph_v-transparency" ) )
482 p_BarGraph->i_alpha = __MAX( __MIN( newval.i_int, 255 ), 0 );
484 else if ( !strcmp( psz_var, "audiobargraph_v-i_values" ) )
486 if( p_BarGraph->p_pic )
488 picture_Release( p_BarGraph->p_pic );
489 p_BarGraph->p_pic = NULL;
491 i_values = strdup( newval.psz_string );
492 free(p_BarGraph->i_values);
493 //p_BarGraph->i_values = NULL;
494 //p_BarGraph->nbChannels = 0;
495 // in case many answer are received at the same time, only keep one
496 res = strchr(i_values, '@');
499 parse_i_values( p_BarGraph, i_values);
500 LoadBarGraph(p_this,p_BarGraph);
502 else if ( !strcmp( psz_var, "audiobargraph_v-alarm" ) )
504 if( p_BarGraph->p_pic )
506 picture_Release( p_BarGraph->p_pic );
507 p_BarGraph->p_pic = NULL;
509 p_BarGraph->alarm = newval.i_int;
510 LoadBarGraph(p_this,p_BarGraph);
512 else if ( !strcmp( psz_var, "audiobargraph_v-barWidth" ) )
514 if( p_BarGraph->p_pic )
516 picture_Release( p_BarGraph->p_pic );
517 p_BarGraph->p_pic = NULL;
519 p_BarGraph->barWidth = newval.i_int;
520 LoadBarGraph(p_this,p_BarGraph);
522 p_sys->b_spu_update = true;
523 vlc_mutex_unlock( &p_sys->lock );
528 /*****************************************************************************
529 * LoadImage: creates and returns the bar graph image
530 *****************************************************************************/
531 static picture_t *LoadImage( vlc_object_t *p_this, int nbChannels, int* i_values, int scale, int alarm, int barWidth)
538 int moinsTrois, moinsCinq, moinsSept, moinsDix, moinsVingt;
540 if (nbChannels == 0) {
543 i_width = 2 * nbChannels * barWidth + 10;
546 moinsTrois = 0.71*scale + 20;
547 moinsCinq = 0.56*scale + 20;
548 moinsSept = 0.45*scale + 20;
549 moinsDix = 0.32*scale + 20;
550 moinsVingt = 0.1*scale + 20;
552 p_pic = picture_New(VLC_FOURCC('Y','U','V','A'), i_width+20, scale+30, 1, 1);
554 // blacken the whole picture
555 for( i = 0 ; i < p_pic->i_planes ; i++ )
557 memset( p_pic->p[i].p_pixels, 0x00,
558 p_pic->p[i].i_visible_lines * p_pic->p[i].i_pitch );
562 for ( i_line = 20; i_line < scale+20; i_line++ ) {
564 #define DrawPointsBlack(a,b) {\
565 for (i=a; i<b; i++) {\
566 *(p_pic->p[0].p_pixels + (scale + 30 - i_line - 1) * p_pic->p[0].i_pitch + i ) = 0x00; \
567 *(p_pic->p[1].p_pixels + (scale + 30 - i_line - 1) * p_pic->p[1].i_pitch + i ) = 128; \
568 *(p_pic->p[2].p_pixels + (scale + 30 - i_line - 1) * p_pic->p[2].i_pitch + i ) = 128; \
569 *(p_pic->p[3].p_pixels + (scale + 30 - i_line - 1) * p_pic->p[3].i_pitch + i ) = 0xFF; \
572 #define DrawPointsWhite(a,b) {\
573 for (i=a; i<b; i++) {\
574 *(p_pic->p[0].p_pixels + (scale + 30 - i_line - 1) * p_pic->p[0].i_pitch + i ) = 0xFF;\
575 *(p_pic->p[1].p_pixels + (scale + 30 - i_line - 1) * p_pic->p[1].i_pitch + i ) = 128;\
576 *(p_pic->p[2].p_pixels + (scale + 30 - i_line - 1) * p_pic->p[2].i_pitch + i ) = 128;\
577 *(p_pic->p[3].p_pixels + (scale + 30 - i_line - 1) * p_pic->p[3].i_pitch + i ) = 0xFF; \
582 DrawPointsBlack(20,22);
583 DrawPointsWhite(22,24);
586 if (i_line == moinsTrois - 2) {
588 DrawPointsBlack(16,19);
590 if (i_line == moinsTrois - 1) {
592 DrawPointsBlack(18,19);
594 DrawPointsWhite(24,27);
596 if (i_line == moinsTrois) {
598 DrawPointsBlack(16,19);
600 DrawPointsBlack(24,27);
602 if (i_line == moinsTrois + 1) {
604 DrawPointsBlack(18,19);
606 DrawPointsBlack(24,27);
608 if (i_line == moinsTrois + 2) {
610 DrawPointsBlack(16,19);
614 if (i_line == moinsCinq - 2) {
616 DrawPointsBlack(16,19);
618 if (i_line == moinsCinq - 1) {
620 DrawPointsBlack(18,19);
622 DrawPointsWhite(24,27);
624 if (i_line == moinsCinq) {
626 DrawPointsBlack(16,19);
628 DrawPointsBlack(24,27);
630 if (i_line == moinsCinq + 1) {
632 DrawPointsBlack(16,17);
634 DrawPointsBlack(24,27);
636 if (i_line == moinsCinq + 2) {
638 DrawPointsBlack(16,19);
642 if (i_line == moinsSept - 2) {
644 DrawPointsBlack(18,19);
646 if (i_line == moinsSept - 1) {
648 DrawPointsBlack(18,19);
650 DrawPointsWhite(24,27);
652 if (i_line == moinsSept) {
654 DrawPointsBlack(18,19);
656 DrawPointsBlack(24,27);
658 if (i_line == moinsSept + 1) {
660 DrawPointsBlack(18,19);
662 DrawPointsBlack(24,27);
664 if (i_line == moinsSept + 2) {
666 DrawPointsBlack(16,19);
671 if (i_line == moinsDix - 2) {
673 DrawPointsBlack(14,15);
675 DrawPointsBlack(16,19);
677 if (i_line == moinsDix - 1) {
679 DrawPointsBlack(14,15);
681 DrawPointsBlack(16,17);
682 DrawPointsBlack(18,19);
684 DrawPointsWhite(24,27);
686 if (i_line == moinsDix) {
688 DrawPointsBlack(14,15);
690 DrawPointsBlack(16,17);
691 DrawPointsBlack(18,19);
693 DrawPointsBlack(24,27);
695 if (i_line == moinsDix + 1) {
697 DrawPointsBlack(14,15);
699 DrawPointsBlack(16,17);
700 DrawPointsBlack(18,19);
702 DrawPointsBlack(24,27);
704 if (i_line == moinsDix + 2) {
706 DrawPointsBlack(14,15);
708 DrawPointsBlack(16,19);
712 if (i_line == moinsVingt - 2) {
714 DrawPointsBlack(12,15);
716 DrawPointsBlack(16,19);
718 if (i_line == moinsVingt - 1) {
720 DrawPointsBlack(12,13);
722 DrawPointsBlack(16,17);
723 DrawPointsBlack(18,19);
725 DrawPointsWhite(24,27);
727 if (i_line == moinsVingt) {
729 DrawPointsBlack(12,15);
731 DrawPointsBlack(16,17);
732 DrawPointsBlack(18,19);
734 DrawPointsBlack(24,27);
736 if (i_line == moinsVingt + 1) {
738 DrawPointsBlack(14,15);
740 DrawPointsBlack(16,17);
741 DrawPointsBlack(18,19);
743 DrawPointsBlack(24,27);
745 if (i_line == moinsVingt + 2) {
747 DrawPointsBlack(12,15);
749 DrawPointsBlack(16,19);
755 // draw the bars and channel indicators
756 for (i=0; i<nbChannels; i++) {
757 for( j = barWidth+20 ; j < 2*barWidth+20; j++)
759 // channel indicators
760 for ( i_line = 12; i_line < 18; i_line++ ) {
762 *(p_pic->p[0].p_pixels +
763 (scale + 30 - i_line - 1) *
764 p_pic->p[0].i_pitch +
765 ( (2*i*barWidth)+j ) ) = 255;
766 *(p_pic->p[1].p_pixels +
767 (scale + 30 - i_line - 1) *
768 p_pic->p[1].i_pitch +
769 ( (2*i*barWidth)+j ) ) = 128;
770 *(p_pic->p[2].p_pixels +
771 (scale + 30 - i_line - 1) *
772 p_pic->p[2].i_pitch +
773 ( (2*i*barWidth)+j ) ) = 128;
774 *(p_pic->p[3].p_pixels +
775 (scale + 30 - i_line - 1) *
776 p_pic->p[3].i_pitch +
777 ( (2*i*barWidth)+j )) = 0xFF;
780 for( i_line = 20; i_line < i_values[i]+20; i_line++ )
782 if (i_line < moinsDix) { // green if < -10 dB
783 *(p_pic->p[0].p_pixels +
784 (scale + 30 - i_line - 1) *
785 p_pic->p[0].i_pitch +
786 ( (2*i*barWidth)+j ) ) = 150;
787 *(p_pic->p[1].p_pixels +
788 (scale + 30 - i_line - 1) *
789 p_pic->p[1].i_pitch +
790 ( (2*i*barWidth)+j ) ) = 44;
791 *(p_pic->p[2].p_pixels +
792 (scale + 30 - i_line - 1) *
793 p_pic->p[2].i_pitch +
794 ( (2*i*barWidth)+j ) ) = 21;
795 *(p_pic->p[3].p_pixels +
796 (scale + 30 - i_line - 1) *
797 p_pic->p[3].i_pitch +
798 ( (2*i*barWidth)+j )) = 0xFF;
799 } else if (i_line < moinsTrois) { // yellow if > -10dB and < -3dB
800 *(p_pic->p[0].p_pixels +
801 (scale + 30 - i_line - 1) *
802 p_pic->p[0].i_pitch +
803 ( (2*i*barWidth)+j ) ) = 226;
804 *(p_pic->p[1].p_pixels +
805 (scale + 30 - i_line - 1) *
806 p_pic->p[1].i_pitch +
807 ( (2*i*barWidth)+j ) ) = 1;
808 *(p_pic->p[2].p_pixels +
809 (scale + 30 - i_line - 1) *
810 p_pic->p[2].i_pitch +
811 ( (2*i*barWidth)+j ) ) = 148;
812 *(p_pic->p[3].p_pixels +
813 (scale + 30 - i_line - 1) *
814 p_pic->p[3].i_pitch +
815 ( (2*i*barWidth)+j )) = 0xFF;
816 } else { // red if > -3 dB
817 *(p_pic->p[0].p_pixels +
818 (scale + 30 - i_line - 1) *
819 p_pic->p[0].i_pitch +
820 ( (2*i*barWidth)+j ) ) = 76;
821 *(p_pic->p[1].p_pixels +
822 (scale + 30 - i_line - 1) *
823 p_pic->p[1].i_pitch +
824 ( (2*i*barWidth)+j ) ) = 85;
825 *(p_pic->p[2].p_pixels +
826 (scale + 30 - i_line - 1) *
827 p_pic->p[2].i_pitch +
828 ( (2*i*barWidth)+j ) ) = 0xFF;
829 *(p_pic->p[3].p_pixels +
830 (scale + 30 - i_line - 1) *
831 p_pic->p[3].i_pitch +
832 ( (2*i*barWidth)+j )) = 0xFF;
840 if (alarm) {// draw the alarm square
842 for ( i_line = 0; i_line < 10; i_line++ ) {
843 for (i=0; i<i_width+20; i++) {
844 *(p_pic->p[0].p_pixels +
845 (scale + 30 - i_line - 1) *
846 p_pic->p[0].i_pitch + i ) = 76;
847 *(p_pic->p[1].p_pixels +
848 (scale + 30 - i_line - 1) *
849 p_pic->p[1].i_pitch + i ) = 85;
850 *(p_pic->p[2].p_pixels +
851 (scale + 30 - i_line - 1) *
852 p_pic->p[2].i_pitch + i ) = 0xFF;
853 *(p_pic->p[3].p_pixels +
854 (scale + 30 - i_line - 1) *
855 p_pic->p[3].i_pitch + i ) = 0xFF;
859 for ( i_line = scale+21; i_line < scale+30; i_line++ ) {
860 for (i=0; i<i_width+20; i++) {
861 *(p_pic->p[0].p_pixels +
862 (scale + 30 - i_line - 1) *
863 p_pic->p[0].i_pitch + i ) = 76;
864 *(p_pic->p[1].p_pixels +
865 (scale + 30 - i_line - 1) *
866 p_pic->p[1].i_pitch + i ) = 85;
867 *(p_pic->p[2].p_pixels +
868 (scale + 30 - i_line - 1) *
869 p_pic->p[2].i_pitch + i ) = 0xFF;
870 *(p_pic->p[3].p_pixels +
871 (scale + 30 - i_line - 1) *
872 p_pic->p[3].i_pitch + i ) = 0xFF;
876 for ( i_line = 9; i_line < scale+21; i_line++ ) {
877 for (i=0; i<10; i++) {
878 *(p_pic->p[0].p_pixels +
879 (scale + 30 - i_line - 1) *
880 p_pic->p[0].i_pitch + i ) = 76;
881 *(p_pic->p[1].p_pixels +
882 (scale + 30 - i_line - 1) *
883 p_pic->p[1].i_pitch + i ) = 85;
884 *(p_pic->p[2].p_pixels +
885 (scale + 30 - i_line - 1) *
886 p_pic->p[2].i_pitch + i ) = 0xFF;
887 *(p_pic->p[3].p_pixels +
888 (scale + 30 - i_line - 1) *
889 p_pic->p[3].i_pitch + i ) = 0xFF;
891 for (i=i_width+11; i<i_width+20; i++) {
892 *(p_pic->p[0].p_pixels +
893 (scale + 30 - i_line - 1) *
894 p_pic->p[0].i_pitch + i ) = 76;
895 *(p_pic->p[1].p_pixels +
896 (scale + 30 - i_line - 1) *
897 p_pic->p[1].i_pitch + i ) = 85;
898 *(p_pic->p[2].p_pixels +
899 (scale + 30 - i_line - 1) *
900 p_pic->p[2].i_pitch + i ) = 0xFF;
901 *(p_pic->p[3].p_pixels +
902 (scale + 30 - i_line - 1) *
903 p_pic->p[3].i_pitch + i ) = 0xFF;
912 /*****************************************************************************
913 * LoadBarGraph: loads the BarGraph images into memory
914 *****************************************************************************/
915 static void LoadBarGraph( vlc_object_t *p_this, BarGraph_t *p_BarGraph )
918 p_BarGraph->p_pic = LoadImage( p_this, p_BarGraph->nbChannels, p_BarGraph->i_values, p_BarGraph->scale, p_BarGraph->alarm, p_BarGraph->barWidth);
919 if( !p_BarGraph->p_pic )
921 msg_Warn( p_this, "error while creating picture" );
926 /*****************************************************************************
927 * parse_i_values : parse i_values parameter and store the corresponding values
928 *****************************************************************************/
929 void parse_i_values( BarGraph_t *p_BarGraph, char *i_values)
935 p_BarGraph->nbChannels = 0;
936 p_BarGraph->i_values = NULL;
937 res = strtok_r(i_values, delim, &tok);
938 while (res != NULL) {
939 p_BarGraph->nbChannels++;
940 p_BarGraph->i_values = xrealloc(p_BarGraph->i_values,
941 p_BarGraph->nbChannels*sizeof(int));
942 p_BarGraph->i_values[p_BarGraph->nbChannels-1] = __MAX( __MIN( atof(res)*p_BarGraph->scale, p_BarGraph->scale ), 0 );
943 res = strtok_r(NULL, delim, &tok);