1 /*****************************************************************************
2 * audiobargraph_v.c : audiobargraph video plugin for vlc
3 *****************************************************************************
4 * Copyright (C) 2003-2006 VLC authors and VideoLAN
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 it
10 * under the terms of the GNU Lesser General Public License as published by
11 * the Free Software Foundation; either version 2.1 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 Lesser General Public License for more details.
19 * You should have received a copy of the GNU Lesser General Public License
20 * along with this program; if not, write to the Free Software Foundation,
21 * 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>
44 /*****************************************************************************
46 *****************************************************************************/
48 #define POSX_TEXT N_("X coordinate")
49 #define POSX_LONGTEXT N_("X coordinate of the bargraph." )
50 #define POSY_TEXT N_("Y coordinate")
51 #define POSY_LONGTEXT N_("Y coordinate of the bargraph." )
52 #define TRANS_TEXT N_("Transparency of the bargraph")
53 #define TRANS_LONGTEXT N_("Bargraph transparency value " \
54 "(from 0 for full transparency to 255 for full opacity)." )
55 #define POS_TEXT N_("Bargraph position")
56 #define POS_LONGTEXT N_( \
57 "Enforce the bargraph position on the video " \
58 "(0=center, 1=left, 2=right, 4=top, 8=bottom, you can " \
59 "also use combinations of these values, eg 6 = top-right).")
60 #define BARWIDTH_TEXT N_("Bar width in pixel (default : 10)")
61 #define BARWIDTH_LONGTEXT N_("Width in pixel of each bar in the BarGraph to be displayed " \
64 #define CFG_PREFIX "audiobargraph_v-"
66 static const int pi_pos_values[] = { 0, 1, 2, 4, 8, 5, 6, 9, 10 };
67 static const char *const ppsz_pos_descriptions[] =
68 { N_("Center"), N_("Left"), N_("Right"), N_("Top"), N_("Bottom"),
69 N_("Top-Left"), N_("Top-Right"), N_("Bottom-Left"), N_("Bottom-Right") };
71 static int OpenSub ( vlc_object_t * );
72 static int OpenVideo( vlc_object_t * );
73 static void Close ( vlc_object_t * );
77 set_category( CAT_VIDEO )
78 set_subcategory( SUBCAT_VIDEO_SUBPIC )
80 set_capability( "sub source", 0 )
81 set_callbacks( OpenSub, Close )
82 set_description( N_("Audio Bar Graph Video sub source") )
83 set_shortname( N_("Audio Bar Graph Video") )
84 add_shortcut( "audiobargraph_v" )
86 add_obsolete_string( CFG_PREFIX "i_values" )
87 add_integer( CFG_PREFIX "x", 0, POSX_TEXT, POSX_LONGTEXT, true )
88 add_integer( CFG_PREFIX "y", 0, POSY_TEXT, POSY_LONGTEXT, true )
89 add_integer_with_range( CFG_PREFIX "transparency", 255, 0, 255,
90 TRANS_TEXT, TRANS_LONGTEXT, false )
91 add_integer( CFG_PREFIX "position", -1, POS_TEXT, POS_LONGTEXT, false )
92 change_integer_list( pi_pos_values, ppsz_pos_descriptions )
93 add_obsolete_integer( CFG_PREFIX "alarm" )
94 add_integer( CFG_PREFIX "barWidth", 10, BARWIDTH_TEXT, BARWIDTH_LONGTEXT, true )
96 /* video output filter submodule */
98 set_capability( "video filter2", 0 )
99 set_callbacks( OpenVideo, Close )
100 set_description( N_("Audio Bar Graph Video sub source") )
101 add_shortcut( "audiobargraph_v" )
105 /*****************************************************************************
107 *****************************************************************************/
109 /*****************************************************************************
110 * Structure to hold the Bar Graph properties
111 ****************************************************************************/
114 int i_alpha; /* -1 means use default alpha */
126 * Private data holder
134 BarGraph_t p_BarGraph;
141 /* On the fly control variable */
145 static const char *const ppsz_filter_options[] = {
146 "x", "y", "transparency", "position", "barWidth", NULL
149 static const char *const ppsz_filter_callbacks[] = {
152 "audiobargraph_v-transparency",
153 "audiobargraph_v-position",
154 "audiobargraph_v-barWidth",
158 /*****************************************************************************
159 * IEC 268-18 Source: meterbridge
160 *****************************************************************************/
161 static float iec_scale(float dB)
166 return (dB + 70.0f) * 0.0025f;
168 return (dB + 60.0f) * 0.005f + 0.025f;
170 return (dB + 50.0f) * 0.0075f + 0.075f;
172 return (dB + 40.0f) * 0.015f + 0.15f;
174 return (dB + 30.0f) * 0.02f + 0.3f;
175 if (dB < -0.001f || dB > 0.001f) /* if (dB < 0.0f) */
176 return (dB + 20.0f) * 0.025f + 0.5f;
180 /*****************************************************************************
181 * parse_i_values : parse i_values parameter and store the corresponding values
182 *****************************************************************************/
183 static void parse_i_values( BarGraph_t *p_BarGraph, char *i_values)
190 p_BarGraph->nbChannels = 0;
191 p_BarGraph->i_values = NULL;
192 res = strtok_r(i_values, delim, &tok);
193 while (res != NULL) {
194 p_BarGraph->nbChannels++;
195 p_BarGraph->i_values = xrealloc(p_BarGraph->i_values,
196 p_BarGraph->nbChannels*sizeof(int));
197 db = log10(atof(res)) * 20;
198 p_BarGraph->i_values[p_BarGraph->nbChannels-1] = VLC_CLIP( iec_scale(db)*p_BarGraph->scale, 0, p_BarGraph->scale );
199 res = strtok_r(NULL, delim, &tok);
204 /*****************************************************************************
205 * LoadImage: creates and returns the bar graph image
206 *****************************************************************************/
207 static picture_t *LoadImage( vlc_object_t *p_this, int nbChannels, int* i_values, int scale, int alarm, int barWidth)
214 int minus8, minus10, minus18, minus20, minus30, minus40, minus50, minus60;
216 if (nbChannels == 0) {
219 i_width = 2 * nbChannels * barWidth + 10;
221 minus8 = iec_scale(-8)*scale + 20;
222 minus10 = iec_scale(-10)*scale + 20;
223 minus18 = iec_scale(-18)*scale + 20;
224 minus20 = iec_scale(-20)*scale + 20;
225 minus30 = iec_scale(-30)*scale + 20;
226 minus40 = iec_scale(-40)*scale + 20;
227 minus50 = iec_scale(-50)*scale + 20;
228 minus60 = iec_scale(-60)*scale + 20;
230 p_pic = picture_New(VLC_FOURCC('Y','U','V','A'), i_width+20, scale+30, 1, 1);
233 #define DrawLine(a,b,Y,U,V,A) \
234 for (i=a; i<b; i++) {\
235 *(p_pic->p[0].p_pixels + (scale + 30 - i_line - 1) * p_pic->p[0].i_pitch + i ) = Y;\
236 *(p_pic->p[1].p_pixels + (scale + 30 - i_line - 1) * p_pic->p[1].i_pitch + i ) = U;\
237 *(p_pic->p[2].p_pixels + (scale + 30 - i_line - 1) * p_pic->p[2].i_pitch + i ) = V;\
238 *(p_pic->p[3].p_pixels + (scale + 30 - i_line - 1) * p_pic->p[3].i_pitch + i ) = A; \
240 #define DrawLineBlack(a,b) DrawLine(a,b,0,128,128,0xFF)
241 #define DrawLineWhite(a,b) DrawLine(a,b,255,128,128,0xFF)
243 // blacken the whole picture
244 for( i = 0 ; i < p_pic->i_planes ; i++ )
246 memset( p_pic->p[i].p_pixels, 0x00,
247 p_pic->p[i].i_visible_lines * p_pic->p[i].i_pitch );
252 for ( i_line = 20; i_line < scale+20; i_line++ ) {
254 DrawLineBlack(20,22);
255 DrawLineWhite(22,24);
258 if (i_line == minus10 - 2) {
260 DrawLineBlack(14,15);
262 DrawLineBlack(16,19);
264 if (i_line == minus10 - 1) {
266 DrawLineBlack(14,15);
268 DrawLineBlack(16,17);
269 DrawLineBlack(18,19);
271 DrawLineWhite(24,27); //White
273 if (i_line == minus10) {
275 DrawLineBlack(14,15);
277 DrawLineBlack(16,17);
278 DrawLineBlack(18,19);
280 DrawLineBlack(24,27);
282 if (i_line == minus10 + 1) {
284 DrawLineBlack(14,15);
286 DrawLineBlack(16,17);
287 DrawLineBlack(18,19);
289 DrawLineBlack(24,27);
291 if (i_line == minus10 + 2) {
293 DrawLineBlack(14,15);
295 DrawLineBlack(16,19);
299 if (i_line == minus20 - 2) {
301 DrawLineBlack(12,15);
303 DrawLineBlack(16,19);
305 if (i_line == minus20 - 1) {
307 DrawLineBlack(12,13);
309 DrawLineBlack(16,17);
310 DrawLineBlack(18,19);
312 DrawLineWhite(24,27); //White
314 if (i_line == minus20) {
316 DrawLineBlack(12,15);
318 DrawLineBlack(16,17);
319 DrawLineBlack(18,19);
321 DrawLineBlack(24,27);
323 if (i_line == minus20 + 1) {
325 DrawLineBlack(14,15);
327 DrawLineBlack(16,17);
328 DrawLineBlack(18,19);
330 DrawLineBlack(24,27);
332 if (i_line == minus20 + 2) {
334 DrawLineBlack(12,15);
336 DrawLineBlack(16,19);
340 if (i_line == minus30 - 2) {
342 DrawLineBlack(12,15);
344 DrawLineBlack(16,19);
346 if (i_line == minus30 - 1) {
348 DrawLineBlack(14,15);
350 DrawLineBlack(16,17);
351 DrawLineBlack(18,19);
353 DrawLineWhite(24,27); //White
355 if (i_line == minus30) {
357 DrawLineBlack(12,15);
359 DrawLineBlack(16,17);
360 DrawLineBlack(18,19);
362 DrawLineBlack(24,27);
364 if (i_line == minus30 + 1) {
366 DrawLineBlack(14,15);
368 DrawLineBlack(16,17);
369 DrawLineBlack(18,19);
371 DrawLineBlack(24,27);
373 if (i_line == minus30 + 2) {
375 DrawLineBlack(12,15);
377 DrawLineBlack(16,19);
381 if (i_line == minus40 - 2) {
383 DrawLineBlack(14,15);
385 DrawLineBlack(16,19);
387 if (i_line == minus40 - 1) {
389 DrawLineBlack(14,15);
391 DrawLineBlack(16,17);
392 DrawLineBlack(18,19);
394 DrawLineWhite(24,27); // white
396 if (i_line == minus40) {
398 DrawLineBlack(12,15);
400 DrawLineBlack(16,17);
401 DrawLineBlack(18,19);
403 DrawLineBlack(24,27);
405 if (i_line == minus40 + 1) {
407 DrawLineBlack(12,13);
408 DrawLineBlack(14,15);
410 DrawLineBlack(16,17);
411 DrawLineBlack(18,19);
413 DrawLineBlack(24,27);
415 if (i_line == minus40 + 2) {
417 DrawLineBlack(12,13);
418 DrawLineBlack(14,15);
420 DrawLineBlack(16,19);
424 if (i_line == minus50 - 2) {
426 DrawLineBlack(12,15);
428 DrawLineBlack(16,19);
430 if (i_line == minus50 - 1) {
432 DrawLineBlack(14,15);
434 DrawLineBlack(16,17);
435 DrawLineBlack(18,19);
437 DrawLineWhite(24,27); //White
439 if (i_line == minus50) {
441 DrawLineBlack(12,15);
443 DrawLineBlack(16,17);
444 DrawLineBlack(18,19);
446 DrawLineBlack(24,27);
448 if (i_line == minus50 + 1) {
450 DrawLineBlack(12,13);
452 DrawLineBlack(16,17);
453 DrawLineBlack(18,19);
455 DrawLineBlack(24,27);
457 if (i_line == minus50 + 2) {
459 DrawLineBlack(12,15);
461 DrawLineBlack(16,19);
464 if (i_line == minus60 - 2) {
466 DrawLineBlack(12,15);
468 DrawLineBlack(16,19);
470 if (i_line == minus60 - 1) {
472 DrawLineBlack(12,13);
473 DrawLineBlack(14,15);
475 DrawLineBlack(16,17);
476 DrawLineBlack(18,19);
478 DrawLineWhite(24,27); //White
480 if (i_line == minus60) {
482 DrawLineBlack(12,15);
484 DrawLineBlack(16,17);
485 DrawLineBlack(18,19);
487 DrawLineBlack(24,27);
489 if (i_line == minus60 + 1) {
491 DrawLineBlack(12,13);
493 DrawLineBlack(16,17);
494 DrawLineBlack(18,19);
496 DrawLineBlack(24,27);
498 if (i_line == minus60 + 2) {
500 DrawLineBlack(12,15);
502 DrawLineBlack(16,19);
506 #define drawPoint(offset,y,u,v,a) \
507 *(p_pic->p[0].p_pixels + (scale + 30 - i_line - 1) * p_pic->p[0].i_pitch + offset ) = y; \
508 *(p_pic->p[1].p_pixels + (scale + 30 - i_line - 1) * p_pic->p[1].i_pitch + offset ) = u; \
509 *(p_pic->p[2].p_pixels + (scale + 30 - i_line - 1) * p_pic->p[2].i_pitch + offset ) = v; \
510 *(p_pic->p[3].p_pixels + (scale + 30 - i_line - 1) * p_pic->p[3].i_pitch + offset ) = a;
513 // draw the bars and channel indicators
514 for (i=0; i<nbChannels; i++) {
515 pi = 25 + ((i+1)*5) + (i*barWidth) ; // 25 separació amb indicador, 5 separació entre barres
517 for( j = pi; j < pi + barWidth; j++)
519 // channel indicators
520 for ( i_line = 12; i_line < 20; i_line++ ) {
522 drawPoint(j,76,85,0xFF,0xFF); // red
525 drawPoint(j,0,128,128,0xFF); // black DrawLine(pi,pf,0xFF,128,128,0xFF);
530 for( i_line = 20; i_line < i_values[i]+20; i_line++ )
532 if (i_line < minus18) { // green if < -18 dB
533 drawPoint(j,150,44,21,0xFF);
534 //DrawLine(pi,pf,150,44,21,0xFF);
535 } else if (i_line < minus8) { // yellow if > -18dB and < -8dB
536 drawPoint(j,226,1,148,0xFF);
537 //DrawLine(pi,pf,226,1,148,0xFF);
538 } else { // red if > -8 dB
539 drawPoint(j,76,85,0xFF,0xFF);
540 //DrawLine(pi,pf,76,85,255,0xFF);
544 for( ; i_line < scale+20; i_line++ )
546 if (i_line < minus18) { // green if < -18 dB
547 drawPoint(j,74,85,74,0xFF);
548 //DrawLine(pi,pf,74,85,74,0xFF);
549 } else if (i_line < minus8) { // yellow if > -18dB and < -8dB
550 drawPoint(j,112,64,138,0xFF);
551 //DrawLine(pi,pf,112,64,138,0xFF);
552 } else { // red if > -8 dB
553 drawPoint(j,37,106,191,0xFF);
554 //DrawLine(pi,pf,37,106,191,0xFF);
562 /*****************************************************************************
563 * LoadBarGraph: loads the BarGraph images into memory
564 *****************************************************************************/
565 static void LoadBarGraph( vlc_object_t *p_this, BarGraph_t *p_BarGraph )
568 p_BarGraph->p_pic = LoadImage( p_this, p_BarGraph->nbChannels, p_BarGraph->i_values, p_BarGraph->scale, p_BarGraph->alarm, p_BarGraph->barWidth);
569 if( !p_BarGraph->p_pic )
571 msg_Warn( p_this, "error while creating picture" );
576 /*****************************************************************************
577 * Callback to update params on the fly
578 *****************************************************************************/
579 static int BarGraphCallback( vlc_object_t *p_this, char const *psz_var,
580 vlc_value_t oldval, vlc_value_t newval, void *p_data )
583 filter_sys_t *p_sys = (filter_sys_t *)p_data;
584 BarGraph_t *p_BarGraph = &(p_sys->p_BarGraph);
587 vlc_mutex_lock( &p_sys->lock );
588 if ( !strcmp( psz_var, "audiobargraph_v-x" ) )
590 p_sys->i_pos_x = newval.i_int;
592 else if ( !strcmp( psz_var, "audiobargraph_v-y" ) )
594 p_sys->i_pos_y = newval.i_int;
596 else if ( !strcmp( psz_var, "audiobargraph_v-position" ) )
598 p_sys->i_pos = newval.i_int;
600 else if ( !strcmp( psz_var, "audiobargraph_v-transparency" ) )
602 p_BarGraph->i_alpha = VLC_CLIP( newval.i_int, 0, 255 );
604 else if ( !strcmp( psz_var, "audiobargraph_v-i_values" ) )
606 if( p_BarGraph->p_pic )
608 picture_Release( p_BarGraph->p_pic );
609 p_BarGraph->p_pic = NULL;
612 char *psz = xstrdup( newval.psz_string ? newval.psz_string : "" );
613 free(p_BarGraph->i_values);
614 //p_BarGraph->i_values = NULL;
615 //p_BarGraph->nbChannels = 0;
616 // in case many answer are received at the same time, only keep one
617 res = strchr(psz, '@');
620 parse_i_values( p_BarGraph, psz);
622 LoadBarGraph(p_this,p_BarGraph);
624 else if ( !strcmp( psz_var, "audiobargraph_v-alarm" ) )
626 if( p_BarGraph->p_pic )
628 picture_Release( p_BarGraph->p_pic );
629 p_BarGraph->p_pic = NULL;
631 p_BarGraph->alarm = newval.b_bool;
632 LoadBarGraph(p_this,p_BarGraph);
634 else if ( !strcmp( psz_var, "audiobargraph_v-barWidth" ) )
636 if( p_BarGraph->p_pic )
638 picture_Release( p_BarGraph->p_pic );
639 p_BarGraph->p_pic = NULL;
641 p_BarGraph->barWidth = newval.i_int;
642 LoadBarGraph(p_this,p_BarGraph);
644 p_sys->b_spu_update = true;
645 vlc_mutex_unlock( &p_sys->lock );
653 static subpicture_t *FilterSub( filter_t *p_filter, mtime_t date )
655 filter_sys_t *p_sys = p_filter->p_sys;
656 BarGraph_t *p_BarGraph = &(p_sys->p_BarGraph);
659 subpicture_region_t *p_region;
663 vlc_mutex_lock( &p_sys->lock );
664 /* Basic test: b_spu_update occurs on a dynamic change */
665 if( !p_sys->b_spu_update )
667 vlc_mutex_unlock( &p_sys->lock );
671 p_pic = p_BarGraph->p_pic;
673 /* Allocate the subpicture internal data. */
674 p_spu = filter_NewSubpicture( p_filter );
678 p_spu->b_absolute = p_sys->b_absolute;
679 p_spu->i_start = date;
681 p_spu->b_ephemer = true;
683 /* Send an empty subpicture to clear the display when needed */
684 if( !p_pic || !p_BarGraph->i_alpha )
687 /* Create new SPU region */
688 memset( &fmt, 0, sizeof(video_format_t) );
689 fmt.i_chroma = VLC_CODEC_YUVA;
690 fmt.i_sar_num = fmt.i_sar_den = 1;
691 fmt.i_width = fmt.i_visible_width = p_pic->p[Y_PLANE].i_visible_pitch;
692 fmt.i_height = fmt.i_visible_height = p_pic->p[Y_PLANE].i_visible_lines;
693 fmt.i_x_offset = fmt.i_y_offset = 0;
694 p_region = subpicture_region_New( &fmt );
697 msg_Err( p_filter, "cannot allocate SPU region" );
698 p_filter->pf_sub_buffer_del( p_filter, p_spu );
704 picture_Copy( p_region->p_picture, p_pic );
706 /* where to locate the bar graph: */
707 if( p_sys->i_pos < 0 )
708 { /* set to an absolute xy */
709 p_region->i_align = SUBPICTURE_ALIGN_RIGHT | SUBPICTURE_ALIGN_TOP;
710 p_spu->b_absolute = true;
713 { /* set to one of the 9 relative locations */
714 p_region->i_align = p_sys->i_pos;
715 p_spu->b_absolute = false;
718 p_region->i_x = p_sys->i_pos_x;
719 p_region->i_y = p_sys->i_pos_y;
721 p_spu->p_region = p_region;
723 p_spu->i_alpha = p_BarGraph->i_alpha ;
726 vlc_mutex_unlock( &p_sys->lock );
734 static picture_t *FilterVideo( filter_t *p_filter, picture_t *p_src )
736 filter_sys_t *p_sys = p_filter->p_sys;
737 BarGraph_t *p_BarGraph = &(p_sys->p_BarGraph);
739 picture_t *p_dst = filter_NewPicture( p_filter );
743 picture_Copy( p_dst, p_src );
746 vlc_mutex_lock( &p_sys->lock );
749 const picture_t *p_pic = p_BarGraph->p_pic;
752 const video_format_t *p_fmt = &p_pic->format;
753 const int i_dst_w = p_filter->fmt_out.video.i_visible_width;
754 const int i_dst_h = p_filter->fmt_out.video.i_visible_height;
758 if( p_sys->i_pos & SUBPICTURE_ALIGN_BOTTOM )
760 p_sys->i_pos_y = i_dst_h - p_fmt->i_visible_height;
762 else if ( !(p_sys->i_pos & SUBPICTURE_ALIGN_TOP) )
764 p_sys->i_pos_y = ( i_dst_h - p_fmt->i_visible_height ) / 2;
771 if( p_sys->i_pos & SUBPICTURE_ALIGN_RIGHT )
773 p_sys->i_pos_x = i_dst_w - p_fmt->i_visible_width;
775 else if ( !(p_sys->i_pos & SUBPICTURE_ALIGN_LEFT) )
777 p_sys->i_pos_x = ( i_dst_w - p_fmt->i_visible_width ) / 2;
786 const int i_alpha = p_BarGraph->i_alpha;
787 if( filter_ConfigureBlend( p_sys->p_blend, i_dst_w, i_dst_h, p_fmt ) ||
788 filter_Blend( p_sys->p_blend, p_dst, p_sys->i_pos_x, p_sys->i_pos_y,
791 msg_Err( p_filter, "failed to blend a picture" );
794 vlc_mutex_unlock( &p_sys->lock );
797 picture_Release( p_src );
802 * Common open function
804 static int OpenCommon( vlc_object_t *p_this, bool b_sub )
806 filter_t *p_filter = (filter_t *)p_this;
810 if( !b_sub && !es_format_IsSimilar( &p_filter->fmt_in, &p_filter->fmt_out ) )
812 msg_Err( p_filter, "Input and output format does not match" );
818 p_filter->p_sys = p_sys = malloc( sizeof( *p_sys ) );
823 p_sys->p_blend = NULL;
826 p_sys->p_blend = filter_NewBlend( VLC_OBJECT(p_filter),
827 &p_filter->fmt_in.video );
828 if( !p_sys->p_blend )
836 config_ChainParse( p_filter, CFG_PREFIX, ppsz_filter_options,
839 /* create and initialize variables */
840 p_sys->i_pos = var_CreateGetIntegerCommand( p_filter, "audiobargraph_v-position" );
841 p_sys->i_pos_x = var_CreateGetIntegerCommand( p_filter, "audiobargraph_v-x" );
842 p_sys->i_pos_y = var_CreateGetIntegerCommand( p_filter, "audiobargraph_v-y" );
843 BarGraph_t *p_BarGraph = &p_sys->p_BarGraph;
844 p_BarGraph->p_pic = NULL;
845 p_BarGraph->i_alpha = var_CreateGetIntegerCommand( p_filter,
846 "audiobargraph_v-transparency" );
847 p_BarGraph->i_alpha = VLC_CLIP( p_BarGraph->i_alpha, 0, 255 );
848 parse_i_values(p_BarGraph, &(char){ 0 });
849 p_BarGraph->alarm = false;
851 p_BarGraph->barWidth = var_CreateGetIntegerCommand( p_filter, "audiobargraph_v-barWidth" );
852 p_BarGraph->scale = 400;
854 /* Ignore aligment if a position is given for video filter */
855 if( !b_sub && p_sys->i_pos_x >= 0 && p_sys->i_pos_y >= 0 )
858 vlc_mutex_init( &p_sys->lock );
860 var_Create(p_filter->p_libvlc, "audiobargraph_v-alarm", VLC_VAR_BOOL);
861 var_Create(p_filter->p_libvlc, "audiobargraph_v-i_values", VLC_VAR_STRING);
863 var_AddCallback(p_filter->p_libvlc, "audiobargraph_v-alarm",
864 BarGraphCallback, p_sys);
865 var_AddCallback(p_filter->p_libvlc, "audiobargraph_v-i_values",
866 BarGraphCallback, p_sys);
868 var_TriggerCallback(p_filter->p_libvlc, "audiobargraph_v-alarm");
869 var_TriggerCallback(p_filter->p_libvlc, "audiobargraph_v-i_values");
871 for( int i = 0; ppsz_filter_callbacks[i]; i++ )
872 var_AddCallback( p_filter, ppsz_filter_callbacks[i],
873 BarGraphCallback, p_sys );
876 p_filter->pf_sub_source = FilterSub;
878 p_filter->pf_video_filter = FilterVideo;
884 * Open the sub source
886 static int OpenSub( vlc_object_t *p_this )
888 return OpenCommon( p_this, true );
892 * Open the video filter
894 static int OpenVideo( vlc_object_t *p_this )
896 return OpenCommon( p_this, false );
900 * Common close function
902 static void Close( vlc_object_t *p_this )
904 filter_t *p_filter = (filter_t *)p_this;
905 filter_sys_t *p_sys = p_filter->p_sys;
907 for( int i = 0; ppsz_filter_callbacks[i]; i++ )
908 var_DelCallback( p_filter, ppsz_filter_callbacks[i],
909 BarGraphCallback, p_sys );
911 var_DelCallback(p_filter->p_libvlc, "audiobargraph_v-i_values",
912 BarGraphCallback, p_sys);
913 var_DelCallback(p_filter->p_libvlc, "audiobargraph_v-alarm",
914 BarGraphCallback, p_sys);
915 var_Destroy(p_filter->p_libvlc, "audiobargraph_v-i_values");
916 var_Destroy(p_filter->p_libvlc, "audiobargraph_v-alarm");
919 filter_DeleteBlend( p_sys->p_blend );
921 vlc_mutex_destroy( &p_sys->lock );
923 if( p_sys->p_BarGraph.p_pic )
924 picture_Release( p_sys->p_BarGraph.p_pic );
926 free( p_sys->p_BarGraph.i_values );