~ubuntu-branches/ubuntu/maverick/vlc/maverick

« back to all changes in this revision

Viewing changes to modules/audio_filter/channel_mixer/simple.c

  • Committer: Bazaar Package Importer
  • Author(s): Reinhard Tartler
  • Date: 2008-09-17 21:56:14 UTC
  • mfrom: (1.1.17 upstream)
  • Revision ID: james.westby@ubuntu.com-20080917215614-tj0vx8xzd57e52t8
Tags: 0.9.2-1ubuntu1
* New Upstream Release, exception granted by
    - dktrkranz, norsetto, Hobbsee (via irc). LP: #270404

Changes done in ubuntu:

* add libxul-dev to build-depends
* make sure that vlc is build against libxul in configure. This doesn't
  change anything in the package, but makes it more robust if building
  in an 'unclean' chroot or when modifying the package.
* debian/control: make Vcs-* fields point to the motumedia branch
* add libx264-dev and libass-dev to build-depends
  LP: #210354, #199870
* actually enable libass support by passing --enable-libass to configure
* enable libdca: add libdca-dev to build depends and --enable-libdca
* install the x264 plugin.

Changes already in the pkg-multimedia branch in debian:

* don't install usr/share/vlc/mozilla in debian/mozilla-plugin-vlc.install  
* new upstream .desktop file now registers flash video mimetype LP: #261567
* add Xb-Npp-Applications to mozilla-plugin-vlc
* remove duplicate entries in debian/vlc-nox.install

Show diffs side-by-side

added added

removed removed

Lines of Context:
2
2
 * simple.c : simple channel mixer plug-in (only 7/7.1/5/5.1 -> Stereo for now)
3
3
 *****************************************************************************
4
4
 * Copyright (C) 2002, 2006 the VideoLAN team
5
 
 * $Id: 8cbd3d2e714c448c8dadf821de31d5d8cb8d2517 $
 
5
 * $Id$
6
6
 *
7
7
 * Authors: Gildas Bazin <gbazin@videolan.org>
8
8
 *
24
24
/*****************************************************************************
25
25
 * Preamble
26
26
 *****************************************************************************/
27
 
#include <stdlib.h>                                      /* malloc(), free() */
28
 
#include <string.h>
 
27
#ifdef HAVE_CONFIG_H
 
28
# include "config.h"
 
29
#endif
29
30
 
30
 
#include <vlc/vlc.h>
31
 
#include "audio_output.h"
32
 
#include "aout_internal.h"
 
31
#include <vlc_common.h>
 
32
#include <vlc_plugin.h>
 
33
#include <vlc_aout.h>
 
34
#include <vlc_filter.h>
 
35
#include <vlc_block.h>
33
36
 
34
37
/*****************************************************************************
35
 
 * Local prototypes
 
38
 * Module descriptor
36
39
 *****************************************************************************/
37
40
static int  Create    ( vlc_object_t * );
38
 
 
39
 
static void DoWork    ( aout_instance_t *, aout_filter_t *, aout_buffer_t *,
40
 
                        aout_buffer_t * );
41
 
 
42
 
/*****************************************************************************
43
 
 * Module descriptor
44
 
 *****************************************************************************/
 
41
static int  OpenFilter( vlc_object_t * );
 
42
 
45
43
vlc_module_begin();
46
 
    set_description( _("Audio filter for simple channel mixing") );
 
44
    set_description( N_("Audio filter for simple channel mixing") );
47
45
    set_capability( "audio filter", 10 );
48
46
    set_category( CAT_AUDIO );
49
47
    set_subcategory( SUBCAT_AUDIO_MISC );
50
48
    set_callbacks( Create, NULL );
 
49
 
 
50
    add_submodule();
 
51
    set_description( N_("audio filter for simple channel mixing") );
 
52
    set_capability( "audio filter2", 10 );
 
53
    set_callbacks( OpenFilter, NULL );
51
54
vlc_module_end();
52
55
 
53
56
/*****************************************************************************
 
57
 * Local prototypes
 
58
 *****************************************************************************/
 
59
#define AOUT_CHANS_STEREO_FRONT  ( AOUT_CHAN_LEFT | AOUT_CHAN_RIGHT )
 
