From 9ee820129bba764729a7ab0914a3b3e7383f5770 Mon Sep 17 00:00:00 2001 From: Thomas Guillem <thomas@gllm.fr> Date: Mon, 10 Oct 2016 16:12:17 +0200 Subject: [PATCH] move converter/mpgatofixed32 to codec/mad Remove historical MAD_BUFFER_GUARD hack in mpeg_audio.c --- extras/package/rpm/vlc.altlinux.spec | 2 +- modules/audio_filter/Makefile.am | 7 - modules/codec/Makefile.am | 6 +- .../converter/mpgatofixed32.c => codec/mad.c} | 205 ++++++++++-------- modules/codec/mpeg_audio.c | 126 +---------- po/POTFILES.in | 2 +- 6 files changed, 137 insertions(+), 211 deletions(-) rename modules/{audio_filter/converter/mpgatofixed32.c => codec/mad.c} (58%) diff --git a/extras/package/rpm/vlc.altlinux.spec b/extras/package/rpm/vlc.altlinux.spec index c66bc3d19151..f51fb331da64 100644 --- a/extras/package/rpm/vlc.altlinux.spec +++ b/extras/package/rpm/vlc.altlinux.spec @@ -1281,7 +1281,7 @@ strfile %buildroot%_gamesdatadir/fortune/vlc %buildroot%_gamesdatadir/fortune/vl %_vlc_pluginsdir/misc/libxosd_plugin.so* %files plugin-mad -%_vlc_pluginsdir/audio_filter/libmpgatofixed32_plugin.so* +%_vlc_pluginsdir/codec/libmad_plugin.so* #%_vlc_pluginsdir/demux/libid3tag_plugin.so* %files plugin-matroska diff --git a/modules/audio_filter/Makefile.am b/modules/audio_filter/Makefile.am index ef48c75250a9..a7b480e83051 100644 --- a/modules/audio_filter/Makefile.am +++ b/modules/audio_filter/Makefile.am @@ -76,13 +76,6 @@ audio_filter_LTLIBRARIES += \ libtrivial_channel_mixer_plugin.la # Converters -libmad_plugin_la_SOURCES = audio_filter/converter/mpgatofixed32.c -libmad_plugin_la_CPPFLAGS = $(AM_CPPFLAGS) $(MAD_CFLAGS) -libmad_plugin_la_LIBADD = $(AM_LIBADD) $(MAD_LIBS) -if HAVE_MAD -audio_filter_LTLIBRARIES += libmad_plugin.la -endif - libaudio_format_plugin_la_SOURCES = audio_filter/converter/format.c libaudio_format_plugin_la_CPPFLAGS = $(AM_CPPFLAGS) libaudio_format_plugin_la_LIBADD = $(LIBM) diff --git a/modules/codec/Makefile.am b/modules/codec/Makefile.am index bf7e9e14bdf1..13bb0006dd1f 100644 --- a/modules/codec/Makefile.am +++ b/modules/codec/Makefile.am @@ -66,8 +66,12 @@ codec_LTLIBRARIES += liblpcm_plugin.la libmpeg_audio_plugin_la_SOURCES = codec/mpeg_audio.c libmpeg_audio_plugin_la_CPPFLAGS = $(AM_CPPFLAGS) codec_LTLIBRARIES += libmpeg_audio_plugin.la + +libmad_plugin_la_SOURCES = codec/mad.c +libmad_plugin_la_CPPFLAGS = $(AM_CPPFLAGS) $(MAD_CFLAGS) +libmad_plugin_la_LIBADD = $(AM_LIBADD) $(MAD_LIBS) if HAVE_MAD -libmpeg_audio_plugin_la_CPPFLAGS += -DHAVE_MPGA_FILTER +audio_filter_LTLIBRARIES += libmad_plugin.la endif libmpg123_plugin_la_SOURCES = codec/mpg123.c diff --git a/modules/audio_filter/converter/mpgatofixed32.c b/modules/codec/mad.c similarity index 58% rename from modules/audio_filter/converter/mpgatofixed32.c rename to modules/codec/mad.c index 15a8ff7c99ef..7f4d1125a7eb 100644 --- a/modules/audio_filter/converter/mpgatofixed32.c +++ b/modules/codec/mad.c @@ -1,8 +1,8 @@ /***************************************************************************** - * mpgatofixed32.c: MPEG-1 & 2 audio layer I, II, III + MPEG 2.5 decoder, + * mad.c: MPEG-1 & 2 audio layer I, II, III + MPEG 2.5 decoder, * using MAD (MPEG Audio Decoder) ***************************************************************************** - * Copyright (C) 2001-2005 VLC authors and VideoLAN + * Copyright (C) 2001-2016 VLC authors and VideoLAN * $Id$ * * Authors: Christophe Massiot <massiot@via.ecp.fr> @@ -44,27 +44,29 @@ #include <vlc_common.h> #include <vlc_plugin.h> -#include <vlc_aout.h> #include <vlc_block.h> -#include <vlc_filter.h> +#include <vlc_aout.h> +#include <vlc_codec.h> + +#define MAD_BUFFER_GUARD 8 /***************************************************************************** * Local prototypes *****************************************************************************/ -static int OpenFilter ( vlc_object_t * ); -static void CloseFilter( vlc_object_t * ); -static block_t *Convert( filter_t *, block_t * ); +static int Open ( vlc_object_t * ); +static void Close( vlc_object_t * ); /***************************************************************************** * Local structures *****************************************************************************/ -struct filter_sys_t +struct decoder_sys_t { struct mad_stream mad_stream; struct mad_frame mad_frame; struct mad_synth mad_synth; int i_reject_count; + block_t *p_last_buf; }; /***************************************************************************** @@ -73,25 +75,58 @@ struct filter_sys_t vlc_module_begin () set_category( CAT_INPUT ) set_subcategory( SUBCAT_INPUT_ACODEC ) - set_description( N_("MPEG audio decoder") ) - set_capability( "audio converter", 100 ) - set_callbacks( OpenFilter, CloseFilter ) + set_description( N_("MPEG audio layer I/II/III decoder") ) + set_capability( "decoder", 100 ) + set_callbacks( Open, Close ) vlc_module_end () /***************************************************************************** - * DoWork: decode an MPEG audio frame. + * DecodeBLock: decode an MPEG audio frame. *****************************************************************************/ -static void DoWork( filter_t * p_filter, - block_t * p_in_buf, block_t * p_out_buf ) +static block_t *DecodeBlock( decoder_t *p_dec, block_t **pp_block ) { - filter_sys_t *p_sys = p_filter->p_sys; + decoder_sys_t *p_sys = p_dec->p_sys; + + if( !pp_block || !*pp_block ) + return NULL; + block_t *p_in_buf = *pp_block, *p_out_buf = NULL, *p_last_buf = NULL; + *pp_block = NULL; + + if( p_in_buf->i_buffer < MAD_BUFFER_GUARD ) + { + block_Release( p_in_buf ); + return NULL; + } + + /* Buffers passed to the mad_stream_buffer() function need to ends with the + * header (MAD_BUFFER_GUARD) of the following block. Therefore, this + * DecodeBlock() function will always return the output buffer + * corresponding to the last input buffer. */ + if( !p_sys->p_last_buf ) + { + /* Wait for the next block */ + p_sys->p_last_buf = p_in_buf; + return NULL; + } + p_last_buf = p_sys->p_last_buf; + p_sys->p_last_buf = p_in_buf; + + /* Put the header of the current buffer at the end of the last one. + * Normally, this won't do a real realloc() since VLC blocks are allocated + * with pre and post padding */ + p_last_buf = block_Realloc( p_last_buf, 0, + p_last_buf->i_buffer + MAD_BUFFER_GUARD ); + if( !p_last_buf ) + return NULL; + memcpy( &p_last_buf->p_buffer[p_last_buf->i_buffer - MAD_BUFFER_GUARD], + p_in_buf->p_buffer, MAD_BUFFER_GUARD); + mad_stream_buffer( &p_sys->mad_stream, p_last_buf->p_buffer, + p_last_buf->i_buffer ); /* Do the actual decoding now. */ - mad_stream_buffer( &p_sys->mad_stream, p_in_buf->p_buffer, - p_in_buf->i_buffer ); if ( mad_frame_decode( &p_sys->mad_frame, &p_sys->mad_stream ) == -1 ) { - msg_Err( p_filter, "libmad error: %s", + msg_Err( p_dec, "libmad error: %s", mad_stream_errorstr( &p_sys->mad_stream ) ); if( !MAD_RECOVERABLE( p_sys->mad_stream.error ) ) p_sys->i_reject_count = 3; @@ -102,13 +137,7 @@ static void DoWork( filter_t * p_filter, } if( p_sys->i_reject_count > 0 ) - { -reject: - memset( p_out_buf->p_buffer, 0, p_out_buf->i_buffer ); - p_sys->i_reject_count--; - return; - } - + goto reject; mad_synth_frame( &p_sys->mad_synth, &p_sys->mad_frame ); @@ -116,19 +145,25 @@ reject: unsigned int i_samples = p_pcm->length; mad_fixed_t const * p_left = p_pcm->samples[0]; mad_fixed_t const * p_right = p_pcm->samples[1]; + p_out_buf = decoder_NewAudioBuffer( p_dec, i_samples ); + if( !p_out_buf ) + goto end; + p_out_buf->i_dts = p_last_buf->i_dts; + p_out_buf->i_pts = p_last_buf->i_pts; + p_out_buf->i_length = p_last_buf->i_length; float *p_samples = (float *)p_out_buf->p_buffer; - if (p_pcm->channels > p_filter->fmt_out.audio.i_channels) + if (p_pcm->channels > p_dec->fmt_out.audio.i_channels) { - msg_Err( p_filter, "wrong channels count (corrupt stream?): %u > %u", - p_pcm->channels, p_filter->fmt_out.audio.i_channels); + msg_Err( p_dec, "wrong channels count (corrupt stream?): %u > %u", + p_pcm->channels, p_dec->fmt_out.audio.i_channels); p_sys->i_reject_count = 3; goto reject; } if( i_samples != p_out_buf->i_nb_samples ) { - msg_Err( p_filter, "unexpected samples count (corrupt stream?): " + msg_Err( p_dec, "unexpected samples count (corrupt stream?): " "%u / %u", i_samples, p_out_buf->i_nb_samples ); p_sys->i_reject_count = 3; goto reject; @@ -157,33 +192,50 @@ reject: *p_samples++ = (float)*p_left++ / (float)MAD_F_ONE; } } + +end: + block_Release( p_last_buf ); + return p_out_buf; +reject: + p_sys->i_reject_count--; + if( p_out_buf ) + block_Release( p_out_buf ); + goto end; } -/***************************************************************************** - * OpenFilter: - *****************************************************************************/ -static int OpenFilter( vlc_object_t *p_this ) +static void DecodeFlush( decoder_t *p_dec ) { - filter_t *p_filter = (filter_t *)p_this; - filter_sys_t *p_sys; + decoder_sys_t *p_sys = p_dec->p_sys; - if( p_filter->fmt_in.audio.i_format != VLC_CODEC_MPGA && - p_filter->fmt_in.audio.i_format != VLC_CODEC_MP3 && - p_filter->fmt_in.audio.i_format != VLC_FOURCC('m','p','g','3') ) - return VLC_EGENERIC; - - if( p_filter->fmt_out.audio.i_format != VLC_CODEC_FL32 ) - return VLC_EGENERIC; + if( p_sys->p_last_buf ) + block_Release( p_sys->p_last_buf ); + p_sys->p_last_buf = NULL; +} - if( !AOUT_FMTS_SIMILAR( &p_filter->fmt_in.audio, &p_filter->fmt_out.audio ) ) +/***************************************************************************** + * Open: + *****************************************************************************/ +static int Open( vlc_object_t *p_this ) +{ + decoder_t *p_dec = (decoder_t *)p_this; + decoder_sys_t *p_sys; + + if( ( p_dec->fmt_in.i_codec != VLC_CODEC_MPGA + && p_dec->fmt_in.i_codec != VLC_CODEC_MP3 + && p_dec->fmt_in.i_codec != VLC_FOURCC('m','p','g','3') ) + || p_dec->fmt_in.audio.i_rate == 0 + || p_dec->fmt_in.audio.i_physical_channels == 0 + || p_dec->fmt_in.audio.i_original_channels == 0 + || p_dec->fmt_in.audio.i_bytes_per_frame == 0 + || p_dec->fmt_in.audio.i_frame_length == 0 ) return VLC_EGENERIC; /* Allocate the memory needed to store the module's structure */ - p_sys = p_filter->p_sys = malloc( sizeof(filter_sys_t) ); + p_sys = p_dec->p_sys = malloc( sizeof(decoder_sys_t) ); if( p_sys == NULL ) return VLC_ENOMEM; p_sys->i_reject_count = 0; - + p_sys->p_last_buf = NULL; /* Initialize libmad */ mad_stream_init( &p_sys->mad_stream ); @@ -191,59 +243,38 @@ static int OpenFilter( vlc_object_t *p_this ) mad_synth_init( &p_sys->mad_synth ); mad_stream_options( &p_sys->mad_stream, MAD_OPTION_IGNORECRC ); - msg_Dbg( p_this, "%4.4s->%4.4s, bits per sample: %i", - (char *)&p_filter->fmt_in.audio.i_format, - (char *)&p_filter->fmt_out.audio.i_format, - p_filter->fmt_out.audio.i_bitspersample ); + p_dec->fmt_out.i_cat = AUDIO_ES; + p_dec->fmt_out.audio = p_dec->fmt_in.audio; + p_dec->fmt_out.audio.i_format = VLC_CODEC_FL32; + p_dec->fmt_out.i_codec = p_dec->fmt_out.audio.i_format; - p_filter->pf_audio_filter = Convert; + aout_FormatPrepare( &p_dec->fmt_out.audio ); + + if( decoder_UpdateAudioFormat( p_dec ) ) + { + es_format_Init( &p_dec->fmt_out, UNKNOWN_ES, 0 ); + Close( p_this ); + return VLC_EGENERIC; + } + + p_dec->pf_decode_audio = DecodeBlock; + p_dec->pf_flush = DecodeFlush; return VLC_SUCCESS; } /***************************************************************************** - * CloseFilter : deallocate data structures + * Close : deallocate data structures *****************************************************************************/ -static void CloseFilter( vlc_object_t *p_this ) +static void Close( vlc_object_t *p_this ) { - filter_t *p_filter = (filter_t *)p_this; - filter_sys_t *p_sys = p_filter->p_sys; + decoder_t *p_dec = (decoder_t *)p_this; + decoder_sys_t *p_sys = p_dec->p_sys; mad_synth_finish( &p_sys->mad_synth ); mad_frame_finish( &p_sys->mad_frame ); mad_stream_finish( &p_sys->mad_stream ); + if( p_sys->p_last_buf ) + block_Release( p_sys->p_last_buf ); free( p_sys ); } - -static block_t *Convert( filter_t *p_filter, block_t *p_block ) -{ - if( !p_block || !p_block->i_nb_samples ) - { - if( p_block ) - block_Release( p_block ); - return NULL; - } - - size_t i_out_size = p_block->i_nb_samples * - p_filter->fmt_out.audio.i_bitspersample * - p_filter->fmt_out.audio.i_channels / 8; - - block_t *p_out = block_Alloc( i_out_size ); - if( unlikely( !p_out ) ) - { - msg_Warn( p_filter, "can't get output buffer" ); - block_Release( p_block ); - return NULL; - } - - p_out->i_nb_samples = p_block->i_nb_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; - - DoWork( p_filter, p_block, p_out ); - - block_Release( p_block ); - - return p_out; -} diff --git a/modules/codec/mpeg_audio.c b/modules/codec/mpeg_audio.c index 4ef2698cb6c3..7dd3d88cec22 100644 --- a/modules/codec/mpeg_audio.c +++ b/modules/codec/mpeg_audio.c @@ -1,7 +1,7 @@ /***************************************************************************** * mpeg_audio.c: parse MPEG audio sync info and packetize the stream ***************************************************************************** - * Copyright (C) 2001-2003 VLC authors and VideoLAN + * Copyright (C) 2001-2016 VLC authors and VideoLAN * $Id$ * * Authors: Laurent Aimar <fenrir@via.ecp.fr> @@ -47,10 +47,6 @@ *****************************************************************************/ struct decoder_sys_t { -#ifdef HAVE_MPGA_FILTER - /* Module mode */ - bool b_packetizer; -#endif /* * Input properties */ @@ -73,11 +69,6 @@ struct decoder_sys_t bool b_discontinuity; }; -/* This isn't the place to put mad-specific stuff. However, it makes the - * mad plug-in's life much easier if we put 8 extra bytes at the end of the - * buffer, because that way it doesn't have to copy the block_t to a bigger - * buffer. This has no implication on other plug-ins, and we only lose 8 bytes - * per frame. --Meuuh */ #define MAD_BUFFER_GUARD 8 #define MPGA_HEADER_SIZE 4 @@ -85,9 +76,6 @@ struct decoder_sys_t * Local prototypes ****************************************************************************/ -#ifdef HAVE_MPGA_FILTER -static int OpenDecoder ( vlc_object_t * ); -#endif static int Open( vlc_object_t * ); static void Close( vlc_object_t * ); @@ -100,12 +88,6 @@ vlc_module_begin () set_description( N_("MPEG audio layer I/II/III packetizer") ) set_capability( "packetizer", 10 ) set_callbacks( Open, Close ) -#ifdef HAVE_MPGA_FILTER - add_submodule () - set_description( N_("MPEG audio layer I/II/III decoder") ) - set_capability( "decoder", 100 ) - set_callbacks( OpenDecoder, Close ) -#endif vlc_module_end () /***************************************************************************** @@ -121,53 +103,6 @@ static void Flush( decoder_t *p_dec ) p_sys->b_discontinuity = true; } -#ifdef HAVE_MPGA_FILTER -/***************************************************************************** - * GetAoutBuffer: - *****************************************************************************/ -static block_t *GetAoutBuffer( decoder_t *p_dec ) -{ - decoder_sys_t *p_sys = p_dec->p_sys; - block_t *p_buf; - - if( decoder_UpdateAudioFormat( p_dec ) ) - return NULL; - p_buf = decoder_NewAudioBuffer( p_dec, p_sys->i_frame_length ); - if( p_buf == NULL ) return NULL; - - p_buf->i_pts = date_Get( &p_sys->end_date ); - p_buf->i_length = date_Increment( &p_sys->end_date, p_sys->i_frame_length ) - - p_buf->i_pts; - if( p_sys->b_discontinuity ) - p_buf->i_flags |= BLOCK_FLAG_DISCONTINUITY; - p_sys->b_discontinuity = false; - - /* Hack for libmad filter */ - p_buf = block_Realloc( p_buf, 0, p_sys->i_frame_size + MAD_BUFFER_GUARD ); - - return p_buf; -} -#endif - -/***************************************************************************** - * GetSoutBuffer: - *****************************************************************************/ -static block_t *GetSoutBuffer( decoder_t *p_dec ) -{ - decoder_sys_t *p_sys = p_dec->p_sys; - block_t *p_block; - - p_block = block_Alloc( p_sys->i_frame_size ); - if( p_block == NULL ) return NULL; - - p_block->i_pts = p_block->i_dts = date_Get( &p_sys->end_date ); - - p_block->i_length = - date_Increment( &p_sys->end_date, p_sys->i_frame_length ) - p_block->i_pts; - - return p_block; -} - /***************************************************************************** * GetOutBuffer: *****************************************************************************/ @@ -188,8 +123,7 @@ static uint8_t *GetOutBuffer( decoder_t *p_dec, block_t **pp_out_buffer ) p_dec->fmt_out.audio.i_rate = p_sys->i_rate; p_dec->fmt_out.audio.i_channels = p_sys->i_channels; p_dec->fmt_out.audio.i_frame_length = p_sys->i_frame_length; - p_dec->fmt_out.audio.i_bytes_per_frame = - p_sys->i_max_frame_size + MAD_BUFFER_GUARD; + p_dec->fmt_out.audio.i_bytes_per_frame = p_sys->i_max_frame_size; p_dec->fmt_out.audio.i_original_channels = p_sys->i_channels_conf; p_dec->fmt_out.audio.i_physical_channels = @@ -197,21 +131,16 @@ static uint8_t *GetOutBuffer( decoder_t *p_dec, block_t **pp_out_buffer ) p_dec->fmt_out.i_bitrate = p_sys->i_bit_rate * 1000; -#ifdef HAVE_MPGA_FILTER - if( !p_sys->b_packetizer ) - { - block_t *p_aout_buffer = GetAoutBuffer( p_dec ); - p_buf = p_aout_buffer ? p_aout_buffer->p_buffer : NULL; - *pp_out_buffer = p_aout_buffer; - } - else -#endif - { - block_t *p_sout_buffer = GetSoutBuffer( p_dec ); - p_buf = p_sout_buffer ? p_sout_buffer->p_buffer : NULL; - *pp_out_buffer = p_sout_buffer; - } - return p_buf; + block_t *p_block = block_Alloc( p_sys->i_frame_size ); + if( p_block == NULL ) + return NULL; + + p_block->i_pts = p_block->i_dts = date_Get( &p_sys->end_date ); + p_block->i_length = + date_Increment( &p_sys->end_date, p_sys->i_frame_length ) - p_block->i_pts; + + *pp_out_buffer = p_block; + return p_block->p_buffer; } /***************************************************************************** @@ -623,15 +552,6 @@ static block_t *DecodeBlock( decoder_t *p_dec, block_t **pp_block ) return NULL; } -#ifdef HAVE_MPGA_FILTER - /* Get beginning of next frame for libmad */ - if( !p_sys->b_packetizer ) - { - assert( p_out_buffer->i_buffer >= (unsigned)p_sys->i_frame_size + MAD_BUFFER_GUARD ); - memcpy( p_buf + p_sys->i_frame_size, - p_header, MAD_BUFFER_GUARD ); - } -#endif p_sys->i_state = STATE_NOSYNC; /* Make sure we don't reuse the same pts twice */ @@ -685,9 +605,6 @@ static int Open( vlc_object_t *p_this ) return VLC_ENOMEM; /* Misc init */ -#ifdef HAVE_MPGA_FILTER - p_sys->b_packetizer = true; -#endif p_sys->i_state = STATE_NOSYNC; date_Set( &p_sys->end_date, 0 ); block_BytestreamInit( &p_sys->bytestream ); @@ -705,7 +622,6 @@ static int Open( vlc_object_t *p_this ) p_dec->fmt_out.audio.i_rate = 0; /* So end_date gets initialized */ /* Set callback */ - p_dec->pf_decode_audio = DecodeBlock; p_dec->pf_packetize = DecodeBlock; p_dec->pf_flush = Flush; @@ -714,21 +630,3 @@ static int Open( vlc_object_t *p_this ) return VLC_SUCCESS; } - -#ifdef HAVE_MPGA_FILTER -static int OpenDecoder( vlc_object_t *p_this ) -{ - decoder_t *p_dec = (decoder_t *)p_this; - - /* HACK: Don't use this codec if we don't have an mpga audio filter */ - if( !module_exists( "mad" ) ) - return VLC_EGENERIC; - - int i_ret = Open( p_this ); - if( i_ret != VLC_SUCCESS ) - return i_ret; - - p_dec->p_sys->b_packetizer = false; - return VLC_SUCCESS; -} -#endif diff --git a/po/POTFILES.in b/po/POTFILES.in index f4ef5040aeab..84abe20266f0 100644 --- a/po/POTFILES.in +++ b/po/POTFILES.in @@ -285,7 +285,6 @@ modules/audio_filter/channel_mixer/trivial.c modules/audio_filter/chorus_flanger.c modules/audio_filter/compressor.c modules/audio_filter/converter/format.c -modules/audio_filter/converter/mpgatofixed32.c modules/audio_filter/converter/tospdif.c modules/audio_filter/equalizer.c modules/audio_filter/equalizer_presets.h @@ -372,6 +371,7 @@ modules/codec/kate.c modules/codec/libass.c modules/codec/libmpeg2.c modules/codec/lpcm.c +modules/codec/mad.c modules/codec/mft.c modules/codec/mpeg_audio.c modules/codec/mpg123.c -- GitLab