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
, 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
)
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
);