60
#define AOUT_CHANS_STEREO_REAR   ( AOUT_CHAN_REARLEFT | AOUT_CHAN_REARRIGHT )
 
61
#define AOUT_CHANS_STEREO_MIDDLE (AOUT_CHAN_MIDDLELEFT | AOUT_CHAN_MIDDLERIGHT )
 
62
 
 
63
#define AOUT_CHANS_2_0 AOUT_CHANS_STEREO_FRONT
 
64
#define AOUT_CHANS_4_0 (AOUT_CHANS_STEREO_FRONT | AOUT_CHANS_STEREO_REAR )
 
65
#define AOUT_CHANS_5_0 ( AOUT_CHANS_4_0 | AOUT_CHAN_CENTER )
 
66
#define AOUT_CHANS_6_0 (AOUT_CHANS_STEREO_FRONT | AOUT_CHANS_STEREO_REAR | AOUT_CHANS_STEREO_MIDDLE )
 
67
#define AOUT_CHANS_7_0 ( AOUT_CHANS_6_0 | AOUT_CHAN_CENTER )
 
68
 
 
69
static bool IsSupported( const audio_format_t *p_input, const audio_format_t *p_output );
 
70
 
 
71
static void DoWork    ( aout_instance_t *, aout_filter_t *, aout_buffer_t *,
 
72
                        aout_buffer_t * );
 
73
 
 
74
static block_t *Filter( filter_t *, block_t * );
 
75
 
 
76
/*****************************************************************************
54
77
 * Create: allocate trivial channel mixer
55
78
 *****************************************************************************/
