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>
45 /*****************************************************************************
47 *****************************************************************************/
49 #define I_VALUES_TEXT N_("Value of the audio channels levels")
50 #define I_VALUES_LONGTEXT N_("Value of the audio level of each channels between 0 and 1" \
51 "Each level should be separated with ':'.")
52 #define POSX_TEXT N_("X coordinate")
53 #define POSX_LONGTEXT N_("X coordinate of the bargraph." )
54 #define POSY_TEXT N_("Y coordinate")
55 #define POSY_LONGTEXT N_("Y coordinate of the bargraph." )
56 #define TRANS_TEXT N_("Transparency of the bargraph")
57 #define TRANS_LONGTEXT N_("Bargraph transparency value " \
58 "(from 0 for full transparency to 255 for full opacity)." )
59 #define POS_TEXT N_("Bargraph position")
60 #define POS_LONGTEXT N_( \
61 "Enforce the bargraph position on the video " \
62 "(0=center, 1=left, 2=right, 4=top, 8=bottom, you can " \
63 "also use combinations of these values, eg 6 = top-right).")
64 #define ALARM_TEXT N_("Alarm")
65 #define ALARM_LONGTEXT N_("Signals a silence and displays and alert " \
66 "(0=no alarm, 1=alarm).")
67 #define BARWIDTH_TEXT N_("Bar width in pixel (default : 10)")
68 #define BARWIDTH_LONGTEXT N_("Width in pixel of each bar in the BarGraph to be displayed " \
71 #define CFG_PREFIX "audiobargraph_v-"
73 static const int pi_pos_values[] = { 0, 1, 2, 4, 8, 5, 6, 9, 10 };
74 static const char *const ppsz_pos_descriptions[] =
75 { N_("Center"), N_("Left"), N_("Right"), N_("Top"), N_("Bottom"),
76 N_("Top-Left"), N_("Top-Right"), N_("Bottom-Left"), N_("Bottom-Right") };
78 static int OpenSub ( vlc_object_t * );
79 static int OpenVideo( vlc_object_t * );
80 static void Close ( vlc_object_t * );
84 set_category( CAT_VIDEO )
85 set_subcategory( SUBCAT_VIDEO_SUBPIC )
87 set_capability( "sub filter", 0 )
88 set_callbacks( OpenSub, Close )
89 set_description( N_("Audio Bar Graph Video sub filter") )
90 set_shortname( N_("Audio Bar Graph Video") )
91 add_shortcut( "audiobargraph_v" )
93 add_string( CFG_PREFIX "i_values", NULL, NULL, I_VALUES_TEXT, I_VALUES_LONGTEXT, false )
94 add_integer( CFG_PREFIX "x", 0, NULL, POSX_TEXT, POSX_LONGTEXT, true )
95 add_integer( CFG_PREFIX "y", 0, NULL, POSY_TEXT, POSY_LONGTEXT, true )
96 add_integer_with_range( CFG_PREFIX "transparency", 255, 0, 255, NULL,
97 TRANS_TEXT, TRANS_LONGTEXT, false )
98 add_integer( CFG_PREFIX "position", -1, NULL, POS_TEXT, POS_LONGTEXT, false )
99 change_integer_list( pi_pos_values, ppsz_pos_descriptions, NULL )
100 add_integer( CFG_PREFIX "alarm", 0, NULL, ALARM_TEXT, ALARM_LONGTEXT, true )
101 add_integer( CFG_PREFIX "barWidth", 10, NULL, BARWIDTH_TEXT, BARWIDTH_LONGTEXT, true )
103 /* video output filter submodule */
105 set_capability( "video filter2", 0 )
106 set_callbacks( OpenVideo, Close )
107 set_description( N_("Audio Bar Graph Video sub filter") )
108 add_shortcut( "audiobargraph_v" )
112 /*****************************************************************************
114 *****************************************************************************/
116 /*****************************************************************************
117 * Structure to hold the Bar Graph properties
118 ****************************************************************************/
121 int i_alpha; /* -1 means use default alpha */
133 * Private data holder
141 BarGraph_t p_BarGraph;
148 /* On the fly control variable */
152 static const char *const ppsz_filter_options[] = {
153 "i_values", "x", "y", "transparency", "position", "alarm", "barWidth", NULL
156 static const char *const ppsz_filter_callbacks[] = {
157 "audiobargraph_v-i_values",
160 "audiobargraph_v-transparency",
161 "audiobargraph_v-position",
162 "audiobargraph_v-alarm",
163 "audiobargraph_v-barWidth",
167 static int OpenCommon( vlc_object_t *, bool b_sub );
169 static subpicture_t *FilterSub( filter_t *, mtime_t );
170 static picture_t *FilterVideo( filter_t *, picture_t * );
172 static int BarGraphCallback( vlc_object_t *, char const *,
173 vlc_value_t, vlc_value_t, void * );
175 static void LoadBarGraph( vlc_object_t *, BarGraph_t *);
176 void parse_i_values( BarGraph_t *p_BarGraph, char *i_values);
179 * Open the sub filter
181 static int OpenSub( vlc_object_t *p_this )
183 return OpenCommon( p_this, true );
187 * Open the video filter
189 static int OpenVideo( vlc_object_t *p_this )
191 return OpenCommon( p_this, false );
195 * Common open function
197 static int OpenCommon( vlc_object_t *p_this, bool b_sub )
199 filter_t *p_filter = (filter_t *)p_this;
201 BarGraph_t *p_BarGraph;
202 char* i_values = NULL;
205 if( !b_sub && !es_format_IsSimilar( &p_filter->fmt_in, &p_filter->fmt_out ) )
207 msg_Err( p_filter, "Input and output format does not match" );
213 p_filter->p_sys = p_sys = malloc( sizeof( *p_sys ) );
216 p_BarGraph = &(p_sys->p_BarGraph);
219 p_sys->p_blend = NULL;
223 p_sys->p_blend = filter_NewBlend( VLC_OBJECT(p_filter),
224 &p_filter->fmt_in.video );
225 if( !p_sys->p_blend )
227 //free( p_BarGraph );
234 config_ChainParse( p_filter, CFG_PREFIX, ppsz_filter_options,
237 /* create and initialize variables */
238 p_sys->i_pos = var_CreateGetIntegerCommand( p_filter, "audiobargraph_v-position" );
239 p_sys->i_pos_x = var_CreateGetIntegerCommand( p_filter, "audiobargraph_v-x" );
240 p_sys->i_pos_y = var_CreateGetIntegerCommand( p_filter, "audiobargraph_v-y" );
241 p_BarGraph->i_alpha = var_CreateGetIntegerCommand( p_filter,
242 "audiobargraph_v-transparency" );
243 p_BarGraph->i_alpha = __MAX( __MIN( p_BarGraph->i_alpha, 255 ), 0 );
244 i_values = var_CreateGetStringCommand( p_filter, "audiobargraph_v-i_values" );
245 //p_BarGraph->nbChannels = 0;
246 //p_BarGraph->i_values = NULL;
247 parse_i_values(p_BarGraph, i_values);
248 p_BarGraph->alarm = var_CreateGetIntegerCommand( p_filter, "audiobargraph_v-alarm" );
249 p_BarGraph->barWidth = var_CreateGetIntegerCommand( p_filter, "audiobargraph_v-barWidth" );
250 p_BarGraph->scale = 400;
252 /* Ignore aligment if a position is given for video filter */
253 if( !b_sub && p_sys->i_pos_x >= 0 && p_sys->i_pos_y >= 0 )
256 vlc_mutex_init( &p_sys->lock );
257 LoadBarGraph( p_this, p_BarGraph );
258 p_sys->b_spu_update = true;
260 for( int i = 0; ppsz_filter_callbacks[i]; i++ )
261 var_AddCallback( p_filter, ppsz_filter_callbacks[i],
262 BarGraphCallback, p_sys );
267 p_filter->pf_sub_filter = FilterSub;
271 p_filter->pf_video_filter = FilterVideo;
279 * Common close function
281 static void Close( vlc_object_t *p_this )
283 filter_t *p_filter = (filter_t *)p_this;
284 filter_sys_t *p_sys = p_filter->p_sys;
285 BarGraph_t *p_BarGraph = &(p_sys->p_BarGraph);
287 for( int i = 0; ppsz_filter_callbacks[i]; i++ )
288 var_DelCallback( p_filter, ppsz_filter_callbacks[i],
289 BarGraphCallback, p_sys );
292 filter_DeleteBlend( p_sys->p_blend );
294 vlc_mutex_destroy( &p_sys->lock );
296 if( p_BarGraph->p_pic )
298 picture_Release( p_BarGraph->p_pic );
299 p_BarGraph->p_pic = NULL;
301 free( p_BarGraph->i_values );
309 static subpicture_t *FilterSub( filter_t *p_filter, mtime_t date )
311 filter_sys_t *p_sys = p_filter->p_sys;
312 BarGraph_t *p_BarGraph = &(p_sys->p_BarGraph);
315 subpicture_region_t *p_region;
319 vlc_mutex_lock( &p_sys->lock );
320 /* Basic test: b_spu_update occurs on a dynamic change */
321 if( !p_sys->b_spu_update )
323 vlc_mutex_unlock( &p_sys->lock );
327 p_pic = p_BarGraph->p_pic;
329 /* Allocate the subpicture internal data. */
330 p_spu = filter_NewSubpicture( p_filter );
334 p_spu->b_absolute = p_sys->b_absolute;
335 p_spu->i_start = date;
337 p_spu->b_ephemer = true;
339 /* Send an empty subpicture to clear the display when needed */
340 if( !p_pic || !p_BarGraph->i_alpha )
343 /* Create new SPU region */
344 memset( &fmt, 0, sizeof(video_format_t) );
345 fmt.i_chroma = VLC_CODEC_YUVA;
346 fmt.i_aspect = VOUT_ASPECT_FACTOR;
347 fmt.i_sar_num = fmt.i_sar_den = 1;
348 fmt.i_width = fmt.i_visible_width = p_pic->p[Y_PLANE].i_visible_pitch;
349 fmt.i_height = fmt.i_visible_height = p_pic->p[Y_PLANE].i_visible_lines;
350 fmt.i_x_offset = fmt.i_y_offset = 0;
351 p_region = subpicture_region_New( &fmt );
354 msg_Err( p_filter, "cannot allocate SPU region" );
355 p_filter->pf_sub_buffer_del( p_filter, p_spu );
361 picture_Copy( p_region->p_picture, p_pic );
363 /* where to locate the bar graph: */
364 if( p_sys->i_pos < 0 )
365 { /* set to an absolute xy */
366 p_region->i_align = OSD_ALIGN_RIGHT | OSD_ALIGN_TOP;
367 p_spu->b_absolute = true;
370 { /* set to one of the 9 relative locations */
371 p_region->i_align = p_sys->i_pos;
372 p_spu->b_absolute = false;
375 p_region->i_x = p_sys->i_pos_x;
376 p_region->i_y = p_sys->i_pos_y;
378 p_spu->p_region = p_region;
380 p_spu->i_alpha = p_BarGraph->i_alpha ;
383 vlc_mutex_unlock( &p_sys->lock );
391 static picture_t *FilterVideo( filter_t *p_filter, picture_t *p_src )
393 filter_sys_t *p_sys = p_filter->p_sys;
394 BarGraph_t *p_BarGraph = &(p_sys->p_BarGraph);
396 picture_t *p_dst = filter_NewPicture( p_filter );
400 picture_Copy( p_dst, p_src );
403 vlc_mutex_lock( &p_sys->lock );
406 const picture_t *p_pic = p_BarGraph->p_pic;
409 const video_format_t *p_fmt = &p_pic->format;
410 const int i_dst_w = p_filter->fmt_out.video.i_visible_width;
411 const int i_dst_h = p_filter->fmt_out.video.i_visible_height;
415 if( p_sys->i_pos & SUBPICTURE_ALIGN_BOTTOM )
417 p_sys->i_pos_y = i_dst_h - p_fmt->i_visible_height;
419 else if ( !(p_sys->i_pos & SUBPICTURE_ALIGN_TOP) )
421 p_sys->i_pos_y = ( i_dst_h - p_fmt->i_visible_height ) / 2;
428 if( p_sys->i_pos & SUBPICTURE_ALIGN_RIGHT )
430 p_sys->i_pos_x = i_dst_w - p_fmt->i_visible_width;
432 else if ( !(p_sys->i_pos & SUBPICTURE_ALIGN_LEFT) )
434 p_sys->i_pos_x = ( i_dst_w - p_fmt->i_visible_width ) / 2;
443 const int i_alpha = p_BarGraph->i_alpha;
444 if( filter_ConfigureBlend( p_sys->p_blend, i_dst_w, i_dst_h, p_fmt ) ||
445 filter_Blend( p_sys->p_blend, p_dst, p_sys->i_pos_x, p_sys->i_pos_y,
448 msg_Err( p_filter, "failed to blend a picture" );
451 vlc_mutex_unlock( &p_sys->lock );
454 picture_Release( p_src );
458 /*****************************************************************************
459 * Callback to update params on the fly
460 *****************************************************************************/
461 static int BarGraphCallback( vlc_object_t *p_this, char const *psz_var,
462 vlc_value_t oldval, vlc_value_t newval, void *p_data )
465 filter_sys_t *p_sys = (filter_sys_t *)p_data;
466 BarGraph_t *p_BarGraph = &(p_sys->p_BarGraph);
470 vlc_mutex_lock( &p_sys->lock );
471 if ( !strcmp( psz_var, "audiobargraph_v-x" ) )
473 p_sys->i_pos_x = newval.i_int;
475 else if ( !strcmp( psz_var, "audiobargraph_v-y" ) )
477 p_sys->i_pos_y = newval.i_int;
479 else if ( !strcmp( psz_var, "audiobargraph_v-position" ) )
481 p_sys->i_pos = newval.i_int;
483 else if ( !strcmp( psz_var, "audiobargraph_v-transparency" ) )
485 p_BarGraph->i_alpha = __MAX( __MIN( newval.i_int, 255 ), 0 );
487 else if ( !strcmp( psz_var, "audiobargraph_v-i_values" ) )
489 if( p_BarGraph->p_pic )
491 picture_Release( p_BarGraph->p_pic );
492 p_BarGraph->p_pic = NULL;
494 i_values = strdup( newval.psz_string );
495 free(p_BarGraph->i_values);
496 //p_BarGraph->i_values = NULL;
497 //p_BarGraph->nbChannels = 0;
498 // in case many answer are received at the same time, only keep one
499 res = strchr(i_values, '@');
502 parse_i_values( p_BarGraph, i_values);
503 LoadBarGraph(p_this,p_BarGraph);
505 else if ( !strcmp( psz_var, "audiobargraph_v-alarm" ) )
507 if( p_BarGraph->p_pic )
509 picture_Release( p_BarGraph->p_pic );
510 p_BarGraph->p_pic = NULL;
512 p_BarGraph->alarm = newval.i_int;
513 LoadBarGraph(p_this,p_BarGraph);
515 else if ( !strcmp( psz_var, "audiobargraph_v-barWidth" ) )
517 if( p_BarGraph->p_pic )
519 picture_Release( p_BarGraph->p_pic );
520 p_BarGraph->p_pic = NULL;
522 p_BarGraph->barWidth = newval.i_int;
523 LoadBarGraph(p_this,p_BarGraph);
525 p_sys->b_spu_update = true;
526 vlc_mutex_unlock( &p_sys->lock );
531 /*****************************************************************************
532 * LoadImage: creates and returns the bar graph image
533 *****************************************************************************/
534 static picture_t *LoadImage( vlc_object_t *p_this, int nbChannels, int* i_values, int scale, int alarm, int barWidth)
541 int moinsTrois, moinsCinq, moinsSept, moinsDix, moinsVingt;
543 if (nbChannels == 0) {
546 i_width = 2 * nbChannels * barWidth + 10;
549 moinsTrois = 0.71*scale + 20;
550 moinsCinq = 0.56*scale + 20;
551 moinsSept = 0.45*scale + 20;
552 moinsDix = 0.32*scale + 20;
553 moinsVingt = 0.1*scale + 20;
555 p_pic = picture_New(VLC_FOURCC('Y','U','V','A'), i_width+20, scale+30, VOUT_ASPECT_FACTOR * (i_width+20)/(scale+30));
557 // blacken the whole picture
558 for( i = 0 ; i < p_pic->i_planes ; i++ )
560 memset( p_pic->p[i].p_pixels, 0x00,
561 p_pic->p[i].i_visible_lines * p_pic->p[i].i_pitch );
565 for ( i_line = 20; i_line < scale+20; i_line++ ) {
567 #define DrawPointsBlack(a,b) {\
568 for (i=a; i<b; i++) {\
569 *(p_pic->p[0].p_pixels + (scale + 30 - i_line - 1) * p_pic->p[0].i_pitch + i ) = 0x00; \
570 *(p_pic->p[1].p_pixels + (scale + 30 - i_line - 1) * p_pic->p[1].i_pitch + i ) = 128; \
571 *(p_pic->p[2].p_pixels + (scale + 30 - i_line - 1) * p_pic->p[2].i_pitch + i ) = 128; \
572 *(p_pic->p[3].p_pixels + (scale + 30 - i_line - 1) * p_pic->p[3].i_pitch + i ) = 0xFF; \
575 #define DrawPointsWhite(a,b) {\
576 for (i=a; i<b; i++) {\
577 *(p_pic->p[0].p_pixels + (scale + 30 - i_line - 1) * p_pic->p[0].i_pitch + i ) = 0xFF;\
578 *(p_pic->p[1].p_pixels + (scale + 30 - i_line - 1) * p_pic->p[1].i_pitch + i ) = 128;\
579 *(p_pic->p[2].p_pixels + (scale + 30 - i_line - 1) * p_pic->p[2].i_pitch + i ) = 128;\
580 *(p_pic->p[3].p_pixels + (scale + 30 - i_line - 1) * p_pic->p[3].i_pitch + i ) = 0xFF; \
585 DrawPointsBlack(20,22);
586 DrawPointsWhite(22,24);
589 if (i_line == moinsTrois - 2) {
591 DrawPointsBlack(16,19);
593 if (i_line == moinsTrois - 1) {
595 DrawPointsBlack(18,19);
597 DrawPointsWhite(24,27);
599 if (i_line == moinsTrois) {
601 DrawPointsBlack(16,19);
603 DrawPointsBlack(24,27);
605 if (i_line == moinsTrois + 1) {
607 DrawPointsBlack(18,19);
609 DrawPointsBlack(24,27);
611 if (i_line == moinsTrois + 2) {
613 DrawPointsBlack(16,19);
617 if (i_line == moinsCinq - 2) {
619 DrawPointsBlack(16,19);
621 if (i_line == moinsCinq - 1) {
623 DrawPointsBlack(18,19);
625 DrawPointsWhite(24,27);
627 if (i_line == moinsCinq) {
629 DrawPointsBlack(16,19);
631 DrawPointsBlack(24,27);
633 if (i_line == moinsCinq + 1) {
635 DrawPointsBlack(16,17);
637 DrawPointsBlack(24,27);
639 if (i_line == moinsCinq + 2) {
641 DrawPointsBlack(16,19);
645 if (i_line == moinsSept - 2) {
647 DrawPointsBlack(18,19);
649 if (i_line == moinsSept - 1) {
651 DrawPointsBlack(18,19);
653 DrawPointsWhite(24,27);
655 if (i_line == moinsSept) {
657 DrawPointsBlack(18,19);
659 DrawPointsBlack(24,27);
661 if (i_line == moinsSept + 1) {
663 DrawPointsBlack(18,19);
665 DrawPointsBlack(24,27);
667 if (i_line == moinsSept + 2) {
669 DrawPointsBlack(16,19);
674 if (i_line == moinsDix - 2) {
676 DrawPointsBlack(14,15);
678 DrawPointsBlack(16,19);
680 if (i_line == moinsDix - 1) {
682 DrawPointsBlack(14,15);
684 DrawPointsBlack(16,17);
685 DrawPointsBlack(18,19);
687 DrawPointsWhite(24,27);
689 if (i_line == moinsDix) {
691 DrawPointsBlack(14,15);
693 DrawPointsBlack(16,17);
694 DrawPointsBlack(18,19);
696 DrawPointsBlack(24,27);
698 if (i_line == moinsDix + 1) {
700 DrawPointsBlack(14,15);
702 DrawPointsBlack(16,17);
703 DrawPointsBlack(18,19);
705 DrawPointsBlack(24,27);
707 if (i_line == moinsDix + 2) {
709 DrawPointsBlack(14,15);
711 DrawPointsBlack(16,19);
715 if (i_line == moinsVingt - 2) {
717 DrawPointsBlack(12,15);
719 DrawPointsBlack(16,19);
721 if (i_line == moinsVingt - 1) {
723 DrawPointsBlack(12,13);
725 DrawPointsBlack(16,17);
726 DrawPointsBlack(18,19);
728 DrawPointsWhite(24,27);
730 if (i_line == moinsVingt) {
732 DrawPointsBlack(12,15);
734 DrawPointsBlack(16,17);
735 DrawPointsBlack(18,19);
737 DrawPointsBlack(24,27);
739 if (i_line == moinsVingt + 1) {
741 DrawPointsBlack(14,15);
743 DrawPointsBlack(16,17);
744 DrawPointsBlack(18,19);
746 DrawPointsBlack(24,27);
748 if (i_line == moinsVingt + 2) {
750 DrawPointsBlack(12,15);
752 DrawPointsBlack(16,19);
758 // draw the bars and channel indicators
759 for (i=0; i<nbChannels; i++) {
760 for( j = barWidth+20 ; j < 2*barWidth+20; j++)
762 // channel indicators
763 for ( i_line = 12; i_line < 18; i_line++ ) {
765 *(p_pic->p[0].p_pixels +
766 (scale + 30 - i_line - 1) *
767 p_pic->p[0].i_pitch +
768 ( (2*i*barWidth)+j ) ) = 255;
769 *(p_pic->p[1].p_pixels +
770 (scale + 30 - i_line - 1) *
771 p_pic->p[1].i_pitch +
772 ( (2*i*barWidth)+j ) ) = 128;
773 *(p_pic->p[2].p_pixels +
774 (scale + 30 - i_line - 1) *
775 p_pic->p[2].i_pitch +
776 ( (2*i*barWidth)+j ) ) = 128;
777 *(p_pic->p[3].p_pixels +
778 (scale + 30 - i_line - 1) *
779 p_pic->p[3].i_pitch +
780 ( (2*i*barWidth)+j )) = 0xFF;
783 for( i_line = 20; i_line < i_values[i]+20; i_line++ )
785 if (i_line < moinsDix) { // green if < -10 dB
786 *(p_pic->p[0].p_pixels +
787 (scale + 30 - i_line - 1) *
788 p_pic->p[0].i_pitch +
789 ( (2*i*barWidth)+j ) ) = 150;
790 *(p_pic->p[1].p_pixels +
791 (scale + 30 - i_line - 1) *
792 p_pic->p[1].i_pitch +
793 ( (2*i*barWidth)+j ) ) = 44;
794 *(p_pic->p[2].p_pixels +
795 (scale + 30 - i_line - 1) *
796 p_pic->p[2].i_pitch +
797 ( (2*i*barWidth)+j ) ) = 21;
798 *(p_pic->p[3].p_pixels +
799 (scale + 30 - i_line - 1) *
800 p_pic->p[3].i_pitch +
801 ( (2*i*barWidth)+j )) = 0xFF;
802 } else if (i_line < moinsTrois) { // yellow if > -10dB and < -3dB
803 *(p_pic->p[0].p_pixels +
804 (scale + 30 - i_line - 1) *
805 p_pic->p[0].i_pitch +
806 ( (2*i*barWidth)+j ) ) = 226;
807 *(p_pic->p[1].p_pixels +
808 (scale + 30 - i_line - 1) *
809 p_pic->p[1].i_pitch +
810 ( (2*i*barWidth)+j ) ) = 1;
811 *(p_pic->p[2].p_pixels +
812 (scale + 30 - i_line - 1) *
813 p_pic->p[2].i_pitch +
814 ( (2*i*barWidth)+j ) ) = 148;
815 *(p_pic->p[3].p_pixels +
816 (scale + 30 - i_line - 1) *
817 p_pic->p[3].i_pitch +
818 ( (2*i*barWidth)+j )) = 0xFF;
819 } else { // red if > -3 dB
820 *(p_pic->p[0].p_pixels +
821 (scale + 30 - i_line - 1) *
822 p_pic->p[0].i_pitch +
823 ( (2*i*barWidth)+j ) ) = 76;
824 *(p_pic->p[1].p_pixels +
825 (scale + 30 - i_line - 1) *
826 p_pic->p[1].i_pitch +
827 ( (2*i*barWidth)+j ) ) = 85;
828 *(p_pic->p[2].p_pixels +
829 (scale + 30 - i_line - 1) *
830 p_pic->p[2].i_pitch +
831 ( (2*i*barWidth)+j ) ) = 0xFF;
832 *(p_pic->p[3].p_pixels +
833 (scale + 30 - i_line - 1) *
834 p_pic->p[3].i_pitch +
835 ( (2*i*barWidth)+j )) = 0xFF;
843 if (alarm) {// draw the alarm square
845 for ( i_line = 0; i_line < 10; i_line++ ) {
846 for (i=0; i<i_width+20; i++) {
847 *(p_pic->p[0].p_pixels +
848 (scale + 30 - i_line - 1) *
849 p_pic->p[0].i_pitch + i ) = 76;
850 *(p_pic->p[1].p_pixels +
851 (scale + 30 - i_line - 1) *
852 p_pic->p[1].i_pitch + i ) = 85;
853 *(p_pic->p[2].p_pixels +
854 (scale + 30 - i_line - 1) *
855 p_pic->p[2].i_pitch + i ) = 0xFF;
856 *(p_pic->p[3].p_pixels +
857 (scale + 30 - i_line - 1) *
858 p_pic->p[3].i_pitch + i ) = 0xFF;
862 for ( i_line = scale+21; i_line < scale+30; i_line++ ) {
863 for (i=0; i<i_width+20; i++) {
864 *(p_pic->p[0].p_pixels +
865 (scale + 30 - i_line - 1) *
866 p_pic->p[0].i_pitch + i ) = 76;
867 *(p_pic->p[1].p_pixels +
868 (scale + 30 - i_line - 1) *
869 p_pic->p[1].i_pitch + i ) = 85;
870 *(p_pic->p[2].p_pixels +
871 (scale + 30 - i_line - 1) *
872 p_pic->p[2].i_pitch + i ) = 0xFF;
873 *(p_pic->p[3].p_pixels +
874 (scale + 30 - i_line - 1) *
875 p_pic->p[3].i_pitch + i ) = 0xFF;
879 for ( i_line = 9; i_line < scale+21; i_line++ ) {
880 for (i=0; i<10; i++) {
881 *(p_pic->p[0].p_pixels +
882 (scale + 30 - i_line - 1) *
883 p_pic->p[0].i_pitch + i ) = 76;
884 *(p_pic->p[1].p_pixels +
885 (scale + 30 - i_line - 1) *
886 p_pic->p[1].i_pitch + i ) = 85;
887 *(p_pic->p[2].p_pixels +
888 (scale + 30 - i_line - 1) *
889 p_pic->p[2].i_pitch + i ) = 0xFF;
890 *(p_pic->p[3].p_pixels +
891 (scale + 30 - i_line - 1) *
892 p_pic->p[3].i_pitch + i ) = 0xFF;
894 for (i=i_width+11; i<i_width+20; i++) {
895 *(p_pic->p[0].p_pixels +
896 (scale + 30 - i_line - 1) *
897 p_pic->p[0].i_pitch + i ) = 76;
898 *(p_pic->p[1].p_pixels +
899 (scale + 30 - i_line - 1) *
900 p_pic->p[1].i_pitch + i ) = 85;
901 *(p_pic->p[2].p_pixels +
902 (scale + 30 - i_line - 1) *
903 p_pic->p[2].i_pitch + i ) = 0xFF;
904 *(p_pic->p[3].p_pixels +
905 (scale + 30 - i_line - 1) *
906 p_pic->p[3].i_pitch + i ) = 0xFF;
915 /*****************************************************************************
916 * LoadBarGraph: loads the BarGraph images into memory
917 *****************************************************************************/
918 static void LoadBarGraph( vlc_object_t *p_this, BarGraph_t *p_BarGraph )
921 p_BarGraph->p_pic = LoadImage( p_this, p_BarGraph->nbChannels, p_BarGraph->i_values, p_BarGraph->scale, p_BarGraph->alarm, p_BarGraph->barWidth);
922 if( !p_BarGraph->p_pic )
924 msg_Warn( p_this, "error while creating picture" );
929 /*****************************************************************************
930 * parse_i_values : parse i_values parameter and store the corresponding values
931 *****************************************************************************/
932 void parse_i_values( BarGraph_t *p_BarGraph, char *i_values)
938 p_BarGraph->nbChannels = 0;
939 p_BarGraph->i_values = NULL;
940 res = strtok_r(i_values, delim, &tok);
941 while (res != NULL) {
942 p_BarGraph->nbChannels++;
943 p_BarGraph->i_values = (int*)realloc(p_BarGraph->i_values, p_BarGraph->nbChannels*sizeof(int));
944 p_BarGraph->i_values[p_BarGraph->nbChannels-1] = __MAX( __MIN( atof(res)*p_BarGraph->scale, p_BarGraph->scale ), 0 );
945 res = strtok_r(NULL, delim, &tok);