Some news about our project with ClemChen.Okay, I indeed did that. The problem is, as I thought, that this gives the audio volume, but what I need is the audio level, as in the visualization modules. For this, I think I need to access the audio buffers...
Code: Select all
start vlc.exe -I rc --video-x 0 --video-y 0 --width 400 --height 300 --rc-host localhost:1201 --audio-filter AudioBarGraph_A
--AudioBarGraph_A-port 1201 --program=1537 --audio-track-id=132 --sub-filter AudioBarGraph_V udp://@224.0.0.1:1001
Code: Select all
Audio Bar Graph Video sub filter
--AudioBarGraph_V-i_values=<Chaîne>
Value of the audio channels levels
Value of the audio level of each channels between 0 and 1Each level
should be separated with ':'.
--AudioBarGraph_V-x=<Entier>
Position X
Position X du logo. Vous pouvez le déplacer en faisant un clic droit
dessus.
--AudioBarGraph_V-y=<Entier>
Position Y
Position Y du logo. Vous pouvez le déplacer en faisant un clic droit
dessus.
--AudioBarGraph_V-transparency=<Entier [0 .. 255]>
Transparence du logo
Transparence du logo (255 = opaque, 0 = transparent).
--AudioBarGraph_V-position={0 (Centré), 1 (Gauche), 2 (Droite), 4 (Haut), 8 (Bas), 5 (Haut-Gauche), 6 (Haut-Droite), 9 (Bas-Gauche), 10 (Bas-Droite)}
Position du logo
Forcer l’alignement du logo dans sa fenêtre. Par défaut (0) :
elle sera centrée (0=centré, 1=gauche, 2=droite, 4=haut, 8=bas,
vous pouvez également spécifier une combinaison des ces valeurs,
par exemple 6 = haut-droit).
--AudioBarGraph_V-alarm=<Entier>
Alarm
Signals a silence and displays and alert (0=no alarm, 1=alarm).
--AudioBarGraph_V-barWidth=<Entier>
Bar width in pixel (default : 10)
Width in pixel of each bar in the BarGraph to be displayed (default :
10).
Audio part of the BarGraph function
--AudioBarGraph_A-address=<Chaîne>
TCP address to use (default localhost)
TCP address to use to communicate with the video part of the Bar
Graph (default localhost).In the case of bargraph incrustation, use
localhost.
--AudioBarGraph_A-port=<Entier>
TCP port to use (default 12345)
TCP port to use to communicate with the video part of the Bar Graph
(default 12345).Use the same port as the one used in the rc interface.
--AudioBarGraph_A-barGraph=<Entier>
Defines if BarGraph information should be
send (default 1)
Defines if BarGraph information should be send. 1 if the information
should be sent, 0 otherwise (default 1).
--AudioBarGraph_A-barGraphRepetition=<Entier>
Sends the barGraph information every n audio
packets (default 4)
Defines how often the barGraph information should be sent. Sends the
barGraph information every n audio packets (default 4).
--AudioBarGraph_A-silence=<Entier>
Defines if silence alarm information should
be send (default 1)
Defines if silence alarm information should be send. 1 if the
information should be sent, 0 otherwise (default 1).
--AudioBarGraph_A-timeWindow=<Entier>
Time window to use in ms (default 5000)
Time Window during when the audio level is measured in ms for silence
detection. If the audio level is under the threshold during this
time, an alarm is sent (default 5000).
--AudioBarGraph_A-alarmThreshold=<Flottant>
Minimum Audio level to raise the alarm
(default 0.1)
Threshold to be attained to raise an alarm. If the audio level is
under the threshold during this time, an alarm is sent (default 0.1).
--AudioBarGraph_A-repetitionTime=<Entier>
Time between two alamr messages in ms
(default 2000)
Time between two alarm messages in ms. This value is used to avoid
alarm saturation (default 2000).
Thx ;o)Amazing!
Code: Select all
# Reset VLM configuration
del all
new HISP60 broadcast enabled
setup HISP60 input "udp://@224.168.223.105:2105"
setup HISP60 option programs=5,15,98,250,490,491,812,6001,29
setup HISP60 output #duplicate{dst=mosaic-bridge{id=1,height=96,width=120},select="program=5",dst=bridge-out{id=10},select=audio,dst=mosaic-bridge{id=2,height=96,width=120},select="program=15",dst=bridge-out{id=20},select=audio,dst=mosaic-bridge{id=3,height=96,width=120},select="program=250",dst=bridge-out{id=30},select=audio,dst=mosaic-bridge{id=4,height=96,width=120},select="program=6001",dst=bridge-out{id=40},select=audio,dst=mosaic-bridge{id=5,height=96,width=120},select="program=98",dst=bridge-out{id=50},select=audio,dst=mosaic-bridge{id=6,height=96,width=120},select="program=490",dst=bridge-out{id=60},select=audio,dst=mosaic-bridge{id=7,height=96,width=120},select="program=491",dst=bridge-out{id=70},select=audio,dst=mosaic-bridge{id=8,height=96,width=120},select="program=812",dst=bridge-out{id=80},select=audio,dst=mosaic-bridge{id=9,height=96,width=120},select="program=29",dst=bridge-out{id=90},select=audio}
#Background options
new bg broadcast enabled
setup bg input "fake://" option "fake-file=C:\Documents and Settings\admin\Escritorio\mosaic\mosaic.png" option "fake-width=360" option "fake-height=288" option "fake-aspect-ratio=4:3"
setup bg option sub-filter=mosaic
setup bg output #transcode{vcodec=mp2v,vb=4096,scale=1,fps=25,acodec=mp3,ab=48,channels=2,sfilter=mosaic}:transcode{vcodec=mp2v,vb=4096,scale=1,fps=25,acodec=mp3,ab=48,channels=2,sfilter='marq{marquee=ViT TV,x=40,y=83,size=12}:marq{marquee=CNC,x=165,y=83,size=12}:marq{marquee=VNEWS,x=280,y=83,size=12}:marq{marquee=AlJAZEERA,x=25,y=182,size=12}:marq{marquee=TV5,x=168,y=182,size=12}:marq{marquee=TBNe,x=285,y=182,size=12}:marq{marquee=CUBAVISION,x=22,y=280,size=12}:marq{marquee=DAYSTAR,x=155,y=280,size=12}:marq{marquee=Otro,x=290,y=280,size=12'}:bridge-in{offset=100,chroma=I420}:duplicate{dst=std{access=udp{ttl=128},mux=ts,dst=224.168.223.240:2240}}
# Mosaic options
setup bg option mosaic-alpha=255
setup bg option mosaic-chroma=I420
setup bg option mosaic-height=288
setup bg option mosaic-width=360
setup bg option mosaic-align=5
setup bg option mosaic-xoffset=0
setup bg option mosaic-yoffset=0
setup bg option mosaic-vborder=0
setup bg option mosaic-hborder=0
setup bg option mosaic-position=1
setup bg option mosaic-rows=3
setup bg option mosaic-cols=3
setup bg option mosaic-order=1,2,3,4,5,6,7,8,9
setup bg option mosaic-keep-aspect-ratio="4:3"
setup bg option mosaic-keep-picture
control bg play
control HISP60 play
Code: Select all
diff -ruN vlc-1.0.2/configure.ac vlc-1.0.2_audiobargraph/configure.ac
--- vlc-1.0.2/configure.ac 2009-09-19 21:30:22.000000000 +0200
+++ vlc-1.0.2_audiobargraph/configure.ac 2009-10-19 12:17:13.906250000 +0200
@@ -1246,6 +1246,8 @@
VLC_ADD_PLUGIN([colorthres])
VLC_ADD_PLUGIN([scene])
VLC_ADD_PLUGIN([yuv])
+VLC_ADD_PLUGIN([audiobargraph_v])
+VLC_ADD_PLUGIN([audiobargraph_a])
ALIASES="${ALIASES} cvlc"
diff -ruN vlc-1.0.2/modules/audio_filter/Modules.am vlc-1.0.2_audiobargraph/modules/audio_filter/Modules.am
--- vlc-1.0.2/modules/audio_filter/Modules.am 2009-09-18 18:37:46.000000000 +0200
+++ vlc-1.0.2_audiobargraph/modules/audio_filter/Modules.am 2009-10-20 11:59:01.375000000 +0200
@@ -4,3 +4,4 @@
SOURCES_audio_format = format.c
SOURCES_param_eq = param_eq.c
SOURCES_scaletempo = scaletempo.c
+SOURCES_audiobargraph_a = audiobargraph_a.c
diff -ruN vlc-1.0.2/modules/audio_filter/audiobargraph_a.c vlc-1.0.2_audiobargraph/modules/audio_filter/audiobargraph_a.c
--- vlc-1.0.2/modules/audio_filter/audiobargraph_a.c 1970-01-01 01:00:00.000000000 +0100
+++ vlc-1.0.2_audiobargraph/modules/audio_filter/audiobargraph_a.c 2009-10-20 10:26:37.171875000 +0200
@@ -0,0 +1,337 @@
+/*****************************************************************************
+ * audiobargraph_a.c : audiobargraph audio plugin for vlc
+ *****************************************************************************
+ * Copyright (C) 2002-2006 the VideoLAN team
+ * $Id$
+ *
+ * Authors: Clement CHESNIN <clement.chesnin@gmail.com>
+ * Philippe COENT <philippe.coent@tdf.fr>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
+ *****************************************************************************/
+
+/*****************************************************************************
+ * Preamble
+ *****************************************************************************/
+#ifdef HAVE_CONFIG_H
+# include "config.h"
+#endif
+
+#include <vlc_common.h>
+#include <vlc_plugin.h>
+#include <vlc_vout.h>
+#include <vlc_aout.h>
+#include <vlc_network.h>
+#include <math.h>
+
+
+
+#define ADDRESS_TEXT N_("TCP address to use (default localhost)")
+#define ADDRESS_LONGTEXT N_("TCP address to use to communicate with the video "\
+ "part of the Bar Graph (default localhost)." \
+ "In the case of bargraph incrustation, use localhost." )
+#define PORT_TEXT N_("TCP port to use (default 12345)")
+#define PORT_LONGTEXT N_("TCP port to use to communicate with the video "\
+ "part of the Bar Graph (default 12345)." \
+ "Use the same port as the one used in the rc interface." )
+#define BARGRAPH_TEXT N_("Defines if BarGraph information should be send (default 1)")
+#define BARGRAPH_LONGTEXT N_("Defines if BarGraph information should be send. "\
+ "1 if the information should be sent, 0 otherwise (default 1)." )
+#define BARGRAPHREPETITION_TEXT N_("Sends the barGraph information every n audio packets (default 4)")
+#define BARGRAPHREPETITION_LONGTEXT N_("Defines how often the barGraph information should be sent. "\
+ "Sends the barGraph information every n audio packets (default 4)." )
+#define SILENCE_TEXT N_("Defines if silence alarm information should be send (default 1)")
+#define SILENCE_LONGTEXT N_("Defines if silence alarm information should be send. "\
+ "1 if the information should be sent, 0 otherwise (default 1)." )
+#define TIMEWINDOW_TEXT N_("Time window to use in ms (default 5000)")
+#define TIMEWINDOW_LONGTEXT N_("Time Window during when the audio level is measured in ms for silence detection. "\
+ "If the audio level is under the threshold during this time, "\
+ "an alarm is sent (default 5000)." )
+#define ALARMTHRESHOLD_TEXT N_("Minimum Audio level to raise the alarm (default 0.1)")
+#define ALARMTHRESHOLD_LONGTEXT N_("Threshold to be attained to raise an alarm. "\
+ "If the audio level is under the threshold during this time, "\
+ "an alarm is sent (default 0.1)." )
+#define REPETITIONTIME_TEXT N_("Time between two alamr messages in ms (default 2000)" )
+#define REPETITIONTIME_LONGTEXT N_("Time between two alarm messages in ms. "\
+ "This value is used to avoid alarm saturation (default 2000)." )
+
+#define CFG_PREFIX "audiobargraph_a-"
+
+/*****************************************************************************
+ * Module descriptor
+ *****************************************************************************/
+
+static int Open ( vlc_object_t * );
+static void Close ( vlc_object_t * );
+
+vlc_module_begin ()
+ set_description( N_("Audio part of the BarGraph function") )
+ set_category( CAT_AUDIO )
+ set_subcategory( SUBCAT_AUDIO_AFILTER )
+ set_capability( "audio filter", 0 )
+ set_callbacks( Open, Close )
+
+ add_string( CFG_PREFIX "address", "localhost", NULL, ADDRESS_TEXT, ADDRESS_LONGTEXT, false )
+ add_integer( CFG_PREFIX "port", 12345, NULL, PORT_TEXT, PORT_LONGTEXT, false )
+ add_integer( CFG_PREFIX "barGraph", 1, NULL, BARGRAPH_TEXT, BARGRAPH_LONGTEXT, false )
+ add_integer( CFG_PREFIX "barGraphRepetition", 4, NULL, BARGRAPHREPETITION_TEXT, BARGRAPHREPETITION_LONGTEXT, false )
+ add_integer( CFG_PREFIX "silence", 0, NULL, SILENCE_TEXT, SILENCE_LONGTEXT, false )
+ add_integer( CFG_PREFIX "timeWindow", 5000, NULL, TIMEWINDOW_TEXT, TIMEWINDOW_LONGTEXT, false )
+ add_float( CFG_PREFIX "alarmThreshold", 0.1, NULL, ALARMTHRESHOLD_TEXT, ALARMTHRESHOLD_LONGTEXT, false )
+ add_integer( CFG_PREFIX "repetitionTime", 2000, NULL, REPETITIONTIME_TEXT, REPETITIONTIME_LONGTEXT, false )
+vlc_module_end ()
+
+static const char *const ppsz_filter_options[] = {
+ "barGraph", "barGraphRepetition", "silence", "address", "port", "timeWindow", "alarmThreshold", "repetitionTime", NULL
+};
+
+/*****************************************************************************
+ * Local prototypes
+ *****************************************************************************/
+static void DoWork( aout_instance_t *, aout_filter_t *,
+ aout_buffer_t *, aout_buffer_t * );
+
+typedef struct ValueDate_t {
+ float value;
+ mtime_t date;
+ struct ValueDate_t* next;
+} ValueDate_t;
+
+struct aout_filter_sys_t
+{
+ char* address;
+ int port;
+ int barGraph;
+ int barGraphRepetition;
+ int silence;
+ int timeWindow;
+ float alarmThreshold;
+ int repetitionTime;
+ int TCPconnection;
+ int counter;
+ int nbChannels;
+ ValueDate_t* first;
+ ValueDate_t* last;
+ int started;
+ mtime_t lastAlarm;
+};
+
+/*****************************************************************************
+ * Open: open the visualizer
+ *****************************************************************************/
+static int Open( vlc_object_t *p_this )
+{
+ aout_filter_t *p_filter = (aout_filter_t *)p_this;
+ aout_filter_sys_t *p_sys;
+
+ if( ( p_filter->input.i_format != VLC_FOURCC('f','l','3','2') &&
+ p_filter->input.i_format != VLC_FOURCC('f','i','3','2') ) )
+ {
+ return VLC_EGENERIC;
+ }
+
+ p_sys = p_filter->p_sys = malloc( sizeof( aout_filter_sys_t ) );
+ if( p_sys == NULL )
+ return VLC_EGENERIC;
+
+ p_sys->barGraph = var_CreateGetIntegerCommand( p_filter, "audiobargraph_a-barGraph" );
+ p_sys->barGraphRepetition = var_CreateGetIntegerCommand( p_filter, "audiobargraph_a-barGraphRepetition" );
+ p_sys->silence = var_CreateGetIntegerCommand( p_filter, "audiobargraph_a-silence" );
+ p_sys->address = var_CreateGetStringCommand( p_filter, "audiobargraph_a-address" );
+ p_sys->port = var_CreateGetIntegerCommand( p_filter, "audiobargraph_a-port" );
+ p_sys->timeWindow = var_CreateGetIntegerCommand( p_filter, "audiobargraph_a-timeWindow" );
+ p_sys->alarmThreshold = var_CreateGetFloatCommand( p_filter, "audiobargraph_a-alarmThreshold" );
+ p_sys->repetitionTime = var_CreateGetIntegerCommand( p_filter, "audiobargraph_a-repetitionTime" );
+ p_sys->TCPconnection = net_ConnectTCP(p_this,p_sys->address,p_sys->port);
+ p_sys->counter = 0;
+ p_sys->nbChannels = 0;
+ p_sys->first = NULL;
+ p_sys->last = NULL;
+ p_sys->started = 0;
+ p_sys->lastAlarm = 0;
+
+ p_filter->pf_do_work = DoWork;
+ p_filter->b_in_place= 1;
+
+ return VLC_SUCCESS;
+}
+
+/*****************************************************************************
+ * DoWork: convert a buffer
+ *****************************************************************************
+ * Audio part pasted from trivial.c
+ ****************************************************************************/
+static void DoWork( aout_instance_t *p_aout, aout_filter_t *p_filter,
+ aout_buffer_t *p_in_buf, aout_buffer_t *p_out_buf )
+{
+ VLC_UNUSED(p_aout);
+ aout_filter_sys_t *p_sys = p_filter->p_sys;
+ int i, j;
+ float *p_sample = (float *)p_out_buf->p_buffer;
+ float *i_value = NULL;
+ //int* value = NULL;
+ float ch;
+ float max = 0.0;
+ char *message = (char*)malloc(255*sizeof(char));
+ int nbChannels = 0;
+ ValueDate_t* new = NULL;
+ ValueDate_t* current = NULL;
+ float sum;
+ int count = 0;
+ int i_ret;
+
+ p_out_buf->i_nb_samples = p_in_buf->i_nb_samples;
+ p_out_buf->i_nb_bytes = p_in_buf->i_nb_bytes *
+ aout_FormatNbChannels( &p_filter->output ) /
+ aout_FormatNbChannels( &p_filter->input );
+
+ nbChannels = aout_FormatNbChannels( &p_filter->output );
+ if (p_sys->nbChannels != nbChannels) {
+ /*free(p_sys->value);
+ p_sys->value = (int*)malloc(nbChannels * sizeof(int));
+ for (i=0; i<nbChannels; i++) {
+ p_sys->value[i] = 0;
+ }*/
+ p_sys->nbChannels = nbChannels;
+ }
+
+ i_value = (float*)malloc(nbChannels * sizeof(float));
+
+ for (i=0; i<nbChannels; i++) {
+ i_value[i] = 0;
+ }
+
+ /* 1 - Compute the peack values */
+ for ( i = 0 ; i < p_in_buf->i_nb_samples; i++ )
+ {
+ for (j=0; j<nbChannels; j++) {
+ ch = (*p_sample++);
+ if (ch > i_value[j])
+ i_value[j] = ch;
+ if (ch > max)
+ max = ch;
+ }
+ }
+ max = pow( max, 2 );
+
+ if (p_sys->silence) {
+ /* 2 - store the new value */
+ new = (ValueDate_t*)malloc(sizeof(ValueDate_t));
+ new->value = max;
+ new->date = p_in_buf->start_date;
+ new->next = NULL;
+ if (p_sys->last != NULL) {
+ p_sys->last->next = new;
+ }
+ p_sys->last = new;
+ if (p_sys->first == NULL) {
+ p_sys->first = new;
+ }
+
+ /* 3 - delete too old values */
+ while (p_sys->first->date < (new->date - (p_sys->timeWindow*1000))) {
+ p_sys->started = 1; // we have enough values to compute a valid total
+ current = p_sys->first;
+ p_sys->first = p_sys->first->next;
+ free(current);
+ }
+
+ /* If last message was sent enough time ago */
+ if ((p_sys->started) && (p_in_buf->start_date > p_sys->lastAlarm + (p_sys->repetitionTime*1000))) {
+
+ /* 4 - compute the RMS */
+ current = p_sys->first;
+ sum = 0.0;
+ while (current != NULL) {
+ sum += current->value;
+ count ++;
+ current = current->next;
+ }
+ sum = sum / count;
+ sum = sqrt(sum);
+
+ /* 5 - compare it to the threshold */
+ sprintf(message,"@audiobargraph_v audiobargraph_v-alarm ");
+ if (sum < p_sys->alarmThreshold) {
+ sprintf(message,"%s1\n",message);
+ } else {
+ sprintf(message,"%s0\n",message);
+ }
+ //TCPconnection = net_ConnectTCP(p_aout,p_sys->address,p_sys->port);
+ net_Write(p_aout, p_sys->TCPconnection, NULL, message, strlen(message));
+ //net_Close(TCPconnection);
+
+ p_sys->lastAlarm = p_in_buf->start_date;
+ }
+ }
+
+ /*for (i=0; i<nbChannels; i++) {
+ value[i] = abs(i_value[i]*100);
+ if ( value[i] > p_sys->value[i] - 6 )
+ p_sys->value[i] = value[i];
+ else
+ p_sys->value[i] = p_sys->value[i] - 6;
+ }*/
+
+ if (p_sys->barGraph) {
+ /* 6 - sent the message with the values for the BarGraph */
+ if ((nbChannels > 0) && (p_sys->counter%(p_sys->barGraphRepetition) == 0)) {
+ sprintf(message,"@audiobargraph_v audiobargraph_v-i_values ");
+ for (i=0; i<(nbChannels-1); i++) {
+ sprintf(message,"%s%f:", message, i_value[i]);
+ }
+ sprintf(message,"%s%f\n", message, i_value[nbChannels-1]);
+
+ //test = send(p_sys->TCPconnection,message,strlen(message),0);
+ //net_Write(p_aout, p_sys->TCPconnection, NULL, message, strlen(message));
+
+ i_ret= net_Write(p_aout, p_sys->TCPconnection, NULL, message, strlen(message));
+
+ }
+ }
+
+ free(i_value);
+ //free(value);
+
+ if (p_sys->counter > p_sys->barGraphRepetition*100) {
+ net_Close(p_sys->TCPconnection);
+ p_sys->TCPconnection = net_ConnectTCP(p_aout,p_sys->address,p_sys->port);
+ p_sys->counter = 0;
+ }
+
+ free(message);
+ p_sys->counter++;
+}
+
+/*****************************************************************************
+ * Close: close the plugin
+ *****************************************************************************/
+static void Close( vlc_object_t *p_this )
+{
+ aout_filter_t * p_filter = (aout_filter_t *)p_this;
+ aout_filter_sys_t *p_sys = p_filter->p_sys;
+ ValueDate_t* current;
+
+ p_sys->last = NULL;
+ while (p_sys->first != NULL) {
+ current = p_sys->first;
+ p_sys->first = p_sys->first->next;
+ free(current);
+ }
+ net_Close(p_sys->TCPconnection);
+ free(p_sys->address);
+ //free(p_sys->value);
+ free( p_filter->p_sys );
+}diff -ruN vlc-1.0.2/modules/video_filter/Modules.am vlc-1.0.2_audiobargraph/modules/video_filter/Modules.am
--- vlc-1.0.2/modules/video_filter/Modules.am 2009-09-18 18:37:46.000000000 +0200
+++ vlc-1.0.2_audiobargraph/modules/video_filter/Modules.am 2009-10-15 17:18:16.125000000 +0200
@@ -45,4 +45,6 @@
SOURCES_swscale_maemo = swscale_maemo.c libswscale_nokia770/arm_jit_swscale.c libswscale_nokia770/arm_colorconv.S libswscale_nokia770/arm_jit_swscale.h libswscale_nokia770/arm_colorconv.h
SOURCES_scene = scene.c
SOURCES_yuvp = yuvp.c
+SOURCES_audiobargraph_v = audiobargraph_v.c
+
noinst_HEADERS = filter_common.h filter_picture.h
diff -ruN vlc-1.0.2/modules/video_filter/audiobargraph_v.c vlc-1.0.2_audiobargraph/modules/video_filter/audiobargraph_v.c
--- vlc-1.0.2/modules/video_filter/audiobargraph_v.c 1970-01-01 01:00:00.000000000 +0100
+++ vlc-1.0.2_audiobargraph/modules/video_filter/audiobargraph_v.c 2009-10-20 10:27:29.796875000 +0200
@@ -0,0 +1,1957 @@
+/*****************************************************************************
+ * audiobargraph_v.c : audiobargraph video plugin for vlc
+ *****************************************************************************
+ * Copyright (C) 2003-2006 the VideoLAN team
+ * $Id: bdc988d3b8f96adbf92ee45cdbf49f56994d5838 $
+ *
+ * Authors: Clement CHESNIN <clement.chesnin@gmail.com>
+ * Philippe COENT <philippe.coent@tdf.fr>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
+ *****************************************************************************/
+
+/*****************************************************************************
+ * Preamble
+ *****************************************************************************/
+
+#ifdef HAVE_CONFIG_H
+# include "config.h"
+#endif
+
+#include <vlc_common.h>
+#include <vlc_plugin.h>
+#include <vlc_vout.h>
+#include <assert.h>
+
+#include "vlc_filter.h"
+#include "filter_common.h"
+#include "vlc_image.h"
+#include "vlc_osd.h"
+#include "vlc_strings.h"
+
+#ifdef LoadImage
+# undef LoadImage
+#endif
+
+/*****************************************************************************
+ * Local prototypes
+ *****************************************************************************/
+static int Create ( vlc_object_t * );
+static void Destroy ( vlc_object_t * );
+
+static int Init ( vout_thread_t * );
+static void End ( vout_thread_t * );
+static void Render ( vout_thread_t *, picture_t * );
+
+static int MouseEvent( vlc_object_t *, char const *,
+ vlc_value_t , vlc_value_t , void * );
+static int Control ( vout_thread_t *, int, va_list );
+
+static int CreateFilter ( vlc_object_t * );
+static void DestroyFilter( vlc_object_t * );
+
+static int BarGraphCallback( vlc_object_t *, char const *,
+ vlc_value_t, vlc_value_t, void * );
+
+/*****************************************************************************
+ * Module descriptor
+ *****************************************************************************/
+
+#define I_VALUES_TEXT N_("Value of the audio channels levels")
+#define I_VALUES_LONGTEXT N_("Value of the audio level of each channels between 0 and 1" \
+ "Each level should be separated with ':'.")
+#define POSX_TEXT N_("X coordinate")
+#define POSX_LONGTEXT N_("X coordinate of the logo. You can move the logo " \
+ "by left-clicking it." )
+#define POSY_TEXT N_("Y coordinate")
+#define POSY_LONGTEXT N_("Y coordinate of the logo. You can move the logo " \
+ "by left-clicking it." )
+#define TRANS_TEXT N_("Transparency of the logo")
+#define TRANS_LONGTEXT N_("Logo transparency value " \
+ "(from 0 for full transparency to 255 for full opacity)." )
+#define POS_TEXT N_("Logo position")
+#define POS_LONGTEXT N_( \
+ "Enforce the logo position on the video " \
+ "(0=center, 1=left, 2=right, 4=top, 8=bottom, you can " \
+ "also use combinations of these values, eg 6 = top-right).")
+#define ALARM_TEXT N_("Alarm")
+#define ALARM_LONGTEXT N_("Signals a silence and displays and alert " \
+ "(0=no alarm, 1=alarm).")
+#define BARWIDTH_TEXT N_("Bar width in pixel (default : 10)")
+#define BARWIDTH_LONGTEXT N_("Width in pixel of each bar in the BarGraph to be displayed " \
+ "(default : 10).")
+
+#define CFG_PREFIX "audiobargraph_v-"
+
+static const int pi_pos_values[] = { 0, 1, 2, 4, 8, 5, 6, 9, 10 };
+static const char *const ppsz_pos_descriptions[] =
+{ N_("Center"), N_("Left"), N_("Right"), N_("Top"), N_("Bottom"),
+ N_("Top-Left"), N_("Top-Right"), N_("Bottom-Left"), N_("Bottom-Right") };
+
+vlc_module_begin ()
+ set_capability( "sub filter", 0 )
+ set_callbacks( CreateFilter, DestroyFilter )
+ set_description( N_("Audio Bar Graph Video sub filter") )
+ set_shortname( N_("Audio Bar Graph Video") )
+ set_category( CAT_VIDEO )
+ set_subcategory( SUBCAT_VIDEO_SUBPIC )
+ add_shortcut( "audiobargraph_v" )
+
+ add_string( CFG_PREFIX "i_values", NULL, NULL, I_VALUES_TEXT, I_VALUES_LONGTEXT, false )
+ add_integer( CFG_PREFIX "x", 0, NULL, POSX_TEXT, POSX_LONGTEXT, true )
+ add_integer( CFG_PREFIX "y", 0, NULL, POSY_TEXT, POSY_LONGTEXT, true )
+ add_integer_with_range( CFG_PREFIX "transparency", 255, 0, 255, NULL,
+ TRANS_TEXT, TRANS_LONGTEXT, false )
+ add_integer( CFG_PREFIX "position", -1, NULL, POS_TEXT, POS_LONGTEXT, false )
+ change_integer_list( pi_pos_values, ppsz_pos_descriptions, NULL )
+ add_integer( CFG_PREFIX "alarm", 0, NULL, ALARM_TEXT, ALARM_LONGTEXT, true )
+ add_integer( CFG_PREFIX "barWidth", 10, NULL, BARWIDTH_TEXT, BARWIDTH_LONGTEXT, true )
+
+ /* video output filter submodule */
+ add_submodule ()
+ set_capability( "video filter", 0 )
+ set_callbacks( Create, Destroy )
+ set_description( N_("Audio Bar Graph Video sub filter") )
+ add_shortcut( "audiobargraph_v" )
+vlc_module_end ()
+
+static const char *const ppsz_filter_options[] = {
+ "i_values", "transparency", "position", "alarm", "barWidth", NULL
+};
+
+/*****************************************************************************
+ * Structure to hold the Bar Graph properties
+ ****************************************************************************/
+typedef struct
+{
+ int i_alpha; /* -1 means use default alpha */
+ int nbChannels;
+ int *i_values;
+ picture_t *p_pic;
+ mtime_t date;
+ int scale;
+ int alarm;
+ int barWidth;
+
+ vlc_mutex_t lock;
+
+} BarGraph_t;
++/*****************************************************************************
+ * LoadImage: creates and returns the bar graph image
+ *****************************************************************************/
+static picture_t *LoadImage( vlc_object_t *p_this, int nbChannels, int* i_values, int scale, int alarm, int barWidth)
+{
+ VLC_UNUSED(p_this);
+ picture_t *p_pic;
+ int i,j;
+ int i_width = 0;
+ int i_line;
+ int moinsTrois, moinsCinq, moinsSept, moinsDix, moinsVingt;
+
+ if (nbChannels == 0) {
+ i_width = 20;
+ } else {
+ i_width = 2 * nbChannels * barWidth + 10;
+ }
+
+ moinsTrois = 0.71*scale + 20;
+ moinsCinq = 0.56*scale + 20;
+ moinsSept = 0.45*scale + 20;
+ moinsDix = 0.32*scale + 20;
+ moinsVingt = 0.1*scale + 20;
+
+ p_pic = picture_New(VLC_FOURCC('Y','U','V','A'), i_width+20, scale+30, VOUT_ASPECT_FACTOR * (i_width+20)/(scale+30));
+
+ // blacken the whole picture
+ for( i = 0 ; i < p_pic->i_planes ; i++ )
+ {
+ memset( p_pic->p[i].p_pixels, 0x00,
+ p_pic->p[i].i_visible_lines * p_pic->p[i].i_pitch );
+ }
+
+ // side bar
+ for ( i_line = 20; i_line < scale+20; i_line++ ) {
+ // black
+ *(p_pic->p[0].p_pixels +
+ (scale + 30 - i_line - 1) *
+ p_pic->p[0].i_pitch + 20) = 0;
+ *(p_pic->p[1].p_pixels +
+ (scale + 30 - i_line - 1) *
+ p_pic->p[1].i_pitch + 20) = 128;
+ *(p_pic->p[2].p_pixels +
+ (scale + 30 - i_line - 1) *
+ p_pic->p[2].i_pitch + 20) = 128;
+ *(p_pic->p[3].p_pixels +
+ (scale + 30 - i_line - 1) *
+ p_pic->p[3].i_pitch + 20) = 0xFF;
+ // black
+ *(p_pic->p[0].p_pixels +
+ (scale + 30 - i_line - 1) *
+ p_pic->p[0].i_pitch + 1 + 20) = 0;
+ *(p_pic->p[1].p_pixels +
+ (scale + 30 - i_line - 1) *
+ p_pic->p[1].i_pitch + 1 + 20) = 128;
+ *(p_pic->p[2].p_pixels +
+ (scale + 30 - i_line - 1) *
+ p_pic->p[2].i_pitch + 1 + 20) = 128;
+ *(p_pic->p[3].p_pixels +
+ (scale + 30 - i_line - 1) *
+ p_pic->p[3].i_pitch + 1 + 20) = 0xFF;
+ // white
+ *(p_pic->p[0].p_pixels +
+ (scale + 30 - i_line - 1) *
+ p_pic->p[0].i_pitch + 2 + 20) = 255;
+ *(p_pic->p[1].p_pixels +
+ (scale + 30 - i_line - 1) *
+ p_pic->p[1].i_pitch + 2 + 20) = 128;
+ *(p_pic->p[2].p_pixels +
+ (scale + 30 - i_line - 1) *
+ p_pic->p[2].i_pitch + 2 + 20) = 128;
+ *(p_pic->p[3].p_pixels +
+ (scale + 30 - i_line - 1) *
+ p_pic->p[3].i_pitch + 2 + 20) = 0xFF;
+ // white
+ *(p_pic->p[0].p_pixels +
+ (scale + 30 - i_line - 1) *
+ p_pic->p[0].i_pitch + 3 + 20) = 255;
+ *(p_pic->p[1].p_pixels +
+ (scale + 30 - i_line - 1) *
+ p_pic->p[1].i_pitch + 3 + 20) = 128;
+ *(p_pic->p[2].p_pixels +
+ (scale + 30 - i_line - 1) *
+ p_pic->p[2].i_pitch + 3 + 20) = 128;
+ *(p_pic->p[3].p_pixels +
+ (scale + 30 - i_line - 1) *
+ p_pic->p[3].i_pitch + 3 + 20) = 0xFF;
+
+
+ // -3dB
+ if (i_line == moinsTrois - 2) {
+ // 3
+ for (i=16; i<19; i++) {
+ *(p_pic->p[0].p_pixels +
+ (scale + 30 - i_line - 1) *
+ p_pic->p[0].i_pitch + i ) = 0x00;
+ *(p_pic->p[1].p_pixels +
+ (scale + 30 - i_line - 1) *
+ p_pic->p[1].i_pitch + i ) = 128;
+ *(p_pic->p[2].p_pixels +
+ (scale + 30 - i_line - 1) *
+ p_pic->p[2].i_pitch + i ) = 128;
+ *(p_pic->p[3].p_pixels +
+ (scale + 30 - i_line - 1) *
+ p_pic->p[3].i_pitch + i ) = 0xFF;
+ }
+ }
+ if (i_line == moinsTrois - 1) {
+ // 3
+ for (i=18; i<19; i++) {
+ *(p_pic->p[0].p_pixels +
+ (scale + 30 - i_line - 1) *
+ p_pic->p[0].i_pitch + i ) = 0x00;
+ *(p_pic->p[1].p_pixels +
+ (scale + 30 - i_line - 1) *
+ p_pic->p[1].i_pitch + i ) = 128;
+ *(p_pic->p[2].p_pixels +
+ (scale + 30 - i_line - 1) *
+ p_pic->p[2].i_pitch + i ) = 128;
+ *(p_pic->p[3].p_pixels +
+ (scale + 30 - i_line - 1) *
+ p_pic->p[3].i_pitch + i ) = 0xFF;
+ }
+ // limit
+ for (i=24; i<27; i++) {
+ *(p_pic->p[0].p_pixels +
+ (scale + 30 - i_line - 1) *
+ p_pic->p[0].i_pitch + i ) = 255;
+ *(p_pic->p[1].p_pixels +
+ (scale + 30 - i_line - 1) *
+ p_pic->p[1].i_pitch + i ) = 128;
+ *(p_pic->p[2].p_pixels +
+ (scale + 30 - i_line - 1) *
+ p_pic->p[2].i_pitch + i ) = 128;
+ *(p_pic->p[3].p_pixels +
+ (scale + 30 - i_line - 1) *
+ p_pic->p[3].i_pitch + i ) = 0xFF;
+ }
+ }
+ if (i_line == moinsTrois) {
+ // 3
+ for (i=16; i<19; i++) {
+ *(p_pic->p[0].p_pixels +
+ (scale + 30 - i_line - 1) *
+ p_pic->p[0].i_pitch + i ) = 0x00;
+ *(p_pic->p[1].p_pixels +
+ (scale + 30 - i_line - 1) *
+ p_pic->p[1].i_pitch + i ) = 128;
+ *(p_pic->p[2].p_pixels +
+ (scale + 30 - i_line - 1) *
+ p_pic->p[2].i_pitch + i ) = 128;
+ *(p_pic->p[3].p_pixels +
+ (scale + 30 - i_line - 1) *
+ p_pic->p[3].i_pitch + i ) = 0xFF;
+ }
+ // limit
+ for (i=24; i<27; i++) {
+ *(p_pic->p[0].p_pixels +
+ (scale + 30 - i_line - 1) *
+ p_pic->p[0].i_pitch + i ) = 0x00;
+ *(p_pic->p[1].p_pixels +
+ (scale + 30 - i_line - 1) *
+ p_pic->p[1].i_pitch + i ) = 128;
+ *(p_pic->p[2].p_pixels +
+ (scale + 30 - i_line - 1) *
+ p_pic->p[2].i_pitch + i ) = 128;
+ *(p_pic->p[3].p_pixels +
+ (scale + 30 - i_line - 1) *
+ p_pic->p[3].i_pitch + i ) = 0xFF;
+ }
+ }
+ if (i_line == moinsTrois + 1) {
+ // 3
+ for (i=18; i<19; i++) {
+ *(p_pic->p[0].p_pixels +
+ (scale + 30 - i_line - 1) *
+ p_pic->p[0].i_pitch + i ) = 0x00;
+ *(p_pic->p[1].p_pixels +
+ (scale + 30 - i_line - 1) *
+ p_pic->p[1].i_pitch + i ) = 128;
+ *(p_pic->p[2].p_pixels +
+ (scale + 30 - i_line - 1) *
+ p_pic->p[2].i_pitch + i ) = 128;
+ *(p_pic->p[3].p_pixels +
+ (scale + 30 - i_line - 1) *
+ p_pic->p[3].i_pitch + i ) = 0xFF;
+ }
+ // limit
+ for (i=24; i<27; i++) {
+ *(p_pic->p[0].p_pixels +
+ (scale + 30 - i_line - 1) *
+ p_pic->p[0].i_pitch + i ) = 0x00;
+ *(p_pic->p[1].p_pixels +
+ (scale + 30 - i_line - 1) *
+ p_pic->p[1].i_pitch + i ) = 128;
+ *(p_pic->p[2].p_pixels +
+ (scale + 30 - i_line - 1) *
+ p_pic->p[2].i_pitch + i ) = 128;
+ *(p_pic->p[3].p_pixels +
+ (scale + 30 - i_line - 1) *
+ p_pic->p[3].i_pitch + i ) = 0xFF;
+ }
+ }
+ if (i_line == moinsTrois + 2) {
+ // 3
+ for (i=16; i<19; i++) {
+ *(p_pic->p[0].p_pixels +
+ (scale + 30 - i_line - 1) *
+ p_pic->p[0].i_pitch + i ) = 0x00;
+ *(p_pic->p[1].p_pixels +
+ (scale + 30 - i_line - 1) *
+ p_pic->p[1].i_pitch + i ) = 128;
+ *(p_pic->p[2].p_pixels +
+ (scale + 30 - i_line - 1) *
+ p_pic->p[2].i_pitch + i ) = 128;
+ *(p_pic->p[3].p_pixels +
+ (scale + 30 - i_line - 1) *
+ p_pic->p[3].i_pitch + i ) = 0xFF;
+ }
+ }
+
Code: Select all
+ // -5dB
+ if (i_line == moinsCinq - 2) {
+ // 5
+ for (i=16; i<19; i++) {
+ *(p_pic->p[0].p_pixels +
+ (scale + 30 - i_line - 1) *
+ p_pic->p[0].i_pitch + i ) = 0x00;
+ *(p_pic->p[1].p_pixels +
+ (scale + 30 - i_line - 1) *
+ p_pic->p[1].i_pitch + i ) = 128;
+ *(p_pic->p[2].p_pixels +
+ (scale + 30 - i_line - 1) *
+ p_pic->p[2].i_pitch + i ) = 128;
+ *(p_pic->p[3].p_pixels +
+ (scale + 30 - i_line - 1) *
+ p_pic->p[3].i_pitch + i ) = 0xFF;
+ }
+ }
+ if (i_line == moinsCinq - 1) {
+ // 5
+ for (i=18; i<19; i++) {
+ *(p_pic->p[0].p_pixels +
+ (scale + 30 - i_line - 1) *
+ p_pic->p[0].i_pitch + i ) = 0x00;
+ *(p_pic->p[1].p_pixels +
+ (scale + 30 - i_line - 1) *
+ p_pic->p[1].i_pitch + i ) = 128;
+ *(p_pic->p[2].p_pixels +
+ (scale + 30 - i_line - 1) *
+ p_pic->p[2].i_pitch + i ) = 128;
+ *(p_pic->p[3].p_pixels +
+ (scale + 30 - i_line - 1) *
+ p_pic->p[3].i_pitch + i ) = 0xFF;
+ }
+ // limit
+ for (i=24; i<27; i++) {
+ *(p_pic->p[0].p_pixels +
+ (scale + 30 - i_line - 1) *
+ p_pic->p[0].i_pitch + i ) = 255;
+ *(p_pic->p[1].p_pixels +
+ (scale + 30 - i_line - 1) *
+ p_pic->p[1].i_pitch + i ) = 128;
+ *(p_pic->p[2].p_pixels +
+ (scale + 30 - i_line - 1) *
+ p_pic->p[2].i_pitch + i ) = 128;
+ *(p_pic->p[3].p_pixels +
+ (scale + 30 - i_line - 1) *
+ p_pic->p[3].i_pitch + i ) = 0xFF;
+ }
+ }
+ if (i_line == moinsCinq) {
+ // 5
+ for (i=16; i<19; i++) {
+ *(p_pic->p[0].p_pixels +
+ (scale + 30 - i_line - 1) *
+ p_pic->p[0].i_pitch + i ) = 0x00;
+ *(p_pic->p[1].p_pixels +
+ (scale + 30 - i_line - 1) *
+ p_pic->p[1].i_pitch + i ) = 128;
+ *(p_pic->p[2].p_pixels +
+ (scale + 30 - i_line - 1) *
+ p_pic->p[2].i_pitch + i ) = 128;
+ *(p_pic->p[3].p_pixels +
+ (scale + 30 - i_line - 1) *
+ p_pic->p[3].i_pitch + i ) = 0xFF;
+ }
+ // limit
+ for (i=24; i<27; i++) {
+ *(p_pic->p[0].p_pixels +
+ (scale + 30 - i_line - 1) *
+ p_pic->p[0].i_pitch + i ) = 0x00;
+ *(p_pic->p[1].p_pixels +
+ (scale + 30 - i_line - 1) *
+ p_pic->p[1].i_pitch + i ) = 128;
+ *(p_pic->p[2].p_pixels +
+ (scale + 30 - i_line - 1) *
+ p_pic->p[2].i_pitch + i ) = 128;
+ *(p_pic->p[3].p_pixels +
+ (scale + 30 - i_line - 1) *
+ p_pic->p[3].i_pitch + i ) = 0xFF;
+ }
+ }
+ if (i_line == moinsCinq + 1) {
+ // 5
+ for (i=16; i<17; i++) {
+ *(p_pic->p[0].p_pixels +
+ (scale + 30 - i_line - 1) *
+ p_pic->p[0].i_pitch + i ) = 0x00;
+ *(p_pic->p[1].p_pixels +
+ (scale + 30 - i_line - 1) *
+ p_pic->p[1].i_pitch + i ) = 128;
+ *(p_pic->p[2].p_pixels +
+ (scale + 30 - i_line - 1) *
+ p_pic->p[2].i_pitch + i ) = 128;
+ *(p_pic->p[3].p_pixels +
+ (scale + 30 - i_line - 1) *
+ p_pic->p[3].i_pitch + i ) = 0xFF;
+ }
+ // limit
+ for (i=24; i<27; i++) {
+ *(p_pic->p[0].p_pixels +
+ (scale + 30 - i_line - 1) *
+ p_pic->p[0].i_pitch + i ) = 0x00;
+ *(p_pic->p[1].p_pixels +
+ (scale + 30 - i_line - 1) *
+ p_pic->p[1].i_pitch + i ) = 128;
+ *(p_pic->p[2].p_pixels +
+ (scale + 30 - i_line - 1) *
+ p_pic->p[2].i_pitch + i ) = 128;
+ *(p_pic->p[3].p_pixels +
+ (scale + 30 - i_line - 1) *
+ p_pic->p[3].i_pitch + i ) = 0xFF;
+ }
+ }
+ if (i_line == moinsCinq + 2) {
+ // 5
+ for (i=16; i<19; i++) {
+ *(p_pic->p[0].p_pixels +
+ (scale + 30 - i_line - 1) *
+ p_pic->p[0].i_pitch + i ) = 0x00;
+ *(p_pic->p[1].p_pixels +
+ (scale + 30 - i_line - 1) *
+ p_pic->p[1].i_pitch + i ) = 128;
+ *(p_pic->p[2].p_pixels +
+ (scale + 30 - i_line - 1) *
+ p_pic->p[2].i_pitch + i ) = 128;
+ *(p_pic->p[3].p_pixels +
+ (scale + 30 - i_line - 1) *
+ p_pic->p[3].i_pitch + i ) = 0xFF;
+ }
+ }
+
+ // -7dB
+ if (i_line == moinsSept - 2) {
+ // 7
+ for (i=18; i<19; i++) {
+ *(p_pic->p[0].p_pixels +
+ (scale + 30 - i_line - 1) *
+ p_pic->p[0].i_pitch + i ) = 0x00;
+ *(p_pic->p[1].p_pixels +
+ (scale + 30 - i_line - 1) *
+ p_pic->p[1].i_pitch + i ) = 128;
+ *(p_pic->p[2].p_pixels +
+ (scale + 30 - i_line - 1) *
+ p_pic->p[2].i_pitch + i ) = 128;
+ *(p_pic->p[3].p_pixels +
+ (scale + 30 - i_line - 1) *
+ p_pic->p[3].i_pitch + i ) = 0xFF;
+ }
+ }
+ if (i_line == moinsSept - 1) {
+ // 7
+ for (i=18; i<19; i++) {
+ *(p_pic->p[0].p_pixels +
+ (scale + 30 - i_line - 1) *
+ p_pic->p[0].i_pitch + i ) = 0x00;
+ *(p_pic->p[1].p_pixels +
+ (scale + 30 - i_line - 1) *
+ p_pic->p[1].i_pitch + i ) = 128;
+ *(p_pic->p[2].p_pixels +
+ (scale + 30 - i_line - 1) *
+ p_pic->p[2].i_pitch + i ) = 128;
+ *(p_pic->p[3].p_pixels +
+ (scale + 30 - i_line - 1) *
+ p_pic->p[3].i_pitch + i ) = 0xFF;
+ }
+ // limit
+ for (i=24; i<27; i++) {
+ *(p_pic->p[0].p_pixels +
+ (scale + 30 - i_line - 1) *
+ p_pic->p[0].i_pitch + i ) = 255;
+ *(p_pic->p[1].p_pixels +
+ (scale + 30 - i_line - 1) *
+ p_pic->p[1].i_pitch + i ) = 128;
+ *(p_pic->p[2].p_pixels +
+ (scale + 30 - i_line - 1) *
+ p_pic->p[2].i_pitch + i ) = 128;
+ *(p_pic->p[3].p_pixels +
+ (scale + 30 - i_line - 1) *
+ p_pic->p[3].i_pitch + i ) = 0xFF;
+ }
+ }
+ if (i_line == moinsSept) {
+ // 7
+ for (i=18; i<19; i++) {
+ *(p_pic->p[0].p_pixels +
+ (scale + 30 - i_line - 1) *
+ p_pic->p[0].i_pitch + i ) = 0x00;
+ *(p_pic->p[1].p_pixels +
+ (scale + 30 - i_line - 1) *
+ p_pic->p[1].i_pitch + i ) = 128;
+ *(p_pic->p[2].p_pixels +
+ (scale + 30 - i_line - 1) *
+ p_pic->p[2].i_pitch + i ) = 128;
+ *(p_pic->p[3].p_pixels +
+ (scale + 30 - i_line - 1) *
+ p_pic->p[3].i_pitch + i ) = 0xFF;
+ }
+ // limit
+ for (i=24; i<27; i++) {
+ *(p_pic->p[0].p_pixels +
+ (scale + 30 - i_line - 1) *
+ p_pic->p[0].i_pitch + i ) = 0x00;
+ *(p_pic->p[1].p_pixels +
+ (scale + 30 - i_line - 1) *
+ p_pic->p[1].i_pitch + i ) = 128;
+ *(p_pic->p[2].p_pixels +
+ (scale + 30 - i_line - 1) *
+ p_pic->p[2].i_pitch + i ) = 128;
+ *(p_pic->p[3].p_pixels +
+ (scale + 30 - i_line - 1) *
+ p_pic->p[3].i_pitch + i ) = 0xFF;
+ }
+ }
+ if (i_line == moinsSept + 1) {
+ // 7
+ for (i=18; i<19; i++) {
+ *(p_pic->p[0].p_pixels +
+ (scale + 30 - i_line - 1) *
+ p_pic->p[0].i_pitch + i ) = 0x00;
+ *(p_pic->p[1].p_pixels +
+ (scale + 30 - i_line - 1) *
+ p_pic->p[1].i_pitch + i ) = 128;
+ *(p_pic->p[2].p_pixels +
+ (scale + 30 - i_line - 1) *
+ p_pic->p[2].i_pitch + i ) = 128;
+ *(p_pic->p[3].p_pixels +
+ (scale + 30 - i_line - 1) *
+ p_pic->p[3].i_pitch + i ) = 0xFF;
+ }
+ // limit
+ for (i=24; i<27; i++) {
+ *(p_pic->p[0].p_pixels +
+ (scale + 30 - i_line - 1) *
+ p_pic->p[0].i_pitch + i ) = 0x00;
+ *(p_pic->p[1].p_pixels +
+ (scale + 30 - i_line - 1) *
+ p_pic->p[1].i_pitch + i ) = 128;
+ *(p_pic->p[2].p_pixels +
+ (scale + 30 - i_line - 1) *
+ p_pic->p[2].i_pitch + i ) = 128;
+ *(p_pic->p[3].p_pixels +
+ (scale + 30 - i_line - 1) *
+ p_pic->p[3].i_pitch + i ) = 0xFF;
+ }
+ }
+ if (i_line == moinsSept + 2) {
+ // 7
+ for (i=16; i<19; i++) {
+ *(p_pic->p[0].p_pixels +
+ (scale + 30 - i_line - 1) *
+ p_pic->p[0].i_pitch + i ) = 0x00;
+ *(p_pic->p[1].p_pixels +
+ (scale + 30 - i_line - 1) *
+ p_pic->p[1].i_pitch + i ) = 128;
+ *(p_pic->p[2].p_pixels +
+ (scale + 30 - i_line - 1) *
+ p_pic->p[2].i_pitch + i ) = 128;
+ *(p_pic->p[3].p_pixels +
+ (scale + 30 - i_line - 1) *
+ p_pic->p[3].i_pitch + i ) = 0xFF;
+ }
+ }
+
+
+ // -10dB
+ if (i_line == moinsDix - 2) {
+ // 1
+ i=14;
+ *(p_pic->p[0].p_pixels +
+ (scale + 30 - i_line - 1) *
+ p_pic->p[0].i_pitch + i ) = 0x00;
+ *(p_pic->p[1].p_pixels +
+ (scale + 30 - i_line - 1) *
+ p_pic->p[1].i_pitch + i ) = 128;
+ *(p_pic->p[2].p_pixels +
+ (scale + 30 - i_line - 1) *
+ p_pic->p[2].i_pitch + i ) = 128;
+ *(p_pic->p[3].p_pixels +
+ (scale + 30 - i_line - 1) *
+ p_pic->p[3].i_pitch + i ) = 0xFF;
+ // 0
+ for (i=16; i<19; i++) {
+ *(p_pic->p[0].p_pixels +
+ (scale + 30 - i_line - 1) *
+ p_pic->p[0].i_pitch + i ) = 0x00;
+ *(p_pic->p[1].p_pixels +
+ (scale + 30 - i_line - 1) *
+ p_pic->p[1].i_pitch + i ) = 128;
+ *(p_pic->p[2].p_pixels +
+ (scale + 30 - i_line - 1) *
+ p_pic->p[2].i_pitch + i ) = 128;
+ *(p_pic->p[3].p_pixels +
+ (scale + 30 - i_line - 1) *
+ p_pic->p[3].i_pitch + i ) = 0xFF;
+ }
+ }
+ if (i_line == moinsDix - 1) {
+ // 1
+ i=14;
+ *(p_pic->p[0].p_pixels +
+ (scale + 30 - i_line - 1) *
+ p_pic->p[0].i_pitch + i ) = 0x00;
+ *(p_pic->p[1].p_pixels +
+ (scale + 30 - i_line - 1) *
+ p_pic->p[1].i_pitch + i ) = 128;
+ *(p_pic->p[2].p_pixels +
+ (scale + 30 - i_line - 1) *
+ p_pic->p[2].i_pitch + i ) = 128;
+ *(p_pic->p[3].p_pixels +
+ (scale + 30 - i_line - 1) *
+ p_pic->p[3].i_pitch + i ) = 0xFF;
+ // 0
+ i=16;
+ *(p_pic->p[0].p_pixels +
+ (scale + 30 - i_line - 1) *
+ p_pic->p[0].i_pitch + i ) = 0x00;
+ *(p_pic->p[1].p_pixels +
+ (scale + 30 - i_line - 1) *
+ p_pic->p[1].i_pitch + i ) = 128;
+ *(p_pic->p[2].p_pixels +
+ (scale + 30 - i_line - 1) *
+ p_pic->p[2].i_pitch + i ) = 128;
+ *(p_pic->p[3].p_pixels +
+ (scale + 30 - i_line - 1) *
+ p_pic->p[3].i_pitch + i ) = 0xFF;
+ i=18;
+ *(p_pic->p[0].p_pixels +
+ (scale + 30 - i_line - 1) *
+ p_pic->p[0].i_pitch + i ) = 0x00;
+ *(p_pic->p[1].p_pixels +
+ (scale + 30 - i_line - 1) *
+ p_pic->p[1].i_pitch + i ) = 128;
+ *(p_pic->p[2].p_pixels +
+ (scale + 30 - i_line - 1) *
+ p_pic->p[2].i_pitch + i ) = 128;
+ *(p_pic->p[3].p_pixels +
+ (scale + 30 - i_line - 1) *
+ p_pic->p[3].i_pitch + i ) = 0xFF;
+ // limit
+ for (i=24; i<27; i++) {
+ *(p_pic->p[0].p_pixels +
+ (scale + 30 - i_line - 1) *
+ p_pic->p[0].i_pitch + i ) = 255;
+ *(p_pic->p[1].p_pixels +
+ (scale + 30 - i_line - 1) *
+ p_pic->p[1].i_pitch + i ) = 128;
+ *(p_pic->p[2].p_pixels +
+ (scale + 30 - i_line - 1) *
+ p_pic->p[2].i_pitch + i ) = 128;
+ *(p_pic->p[3].p_pixels +
+ (scale + 30 - i_line - 1) *
+ p_pic->p[3].i_pitch + i ) = 0xFF;
+ }
+ }
+ if (i_line == moinsDix) {
+ // 1
+ i=14;
+ *(p_pic->p[0].p_pixels +
+ (scale + 30 - i_line - 1) *
+ p_pic->p[0].i_pitch + i ) = 0x00;
+ *(p_pic->p[1].p_pixels +
+ (scale + 30 - i_line - 1) *
+ p_pic->p[1].i_pitch + i ) = 128;
+ *(p_pic->p[2].p_pixels +
+ (scale + 30 - i_line - 1) *
+ p_pic->p[2].i_pitch + i ) = 128;
+ *(p_pic->p[3].p_pixels +
+ (scale + 30 - i_line - 1) *
+ p_pic->p[3].i_pitch + i ) = 0xFF;
+ // 0
+ i=16;
+ *(p_pic->p[0].p_pixels +
+ (scale + 30 - i_line - 1) *
+ p_pic->p[0].i_pitch + i ) = 0x00;
+ *(p_pic->p[1].p_pixels +
+ (scale + 30 - i_line - 1) *
+ p_pic->p[1].i_pitch + i ) = 128;
+ *(p_pic->p[2].p_pixels +
+ (scale + 30 - i_line - 1) *
+ p_pic->p[2].i_pitch + i ) = 128;
+ *(p_pic->p[3].p_pixels +
+ (scale + 30 - i_line - 1) *
+ p_pic->p[3].i_pitch + i ) = 0xFF;
+ i=18;
+ *(p_pic->p[0].p_pixels +
+ (scale + 30 - i_line - 1) *
+ p_pic->p[0].i_pitch + i ) = 0x00;
+ *(p_pic->p[1].p_pixels +
+ (scale + 30 - i_line - 1) *
+ p_pic->p[1].i_pitch + i ) = 128;
+ *(p_pic->p[2].p_pixels +
+ (scale + 30 - i_line - 1) *
+ p_pic->p[2].i_pitch + i ) = 128;
+ *(p_pic->p[3].p_pixels +
+ (scale + 30 - i_line - 1) *
+ p_pic->p[3].i_pitch + i ) = 0xFF;
+ // limit
+ for (i=24; i<27; i++) {
+ *(p_pic->p[0].p_pixels +
+ (scale + 30 - i_line - 1) *
+ p_pic->p[0].i_pitch + i ) = 0x00;
+ *(p_pic->p[1].p_pixels +
+ (scale + 30 - i_line - 1) *
+ p_pic->p[1].i_pitch + i ) = 128;
+ *(p_pic->p[2].p_pixels +
+ (scale + 30 - i_line - 1) *
+ p_pic->p[2].i_pitch + i ) = 128;
+ *(p_pic->p[3].p_pixels +
+ (scale + 30 - i_line - 1) *
+ p_pic->p[3].i_pitch + i ) = 0xFF;
+ }
+ }
+ if (i_line == moinsDix + 1) {
+ // 1
+ i=14;
+ *(p_pic->p[0].p_pixels +
+ (scale + 30 - i_line - 1) *
+ p_pic->p[0].i_pitch + i ) = 0x00;
+ *(p_pic->p[1].p_pixels +
+ (scale + 30 - i_line - 1) *
+ p_pic->p[1].i_pitch + i ) = 128;
+ *(p_pic->p[2].p_pixels +
+ (scale + 30 - i_line - 1) *
+ p_pic->p[2].i_pitch + i ) = 128;
+ *(p_pic->p[3].p_pixels +
+ (scale + 30 - i_line - 1) *
+ p_pic->p[3].i_pitch + i ) = 0xFF;
+ // 0
+ i=16;
+ *(p_pic->p[0].p_pixels +
+ (scale + 30 - i_line - 1) *
+ p_pic->p[0].i_pitch + i ) = 0x00;
+ *(p_pic->p[1].p_pixels +
+ (scale + 30 - i_line - 1) *
+ p_pic->p[1].i_pitch + i ) = 128;
+ *(p_pic->p[2].p_pixels +
+ (scale + 30 - i_line - 1) *
+ p_pic->p[2].i_pitch + i ) = 128;
+ *(p_pic->p[3].p_pixels +
+ (scale + 30 - i_line - 1) *
+ p_pic->p[3].i_pitch + i ) = 0xFF;
+ i=18;
+ *(p_pic->p[0].p_pixels +
+ (scale + 30 - i_line - 1) *
+ p_pic->p[0].i_pitch + i ) = 0x00;
+ *(p_pic->p[1].p_pixels +
+ (scale + 30 - i_line - 1) *
+ p_pic->p[1].i_pitch + i ) = 128;
+ *(p_pic->p[2].p_pixels +
+ (scale + 30 - i_line - 1) *
+ p_pic->p[2].i_pitch + i ) = 128;
+ *(p_pic->p[3].p_pixels +
+ (scale + 30 - i_line - 1) *
+ p_pic->p[3].i_pitch + i ) = 0xFF;
+ // limit
+ for (i=24; i<27; i++) {
+ *(p_pic->p[0].p_pixels +
+ (scale + 30 - i_line - 1) *
+ p_pic->p[0].i_pitch + i ) = 0x00;
+ *(p_pic->p[1].p_pixels +
+ (scale + 30 - i_line - 1) *
+ p_pic->p[1].i_pitch + i ) = 128;
+ *(p_pic->p[2].p_pixels +
+ (scale + 30 - i_line - 1) *
+ p_pic->p[2].i_pitch + i ) = 128;
+ *(p_pic->p[3].p_pixels +
+ (scale + 30 - i_line - 1) *
+ p_pic->p[3].i_pitch + i ) = 0xFF;
+ }
+ }
+ if (i_line == moinsDix + 2) {
+ // 1
+ i=14;
+ *(p_pic->p[0].p_pixels +
+ (scale + 30 - i_line - 1) *
+ p_pic->p[0].i_pitch + i ) = 0x00;
+ *(p_pic->p[1].p_pixels +
+ (scale + 30 - i_line - 1) *
+ p_pic->p[1].i_pitch + i ) = 128;
+ *(p_pic->p[2].p_pixels +
+ (scale + 30 - i_line - 1) *
+ p_pic->p[2].i_pitch + i ) = 128;
+ *(p_pic->p[3].p_pixels +
+ (scale + 30 - i_line - 1) *
+ p_pic->p[3].i_pitch + i ) = 0xFF;
+ // 0
+ for (i=16; i<19; i++) {
+ *(p_pic->p[0].p_pixels +
+ (scale + 30 - i_line - 1) *
+ p_pic->p[0].i_pitch + i ) = 0x00;
+ *(p_pic->p[1].p_pixels +
+ (scale + 30 - i_line - 1) *
+ p_pic->p[1].i_pitch + i ) = 128;
+ *(p_pic->p[2].p_pixels +
+ (scale + 30 - i_line - 1) *
+ p_pic->p[2].i_pitch + i ) = 128;
+ *(p_pic->p[3].p_pixels +
+ (scale + 30 - i_line - 1) *
+ p_pic->p[3].i_pitch + i ) = 0xFF;
+ }
+ }
+
+ // -20dB
+ if (i_line == moinsVingt - 2) {
+ // 2
+ for (i=12; i<15; i++) {
+ *(p_pic->p[0].p_pixels +
+ (scale + 30 - i_line - 1) *
+ p_pic->p[0].i_pitch + i ) = 0x00;
+ *(p_pic->p[1].p_pixels +
+ (scale + 30 - i_line - 1) *
+ p_pic->p[1].i_pitch + i ) = 128;
+ *(p_pic->p[2].p_pixels +
+ (scale + 30 - i_line - 1) *
+ p_pic->p[2].i_pitch + i ) = 128;
+ *(p_pic->p[3].p_pixels +
+ (scale + 30 - i_line - 1) *
+ p_pic->p[3].i_pitch + i ) = 0xFF;
+ }
+ // 0
+ for (i=16; i<19; i++) {
+ *(p_pic->p[0].p_pixels +
+ (scale + 30 - i_line - 1) *
+ p_pic->p[0].i_pitch + i ) = 0x00;
+ *(p_pic->p[1].p_pixels +
+ (scale + 30 - i_line - 1) *
+ p_pic->p[1].i_pitch + i ) = 128;
+ *(p_pic->p[2].p_pixels +
+ (scale + 30 - i_line - 1) *
+ p_pic->p[2].i_pitch + i ) = 128;
+ *(p_pic->p[3].p_pixels +
+ (scale + 30 - i_line - 1) *
+ p_pic->p[3].i_pitch + i ) = 0xFF;
+ }
+ }
+ if (i_line == moinsVingt - 1) {
+ // 2
+ i=12;
+ *(p_pic->p[0].p_pixels +
+ (scale + 30 - i_line - 1) *
+ p_pic->p[0].i_pitch + i ) = 0x00;
+ *(p_pic->p[1].p_pixels +
+ (scale + 30 - i_line - 1) *
+ p_pic->p[1].i_pitch + i ) = 128;
+ *(p_pic->p[2].p_pixels +
+ (scale + 30 - i_line - 1) *
+ p_pic->p[2].i_pitch + i ) = 128;
+ *(p_pic->p[3].p_pixels +
+ (scale + 30 - i_line - 1) *
+ p_pic->p[3].i_pitch + i ) = 0xFF;
+ // 0
+ i=16;
+ *(p_pic->p[0].p_pixels +
+ (scale + 30 - i_line - 1) *
+ p_pic->p[0].i_pitch + i ) = 0x00;
+ *(p_pic->p[1].p_pixels +
+ (scale + 30 - i_line - 1) *
+ p_pic->p[1].i_pitch + i ) = 128;
+ *(p_pic->p[2].p_pixels +
+ (scale + 30 - i_line - 1) *
+ p_pic->p[2].i_pitch + i ) = 128;
+ *(p_pic->p[3].p_pixels +
+ (scale + 30 - i_line - 1) *
+ p_pic->p[3].i_pitch + i ) = 0xFF;
+ i=18;
+ *(p_pic->p[0].p_pixels +
+ (scale + 30 - i_line - 1) *
+ p_pic->p[0].i_pitch + i ) = 0x00;
+ *(p_pic->p[1].p_pixels +
+ (scale + 30 - i_line - 1) *
+ p_pic->p[1].i_pitch + i ) = 128;
+ *(p_pic->p[2].p_pixels +
+ (scale + 30 - i_line - 1) *
+ p_pic->p[2].i_pitch + i ) = 128;
+ *(p_pic->p[3].p_pixels +
+ (scale + 30 - i_line - 1) *
+ p_pic->p[3].i_pitch + i ) = 0xFF;
+ // limit
+ for (i=24; i<27; i++) {
+ *(p_pic->p[0].p_pixels +
+ (scale + 30 - i_line - 1) *
+ p_pic->p[0].i_pitch + i ) = 255;
+ *(p_pic->p[1].p_pixels +
+ (scale + 30 - i_line - 1) *
+ p_pic->p[1].i_pitch + i ) = 128;
+ *(p_pic->p[2].p_pixels +
+ (scale + 30 - i_line - 1) *
+ p_pic->p[2].i_pitch + i ) = 128;
+ *(p_pic->p[3].p_pixels +
+ (scale + 30 - i_line - 1) *
+ p_pic->p[3].i_pitch + i ) = 0xFF;
+ }
+ }
+ if (i_line == moinsVingt) {
+ // 2
+ for (i=12; i<15; i++) {
+ *(p_pic->p[0].p_pixels +
+ (scale + 30 - i_line - 1) *
+ p_pic->p[0].i_pitch + i ) = 0x00;
+ *(p_pic->p[1].p_pixels +
+ (scale + 30 - i_line - 1) *
+ p_pic->p[1].i_pitch + i ) = 128;
+ *(p_pic->p[2].p_pixels +
+ (scale + 30 - i_line - 1) *
+ p_pic->p[2].i_pitch + i ) = 128;
+ *(p_pic->p[3].p_pixels +
+ (scale + 30 - i_line - 1) *
+ p_pic->p[3].i_pitch + i ) = 0xFF;
+ }
+ // 0
+ i=16;
+ *(p_pic->p[0].p_pixels +
+ (scale + 30 - i_line - 1) *
+ p_pic->p[0].i_pitch + i ) = 0x00;
+ *(p_pic->p[1].p_pixels +
+ (scale + 30 - i_line - 1) *
+ p_pic->p[1].i_pitch + i ) = 128;
+ *(p_pic->p[2].p_pixels +
+ (scale + 30 - i_line - 1) *
+ p_pic->p[2].i_pitch + i ) = 128;
+ *(p_pic->p[3].p_pixels +
+ (scale + 30 - i_line - 1) *
+ p_pic->p[3].i_pitch + i ) = 0xFF;
+ i=18;
+ *(p_pic->p[0].p_pixels +
+ (scale + 30 - i_line - 1) *
+ p_pic->p[0].i_pitch + i ) = 0x00;
+ *(p_pic->p[1].p_pixels +
+ (scale + 30 - i_line - 1) *
+ p_pic->p[1].i_pitch + i ) = 128;
+ *(p_pic->p[2].p_pixels +
+ (scale + 30 - i_line - 1) *
+ p_pic->p[2].i_pitch + i ) = 128;
+ *(p_pic->p[3].p_pixels +
+ (scale + 30 - i_line - 1) *
+ p_pic->p[3].i_pitch + i ) = 0xFF;
+ // limit
+ for (i=24; i<27; i++) {
+ *(p_pic->p[0].p_pixels +
+ (scale + 30 - i_line - 1) *
+ p_pic->p[0].i_pitch + i ) = 0x00;
+ *(p_pic->p[1].p_pixels +
+ (scale + 30 - i_line - 1) *
+ p_pic->p[1].i_pitch + i ) = 128;
+ *(p_pic->p[2].p_pixels +
+ (scale + 30 - i_line - 1) *
+ p_pic->p[2].i_pitch + i ) = 128;
+ *(p_pic->p[3].p_pixels +
+ (scale + 30 - i_line - 1) *
+ p_pic->p[3].i_pitch + i ) = 0xFF;
+ }
+ }
+ if (i_line == moinsVingt + 1) {
+ // 2
+ i=14;
+ *(p_pic->p[0].p_pixels +
+ (scale + 30 - i_line - 1) *
+ p_pic->p[0].i_pitch + i ) = 0x00;
+ *(p_pic->p[1].p_pixels +
+ (scale + 30 - i_line - 1) *
+ p_pic->p[1].i_pitch + i ) = 128;
+ *(p_pic->p[2].p_pixels +
+ (scale + 30 - i_line - 1) *
+ p_pic->p[2].i_pitch + i ) = 128;
+ *(p_pic->p[3].p_pixels +
+ (scale + 30 - i_line - 1) *
+ p_pic->p[3].i_pitch + i ) = 0xFF;
+ // 0
+ i=16;
+ *(p_pic->p[0].p_pixels +
+ (scale + 30 - i_line - 1) *
+ p_pic->p[0].i_pitch + i ) = 0x00;
+ *(p_pic->p[1].p_pixels +
+ (scale + 30 - i_line - 1) *
+ p_pic->p[1].i_pitch + i ) = 128;
+ *(p_pic->p[2].p_pixels +
+ (scale + 30 - i_line - 1) *
+ p_pic->p[2].i_pitch + i ) = 128;
+ *(p_pic->p[3].p_pixels +
+ (scale + 30 - i_line - 1) *
+ p_pic->p[3].i_pitch + i ) = 0xFF;
+ i=18;
+ *(p_pic->p[0].p_pixels +
+ (scale + 30 - i_line - 1) *
+ p_pic->p[0].i_pitch + i ) = 0x00;
+ *(p_pic->p[1].p_pixels +
+ (scale + 30 - i_line - 1) *
+ p_pic->p[1].i_pitch + i ) = 128;
+ *(p_pic->p[2].p_pixels +
+ (scale + 30 - i_line - 1) *
+ p_pic->p[2].i_pitch + i ) = 128;
+ *(p_pic->p[3].p_pixels +
+ (scale + 30 - i_line - 1) *
+ p_pic->p[3].i_pitch + i ) = 0xFF;
+ // limit
+ for (i=24; i<27; i++) {
+ *(p_pic->p[0].p_pixels +
+ (scale + 30 - i_line - 1) *
+ p_pic->p[0].i_pitch + i ) = 0x00;
+ *(p_pic->p[1].p_pixels +
+ (scale + 30 - i_line - 1) *
+ p_pic->p[1].i_pitch + i ) = 128;
+ *(p_pic->p[2].p_pixels +
+ (scale + 30 - i_line - 1) *
+ p_pic->p[2].i_pitch + i ) = 128;
+ *(p_pic->p[3].p_pixels +
+ (scale + 30 - i_line - 1) *
+ p_pic->p[3].i_pitch + i ) = 0xFF;
+ }
+ }
+ if (i_line == moinsVingt + 2) {
+ // 2
+ for (i=12; i<15; i++) {
+ *(p_pic->p[0].p_pixels +
+ (scale + 30 - i_line - 1) *
+ p_pic->p[0].i_pitch + i ) = 0x00;
+ *(p_pic->p[1].p_pixels +
+ (scale + 30 - i_line - 1) *
+ p_pic->p[1].i_pitch + i ) = 128;
+ *(p_pic->p[2].p_pixels +
+ (scale + 30 - i_line - 1) *
+ p_pic->p[2].i_pitch + i ) = 128;
+ *(p_pic->p[3].p_pixels +
+ (scale + 30 - i_line - 1) *
+ p_pic->p[3].i_pitch + i ) = 0xFF;
+ }
+ // 0
+ for (i=16; i<19; i++) {
+ *(p_pic->p[0].p_pixels +
+ (scale + 30 - i_line - 1) *
+ p_pic->p[0].i_pitch + i ) = 0x00;
+ *(p_pic->p[1].p_pixels +
+ (scale + 30 - i_line - 1) *
+ p_pic->p[1].i_pitch + i ) = 128;
+ *(p_pic->p[2].p_pixels +
+ (scale + 30 - i_line - 1) *
+ p_pic->p[2].i_pitch + i ) = 128;
+ *(p_pic->p[3].p_pixels +
+ (scale + 30 - i_line - 1) *
+ p_pic->p[3].i_pitch + i ) = 0xFF;
+ }
+ }
+
+
+ }
+
+ // draw the bars and channel indicators
+ for (i=0; i<nbChannels; i++) {
+ for( j = barWidth+20 ; j < 2*barWidth+20; j++)
+ {
+ // channel indicators
+ for ( i_line = 12; i_line < 18; i_line++ ) {
+ // white
+ *(p_pic->p[0].p_pixels +
+ (scale + 30 - i_line - 1) *
+ p_pic->p[0].i_pitch +
+ ( (2*i*barWidth)+j ) ) = 255;
+ *(p_pic->p[1].p_pixels +
+ (scale + 30 - i_line - 1) *
+ p_pic->p[1].i_pitch +
+ ( (2*i*barWidth)+j ) ) = 128;
+ *(p_pic->p[2].p_pixels +
+ (scale + 30 - i_line - 1) *
+ p_pic->p[2].i_pitch +
+ ( (2*i*barWidth)+j ) ) = 128;
+ *(p_pic->p[3].p_pixels +
+ (scale + 30 - i_line - 1) *
+ p_pic->p[3].i_pitch +
+ ( (2*i*barWidth)+j )) = 0xFF;
+ }
+ // bars
+ for( i_line = 20; i_line < i_values[i]+20; i_line++ )
+ {
+ if (i_line < moinsDix) { // green if < -10 dB
+ *(p_pic->p[0].p_pixels +
+ (scale + 30 - i_line - 1) *
+ p_pic->p[0].i_pitch +
+ ( (2*i*barWidth)+j ) ) = 150;
+ *(p_pic->p[1].p_pixels +
+ (scale + 30 - i_line - 1) *
+ p_pic->p[1].i_pitch +
+ ( (2*i*barWidth)+j ) ) = 44;
+ *(p_pic->p[2].p_pixels +
+ (scale + 30 - i_line - 1) *
+ p_pic->p[2].i_pitch +
+ ( (2*i*barWidth)+j ) ) = 21;
+ *(p_pic->p[3].p_pixels +
+ (scale + 30 - i_line - 1) *
+ p_pic->p[3].i_pitch +
+ ( (2*i*barWidth)+j )) = 0xFF;
+ } else if (i_line < moinsTrois) { // yellow if > -10dB and < -3dB
+ *(p_pic->p[0].p_pixels +
+ (scale + 30 - i_line - 1) *
+ p_pic->p[0].i_pitch +
+ ( (2*i*barWidth)+j ) ) = 226;
+ *(p_pic->p[1].p_pixels +
+ (scale + 30 - i_line - 1) *
+ p_pic->p[1].i_pitch +
+ ( (2*i*barWidth)+j ) ) = 1;
+ *(p_pic->p[2].p_pixels +
+ (scale + 30 - i_line - 1) *
+ p_pic->p[2].i_pitch +
+ ( (2*i*barWidth)+j ) ) = 148;
+ *(p_pic->p[3].p_pixels +
+ (scale + 30 - i_line - 1) *
+ p_pic->p[3].i_pitch +
+ ( (2*i*barWidth)+j )) = 0xFF;
+ } else { // red if > -3 dB
+ *(p_pic->p[0].p_pixels +
+ (scale + 30 - i_line - 1) *
+ p_pic->p[0].i_pitch +
+ ( (2*i*barWidth)+j ) ) = 76;
+ *(p_pic->p[1].p_pixels +
+ (scale + 30 - i_line - 1) *
+ p_pic->p[1].i_pitch +
+ ( (2*i*barWidth)+j ) ) = 85;
+ *(p_pic->p[2].p_pixels +
+ (scale + 30 - i_line - 1) *
+ p_pic->p[2].i_pitch +
+ ( (2*i*barWidth)+j ) ) = 0xFF;
+ *(p_pic->p[3].p_pixels +
+ (scale + 30 - i_line - 1) *
+ p_pic->p[3].i_pitch +
+ ( (2*i*barWidth)+j )) = 0xFF;
+ }
+ }
+ }
+ }
+
+
+
+ if (alarm) {// draw the alarm square
+ // bottom
+ for ( i_line = 0; i_line < 10; i_line++ ) {
+ for (i=0; i<i_width+20; i++) {
+ *(p_pic->p[0].p_pixels +
+ (scale + 30 - i_line - 1) *
+ p_pic->p[0].i_pitch + i ) = 76;
+ *(p_pic->p[1].p_pixels +
+ (scale + 30 - i_line - 1) *
+ p_pic->p[1].i_pitch + i ) = 85;
+ *(p_pic->p[2].p_pixels +
+ (scale + 30 - i_line - 1) *
+ p_pic->p[2].i_pitch + i ) = 0xFF;
+ *(p_pic->p[3].p_pixels +
+ (scale + 30 - i_line - 1) *
+ p_pic->p[3].i_pitch + i ) = 0xFF;
+ }
+ }
+ // top
+ for ( i_line = scale+21; i_line < scale+30; i_line++ ) {
+ for (i=0; i<i_width+20; i++) {
+ *(p_pic->p[0].p_pixels +
+ (scale + 30 - i_line - 1) *
+ p_pic->p[0].i_pitch + i ) = 76;
+ *(p_pic->p[1].p_pixels +
+ (scale + 30 - i_line - 1) *
+ p_pic->p[1].i_pitch + i ) = 85;
+ *(p_pic->p[2].p_pixels +
+ (scale + 30 - i_line - 1) *
+ p_pic->p[2].i_pitch + i ) = 0xFF;
+ *(p_pic->p[3].p_pixels +
+ (scale + 30 - i_line - 1) *
+ p_pic->p[3].i_pitch + i ) = 0xFF;
+ }
+ }
+ // sides
+ for ( i_line = 9; i_line < scale+21; i_line++ ) {
+ for (i=0; i<10; i++) {
+ *(p_pic->p[0].p_pixels +
+ (scale + 30 - i_line - 1) *
+ p_pic->p[0].i_pitch + i ) = 76;
+ *(p_pic->p[1].p_pixels +
+ (scale + 30 - i_line - 1) *
+ p_pic->p[1].i_pitch + i ) = 85;
+ *(p_pic->p[2].p_pixels +
+ (scale + 30 - i_line - 1) *
+ p_pic->p[2].i_pitch + i ) = 0xFF;
+ *(p_pic->p[3].p_pixels +
+ (scale + 30 - i_line - 1) *
+ p_pic->p[3].i_pitch + i ) = 0xFF;
+ }
+ for (i=i_width+11; i<i_width+20; i++) {
+ *(p_pic->p[0].p_pixels +
+ (scale + 30 - i_line - 1) *
+ p_pic->p[0].i_pitch + i ) = 76;
+ *(p_pic->p[1].p_pixels +
+ (scale + 30 - i_line - 1) *
+ p_pic->p[1].i_pitch + i ) = 85;
+ *(p_pic->p[2].p_pixels +
+ (scale + 30 - i_line - 1) *
+ p_pic->p[2].i_pitch + i ) = 0xFF;
+ *(p_pic->p[3].p_pixels +
+ (scale + 30 - i_line - 1) *
+ p_pic->p[3].i_pitch + i ) = 0xFF;
+ }
+ }
+ }
+
+
+ return p_pic;
+}
+
+/*****************************************************************************
+ * LoadBarGraph: loads the BarGraph images into memory
+ *****************************************************************************/
+#define LoadBarGraph( a, b ) __LoadBarGraph( VLC_OBJECT( a ), b )
+static void __LoadBarGraph( vlc_object_t *p_this, BarGraph_t *p_BarGraph )
+{
+
+ p_BarGraph->p_pic = LoadImage( p_this, p_BarGraph->nbChannels, p_BarGraph->i_values, p_BarGraph->scale, p_BarGraph->alarm, p_BarGraph->barWidth);
+ if( !p_BarGraph->p_pic )
+ {
+ msg_Warn( p_this, "error while creating picture" );
+ }
+
+}
+
+/*****************************************************************************
+ * vout_sys_t: logo video output method descriptor
+ *****************************************************************************
+ * This structure is part of the video output thread descriptor.
+ * It describes the Invert specific properties of an output thread.
+ *****************************************************************************/
+struct vout_sys_t
+{
+ BarGraph_t *p_BarGraph;
+
+ vout_thread_t *p_vout;
+
+ filter_t *p_blend;
+
+ int i_width, i_height;
+ int pos, posx, posy;
+};
+
+/*****************************************************************************
+ * Create: allocates logo video thread output method
+ *****************************************************************************/
+static int Create( vlc_object_t *p_this )
+{
+ vout_thread_t *p_vout = (vout_thread_t *)p_this;
+ vout_sys_t *p_sys;
+ BarGraph_t *p_BarGraph;
+ char* i_values = NULL;
+ char* res = NULL;
+ char delim[] = ":";
+ int nbChannels = 0;
+
+ /* Allocate structure */
+ p_sys = p_vout->p_sys = malloc( sizeof( vout_sys_t ) );
+ if( p_sys == NULL )
+ return VLC_ENOMEM;
+ p_BarGraph = p_sys->p_BarGraph = malloc( sizeof( BarGraph_t ) );
+ if( p_BarGraph == NULL )
+ {
+ free( p_sys );
+ return VLC_ENOMEM;
+ }
+
+ config_ChainParse( p_vout, CFG_PREFIX, ppsz_filter_options,
+ p_vout->p_cfg );
+
+ p_vout->pf_init = Init;
+ p_vout->pf_end = End;
+ p_vout->pf_manage = NULL;
+ p_vout->pf_render = Render;
+ p_vout->pf_display = NULL;
+ p_vout->pf_control = Control;
+
+ p_sys->pos = var_CreateGetIntegerCommand( p_vout, "audiobargraph_v-position" );
+ p_sys->posx = var_CreateGetIntegerCommand( p_vout, "audiobargraph_v-x" );
+ p_sys->posy = var_CreateGetIntegerCommand( p_vout, "audiobargraph_v-y" );
+ p_BarGraph->i_alpha = var_CreateGetIntegerCommand( p_vout,
+ "audiobargraph_v-transparency" );
+ p_BarGraph->i_alpha = __MAX( __MIN( p_BarGraph->i_alpha, 255 ), 0 );
+ i_values = var_CreateGetStringCommand( p_vout, "audiobargraph_v-i_values" );
+ p_BarGraph->scale = 400;
+ p_BarGraph->nbChannels = 0;
+ p_BarGraph->i_values = NULL;
+ res = strtok(i_values, delim);
+ while (res != NULL) {
+ nbChannels++;
+ p_BarGraph->i_values = (int*)realloc(p_BarGraph->i_values, nbChannels*sizeof(int));
+ p_BarGraph->i_values[nbChannels-1] = __MAX( __MIN( atof(res)*p_BarGraph->scale, p_BarGraph->scale ), 0 );
+ p_BarGraph->nbChannels = nbChannels;
+ res = strtok(NULL, delim);
+ }
+ p_BarGraph->alarm = var_CreateGetIntegerCommand( p_vout, "audiobargraph_v-alarm" );
+ p_BarGraph->barWidth = var_CreateGetIntegerCommand( p_vout, "audiobargraph_v-barWidth" );
+
+ LoadBarGraph( p_vout, p_BarGraph );
+
+ return VLC_SUCCESS;
+}
+
+/*****************************************************************************
+ * Init: initialize bar graph video thread output method
+ *****************************************************************************/
+static int Init( vout_thread_t *p_vout )
+{
+ vout_sys_t *p_sys = p_vout->p_sys;
+ picture_t *p_pic;
+ video_format_t fmt;
+ BarGraph_t *p_BarGraph = p_sys->p_BarGraph;
+
+ I_OUTPUTPICTURES = 0;
+ memset( &fmt, 0, sizeof(video_format_t) );
+
+ p_pic = p_BarGraph->p_pic;
+ /* Initialize the output structure */
+ p_vout->output.i_chroma = p_vout->render.i_chroma;
+ p_vout->output.i_width = p_vout->render.i_width;
+ p_vout->output.i_height = p_vout->render.i_height;
+ p_vout->output.i_aspect = p_vout->render.i_aspect;
+ p_vout->fmt_out = p_vout->fmt_in;
+ fmt = p_vout->fmt_out;
+
+ /* Load the video blending filter */
+ p_sys->p_blend = vlc_object_create( p_vout, sizeof(filter_t) );
+ vlc_object_attach( p_sys->p_blend, p_vout );
+ p_sys->p_blend->fmt_out.video.i_x_offset =
+ p_sys->p_blend->fmt_out.video.i_y_offset = 0;
+ p_sys->p_blend->fmt_in.video.i_x_offset =
+ p_sys->p_blend->fmt_in.video.i_y_offset = 0;
+ p_sys->p_blend->fmt_out.video.i_aspect = p_vout->render.i_aspect;
+ p_sys->p_blend->fmt_out.video.i_chroma = p_vout->output.i_chroma;
+ p_sys->p_blend->fmt_in.video.i_chroma = VLC_FOURCC('Y','U','V','A');
+ p_sys->p_blend->fmt_in.video.i_aspect = VOUT_ASPECT_FACTOR;
+ p_sys->i_width =
+ p_sys->p_blend->fmt_in.video.i_width =
+ p_sys->p_blend->fmt_in.video.i_visible_width =
+ p_pic ? p_pic->p[Y_PLANE].i_visible_pitch : 0;
+ p_sys->i_height =
+ p_sys->p_blend->fmt_in.video.i_height =
+ p_sys->p_blend->fmt_in.video.i_visible_height =
+ p_pic ? p_pic->p[Y_PLANE].i_visible_lines : 0;
+ p_sys->p_blend->fmt_out.video.i_width =
+ p_sys->p_blend->fmt_out.video.i_visible_width =
+ p_vout->output.i_width;
+ p_sys->p_blend->fmt_out.video.i_height =
+ p_sys->p_blend->fmt_out.video.i_visible_height =
+ p_vout->output.i_height;
+
+ p_sys->p_blend->p_module =
+ module_need( p_sys->p_blend, "video blending", NULL, false );
+ if( !p_sys->p_blend->p_module )
+ {
+ msg_Err( p_vout, "can't open blending filter, aborting" );
+ vlc_object_detach( p_sys->p_blend );
+ vlc_object_release( p_sys->p_blend );
+ return VLC_EGENERIC;
+ }
+
+ if( p_sys->posx < 0 || p_sys->posy < 0 )
+ {
+ p_sys->posx = 0; p_sys->posy = 0;
+
+ if( p_sys->pos & SUBPICTURE_ALIGN_BOTTOM )
+ {
+ p_sys->posy = p_vout->render.i_height - p_sys->i_height;
+ }
+ else if ( !(p_sys->pos & SUBPICTURE_ALIGN_TOP) )
+ {
+ p_sys->posy = p_vout->render.i_height / 2 - p_sys->i_height / 2;
+ }
+
+ if( p_sys->pos & SUBPICTURE_ALIGN_RIGHT )
+ {
+ p_sys->posx = p_vout->render.i_width - p_sys->i_width;
+ }
+ else if ( !(p_sys->pos & SUBPICTURE_ALIGN_LEFT) )
+ {
+ p_sys->posx = p_vout->render.i_width / 2 - p_sys->i_width / 2;
+ }
+ }
+ else
+ {
+ p_sys->pos = 0;
+ }
+
+ /* Try to open the real video output */
+ msg_Dbg( p_vout, "spawning the real video output" );
+
+ p_sys->p_vout = vout_Create( p_vout, &fmt );
+
+ /* Everything failed */
+ if( p_sys->p_vout == NULL )
+ {
+ msg_Err( p_vout, "can't open vout, aborting" );
+ return VLC_EGENERIC;
+ }
+
+ vout_filter_AllocateDirectBuffers( p_vout, VOUT_MAX_PICTURES );
+
+ vout_filter_AddChild( p_vout, p_sys->p_vout, MouseEvent );
+
+ return VLC_SUCCESS;
+}
+
+/*****************************************************************************
+ * End: terminate bar graph video thread output method
+ *****************************************************************************/
+static void End( vout_thread_t *p_vout )
+{
+ vout_sys_t *p_sys = p_vout->p_sys;
+
+ vout_filter_DelChild( p_vout, p_sys->p_vout, MouseEvent );
+ vout_CloseAndRelease( p_sys->p_vout );
+
+ vout_filter_ReleaseDirectBuffers( p_vout );
+
+ if( p_sys->p_blend->p_module )
+ module_unneed( p_sys->p_blend, p_sys->p_blend->p_module );
+ vlc_object_detach( p_sys->p_blend );
+ vlc_object_release( p_sys->p_blend );
+}
+
+/*****************************************************************************
+ * Destroy: destroy bar graph video thread output method
+ *****************************************************************************/
+static void Destroy( vlc_object_t *p_this )
+{
+ vout_thread_t *p_vout = (vout_thread_t *)p_this;
+ vout_sys_t *p_sys = p_vout->p_sys;
+
+ vlc_mutex_destroy( &p_sys->p_BarGraph->lock );
+ if( p_sys->p_BarGraph->p_pic )
+ {
+ picture_Release( p_sys->p_BarGraph->p_pic );
+ p_sys->p_BarGraph->p_pic = NULL;
+ }
+ free( p_sys->p_BarGraph->i_values );
+ free( p_sys->p_BarGraph );
+
+ free( p_sys );
+}
+
+/*****************************************************************************
+ * Render: render the bar graph onto the video
+ *****************************************************************************/
+static void Render( vout_thread_t *p_vout, picture_t *p_inpic )
+{
+ vout_sys_t *p_sys = p_vout->p_sys;
+ picture_t *p_outpic;
+ picture_t *p_pic;
+ BarGraph_t *p_BarGraph;
+
+ p_BarGraph = p_sys->p_BarGraph;
+
+
+ //TODO : deal with a picture list with dates
+ /*if( BarGraph_t->date > p_inpic->date )
+ {
+ p_logo_list->i_counter =
+ ( p_logo_list->i_counter + 1 )%p_logo_list->i_count;
+ p_logo = &p_logo_list->p_logo[p_sys->p_logo_list->i_counter];
+ p_pic = p_logo->p_pic;
+ p_logo_list->i_next_pic = p_inpic->date + ( p_logo->i_delay != -1 ?
+ p_logo->i_delay : p_logo_list->i_delay ) * 1000;
+ if( p_pic )
+ {
+
+ p_sys->i_width =
+ p_sys->p_blend->fmt_in.video.i_width =
+ p_sys->p_blend->fmt_in.video.i_visible_width =
+ p_pic->p[Y_PLANE].i_visible_pitch;
+ p_sys->i_height =
+ p_sys->p_blend->fmt_in.video.i_height =
+ p_sys->p_blend->fmt_in.video.i_visible_height =
+ p_pic->p[Y_PLANE].i_visible_lines;
+
+ if( p_sys->pos )
+ {
+ if( p_sys->pos & SUBPICTURE_ALIGN_BOTTOM )
+ {
+ p_sys->posy = p_vout->render.i_height - p_sys->i_height;
+ }
+ else if ( !(p_sys->pos & SUBPICTURE_ALIGN_TOP) )
+ {
+ p_sys->posy = p_vout->render.i_height/2 - p_sys->i_height/2;
+ }
+ if( p_sys->pos & SUBPICTURE_ALIGN_RIGHT )
+ {
+ p_sys->posx = p_vout->render.i_width - p_sys->i_width;
+ }
+ else if ( !(p_sys->pos & SUBPICTURE_ALIGN_LEFT) )
+ {
+ p_sys->posx = p_vout->render.i_width/2 - p_sys->i_width/2;
+ }
+ }
+ }
+
+ }
+ else
+ {
+ p_logo = &p_logo_list->p_logo[p_sys->p_logo_list->i_counter];
+ p_pic = p_logo->p_pic;
+ }*/
+
+ // for the time being, do not deal with dates...
+ p_pic = p_BarGraph->p_pic;
+
+ /* This is a new frame. Get a structure from the video_output. */
+ while( !(p_outpic = vout_CreatePicture( p_sys->p_vout, 0, 0, 0 )) )
+ {
+ if( !vlc_object_alive (p_vout) || p_vout->b_error ) return;
+ msleep( VOUT_OUTMEM_SLEEP );
+ }
+
+ picture_Copy( p_outpic, p_inpic );
+
+ if( p_pic )
+ p_sys->p_blend->pf_video_blend( p_sys->p_blend, p_outpic,
+ p_pic, p_sys->posx, p_sys->posy,
+ p_BarGraph->i_alpha != -1 ? p_BarGraph->i_alpha
+ : p_BarGraph->i_alpha );
+
+ vout_DisplayPicture( p_sys->p_vout, p_outpic );
+}
+
+/*****************************************************************************
+ * MouseEvent: callback for mouse events
+ *****************************************************************************/
+static int MouseEvent( vlc_object_t *p_this, char const *psz_var,
+ vlc_value_t oldval, vlc_value_t newval, void *p_data )
+{
+ vout_thread_t *p_vout = p_data;
+ assert( p_this == VLC_OBJECT(p_vout->p_sys->p_vout) );
+ VLC_UNUSED(p_this);
+ VLC_UNUSED(oldval);
+
+ vout_sys_t *p_sys = p_vout->p_sys;
+ const int i_delta = newval.i_int - oldval.i_int;
+ const int i_bdown = var_GetInteger( p_sys->p_vout, "mouse-button-down" );
+
+ if( (i_bdown & 0x1) == 0 )
+ goto forward;
+
+ int i_x, i_y;
+ int i_dx = 0;
+ int i_dy = 0;
+ if( psz_var[6] == 'x' )
+ {
+ i_y = var_GetInteger( p_sys->p_vout, "mouse-y" );
+ i_x = newval.i_int;
+ i_dx = i_delta;
+ }
+ else if( psz_var[6] == 'y' )
+ {
+ i_y = newval.i_int;
+ i_x = var_GetInteger( p_sys->p_vout, "mouse-x" );
+ i_dy = i_delta;
+ }
+ else
+ {
+ goto forward;
+ }
+
+ /* FIXME missing lock */
+ if( i_x < (int)p_sys->posx ||
+ i_y < (int)p_sys->posy ||
+ i_x > (int)(p_sys->posx + p_sys->i_width) ||
+ i_y > (int)(p_sys->posy + p_sys->i_height) )
+ goto forward;
+
+ p_sys->posx = __MIN( __MAX( p_sys->posx + i_dx, 0 ),
+ p_vout->output.i_width - p_sys->i_width );
+ p_sys->posy = __MIN( __MAX( p_sys->posy + i_dy, 0 ),
+ p_vout->output.i_height - p_sys->i_height );
+ return VLC_SUCCESS;
+
+forward:
+ return var_Set( p_vout, psz_var, newval );
+}
+
+/*****************************************************************************
+ * Control: control facility for the vout (forwards to child vout)
+ *****************************************************************************/
+static int Control( vout_thread_t *p_vout, int i_query, va_list args )
+{
+ return vout_vaControl( p_vout->p_sys->p_vout, i_query, args );
+}
+
+/*****************************************************************************
+ * filter_sys_t: bar graph filter descriptor
+ *****************************************************************************/
+struct filter_sys_t
+{
+ BarGraph_t *p_BarGraph;
+
+ int pos, posx, posy;
+
+ bool b_absolute;
+ mtime_t i_last_date;
+
+ /* On the fly control variable */
+ bool b_need_update;
+};
+
+static subpicture_t *Filter( filter_t *, mtime_t );
+
+/*****************************************************************************
+ * CreateFilter: allocates bar graph video filter
+ *****************************************************************************/
+static int CreateFilter( vlc_object_t *p_this )
+{
+ filter_t *p_filter = (filter_t *)p_this;
+ filter_sys_t *p_sys;
+ BarGraph_t *p_BarGraph;
+ char* i_values;
+ char* res = NULL;
+ char delim[] = ":";
+ int nbChannels = 0;
+
+ /* Allocate structure */
+ p_sys = p_filter->p_sys = malloc( sizeof( filter_sys_t ) );
+ if( p_sys == NULL )
+ return VLC_ENOMEM;
+ p_BarGraph = p_sys->p_BarGraph = malloc( sizeof( BarGraph_t ) );
+ if( p_BarGraph == NULL )
+ {
+ free( p_sys );
+ return VLC_ENOMEM;
+ }
+
+ config_ChainParse( p_filter, CFG_PREFIX, ppsz_filter_options,
+ p_filter->p_cfg );
+
+
+ p_sys->pos = var_CreateGetIntegerCommand( p_filter, "audiobargraph_v-position" );
+ p_sys->posx = var_CreateGetIntegerCommand( p_filter, "audiobargraph_v-x" );
+ p_sys->posy = var_CreateGetIntegerCommand( p_filter, "audiobargraph_v-y" );
+ p_BarGraph->i_alpha = var_CreateGetIntegerCommand( p_filter,
+ "audiobargraph_v-transparency" );
+ p_BarGraph->i_alpha = __MAX( __MIN( p_BarGraph->i_alpha, 255 ), 0 );
+ i_values = var_CreateGetStringCommand( p_filter, "audiobargraph_v-i_values" );
+ p_BarGraph->scale = 400;
+ p_BarGraph->nbChannels = 0;
+ p_BarGraph->i_values = NULL;
+ res = strtok(i_values, delim);
+ while (res != NULL) {
+ nbChannels++;
+ p_BarGraph->i_values = (int*)realloc(p_BarGraph->i_values, nbChannels*sizeof(int));
+ p_BarGraph->i_values[nbChannels-1] = __MAX( __MIN( atof(res)*p_BarGraph->scale, p_BarGraph->scale ), 0 );
+ p_BarGraph->nbChannels = nbChannels;
+ res = strtok(NULL, delim);
+ }
+ p_BarGraph->alarm = var_CreateGetIntegerCommand( p_filter, "audiobargraph_v-alarm" );
+ p_BarGraph->barWidth = var_CreateGetIntegerCommand( p_filter, "audiobargraph_v-barWidth" );
+
+ vlc_mutex_init( &p_BarGraph->lock );
+ LoadBarGraph( p_this, p_BarGraph );
+
+ var_AddCallback( p_filter, "audiobargraph_v-position", BarGraphCallback, p_sys );
+ var_AddCallback( p_filter, "audiobargraph_v-x", BarGraphCallback, p_sys );
+ var_AddCallback( p_filter, "audiobargraph_v-y", BarGraphCallback, p_sys );
+ var_AddCallback( p_filter, "audiobargraph_v-transparency", BarGraphCallback, p_sys );
+ var_AddCallback( p_filter, "audiobargraph_v-i_values", BarGraphCallback, p_sys );
+ var_AddCallback( p_filter, "audiobargraph_v-alarm", BarGraphCallback, p_sys );
+ var_AddCallback( p_filter, "audiobargraph_v-barWidth", BarGraphCallback, p_sys );
+
+ /* Misc init */
+ p_filter->pf_sub_filter = Filter;
+ p_sys->b_need_update = true;
+
+ p_sys->i_last_date = 0;
+
+ return VLC_SUCCESS;
+}
+
+/*****************************************************************************
+ * DestroyFilter: destroy bar graph video filter
+ *****************************************************************************/
+static void DestroyFilter( vlc_object_t *p_this )
+{
+ filter_t *p_filter = (filter_t *)p_this;
+ filter_sys_t *p_sys = p_filter->p_sys;
+
+ /* Delete the bar graph variables from INPUT */
+ var_Destroy( p_filter->p_libvlc, "audiobargraph_v-x" );
+ var_Destroy( p_filter->p_libvlc, "audiobargraph_v-y" );
+ var_Destroy( p_filter->p_libvlc, "audiobargraph_v-position" );
+ var_Destroy( p_filter->p_libvlc, "audiobargraph_v-transparency" );
+ var_Destroy( p_filter->p_libvlc, "audiobargraph_v-i_values" );
+ var_Destroy( p_filter->p_libvlc, "audiobargraph_v-alarm" );
+ var_Destroy( p_filter->p_libvlc, "audiobargraph_v-barWidth" );
+
+ vlc_mutex_destroy( &p_sys->p_BarGraph->lock );
+ if( p_sys->p_BarGraph->p_pic )
+ {
+ picture_Release( p_sys->p_BarGraph->p_pic );
+ p_sys->p_BarGraph->p_pic = NULL;
+ }
+ free( p_sys->p_BarGraph->i_values );
+ free( p_sys->p_BarGraph );
+
+ free( p_sys );
+}
+
+/*****************************************************************************
+ * Filter: the whole thing
+ *****************************************************************************
+ * This function outputs subpictures at regular time intervals.
+ *****************************************************************************/
+static subpicture_t *Filter( filter_t *p_filter, mtime_t date )
+{
+ filter_sys_t *p_sys = p_filter->p_sys;
+ BarGraph_t *p_BarGraph = p_sys->p_BarGraph;
+ subpicture_t *p_spu;
+ subpicture_region_t *p_region;
+ video_format_t fmt;
+ picture_t *p_pic;
+
+ vlc_mutex_lock( &p_BarGraph->lock );
+ /* Basic test: b_need_update occurs on a dynamic change,
+ & i_next_pic is the general timer, when to
+ look at updating the logo image */
+
+ // TODO : deal with dates
+ /*if( ( ( !p_sys->b_need_update ) && ( p_logo_list->i_next_pic > date ) )
+ || !p_logo_list->i_repeat )
+ {
+ vlc_mutex_unlock( &p_logo_list->lock );
+ return 0;
+ }*/
+ /* prior code tested on && p_sys->i_last_date +5000000 > date ) return 0; */
+ if( !p_sys->b_need_update )
+ {
+ vlc_mutex_unlock( &p_BarGraph->lock );
+ return 0;
+ }
+
+ p_pic = p_BarGraph->p_pic;
+
+ /* Allocate the subpicture internal data. */
+ p_spu = filter_NewSubpicture( p_filter );
+ if( !p_spu )
+ {
+ vlc_mutex_unlock( &p_BarGraph->lock );
+ return NULL;
+ }
+
+ p_spu->b_absolute = p_sys->b_absolute;
+ p_spu->i_start = p_sys->i_last_date = date;
+ p_spu->i_stop = 0;
+ p_spu->b_ephemer = true;
+
+ p_sys->b_need_update = false;
+
+ if( !p_pic || !p_BarGraph->i_alpha )
+ {
+ /* Send an empty subpicture to clear the display */
+ vlc_mutex_unlock( &p_BarGraph->lock );
+ return p_spu;
+ }
+
+ /* Create new SPU region */
+ memset( &fmt, 0, sizeof(video_format_t) );
+ fmt.i_chroma = VLC_FOURCC('Y','U','V','A');
+ fmt.i_aspect = VOUT_ASPECT_FACTOR;
+ fmt.i_sar_num = fmt.i_sar_den = 1;
+ fmt.i_width = fmt.i_visible_width = p_pic->p[Y_PLANE].i_visible_pitch;
+ fmt.i_height = fmt.i_visible_height = p_pic->p[Y_PLANE].i_visible_lines;
+ fmt.i_x_offset = fmt.i_y_offset = 0;
+ p_region = subpicture_region_New( &fmt );
+ if( !p_region )
+ {
+ msg_Err( p_filter, "cannot allocate SPU region" );
+ p_filter->pf_sub_buffer_del( p_filter, p_spu );
+ vlc_mutex_unlock( &p_BarGraph->lock );
+ return NULL;
+ }
+
+ /* FIXME the copy is probably not needed anymore */
+ picture_Copy( p_region->p_picture, p_pic );
+ vlc_mutex_unlock( &p_BarGraph->lock );
+
+ /* where to locate the bar graph: */
+ if( p_sys->pos < 0 )
+ { /* set to an absolute xy */
+ p_region->i_align = OSD_ALIGN_RIGHT | OSD_ALIGN_TOP;
+ p_spu->b_absolute = true;
+ }
+ else
+ { /* set to one of the 9 relative locations */
+ p_region->i_align = p_sys->pos;
+ p_spu->b_absolute = false;
+ }
+
+ p_region->i_x = p_sys->posx;
+ p_region->i_y = p_sys->posy;
+
+ p_spu->p_region = p_region;
+
+ p_spu->i_alpha = p_BarGraph->i_alpha ;
+
+ return p_spu;
+}
+
+/*****************************************************************************
+ * Callback to update params on the fly
+ *****************************************************************************/
+static int BarGraphCallback( vlc_object_t *p_this, char const *psz_var,
+ vlc_value_t oldval, vlc_value_t newval, void *p_data )
+{
+ VLC_UNUSED(oldval);
+ filter_sys_t *p_sys = (filter_sys_t *)p_data;
+ BarGraph_t *p_BarGraph = p_sys->p_BarGraph;
+ char* i_values;
+ char* res = NULL;
+ char delim[] = ":";
+
+ if ( !strcmp( psz_var, "audiobargraph_v-x" ) )
+ {
+ p_sys->posx = newval.i_int;
+ }
+ else if ( !strcmp( psz_var, "audiobargraph_v-y" ) )
+ {
+ p_sys->posy = newval.i_int;
+ }
+ else if ( !strcmp( psz_var, "audiobargraph_v-position" ) )
+ {
+ p_sys->pos = newval.i_int;
+ }
+ else if ( !strcmp( psz_var, "audiobargraph_v-transparency" ) )
+ {
+ vlc_mutex_lock( &p_BarGraph->lock );
+ p_BarGraph->i_alpha = __MAX( __MIN( newval.i_int, 255 ), 0 );
+ vlc_mutex_unlock( &p_BarGraph->lock );
+ }
+ else if ( !strcmp( psz_var, "audiobargraph_v-i_values" ) )
+ {
+ vlc_mutex_lock( &p_BarGraph->lock );
+ if( p_BarGraph->p_pic )
+ {
+ picture_Release( p_BarGraph->p_pic );
+ p_BarGraph->p_pic = NULL;
+ }
+ i_values = strdup( newval.psz_string );
+ free(p_BarGraph->i_values);
+ p_BarGraph->i_values = NULL;
+ p_BarGraph->nbChannels = 0;
+ // in case many answer are received at the same time, only keep one
+ res = strchr(i_values, '@');
+ if (res)
+ *res = 0;
+ res = strtok(i_values, delim);
+ while (res != NULL) {
+ p_BarGraph->nbChannels++;
+ p_BarGraph->i_values = (int*)realloc(p_BarGraph->i_values, p_BarGraph->nbChannels*sizeof(int));
+ p_BarGraph->i_values[p_BarGraph->nbChannels-1] = __MAX( __MIN( atof(res)*p_BarGraph->scale, p_BarGraph->scale ), 0 );
+ res = strtok(NULL, delim);
+ }
+ LoadBarGraph(p_this,p_BarGraph);
+ vlc_mutex_unlock( &p_BarGraph->lock );
+ }
+ else if ( !strcmp( psz_var, "audiobargraph_v-alarm" ) )
+ {
+ vlc_mutex_lock( &p_BarGraph->lock );
+ if( p_BarGraph->p_pic )
+ {
+ picture_Release( p_BarGraph->p_pic );
+ p_BarGraph->p_pic = NULL;
+ }
+ p_BarGraph->alarm = newval.i_int;
+ LoadBarGraph(p_this,p_BarGraph);
+ vlc_mutex_unlock( &p_BarGraph->lock );
+ }
+ else if ( !strcmp( psz_var, "audiobargraph_v-barWidth" ) )
+ {
+ vlc_mutex_lock( &p_BarGraph->lock );
+ if( p_BarGraph->p_pic )
+ {
+ picture_Release( p_BarGraph->p_pic );
+ p_BarGraph->p_pic = NULL;
+ }
+ p_BarGraph->barWidth = newval.i_int;
+ LoadBarGraph(p_this,p_BarGraph);
+ vlc_mutex_unlock( &p_BarGraph->lock );
+ }
+ p_sys->b_need_update = true;
+ return VLC_SUCCESS;
+}
Return to “Development around libVLC”
Users browsing this forum: No registered users and 21 guests