56
79
static int Create( vlc_object_t *p_this )
57
80
{
58
81
    aout_filter_t * p_filter = (aout_filter_t *)p_this;
59
82
 
60
 
    if ( (p_filter->input.i_physical_channels
61
 
           == p_filter->output.i_physical_channels
62
 
           && p_filter->input.i_original_channels
63
 
               == p_filter->output.i_original_channels)
64
 
          || p_filter->input.i_format != p_filter->output.i_format
65
 
          || p_filter->input.i_rate != p_filter->output.i_rate
66
 
          || p_filter->input.i_format != VLC_FOURCC('f','l','3','2') )
67
 
    {
68
 
        return -1;
69
 
    }
70
 
 
71
 
    /* Only conversion to Stereo and 4.0 right now */
72
 
    if( p_filter->output.i_physical_channels !=
73
 
        (AOUT_CHAN_LEFT | AOUT_CHAN_RIGHT) 
74
 
        && p_filter->output.i_physical_channels !=
75
 
        ( AOUT_CHAN_LEFT | AOUT_CHAN_RIGHT |
76
 
        AOUT_CHAN_REARLEFT | AOUT_CHAN_REARRIGHT) )
77
 
        {
78
 
            return -1;
79
 
        }
80
 
 
81
 
    /* Only from 7/7.1/5/5.1 */
82
 
    if( (p_filter->input.i_physical_channels & ~AOUT_CHAN_LFE) !=
83
 
        (AOUT_CHAN_LEFT | AOUT_CHAN_RIGHT | AOUT_CHAN_CENTER |
84
 
         AOUT_CHAN_REARLEFT | AOUT_CHAN_REARRIGHT) &&
85
 
        (p_filter->input.i_physical_channels & ~AOUT_CHAN_LFE) !=
86
 
        (AOUT_CHAN_LEFT | AOUT_CHAN_RIGHT | AOUT_CHAN_CENTER |
87
 
         AOUT_CHAN_MIDDLELEFT | AOUT_CHAN_MIDDLERIGHT |
88
 
         AOUT_CHAN_REARLEFT | AOUT_CHAN_REARRIGHT) )
89
 
    {
90
 
        return -1;
91
 
    }
 
83
    if( !IsSupported( &p_filter->input, &p_filter->output ) )
 
84
        return -1;
92
85
 
93
86
    p_filter->pf_do_work = DoWork;
94
87
    p_filter->b_in_place = 0;
102
95
static void DoWork( aout_instance_t * p_aout, aout_filter_t * p_filter,
103
96
                    aout_buffer_t * p_in_buf, aout_buffer_t * p_out_buf )
104
97
{
 
98
    VLC_UNUSED(p_aout);
105
99
    int i_input_nb = aout_FormatNbChannels( &p_filter->input );
106
100
    int i_output_nb = aout_FormatNbChannels( &p_filter->output );
107
101
    float *p_dest = (float *)p_out_buf->p_buffer;
108
 
    float *p_src = (float *)p_in_buf->p_buffer;
 
102
    const float *p_src = (const float *)p_in_buf->p_buffer;
109
103
    int i;
110
104
 
111
105
    p_out_buf->i_nb_samples = p_in_buf->i_nb_samples;
112
106
    p_out_buf->i_nb_bytes = p_in_buf->i_nb_bytes * i_output_nb / i_input_nb;
113
107
 
114
 
    if( p_filter->output.i_physical_channels ==
115
 
                            (AOUT_CHAN_LEFT | AOUT_CHAN_RIGHT) )
 
108
    if( p_filter->output.i_physical_channels == AOUT_CHANS_2_0 )
116
109
    {
117
110
        if( p_filter->input.i_physical_channels & AOUT_CHAN_MIDDLELEFT )
118
111
        for( i = p_in_buf->i_nb_samples; i--; )
139
132
            if( p_filter->input.i_physical_channels & AOUT_CHAN_LFE ) p_src++;
140
133
        }
141
134
    }
 
135
    else if( p_filter->output.i_physical_channels == AOUT_CHAN_CENTER )
 
136
    {
 
137
        if( p_filter->input.i_physical_channels & AOUT_CHAN_MIDDLELEFT )
 
138
        for( i = p_in_buf->i_nb_samples; i--; )
 
139
        {
 
140
            *p_dest = p_src[6] + p_src[0] / 4 + p_src[1] / 4 + p_src[2] / 8 + p_src[3] / 8 + p_src[4] / 8 + p_src[5] / 8;
 
141
            p_dest++;
 
142
 
 
143
            p_src += 7;
 
144
 
 
145
            if( p_filter->input.i_physical_channels & AOUT_CHAN_LFE ) p_src++;
 
146
        }
 
147
        else if( p_filter->input.i_physical_channels & AOUT_CHAN_REARLEFT )
 
148
        for( i = p_in_buf->i_nb_samples; i--; )
 
149
        {
 
150
            *p_dest = p_src[4] + p_src[0] / 4 + p_src[1] / 4 + p_src[2] / 6 + p_src[3] / 6;
 
151
            p_dest++;
 
152
 
 
153
            p_src += 5;
 
154
 
 
155
            if( p_filter->input.i_physical_channels & AOUT_CHAN_LFE ) p_src++;
 
156
        }
 
157
        else
 
158
        for( i = p_in_buf->i_nb_samples; i--; )
 
159
        {
 
160
            *p_dest = p_src[0] / 2 + p_src[1] / 2;
 
161
            p_dest++;
 
162
 
 
163
            p_src += 2;
 
164
        }
 
165
    }
142
166
    else
143
167
    {
144
168
        if( p_filter->input.i_physical_channels & AOUT_CHAN_MIDDLELEFT )
173
197
 
174
198
            if( p_filter->input.i_physical_channels & AOUT_CHAN_LFE ) p_src++;
175
199
        }
176
 
 
177
 
    }
178
 
}
 
200
    }
 
201
}
 
202
 
 
203
/*****************************************************************************
 
204
 * OpenFilter:
 
205
 *****************************************************************************/
 
206
static int OpenFilter( vlc_object_t *p_this )
 
207
{
 
208
    filter_t *p_filter = (filter_t *)p_this;
 
209
 
 
210
    audio_format_t fmt_in  = p_filter->fmt_in.audio;
 
211
    audio_format_t fmt_out = p_filter->fmt_out.audio;
 
212
 
 
213
    fmt_in.i_format = p_filter->fmt_in.i_codec;
 
214
    fmt_out.i_format = p_filter->fmt_out.i_codec;
 
215
 
 
216
    if( !IsSupported( &fmt_in, &fmt_out ) )
 
217
        return -1;
 
218
 
 
219
    p_filter->pf_audio_filter = Filter;
 
220
 
 
221
    return 0;
 
222
}
 
223
 
 
224
/*****************************************************************************
 
225
 * Filter:
 
226
 *****************************************************************************/
 
227
static block_t *Filter( filter_t *p_filter, block_t *p_block )
 
