Page 1 of 3

Audio and video module

Posted: 12 Mar 2009 17:38
by clemchen
Hi !

Don't know if I am in the right section, if not tell me ;)
For a development, I'd like to create a module that can access to both audio and video. This idea is to display some audio information on the video. Does such a module type allowing to access to wideo and audio at the same time exist ?

Thanks for any answer ;)

Re: Audio and video module

Posted: 13 Mar 2009 00:52
by Jean-Baptiste Kempf
You need more details, I think, so we can answer.

Re: Audio and video module

Posted: 13 Mar 2009 09:44
by clemchen
Thanks for the answer, I'll make it more detailled so ;)

The idea would be to display some sort of bar graph to see the audio level in the video output. When going through the exisiting modules, I studied the visualization, but the problem is that, at this level, we do have no access to the "main" video output. In some other modules, we can modify the video, but the problem is that I did not manage to gain access to the audio part...
The thing is I am not very used to VLC developments and so I wanted to know if it was possible to gain access to video and oudio at the same time, and if yes at which level.

Hope I was clear enough :) If not, please ask me some more questions

/clemchen.

Re: Audio and video module

Posted: 13 Mar 2009 10:22
by Jean-Baptiste Kempf
You want to do a video filter that would depend on the audio volume?

Re: Audio and video module

Posted: 13 Mar 2009 11:22
by clemchen
Yes, that's it ;)

Re: Audio and video module

Posted: 13 Mar 2009 11:58
by Jean-Baptiste Kempf
Include <vlc_aout.h> and use aout_VolumeGet to get the volume.

Re: Audio and video module

Posted: 13 Mar 2009 12:17
by clemchen
In fact, it's more about the audio level, like in the visualization (something like in vumeter), but i'd like to be able to interact with the video output.

Re: Audio and video module

Posted: 13 Mar 2009 13:15
by Jean-Baptiste Kempf
Yes, do a video_filter (so you can modify the video output) and use aout_VolumeGet so you have the audio level...

Re: Audio and video module

Posted: 13 Mar 2009 13:35
by clemchen
Okay, tanks for the answers ;)
I'll try and do that, I'll inform you of the outcome...

Re: Audio and video module

Posted: 16 Mar 2009 11:11
by 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...

Re: Audio and video module

Posted: 12 Jun 2009 12:52
by CrapulaX
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...
Some news about our project with ClemChen.
We succeded in our "proof of concept" using a new audio module that is sending messages through rc interface to a patched logo module.
Audio level information is contained in those messages. Once the message is received by the modified logo module, an image is drawn
showing an audio level dynamically; it looks like there is a kind of delay but that is not a big issue (at least for our need ;o) ).

We are looking at multi-channel audio and how to access those levels.

Here is a screenshot http://burnosland.com/PERSO/BXN/vlc/vlc_bargraph.jpg

Re: Audio and video module

Posted: 13 Jun 2009 00:59
by Jean-Baptiste Kempf
Great progress :D

Re: Audio and video module

Posted: 16 Jun 2009 11:54
by CrapulaX
We are now working on the multichannel support. I tried to read a TS file with DD+ (captured frlive signals on french DTT),
it looks like the DD+ (or eAC3) support is quite new for VLC, I understood that this format was handled through ffmpeg so may
be I need a more recent contribs package than the one I use today in a XP & Cygwin environment with 1.0.0 source tree.
I am using the latest available here :
http://download.videolan.org/pub/testing/win32/ compiled in march 2009,
but it might be too old ?

My issue is that the TS file is opened correctly, video is ok but I can't get any sound and curiously in the Metadata window the "stats" tab is showing
that blocks are decoded .

Following messages are available when playing M6 HD
To help you, we need messages, to completely understand what your problems is.
To fix this, please be sure before you start the playback to:
  1. Open: Tools -> Messages.
  2. Set Verbosity to 2
  3. Start playback to reproduce your issue
  4. Save text in a file or copy into clipboard
  5. Then paste the full resulting log here between [​code]and[​/code] (or use Pastebin.com if it's too long)
Also don't forget to name your Operating System and provide the VLC media player version.

Re: Audio and video module

Posted: 16 Jun 2009 13:02
by CrapulaX
I found this other thread dealing with this subject :
viewtopic.php?f=2&t=58908

Re: Audio and video module

Posted: 02 Jul 2009 14:25
by The DJ
OK, so what i would do is the following, create a visualization (audio) filter, and create an sub filter (like logo). From the visualization filter, you get your levels for the channels. Now you communicate these trough vlc variables that you create on the input object. Then from the "logo" filter you add callbacks to those variables on the input object. These callbacks set level values on your sys object of the "logo" filter, and from those values, you draw your visual representation.

In THEORY, you can do all this from one module, but you would need a aout_filter_RequestSpu() instead of a aout_filter_RequestVout(). I'm not sure how and if this is possibly at the moment.... I'll ask around.

Re: Audio and video module

Posted: 09 Oct 2009 09:27
by CrapulaX
News news !!
We just get the go! for being able to contribute back the development made around audio bargraph and silence detection.

dev has been made using 1.1.0rc4 version but I am not sure we will have time in the following weeks to "port" it to the new version.
So we are wondering how to exactly contribute in the easiest way.

Mosaic using bargraph
Image

How we use it :

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
rc interface is listening on port 1201 (--rc-host localhost:1201 )
The AudioBarGraph_A filter is sending messages on that port (--AudioBarGraph_A-port 1201)
Those messages contains information (audio level information) that will be processed by the AudioBarGraph_V filter.

Audio silence detection can be activated, in that case a red rectangle is drawn around the bargraph.
(a snmp trap is what we wanted to implement but we ran out of time)

As those filters "sit" at the end of decoding process, they should be quite transparent regarding format/transport of input signals.

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).

Re: Audio and video module

Posted: 10 Oct 2009 17:00
by Jean-Baptiste Kempf
Amazing!

Re: Audio and video module

Posted: 10 Oct 2009 21:51
by CrapulaX
Amazing!
Thx ;o)

what's the best way to contribute, a zip file containing src files & makefile sent to the dev mailling list ?

we may also provide a compiled version for some testers/integrators if necessary

Re: Audio and video module

Posted: 10 Oct 2009 22:51
by Jean-Baptiste Kempf
No, the best is to provide a patch made with diff -ruN and then send it on vlc-devel@

Re: Audio and video module

Posted: 27 Oct 2009 14:26
by rmsoto
Hello,

How I can Add this vumeters to my mosaic???

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
Does anyone have any clue. It´s more or less what I'am trying to get.

REgards,
Raúl.

Re: Audio and video module

Posted: 27 Oct 2009 15:03
by clemchen
Hi !

We are currently working on integrating the module in VLC. This should be the case quite quickly, I hope. Since then, here is the result of the diff command for the 1.0.2 version, still being worked on ...

Cordially

-------------------

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; + } + } +

Re: Audio and video module

Posted: 27 Oct 2009 15:03
by clemchen
The end of the patch...

-------------------

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; +}

Re: Audio and video module

Posted: 30 Oct 2009 12:20
by rmsoto
Thanks!!!

Re: Audio and video module

Posted: 25 Nov 2009 08:02
by Jean-Baptiste Kempf
And patch is merged for 1.1

Re: Audio and video module

Posted: 16 Dec 2009 23:45
by rmsoto
Any news about this amazing stuff???

I really want to use it in my mosaics....I have the mosaic but I cannot see the audio bars on the screen of each service :-(

Thanks a lot for your efforts!

Raúl.