Commit 2a24c87b authored by Gildas Bazin's avatar Gildas Bazin

* modules/stream_out/transcode.c:

  - Re-use our audio decoder modules instead of using libavcodec directly.
  - No more dependance on libavcodec.
  (downmixing is currently broken + you have to force the ffmpeg codec for a52)
* modules/audio_filter/format.c:
  - PCM audio format conversion filter using the new common filter architecture.
* modules/audio_filter/converter/mpgatofixed32.c:
  - implements both the old and new filter architecture (ie. useable in the transcoder).
* modules/codec/ffmpeg/audio.c:
  - fixes and cleanup.
parent 95977003
...@@ -440,7 +440,7 @@ AC_CHECK_LIB(m,cos,[ ...@@ -440,7 +440,7 @@ AC_CHECK_LIB(m,cos,[
VLC_ADD_LDFLAGS([adjust distort a52tofloat32 dtstofloat32 x264],[-lm]) VLC_ADD_LDFLAGS([adjust distort a52tofloat32 dtstofloat32 x264],[-lm])
]) ])
AC_CHECK_LIB(m,pow,[ AC_CHECK_LIB(m,pow,[
VLC_ADD_LDFLAGS([ffmpeg ffmpegaltivec stream_out_transcode stream_out_transcodealtivec stream_out_transrate i420_rgb faad toolame equalizer vlc],[-lm]) VLC_ADD_LDFLAGS([ffmpeg ffmpegaltivec stream_out_transrate i420_rgb faad toolame equalizer vlc],[-lm])
]) ])
AC_CHECK_LIB(m,sqrt,[ AC_CHECK_LIB(m,sqrt,[
VLC_ADD_LDFLAGS([headphone_channel_mixer normvol],[-lm]) VLC_ADD_LDFLAGS([headphone_channel_mixer normvol],[-lm])
...@@ -1175,7 +1175,7 @@ then ...@@ -1175,7 +1175,7 @@ then
VLC_ADD_PLUGINS([packetizer_copy]) VLC_ADD_PLUGINS([packetizer_copy])
VLC_ADD_PLUGINS([stream_out_dummy stream_out_standard stream_out_es stream_out_rtp]) VLC_ADD_PLUGINS([stream_out_dummy stream_out_standard stream_out_es stream_out_rtp])
VLC_ADD_PLUGINS([stream_out_duplicate stream_out_gather stream_out_display]) VLC_ADD_PLUGINS([stream_out_duplicate stream_out_gather stream_out_display stream_out_transcode])
# VLC_ADD_PLUGINS([stream_out_transrate]) # VLC_ADD_PLUGINS([stream_out_transrate])
dnl Ogg and vorbis are handled in their respective section dnl Ogg and vorbis are handled in their respective section
...@@ -1818,25 +1818,18 @@ then ...@@ -1818,25 +1818,18 @@ then
then then
AC_CHECK_HEADERS(ffmpeg/avcodec.h) AC_CHECK_HEADERS(ffmpeg/avcodec.h)
AC_CHECK_HEADERS(postproc/postprocess.h) AC_CHECK_HEADERS(postproc/postprocess.h)
VLC_ADD_PLUGINS([ffmpeg stream_out_transcode]) VLC_ADD_PLUGINS([ffmpeg])
VLC_ADD_CFLAGS([ffmpeg stream_out_transcode],[`${FFMPEG_CONFIG} --cflags`]) VLC_ADD_CFLAGS([ffmpeg],[`${FFMPEG_CONFIG} --cflags`])
VLC_ADD_LDFLAGS([ffmpeg],[`${FFMPEG_CONFIG} --plugin-libs avcodec avformat postproc`]) VLC_ADD_LDFLAGS([ffmpeg],[`${FFMPEG_CONFIG} --plugin-libs avcodec avformat postproc`])
VLC_ADD_LDFLAGS([stream_out_transcode],[`${FFMPEG_CONFIG} --libs avcodec`])
else else
AC_ARG_WITH(ffmpeg-mp3lame, AC_ARG_WITH(ffmpeg-mp3lame,
[ --with-ffmpeg-mp3lame if ffmpeg has been compiled with mp3lame support], [ --with-ffmpeg-mp3lame if ffmpeg has been compiled with mp3lame support],
[ [
dnl XXX: we don't link with -lavcodec a 2nd time because the OS X
dnl linker would miserably barf on multiple definitions.
VLC_ADD_LDFLAGS([stream_out_transcode],[])
VLC_ADD_LDFLAGS([ffmpeg],[-lmp3lame]) ]) VLC_ADD_LDFLAGS([ffmpeg],[-lmp3lame]) ])
AC_ARG_WITH(ffmpeg-faac, AC_ARG_WITH(ffmpeg-faac,
[ --with-ffmpeg-faac if ffmpeg has been compiled with faac support], [ --with-ffmpeg-faac if ffmpeg has been compiled with faac support],
[ [
dnl XXX: we don't link with -lavcodec a 2nd time because the OS X
dnl linker would miserably barf on multiple definitions.
VLC_ADD_LDFLAGS([stream_out_transcode],[])
VLC_ADD_LDFLAGS([ffmpeg],[-lfaac]) ]) VLC_ADD_LDFLAGS([ffmpeg],[-lfaac]) ])
AC_ARG_WITH(ffmpeg-tree, AC_ARG_WITH(ffmpeg-tree,
...@@ -1851,11 +1844,8 @@ then ...@@ -1851,11 +1844,8 @@ then
AC_CHECK_HEADERS(ffmpeg/avcodec.h, [], [AC_MSG_ERROR([Missing header file ffmpeg/avcodec.h.])] ) AC_CHECK_HEADERS(ffmpeg/avcodec.h, [], [AC_MSG_ERROR([Missing header file ffmpeg/avcodec.h.])] )
AC_CHECK_HEADERS(postproc/postprocess.h, [], [AC_MSG_ERROR([Missing header file postproc/postprocess.h.])] ) AC_CHECK_HEADERS(postproc/postprocess.h, [], [AC_MSG_ERROR([Missing header file postproc/postprocess.h.])] )
AC_CHECK_LIB(avcodec, avcodec_init, [ AC_CHECK_LIB(avcodec, avcodec_init, [
VLC_ADD_BUILTINS([ffmpeg stream_out_transcode]) VLC_ADD_BUILTINS([ffmpeg])
VLC_ADD_LDFLAGS([ffmpeg],[-lavcodec]) VLC_ADD_LDFLAGS([ffmpeg],[-lavcodec])
dnl XXX: we don't link with -lavcodec a 2nd time because the OS X
dnl linker would miserably barf on multiple definitions.
VLC_ADD_LDFLAGS([stream_out_transcode],[]) ],
[ AC_MSG_ERROR([Could not find ffmpeg on your system: you may get it from http://ffmpeg.sf.net/ (cvs version is recommended). Alternatively you can use --disable-ffmpeg to disable the ffmpeg plugins.]) ]) [ AC_MSG_ERROR([Could not find ffmpeg on your system: you may get it from http://ffmpeg.sf.net/ (cvs version is recommended). Alternatively you can use --disable-ffmpeg to disable the ffmpeg plugins.]) ])
AC_CHECK_LIB(avformat, av_open_input_stream, [ AC_CHECK_LIB(avformat, av_open_input_stream, [
AC_DEFINE(HAVE_LIBAVFORMAT, 1, AC_DEFINE(HAVE_LIBAVFORMAT, 1,
...@@ -1888,7 +1878,7 @@ then ...@@ -1888,7 +1878,7 @@ then
fi fi
dnl Use a custom libffmpeg dnl Use a custom libffmpeg
AC_MSG_RESULT(${real_ffmpeg_tree}/libavcodec/libavcodec.a) AC_MSG_RESULT(${real_ffmpeg_tree}/libavcodec/libavcodec.a)
VLC_ADD_BUILTINS([ffmpeg stream_out_transcode]) VLC_ADD_BUILTINS([ffmpeg])
VLC_ADD_LDFLAGS([ffmpeg],[-L${real_ffmpeg_tree}/libavcodec -lavcodec]) VLC_ADD_LDFLAGS([ffmpeg],[-L${real_ffmpeg_tree}/libavcodec -lavcodec])
VLC_ADD_CPPFLAGS([ffmpeg],[-I${real_ffmpeg_tree}/libavcodec -I${real_ffmpeg_tree}/libavformat]) VLC_ADD_CPPFLAGS([ffmpeg],[-I${real_ffmpeg_tree}/libavcodec -I${real_ffmpeg_tree}/libavformat])
...@@ -1897,11 +1887,6 @@ then ...@@ -1897,11 +1887,6 @@ then
VLC_ADD_LDFLAGS([ffmpeg],[-L${real_ffmpeg_tree}/libavformat -lavformat -lz]) VLC_ADD_LDFLAGS([ffmpeg],[-L${real_ffmpeg_tree}/libavformat -lavformat -lz])
VLC_ADD_CPPFLAGS([ffmpeg],[-I${real_ffmpeg_tree}/libavformat]) VLC_ADD_CPPFLAGS([ffmpeg],[-I${real_ffmpeg_tree}/libavformat])
fi fi
dnl XXX: we don't link with -lavcodec a 2nd time because the OS X
dnl linker would miserably barf on multiple definitions.
VLC_ADD_LDFLAGS([stream_out_transcode],[-L${real_ffmpeg_tree}/libavcodec])
VLC_ADD_CPPFLAGS([stream_out_transcode],[-I${real_ffmpeg_tree}/libavcodec -I${real_ffmpeg_tree}/libavformat])
fi fi
fi fi
fi fi
...@@ -1933,7 +1918,7 @@ then ...@@ -1933,7 +1918,7 @@ then
fi fi
dnl Use a custom libffmpeg dnl Use a custom libffmpeg
AC_MSG_RESULT(${real_ffmpeg_tree}/libavcodec/libavcodecaltivec.a) AC_MSG_RESULT(${real_ffmpeg_tree}/libavcodec/libavcodecaltivec.a)
VLC_ADD_BUILTINS([ffmpegaltivec stream_out_transcodealtivec]) VLC_ADD_BUILTINS([ffmpegaltivec])
VLC_ADD_LDFLAGS([ffmpegaltivec],[-L${real_ffmpeg_tree}/libavcodec -lavcodecaltivec]) VLC_ADD_LDFLAGS([ffmpegaltivec],[-L${real_ffmpeg_tree}/libavcodec -lavcodecaltivec])
VLC_ADD_CPPFLAGS([ffmpeg],[-DNO_ALTIVEC_IN_FFMPEG]) VLC_ADD_CPPFLAGS([ffmpeg],[-DNO_ALTIVEC_IN_FFMPEG])
VLC_ADD_CPPFLAGS([ffmpegaltivec],[-I${real_ffmpeg_tree}/libavcodec -I${real_ffmpeg_tree}/libavformat]) VLC_ADD_CPPFLAGS([ffmpegaltivec],[-I${real_ffmpeg_tree}/libavcodec -I${real_ffmpeg_tree}/libavformat])
...@@ -1943,12 +1928,6 @@ then ...@@ -1943,12 +1928,6 @@ then
VLC_ADD_LDFLAGS([ffmpegaltivec],[-L${real_ffmpeg_tree}/libavformat -lavformataltivec -lz]) VLC_ADD_LDFLAGS([ffmpegaltivec],[-L${real_ffmpeg_tree}/libavformat -lavformataltivec -lz])
VLC_ADD_CPPFLAGS([ffmpegaltivec],[-I${real_ffmpeg_tree}/libavformat]) VLC_ADD_CPPFLAGS([ffmpegaltivec],[-I${real_ffmpeg_tree}/libavformat])
fi fi
dnl XXX: we don't link with -lavcodec a 2nd time because the OS X
dnl linker would miserably barf on multiple definitions.
VLC_ADD_LDFLAGS([stream_out_transcodealtivec],[-L${real_ffmpeg_tree}/libavcodec])
VLC_ADD_CPPFLAGS([stream_out_transcode],[-DNO_ALTIVEC_IN_FFMPEG])
VLC_ADD_CPPFLAGS([stream_out_transcodealtivec],[-I${real_ffmpeg_tree}/libavcodec -I${real_ffmpeg_tree}/libavformat])
fi fi
fi fi
......
...@@ -2,7 +2,7 @@ ...@@ -2,7 +2,7 @@
* audio_output.h : audio output interface * audio_output.h : audio output interface
***************************************************************************** *****************************************************************************
* Copyright (C) 2002 VideoLAN * Copyright (C) 2002 VideoLAN
* $Id: audio_output.h,v 1.86 2003/11/20 22:10:55 fenrir Exp $ * $Id$
* *
* Authors: Christophe Massiot <massiot@via.ecp.fr> * Authors: Christophe Massiot <massiot@via.ecp.fr>
* *
...@@ -129,6 +129,13 @@ struct aout_buffer_t ...@@ -129,6 +129,13 @@ struct aout_buffer_t
mtime_t start_date, end_date; mtime_t start_date, end_date;
struct aout_buffer_t * p_next; struct aout_buffer_t * p_next;
/** Private data (aout_buffer_t will disappear soon so no need for an
* aout_buffer_sys_t type) */
void * p_sys;
/** This way the release can be overloaded */
void (*pf_release)( aout_buffer_t * );
}; };
/* Size of a frame for S/PDIF output. */ /* Size of a frame for S/PDIF output. */
......
...@@ -74,6 +74,7 @@ struct block_t ...@@ -74,6 +74,7 @@ struct block_t
mtime_t i_dts; mtime_t i_dts;
mtime_t i_length; mtime_t i_length;
int i_samples; /* Used for audio */
int i_rate; int i_rate;
int i_buffer; int i_buffer;
......
...@@ -74,6 +74,14 @@ struct audio_format_t ...@@ -74,6 +74,14 @@ struct audio_format_t
int i_bitspersample; int i_bitspersample;
}; };
#ifdef WORDS_BIGENDIAN
# define AUDIO_FMT_S16_NE VLC_FOURCC('s','1','6','b')
# define AUDIO_FMT_U16_NE VLC_FOURCC('u','1','6','b')
#else
# define AUDIO_FMT_S16_NE VLC_FOURCC('s','1','6','l')
# define AUDIO_FMT_U16_NE VLC_FOURCC('u','1','6','l')
#endif
/** /**
* video format description * video format description
*/ */
...@@ -202,8 +210,10 @@ static inline void es_format_Copy( es_format_t *dst, es_format_t *src ) ...@@ -202,8 +210,10 @@ static inline void es_format_Copy( es_format_t *dst, es_format_t *src )
if( src->video.p_palette ) if( src->video.p_palette )
{ {
dst->video.p_palette = (video_palette_t*)malloc( sizeof( video_palette_t ) ); dst->video.p_palette =
memcpy( dst->video.p_palette, src->video.p_palette, sizeof( video_palette_t ) ); (video_palette_t*)malloc( sizeof( video_palette_t ) );
memcpy( dst->video.p_palette, src->video.p_palette,
sizeof( video_palette_t ) );
} }
} }
......
...@@ -51,10 +51,11 @@ struct filter_t ...@@ -51,10 +51,11 @@ struct filter_t
/* Output format of filter */ /* Output format of filter */
es_format_t fmt_out; es_format_t fmt_out;
picture_t * ( * pf_video_filter ) ( filter_t *, picture_t * );
block_t * ( * pf_audio_filter ) ( filter_t *, block_t * );
void ( * pf_video_blend ) ( filter_t *, picture_t *, void ( * pf_video_blend ) ( filter_t *, picture_t *,
picture_t *, picture_t *, picture_t *, picture_t *,
int, int ); int, int );
picture_t * ( * pf_video_filter ) ( filter_t *, picture_t * );
subpicture_t * ( *pf_render_string ) ( filter_t *, block_t * ); subpicture_t * ( *pf_render_string ) ( filter_t *, block_t * );
...@@ -63,8 +64,7 @@ struct filter_t ...@@ -63,8 +64,7 @@ struct filter_t
*/ */
/* Audio output callbacks */ /* Audio output callbacks */
aout_buffer_t * ( * pf_aout_buffer_new) ( filter_t *, int ); block_t * ( * pf_audio_buffer_new) ( filter_t *, int );
void ( * pf_aout_buffer_del) ( filter_t *, aout_buffer_t * );
/* Video output callbacks */ /* Video output callbacks */
picture_t * ( * pf_vout_buffer_new) ( filter_t * ); picture_t * ( * pf_vout_buffer_new) ( filter_t * );
......
SOURCES_equalizer = equalizer.c equalizer_presets.h SOURCES_equalizer = equalizer.c equalizer_presets.h
SOURCES_normvol = normvol.c SOURCES_normvol = normvol.c
SOURCES_format = format.c
...@@ -32,8 +32,9 @@ ...@@ -32,8 +32,9 @@
#include <mad.h> #include <mad.h>
#include <vlc/vlc.h> #include <vlc/vlc.h>
#include "audio_output.h" #include <vlc/decoder.h>
#include "aout_internal.h" #include "aout_internal.h"
#include "vlc_filter.h"
/***************************************************************************** /*****************************************************************************
* Local prototypes * Local prototypes
...@@ -43,10 +44,14 @@ static void Destroy ( vlc_object_t * ); ...@@ -43,10 +44,14 @@ static void Destroy ( vlc_object_t * );
static void DoWork ( aout_instance_t *, aout_filter_t *, aout_buffer_t *, static void DoWork ( aout_instance_t *, aout_filter_t *, aout_buffer_t *,
aout_buffer_t * ); aout_buffer_t * );
static int OpenFilter ( vlc_object_t * );
static void CloseFilter( vlc_object_t * );
static block_t *Convert( filter_t *, block_t * );
/***************************************************************************** /*****************************************************************************
* Local structures * Local structures
*****************************************************************************/ *****************************************************************************/
struct aout_filter_sys_t struct filter_sys_t
{ {
struct mad_stream mad_stream; struct mad_stream mad_stream;
struct mad_frame mad_frame; struct mad_frame mad_frame;
...@@ -60,15 +65,20 @@ vlc_module_begin(); ...@@ -60,15 +65,20 @@ vlc_module_begin();
set_description( _("MPEG audio decoder") ); set_description( _("MPEG audio decoder") );
set_capability( "audio filter", 100 ); set_capability( "audio filter", 100 );
set_callbacks( Create, Destroy ); set_callbacks( Create, Destroy );
add_submodule();
set_description( _("MPEG audio decoder") );
set_capability( "audio filter2", 100 );
set_callbacks( OpenFilter, CloseFilter );
vlc_module_end(); vlc_module_end();
/***************************************************************************** /*****************************************************************************
* Create: * Create:
*****************************************************************************/ *****************************************************************************/
static int Create( vlc_object_t * _p_filter ) static int Create( vlc_object_t *p_this )
{ {
aout_filter_t * p_filter = (aout_filter_t *)_p_filter; aout_filter_t *p_filter = (aout_filter_t *)p_this;
struct aout_filter_sys_t * p_sys; struct filter_sys_t *p_sys;
if ( (p_filter->input.i_format != VLC_FOURCC('m','p','g','a') if ( (p_filter->input.i_format != VLC_FOURCC('m','p','g','a')
&& p_filter->input.i_format != VLC_FOURCC('m','p','g','3')) && p_filter->input.i_format != VLC_FOURCC('m','p','g','3'))
...@@ -84,7 +94,8 @@ static int Create( vlc_object_t * _p_filter ) ...@@ -84,7 +94,8 @@ static int Create( vlc_object_t * _p_filter )
} }
/* Allocate the memory needed to store the module's structure */ /* Allocate the memory needed to store the module's structure */
p_sys = p_filter->p_sys = malloc( sizeof(struct aout_filter_sys_t) ); p_sys = malloc( sizeof(filter_sys_t) );
p_filter->p_sys = (struct aout_filter_sys_t *)p_sys;
if( p_sys == NULL ) if( p_sys == NULL )
{ {
msg_Err( p_filter, "out of memory" ); msg_Err( p_filter, "out of memory" );
...@@ -109,7 +120,7 @@ static int Create( vlc_object_t * _p_filter ) ...@@ -109,7 +120,7 @@ static int Create( vlc_object_t * _p_filter )
static void DoWork( aout_instance_t * p_aout, aout_filter_t * p_filter, 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 ) aout_buffer_t * p_in_buf, aout_buffer_t * p_out_buf )
{ {
struct aout_filter_sys_t * p_sys = p_filter->p_sys; filter_sys_t *p_sys = (filter_sys_t *)p_filter->p_sys;
p_out_buf->i_nb_samples = p_in_buf->i_nb_samples; p_out_buf->i_nb_samples = p_in_buf->i_nb_samples;
p_out_buf->i_nb_bytes = p_in_buf->i_nb_samples * sizeof(vlc_fixed_t) * p_out_buf->i_nb_bytes = p_in_buf->i_nb_samples * sizeof(vlc_fixed_t) *
...@@ -179,7 +190,7 @@ static void DoWork( aout_instance_t * p_aout, aout_filter_t * p_filter, ...@@ -179,7 +190,7 @@ static void DoWork( aout_instance_t * p_aout, aout_filter_t * p_filter,
mad_fixed_t const * p_right = p_pcm->samples[1]; mad_fixed_t const * p_right = p_pcm->samples[1];
float f_temp = (float)FIXED32_ONE; float f_temp = (float)FIXED32_ONE;
switch ( p_pcm->channels ) switch ( p_pcm->channels )
{ {
case 2: case 2:
while ( i_samples-- ) while ( i_samples-- )
...@@ -206,10 +217,10 @@ static void DoWork( aout_instance_t * p_aout, aout_filter_t * p_filter, ...@@ -206,10 +217,10 @@ static void DoWork( aout_instance_t * p_aout, aout_filter_t * p_filter,
/***************************************************************************** /*****************************************************************************
* Destroy : deallocate data structures * Destroy : deallocate data structures
*****************************************************************************/ *****************************************************************************/
static void Destroy( vlc_object_t * _p_filter ) static void Destroy( vlc_object_t *p_this )
{ {
aout_filter_t * p_filter = (aout_filter_t *)_p_filter; aout_filter_t *p_filter = (aout_filter_t *)p_this;
struct aout_filter_sys_t * p_sys = p_filter->p_sys; filter_sys_t *p_sys = (filter_sys_t *)p_filter->p_sys;
mad_synth_finish( &p_sys->mad_synth ); mad_synth_finish( &p_sys->mad_synth );
mad_frame_finish( &p_sys->mad_frame ); mad_frame_finish( &p_sys->mad_frame );
...@@ -217,3 +228,98 @@ static void Destroy( vlc_object_t * _p_filter ) ...@@ -217,3 +228,98 @@ static void Destroy( vlc_object_t * _p_filter )
free( p_sys ); free( p_sys );
} }
/*****************************************************************************
* OpenFilter:
*****************************************************************************/
static int OpenFilter( vlc_object_t *p_this )
{
filter_t *p_filter = (filter_t *)p_this;
filter_sys_t *p_sys;
if( p_filter->fmt_in.i_codec != VLC_FOURCC('m','p','g','a') &&
p_filter->fmt_in.i_codec != VLC_FOURCC('m','p','g','3') )
{
return VLC_EGENERIC;
}
/* Allocate the memory needed to store the module's structure */
p_sys = p_filter->p_sys = malloc( sizeof(filter_sys_t) );
if( p_sys == NULL )
{
msg_Err( p_filter, "out of memory" );
return -1;
}
p_filter->pf_audio_filter = Convert;
/* Initialize libmad */
mad_stream_init( &p_sys->mad_stream );
mad_frame_init( &p_sys->mad_frame );
mad_synth_init( &p_sys->mad_synth );
mad_stream_options( &p_sys->mad_stream, MAD_OPTION_IGNORECRC );
msg_Err( p_this, "%4.4s->%4.4s, bits per sample: %i",
(char *)&p_filter->fmt_in.i_codec,
(char *)&p_filter->fmt_out.i_codec,
p_filter->fmt_out.audio.i_bitspersample );
p_filter->fmt_out.i_codec =
p_filter->fmt_out.audio.i_format = VLC_FOURCC('f','l','3','2');
p_filter->fmt_out.audio.i_bitspersample = sizeof(float);
return 0;
}
/*****************************************************************************
* CloseFilter : deallocate data structures
*****************************************************************************/
static void CloseFilter( vlc_object_t *p_this )
{
filter_t *p_filter = (filter_t *)p_this;
filter_sys_t *p_sys = p_filter->p_sys;
mad_synth_finish( &p_sys->mad_synth );
mad_frame_finish( &p_sys->mad_frame );
mad_stream_finish( &p_sys->mad_stream );
free( p_sys );
}
static block_t *Convert( filter_t *p_filter, block_t *p_block )
{
aout_filter_t aout_filter;
aout_buffer_t in_buf, out_buf;
block_t *p_out;
int i_out_size = p_block->i_samples *
p_filter->fmt_out.audio.i_bitspersample *
p_filter->fmt_out.audio.i_channels;
p_out = p_filter->pf_audio_buffer_new( p_filter, i_out_size );
if( !p_out )
{
msg_Warn( p_filter, "can't get output buffer" );
return NULL;
}
p_out->i_samples = p_block->i_samples;
p_out->i_dts = p_block->i_dts;
p_out->i_pts = p_block->i_pts;
p_out->i_length = p_block->i_length;
aout_filter.p_sys = (struct aout_filter_sys_t *)p_filter->p_sys;
aout_filter.input = p_filter->fmt_in.audio;
aout_filter.input.i_format = p_filter->fmt_in.i_codec;
aout_filter.output = p_filter->fmt_out.audio;
aout_filter.output.i_format = p_filter->fmt_out.i_codec;
in_buf.p_buffer = p_block->p_buffer;
in_buf.i_nb_bytes = p_block->i_buffer;
in_buf.i_nb_samples = p_block->i_samples;
out_buf.p_buffer = p_out->p_buffer;
out_buf.i_nb_bytes = p_out->i_buffer;
out_buf.i_nb_samples = p_out->i_samples;
DoWork( (aout_instance_t *)p_filter, &aout_filter, &in_buf, &out_buf );
return p_out;
}
/*****************************************************************************
* format.c : PCM format converter
*****************************************************************************
* Copyright (C) 2002 VideoLAN
* $Id: float32tos16.c 8391 2004-08-06 17:28:36Z sam $
*
* Authors: Christophe Massiot <massiot@via.ecp.fr>
* Gildas Bazin <gbazin@videolan.org>
*
* 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., 59 Temple Place - Suite 330, Boston, MA 02111, USA.
*****************************************************************************/
/*****************************************************************************
* Preamble
*****************************************************************************/
#include <stdlib.h> /* malloc(), free() */
#include <string.h>
#include <vlc/vlc.h>
#include <vlc/decoder.h>
#include "vlc_filter.h"
/*****************************************************************************
* Local prototypes
*****************************************************************************/
static int Open ( vlc_object_t * );
static block_t *Float32toS16( filter_t *, block_t * );
static block_t *Float32toU16( filter_t *, block_t * );
static block_t *S16toFloat32( filter_t *, block_t * );
/*****************************************************************************
* Module descriptor
*****************************************************************************/
vlc_module_begin();
set_description( _("audio filter for PCM format conversion") );
set_capability( "audio filter2", 1 );
set_callbacks( Open, NULL );
vlc_module_end();
/*****************************************************************************
* Open:
*****************************************************************************/
static int Open( vlc_object_t *p_this )
{
filter_t *p_filter = (filter_t *)p_this;
if( p_filter->fmt_in.i_codec == VLC_FOURCC('f','l','3','2') &&
p_filter->fmt_out.i_codec == AUDIO_FMT_S16_NE )
{
p_filter->pf_audio_filter = Float32toS16;
}
else if ( p_filter->fmt_in.i_codec == VLC_FOURCC('f','l','3','2') &&
p_filter->fmt_out.i_codec == AUDIO_FMT_U16_NE )
{
p_filter->pf_audio_filter = Float32toU16;
}
else if ( p_filter->fmt_in.i_codec == AUDIO_FMT_S16_NE &&
p_filter->fmt_out.i_codec == VLC_FOURCC('f','l','3','2') )
{
p_filter->pf_audio_filter = S16toFloat32;
}
else return VLC_EGENERIC;
msg_Err( p_this, "%4.4s->%4.4s, bits per sample: %i",
(char *)&p_filter->fmt_in.i_codec,
(char *)&p_filter->fmt_out.i_codec,
p_filter->fmt_in.audio.i_bitspersample );
return VLC_SUCCESS;
}
/*****************************************************************************
* Convert a buffer
*****************************************************************************/
static block_t *Float32toS16( filter_t *p_filter, block_t *p_block )
{
int i;
float *p_in = (float *)p_block->p_buffer;
int16_t *p_out = (int16_t *)p_in;
for( i = p_block->i_buffer/ p_filter->fmt_in.audio.i_bitspersample; i-- ; )
{
#if 0
/* Slow version. */
if ( *p_in >= 1.0 ) *p_out = 32767;
else if ( *p_in < -1.0 ) *p_out = -32768;
else *p_out = *p_in * 32768.0;
#else
/* This is walken's trick based on IEEE float format. */
union { float f; int32_t i; } u;
u.f = *p_in + 384.0;
if ( u.i > 0x43c07fff ) *p_out = 32767;
else if ( u.i < 0x43bf8000 ) *p_out = -32768;
else *p_out = u.i - 0x43c00000;
#endif
p_in++; p_out++;
}
p_block->i_buffer /= 2;
return p_block;
}
static block_t *Float32toU16( filter_t *p_filter, block_t *p_block )
{
int i;
float *p_in = (float *)p_block->p_buffer;
uint16_t *p_out = (uint16_t *)p_in;
for( i = p_block->i_buffer/ p_filter->fmt_in.audio.i_bitspersample; i-- ; )
{
if ( *p_in >= 1.0 ) *p_out = 65535;
else if ( *p_in < -1.0 ) *p_out = 0;
else *p_out = (uint16_t)(32768 + *p_in * 32768);
p_in++; p_out++;
}
p_block->i_buffer /= 2;
return p_block;
}
static block_t *S16toFloat32( filter_t *p_filter, block_t *p_block )
{
block_t *p_block_out;
int16_t *p_in;
float *p_out;
int i;
p_block_out =
p_filter->pf_audio_buffer_new( p_filter, p_block->i_buffer*2 );
if( !p_block_out )
{
msg_Warn( p_filter, "can't get output buffer" );
return NULL;
}
p_in = (int16_t *)(p_block->p_buffer + p_block->i_buffer) - 1;
p_out = (float *)(p_block_out->p_buffer + p_block_out->i_buffer) - 1;
for( i = p_block->i_buffer/ p_filter->fmt_in.audio.i_bitspersample; i-- ; )
{
#if 0
/* Slow version */
*p_out = (float)*p_in / 32768.0;
#else
/* This is walken's trick based on IEEE float format. On my PIII
* this takes 16 seconds to perform one billion conversions, instead
* of 19 seconds for the above division. */
union { float f; int32_t i; } u;
u.i = *p_in + 0x43c00000;
*p_out = u.f - 384.0;
#endif
p_in--; p_out--;
}
p_block_out->i_samples = p_block->i_samples;
p_block_out->i_dts = p_block->i_dts;
p_block_out->i_pts = p_block->i_pts;
p_block_out->i_length = p_block->i_length;
p_block_out->i_rate = p_block->i_rate;
return p_block_out;
}
...@@ -5,7 +5,7 @@ ...@@ -5,7 +5,7 @@
* $Id$ * $Id$
* *
* Authors: Laurent Aimar <fenrir@via.ecp.fr> * Authors: Laurent Aimar <fenrir@via.ecp.fr>
* Gildas Bazin <gbazin@netcourrier.com> * Gildas Bazin <gbazin@videolan.org>
* *
* This program is free software; you can redistribute it and/or modify * 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 * it under the terms of the GNU General Public License as published by
...@@ -134,26 +134,32 @@ int E_(InitAudioDec)( decoder_t *p_dec, AVCodecContext *p_context, ...@@ -134,26 +134,32 @@ int E_(InitAudioDec)( decoder_t *p_dec, AVCodecContext *p_context,
p_sys->p_samples = NULL; p_sys->p_samples = NULL;
p_sys->i_samples = 0; p_sys->i_samples = 0;
aout_DateSet( &p_sys->end_date, 0 ); if( p_dec->fmt_in.audio.i_rate )
{
aout_DateInit( &p_sys->end_date, p_dec->fmt_in.audio.i_rate );
aout_DateSet( &p_sys->end_date, 0 );
}
/* Set output properties */ /* Set output properties */
p_dec->fmt_out.i_cat = AUDIO_ES; p_dec->fmt_out.i_cat = AUDIO_ES;
p_dec->fmt_out.i_codec = AOUT_FMT_S16_NE; p_dec->fmt_out.i_codec = AOUT_FMT_S16_NE;
p_dec->fmt_out.audio.i_bitspersample = 2;
return VLC_SUCCESS; return VLC_SUCCESS;
} }
/* XXX Needed as aout really doesn't like big audio chunk and wma produce easily > 30000 samples... */ /*****************************************************************************
* SplitBuffer: Needed because aout really doesn't like big audio chunk and
* wma produces easily > 30000 samples...
*****************************************************************************/
aout_buffer_t *SplitBuffer( decoder_t *p_dec ) aout_buffer_t *SplitBuffer( decoder_t *p_dec )
{ {
decoder_sys_t *p_sys =