228
{
 
229
    aout_filter_t aout_filter;
 
230
    aout_buffer_t in_buf, out_buf;
 
231
    block_t *p_out;
 
232
    int i_out_size;
 
233
 
 
234
    if( !p_block || !p_block->i_samples )
 
235
    {
 
236
        if( p_block )
 
237
            block_Release( p_block );
 
238
        return NULL;
 
239
    }
 
240
 
 
241
    i_out_size = p_block->i_samples *
 
242
      p_filter->fmt_out.audio.i_bitspersample *
 
243
        p_filter->fmt_out.audio.i_channels / 8;
 
244
 
 
245
    p_out = p_filter->pf_audio_buffer_new( p_filter, i_out_size );
 
246
    if( !p_out )
 
247
    {
 
248
        msg_Warn( p_filter, "can't get output buffer" );
 
249
        block_Release( p_block );
 
250
        return NULL;
 
251
    }
 
252
 
 
253
    p_out->i_samples = p_block->i_samples;
 
254
    p_out->i_dts = p_block->i_dts;
 
255
    p_out->i_pts = p_block->i_pts;
 
256
    p_out->i_length = p_block->i_length;
 
257
 
 
258
    aout_filter.p_sys = (struct aout_filter_sys_t *)p_filter->p_sys;
 
259
    aout_filter.input = p_filter->fmt_in.audio;
 
260
    aout_filter.input.i_format = p_filter->fmt_in.i_codec;
 
261
    aout_filter.output = p_filter->fmt_out.audio;
 
262
    aout_filter.output.i_format = p_filter->fmt_out.i_codec;
 
263
 
 
264
    in_buf.p_buffer = p_block->p_buffer;
 
265
    in_buf.i_nb_bytes = p_block->i_buffer;
 
266
    in_buf.i_nb_samples = p_block->i_samples;
 
267
    out_buf.p_buffer = p_out->p_buffer;
 
268
    out_buf.i_nb_bytes = p_out->i_buffer;
 
269
    out_buf.i_nb_samples = p_out->i_samples;
 
270
 
 
271
    DoWork( (aout_instance_t *)p_filter, &aout_filter, &in_buf, &out_buf );
 
272
 
 
273
    block_Release( p_block );
 
274
 
 
275
    p_out->i_buffer = out_buf.i_nb_bytes;
 
276
    p_out->i_samples = out_buf.i_nb_samples;
 
277
 
 
278
    return p_out;
 
279
}
 
280
 
 
281
/*****************************************************************************
 
282
 * Helpers:
 
283
 *****************************************************************************/
 
284
static bool IsSupported( const audio_format_t *p_input, const audio_format_t *p_output )
 
285
{
 
286
    if( p_input->i_format != VLC_FOURCC('f','l','3','2') ||
 
287
          p_input->i_format != p_output->i_format ||
 
288
          p_input->i_rate != p_output->i_rate )
 
289
        return false;
 
290
 
 
291
    if( p_input->i_physical_channels == p_output->i_physical_channels &&
 
292
        p_input->i_original_channels == p_output->i_original_channels )
 
293
    {
 
294
        return false;
 
295
    }
 
296
 
 
297
    /* Only conversion to Mono, Stereo and 4.0 right now */
 
298
    if( p_output->i_physical_channels != AOUT_CHAN_CENTER &&
 
299
        p_output->i_physical_channels != AOUT_CHANS_2_0 &&
 
300
        p_output->i_physical_channels != AOUT_CHANS_4_0 )
 
301
    {
 
302
        return false;
 
303
    }
 
304
 
 
305
    /* Only from 7/7.1/5/5.1/2.0 */
 
306
    if( (p_input->i_physical_channels & ~AOUT_CHAN_LFE) != AOUT_CHANS_7_0 &&
 
307
        (p_input->i_physical_channels & ~AOUT_CHAN_LFE) != AOUT_CHANS_5_0 &&
 
308
         p_input->i_physical_channels != AOUT_CHANS_2_0 )
 
309
    {
 
310
        return false;
 
311
    }
 
312
 
 
313
    /* Only if we downmix */
 
314
    if( aout_FormatNbChannels( p_input ) <= aout_FormatNbChannels( p_output ) )
 
315
        return false;
 
316
 
 
317
    return true;
 
318
}
 
319