diff --git a/Makefile b/Makefile index 8b6a0f4bde..35fbb34f33 100644 --- a/Makefile +++ b/Makefile @@ -35,7 +35,7 @@ OBJS_MPLAYER = $(SRCS_MPLAYER:.c=.o) VO_LIBS = $(AA_LIB) $(X_LIB) $(SDL_LIB) $(GGI_LIB) $(MP1E_LIB) $(MLIB_LIB) $(SVGA_LIB) $(DIRECTFB_LIB) AO_LIBS = $(ARTS_LIB) $(ESD_LIB) $(NAS_LIB) $(SGIAUDIO_LIB) CODEC_LIBS = $(AV_LIB) $(FAME_LIB) $(MAD_LIB) $(VORBIS_LIB) $(THEORA_LIB) $(FAAD_LIB) $(LIBLZO_LIB) $(DECORE_LIB) $(XVID_LIB) $(PNG_LIB) $(Z_LIB) $(JPEG_LIB) $(ALSA_LIB) $(XMMS_LIB) $(MATROSKA_LIB) -COMMON_LIBS = libmpcodecs/libmpcodecs.a mp3lib/libMP3.a liba52/liba52.a libmpeg2/libmpeg2.a $(W32_LIB) $(DS_LIB) libaf/libaf.a libmpdemux/libmpdemux.a input/libinput.a postproc/libswscale.a osdep/libosdep.a $(DVDREAD_LIB) $(CODEC_LIBS) $(FREETYPE_LIB) $(TERMCAP_LIB) $(CDPARANOIA_LIB) $(MPLAYER_NETWORK_LIB) $(WIN32_LIB) $(GIF_LIB) $(MACOSX_FRAMEWORKS) $(SMBSUPPORT_LIB) $(FRIBIDI_LIB) $(FLAC_LIB) $(FONTCONFIG_LIB) +COMMON_LIBS = libmpcodecs/libmpcodecs.a mp3lib/libMP3.a liba52/liba52.a libmpeg2/libmpeg2.a $(W32_LIB) $(DS_LIB) libaf/libaf.a libmpdemux/libmpdemux.a input/libinput.a postproc/libswscale.a osdep/libosdep.a $(DVDREAD_LIB) $(CODEC_LIBS) $(FREETYPE_LIB) $(TERMCAP_LIB) $(CDPARANOIA_LIB) $(MPLAYER_NETWORK_LIB) $(WIN32_LIB) $(GIF_LIB) $(MACOSX_FRAMEWORKS) $(SMBSUPPORT_LIB) $(FRIBIDI_LIB) $(FONTCONFIG_LIB) CFLAGS = $(OPTFLAGS) -Ilibmpdemux -Iloader -Ilibvo $(FREETYPE_INC) $(EXTRA_INC) $(CDPARANOIA_INC) $(SDL_INC) $(X11_INC) $(FRIBIDI_INC) $(DVB_INC) $(XVID_INC) $(FONTCONFIG_INC) # -Wall @@ -66,9 +66,6 @@ endif ifeq ($(LIBMENU),yes) PARTS += libmenu endif -ifneq ($(MPFLAC),none) -PARTS += libmpflac -endif ALL_PRG = $(PRG) ifeq ($(MENCODER),yes) @@ -104,10 +101,6 @@ COMMON_DEPS += Gui/libgui.a GUI_LIBS = Gui/libgui.a endif -ifneq ($(MPFLAC),none) -COMMON_DEPS += libmpflac/libmpflac.a -endif - .SUFFIXES: .cc .c .o # .PHONY: $(COMMON_DEPS) @@ -189,9 +182,6 @@ libmenu/libmenu.a: libavcodec/libpostproc/libpostproc.so: $(MAKE) -C libavcodec/libpostproc -libmpflac/libmpflac.a: - $(MAKE) -C libmpflac - MPLAYER_DEP = $(OBJS_MPLAYER) $(COMMON_DEPS) ifeq ($(LIBMENU),yes) diff --git a/configure b/configure index cde3e15519..50173a0a97 100755 --- a/configure +++ b/configure @@ -210,8 +210,6 @@ Codecs: --disable-libdv disable libdv 0.9.5 en/decoding support [autodetect] --disable-mad disable libmad (MPEG audio) support [autodetect] --enable-xmms build with XMMS inputplugin support [disabled] - --enable-flac build with FLAC support [autodetect] - --enable-external-flac build with external libFLAC [disable] Video output: --disable-vidix disable VIDIX [enable on x86 *nix] @@ -1158,8 +1156,6 @@ _tremor=no _faad_internal=auto _faad_external=auto _xmms=no -_flac=auto -_external_flac=auto # dvdnav disabled, it does not work #_dvdnav=no _dvdread=auto @@ -1329,10 +1325,6 @@ for ac_option do --disable-external-faad) _faad_external=no ;; --enable-xmms) _xmms=yes ;; --disable-xmms) _xmms=no ;; - --enable-flac) _flac=yes ;; - --disable-flac) _flac=no ;; - --enable-external-flac) _external_flac=yes ;; - --disable-external-flac) _external_flac=no ;; --enable-dvdread) _dvdread=yes ;; --disable-dvdread) _dvdread=no ;; --enable-mpdvdkit) _dvdkit=yes ;; @@ -5465,63 +5457,6 @@ else fi echores "$_xmms" -echocheck "FLAC support" -if ! test "$_flac" = "no" ; then - if ! test -f libmpflac/dither.c ; then - _flac=no - echores "no (necessary files missing)" - break - fi - if ! test -f libmpflac/stream_decoder.c ; then - _external_flac=yes - fi - if test "$_external_flac" = "yes" ; then - cat > $TMPC << EOF -#include -#include - -int main() -{ - FLAC__StreamDecoder *fdec = FLAC__stream_decoder_new(); - return fdec != NULL; -} -EOF - _flac=no - if cc_check -lFLAC -lm ; then - _flac=external - fi - else - _flac=yes - fi -fi - -if test "$_flac" = external ; then - _def_flac='#define HAVE_FLAC 1' - #Still use dither.c & replay_gain from libmpflac - _def_mpflac='#undef USE_MPFLAC_DECODER' - _mpflac='process' - _ld_flac='-lFLAC -lm -Llibmpflac -lmpflac' - _codecmodules="flac(external) $_codecmodules" - echores "yes (using external libFLAC)" -else - if test "$_flac" = yes ; then - _def_flac='#define HAVE_FLAC 1' - #use decoder, dither.c & replay_gain from libmpflac - _def_mpflac='#define USE_MPFLAC_DECODER 1' - _mpflac='full' - _ld_flac='-Llibmpflac -lmpflac' - _codecmodules="flac(internal) $_codecmodules" - echores "yes (using internal libmpflac)" - else - _def_flac='#undef HAVE_FLAC' - _def_mpflac='#undef USE_MPFLAC_DECODER' - _mpflac='none' - _ld_flac='' - _nocodecmodules="flac $_nocodecmodules" - echores "no" - fi -fi - echocheck "inet6" if test "$_inet6" = auto ; then cat > $TMPC << EOF @@ -5984,8 +5919,6 @@ XMMS_PLUGINS = $_xmms XMMS_LIB = $_xmms_lib MACOSX = $_macosx MACOSX_FRAMEWORKS = $_macosx_frameworks -FLAC_LIB = $_ld_flac -MPFLAC = $_mpflac # --- Some stuff for autoconfigure ---- $_target_arch @@ -6231,12 +6164,6 @@ $_def_lirc */ $_def_lircc -/* - * FLAC decoding - */ -$_def_flac -$_def_mpflac - /* DVD navigation support using libdvdnav */ $_def_dvdnav $_def_dvdnav_version @@ -6282,11 +6209,6 @@ $_def_libavcodecso #define USE_LIBA52 #define USE_LIBMPEG2 -/* Use the SVQ1 decoder in libmpcodecs - we don't want/need it with libavcodec */ -#ifndef USE_LIBAVCODEC -#define USE_SVQ1 -#endif - /* Use libfame encoder filter */ $_def_fame diff --git a/libmpcodecs/Makefile b/libmpcodecs/Makefile index 748dcbfc52..f95fcf9178 100644 --- a/libmpcodecs/Makefile +++ b/libmpcodecs/Makefile @@ -6,7 +6,7 @@ LIBNAME2 = libmpencoders.a AUDIO_SRCS_LIB=ad_liba52.c ad_hwac3.c ad_mp3lib.c AUDIO_SRCS_NAT=ad_alaw.c ad_dk3adpcm.c ad_pcm.c ad_dvdpcm.c ad_imaadpcm.c ad_msadpcm.c ad_msgsm.c ad_roqaudio.c ad_ra1428.c -AUDIO_SRCS_OPT=ad_acm.c ad_dshow.c ad_dmo.c ad_qtaudio.c ad_ffmpeg.c ad_faad.c ad_libvorbis.c ad_libmad.c ad_realaud.c ad_libdv.c ad_flac.c +AUDIO_SRCS_OPT=ad_acm.c ad_dshow.c ad_dmo.c ad_qtaudio.c ad_ffmpeg.c ad_faad.c ad_libvorbis.c ad_libmad.c ad_realaud.c ad_libdv.c AUDIO_SRCS=dec_audio.c ad.c $(AUDIO_SRCS_LIB) $(AUDIO_SRCS_NAT) $(AUDIO_SRCS_OPT) VIDEO_SRCS_LIB=vd_libmpeg2.c vd_nuv.c vd_lzo.c @@ -46,9 +46,6 @@ SRCS2=$(ENCODER_SRCS) OBJS2=$(SRCS2:.c=.o) CFLAGS = $(OPTFLAGS) -I. -Inative -I.. -I../libmpdemux -I../loader $(EXTRA_INC) -D_GNU_SOURCE -ifneq ($(MPFLAC),none) -CFLAGS += -I../libmpflac -endif .SUFFIXES: .c .o diff --git a/libmpcodecs/ad.c b/libmpcodecs/ad.c index 44d5bae383..e813078fa1 100644 --- a/libmpcodecs/ad.c +++ b/libmpcodecs/ad.c @@ -39,7 +39,6 @@ extern ad_functions_t mpcodecs_ad_realaud; extern ad_functions_t mpcodecs_ad_libdv; extern ad_functions_t mpcodecs_ad_qtaudio; extern ad_functions_t mpcodecs_ad_ra1428; -extern ad_functions_t mpcodecs_ad_flac; ad_functions_t* mpcodecs_ad_drivers[] = { @@ -88,8 +87,5 @@ ad_functions_t* mpcodecs_ad_drivers[] = &mpcodecs_ad_libdv, #endif &mpcodecs_ad_ra1428, -#ifdef HAVE_FLAC - &mpcodecs_ad_flac, -#endif NULL }; diff --git a/libmpcodecs/ad_flac.c b/libmpcodecs/ad_flac.c deleted file mode 100644 index 811709e6ac..0000000000 --- a/libmpcodecs/ad_flac.c +++ /dev/null @@ -1,535 +0,0 @@ -/* - * This is FLAC decoder for MPlayer using stream_decoder from libFLAC - * (directly or from libmpflac). - * This file is part of MPlayer, see http://mplayerhq.hu/ for info. - * Copyright (C) 2003 Dmitry Baryshkov - * - * 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-1307 USA - * - * parse_double_, grabbag__replaygain_load_from_vorbiscomment, grabbag__replaygain_compute_scale_factor - * functions are imported from FLAC project (from grabbag lib sources (replaygain.c)) and are - * Copyright (C) 2002,2003 Josh Coalson under the terms of GPL. - */ - -/* - * TODO: - * in demux_audio use data from seektable block for seeking. - * support FLAC-in-Ogg. - */ - -#include -#include -#include -#include - -#include "config.h" -#ifdef HAVE_FLAC -#include "ad_internal.h" -#include "mp_msg.h" - -static ad_info_t info = { - "FLAC audio decoder", // name of the driver - "flac", // driver name. should be the same as filename without ad_ - "Dmitry Baryshkov", // writer/maintainer of _this_ file - "http://flac.sf.net/", // writer/maintainer/site of the _codec_ - "" // comments -}; - -LIBAD_EXTERN(flac) - -#ifdef USE_MPFLAC_DECODER -#include "FLAC_stream_decoder.h" -#include "FLAC_assert.h" -#include "FLAC_metadata.h" -#else -#include "FLAC/stream_decoder.h" -#include "FLAC/assert.h" -#include "FLAC/metadata.h" -#endif - -/* dithering & replaygain always from libmpflac */ -#include "dither.h" -#include "replaygain_synthesis.h" - -/* Some global constants. Thay have to be configurable, so leaved them as globals. */ -static const FLAC__bool album_mode = true; -static const int preamp = 0; -static const FLAC__bool hard_limit = false; -static const int noise_shaping = 1; -static const FLAC__bool dither = true; -typedef struct flac_struct_st -{ - FLAC__StreamDecoder *flac_dec; /*decoder handle*/ - sh_audio_t *sh; /* link back to corresponding sh */ - - /* set this fields before calling FLAC__stream_decoder_process_single */ - unsigned char *buf; - int minlen; - int maxlen; - /* Here goes number written at write_callback */ - int written; - - /* replaygain and dithering via plugin_common */ - FLAC__bool has_replaygain; - double replay_scale; - DitherContext dither_context; - int bits_per_sample; -} flac_struct_t; - -FLAC__StreamDecoderReadStatus flac_read_callback (const FLAC__StreamDecoder *decoder, FLAC__byte buffer[], unsigned *bytes, void *client_data) -{ - /* Don't be greedy. Try to read as few packets as possible. *bytes is often - > 60kb big which is more than one second of data. Reading it all at - once sucks in all packets available making d_audio->pts jump to the - pts of the last packet read which is not what we want. We're decoging - only one FLAC block anyway, so let's just read as few bytes as - neccessary. */ - int b = demux_read_data(((flac_struct_t*)client_data)->sh->ds, buffer, *bytes > 500 ? 500 : *bytes); - mp_msg(MSGT_DECAUDIO, MSGL_DBG2, "\nFLAC READ CB read %d bytes\n", b); - *bytes = b; - if (b <= 0) - return FLAC__STREAM_DECODER_READ_STATUS_END_OF_STREAM; - return FLAC__STREAM_DECODER_READ_STATUS_CONTINUE; -} - -/*FIXME: we need to support format conversion:(flac specs allow bits/sample to be from 4 to 32. Not only 8 and 16 !!!)*/ -FLAC__StreamDecoderWriteStatus flac_write_callback(const FLAC__StreamDecoder *decoder, const FLAC__Frame *frame, const FLAC__int32 * const buffer[], void *client_data) -{ - FLAC__byte *buf = ((flac_struct_t*)(client_data))->buf; - int bps = ((flac_struct_t*)(client_data))->sh->samplesize; - int lowendian = (((flac_struct_t*)(client_data))->sh->sample_format == AFMT_S16_LE); - int unsigned_data = (((flac_struct_t*)(client_data))->sh->sample_format == AFMT_U8); - mp_msg(MSGT_DECAUDIO, MSGL_DBG2, "\nWrite callback (%d bytes)!!!!\n", bps*frame->header.blocksize*frame->header.channels); - if (buf == NULL) - { - /* This is used in control for skipping 1 audio frame */ - return FLAC__STREAM_DECODER_WRITE_STATUS_CONTINUE; - } - FLAC__replaygain_synthesis__apply_gain( - buf, - lowendian, - unsigned_data, - buffer, - frame->header.blocksize, - frame->header.channels, - ((flac_struct_t*)(client_data))->bits_per_sample, - ((flac_struct_t*)(client_data))->sh->samplesize * 8, - ((flac_struct_t*)(client_data))->replay_scale, - hard_limit, - dither, - &(((flac_struct_t*)(client_data))->dither_context) - ); - ((flac_struct_t*)(client_data))->written += bps*frame->header.blocksize*frame->header.channels; - return FLAC__STREAM_DECODER_WRITE_STATUS_CONTINUE; -} - -#ifdef local_min -#undef local_min -#endif -#define local_min(a,b) ((a)<(b)?(a):(b)) - -static FLAC__bool parse_double_(const FLAC__StreamMetadata_VorbisComment_Entry *entry, double *val) -{ - char s[32], *end; - const char *p, *q; - double v; - - FLAC__ASSERT(0 != entry); - FLAC__ASSERT(0 != val); - - p = (const char *)entry->entry; - q = strchr(p, '='); - if(0 == q) - return false; - q++; - memset(s, 0, sizeof(s)-1); - strncpy(s, q, local_min(sizeof(s)-1, entry->length - (q-p))); - - v = strtod(s, &end); - if(end == s) - return false; - - *val = v; - return true; -} - -FLAC__bool grabbag__replaygain_load_from_vorbiscomment(const FLAC__StreamMetadata *block, FLAC__bool album_mode, double *gain, double *peak) -{ - int gain_offset, peak_offset; -static const FLAC__byte *tag_title_gain_ = "REPLAYGAIN_TRACK_GAIN"; -static const FLAC__byte *tag_title_peak_ = "REPLAYGAIN_TRACK_PEAK"; -static const FLAC__byte *tag_album_gain_ = "REPLAYGAIN_ALBUM_GAIN"; -static const FLAC__byte *tag_album_peak_ = "REPLAYGAIN_ALBUM_PEAK"; - - FLAC__ASSERT(0 != block); - FLAC__ASSERT(block->type == FLAC__METADATA_TYPE_VORBIS_COMMENT); - - if(0 > (gain_offset = FLAC__metadata_object_vorbiscomment_find_entry_from(block, /*offset=*/0, (const char *)(album_mode? tag_album_gain_ : tag_title_gain_)))) - return false; - if(0 > (peak_offset = FLAC__metadata_object_vorbiscomment_find_entry_from(block, /*offset=*/0, (const char *)(album_mode? tag_album_peak_ : tag_title_peak_)))) - return false; - - if(!parse_double_(block->data.vorbis_comment.comments + gain_offset, gain)) - return false; - if(!parse_double_(block->data.vorbis_comment.comments + peak_offset, peak)) - return false; - - return true; -} - -double grabbag__replaygain_compute_scale_factor(double peak, double gain, double preamp, FLAC__bool prevent_clipping) -{ - double scale; - FLAC__ASSERT(peak >= 0.0); - gain += preamp; - scale = (float) pow(10.0, gain * 0.05); - if(prevent_clipping && peak > 0.0) { - const double max_scale = (float)(1.0 / peak); - if(scale > max_scale) - scale = max_scale; - } - return scale; -} - -void flac_metadata_callback (const FLAC__StreamDecoder *decoder, const FLAC__StreamMetadata *metadata, void *client_data) -{ - int i, j; - sh_audio_t *sh = ((flac_struct_t*)client_data)->sh; - mp_msg(MSGT_DECAUDIO, MSGL_DBG2, "Metadata received\n"); - switch (metadata->type) - { - case FLAC__METADATA_TYPE_STREAMINFO: - mp_msg(MSGT_DECAUDIO, MSGL_V, "STREAMINFO block (%u bytes):\n", metadata->length); - mp_msg(MSGT_DECAUDIO, MSGL_V, "min_blocksize: %u samples\n", metadata->data.stream_info.min_blocksize); - mp_msg(MSGT_DECAUDIO, MSGL_V, "max_blocksize: %u samples\n", metadata->data.stream_info.max_blocksize); - mp_msg(MSGT_DECAUDIO, MSGL_V, "min_framesize: %u bytes\n", metadata->data.stream_info.min_framesize); - mp_msg(MSGT_DECAUDIO, MSGL_V, "max_framesize: %u bytes\n", metadata->data.stream_info.max_framesize); - mp_msg(MSGT_DECAUDIO, MSGL_V, "sample_rate: %u Hz\n", metadata->data.stream_info.sample_rate); - sh->samplerate = metadata->data.stream_info.sample_rate; - mp_msg(MSGT_DECAUDIO, MSGL_V, "channels: %u\n", metadata->data.stream_info.channels); - sh->channels = metadata->data.stream_info.channels; - mp_msg(MSGT_DECAUDIO, MSGL_V, "bits_per_sample: %u\n", metadata->data.stream_info.bits_per_sample); - ((flac_struct_t*)client_data)->bits_per_sample = metadata->data.stream_info.bits_per_sample; - sh->samplesize = (metadata->data.stream_info.bits_per_sample<=8)?1:2; - /* FIXME: need to support dithering to samplesize 4 */ - sh->sample_format=(sh->samplesize==1)?AFMT_U8: -#ifdef WORDS_BIGENDIAN - AFMT_S16_BE; -#else - AFMT_S16_LE; -#endif - sh->o_bps = sh->samplesize * metadata->data.stream_info.channels * metadata->data.stream_info.sample_rate; - sh->i_bps = metadata->data.stream_info.bits_per_sample * metadata->data.stream_info.channels * metadata->data.stream_info.sample_rate / 8 / 2; - // input data rate (compressed bytes per second) - // Compression rate is near 0.5 - mp_msg(MSGT_DECAUDIO, MSGL_V, "total_samples: %llu\n", metadata->data.stream_info.total_samples); - mp_msg(MSGT_DECAUDIO, MSGL_V, "md5sum: "); - for (i = 0; i < 16; i++) - mp_msg(MSGT_DECAUDIO, MSGL_V, "%02hhx", metadata->data.stream_info.md5sum[i]); - mp_msg(MSGT_DECAUDIO, MSGL_V, "\n"); - - break; - case FLAC__METADATA_TYPE_PADDING: - mp_msg(MSGT_DECAUDIO, MSGL_V, "PADDING block (%u bytes)\n", metadata->length); - break; - case FLAC__METADATA_TYPE_APPLICATION: - mp_msg(MSGT_DECAUDIO, MSGL_V, "APPLICATION block (%u bytes):\n", metadata->length); - mp_msg(MSGT_DECAUDIO, MSGL_V, "Application id: 0x"); - for (i = 0; i < 4; i++) - mp_msg(MSGT_DECAUDIO, MSGL_V, "%02hhx", metadata->data.application.id[i]); - mp_msg(MSGT_DECAUDIO, MSGL_V, "\nData: \n"); - for (i = 0; i < (metadata->length-4)/8; i++) - { - for(j = 0; j < 8; j++) - mp_msg(MSGT_DECAUDIO, MSGL_V, "%c", (unsigned char)metadata->data.application.data[i*8+j]<0x20?'.':metadata->data.application.data[i*8+j]); - mp_msg(MSGT_DECAUDIO, MSGL_V, " | "); - for(j = 0; j < 8; j++) - mp_msg(MSGT_DECAUDIO, MSGL_V, "%#02hhx ", metadata->data.application.data[i*8+j]); - mp_msg(MSGT_DECAUDIO, MSGL_V, "\n"); - } - if (metadata->length-4-i*8 != 0) - { - for(j = 0; j < metadata->length-4-i*8; j++) - mp_msg(MSGT_DECAUDIO, MSGL_V, "%c", (unsigned char)metadata->data.application.data[i*8+j]<0x20?'.':metadata->data.application.data[i*8+j]); - for(; j <8; j++) - mp_msg(MSGT_DECAUDIO, MSGL_V, " "); - mp_msg(MSGT_DECAUDIO, MSGL_V, " | "); - for(j = 0; j < metadata->length-4-i*8; j++) - mp_msg(MSGT_DECAUDIO, MSGL_V, "%#02hhx ", metadata->data.application.data[i*8+j]); - mp_msg(MSGT_DECAUDIO, MSGL_V, "\n"); - } - break; - case FLAC__METADATA_TYPE_SEEKTABLE: - mp_msg(MSGT_DECAUDIO, MSGL_V, "SEEKTABLE block (%u bytes):\n", metadata->length); - mp_msg(MSGT_DECAUDIO, MSGL_V, "%d seekpoints:\n", metadata->data.seek_table.num_points); - for (i = 0; i < metadata->data.seek_table.num_points; i++) - if (metadata->data.seek_table.points[i].sample_number != FLAC__STREAM_METADATA_SEEKPOINT_PLACEHOLDER) - mp_msg(MSGT_DECAUDIO, MSGL_V, " %3d) sample_number=%llu stream_offset=%llu frame_samples=%u\n", i, - metadata->data.seek_table.points[i].sample_number, - metadata->data.seek_table.points[i].stream_offset, - metadata->data.seek_table.points[i].frame_samples); - else - mp_msg(MSGT_DECAUDIO, MSGL_V, " %3d) PLACEHOLDER\n", i); - break; - case FLAC__METADATA_TYPE_VORBIS_COMMENT: - mp_msg(MSGT_DECAUDIO, MSGL_V, "VORBISCOMMENT block (%u bytes):\n", metadata->length); - { - char entry[metadata->data.vorbis_comment.vendor_string.length+1]; - memcpy(&entry, metadata->data.vorbis_comment.vendor_string.entry, metadata->data.vorbis_comment.vendor_string.length); - entry[metadata->data.vorbis_comment.vendor_string.length] = '\0'; - mp_msg(MSGT_DECAUDIO, MSGL_V, "vendor_string: %s\n", entry); - } - mp_msg(MSGT_DECAUDIO, MSGL_V, "%d comment(s):\n", metadata->data.vorbis_comment.num_comments); - for (i = 0; i < metadata->data.vorbis_comment.num_comments; i++) - { - char entry[metadata->data.vorbis_comment.comments[i].length]; - memcpy(&entry, metadata->data.vorbis_comment.comments[i].entry, metadata->data.vorbis_comment.comments[i].length); - entry[metadata->data.vorbis_comment.comments[i].length] = '\0'; - mp_msg(MSGT_DECAUDIO, MSGL_V, "%s\n", entry); - } - { - double gain, peak; - if(grabbag__replaygain_load_from_vorbiscomment(metadata, album_mode, &gain, &peak)) - { - ((flac_struct_t*)client_data)->has_replaygain = true; - ((flac_struct_t*)client_data)->replay_scale = grabbag__replaygain_compute_scale_factor(peak, gain, (double)preamp, /*prevent_clipping=*/!hard_limit); - mp_msg(MSGT_DECAUDIO, MSGL_V, "calculated replay_scale: %lf\n", ((flac_struct_t*)client_data)->replay_scale); - } - } - break; - case FLAC__METADATA_TYPE_CUESHEET: - mp_msg(MSGT_DECAUDIO, MSGL_V, "CUESHEET block (%u bytes):\n", metadata->length); - mp_msg(MSGT_DECAUDIO, MSGL_V, "mcn: '%s'\n", metadata->data.cue_sheet.media_catalog_number); - mp_msg(MSGT_DECAUDIO, MSGL_V, "lead_in: %llu\n", metadata->data.cue_sheet.lead_in); - mp_msg(MSGT_DECAUDIO, MSGL_V, "is_cd: %s\n", metadata->data.cue_sheet.is_cd?"true":"false"); - mp_msg(MSGT_DECAUDIO, MSGL_V, "num_tracks: %u\n", metadata->data.cue_sheet.num_tracks); - for (i = 0; i < metadata->data.cue_sheet.num_tracks; i++) - { - mp_msg(MSGT_DECAUDIO, MSGL_V, "track[%d]:\n", i); - mp_msg(MSGT_DECAUDIO, MSGL_V, "offset: %llu\n", metadata->data.cue_sheet.tracks[i].offset); - mp_msg(MSGT_DECAUDIO, MSGL_V, "number: %hhu%s\n", metadata->data.cue_sheet.tracks[i].number, metadata->data.cue_sheet.tracks[i].number==170?"(LEAD-OUT)":""); - mp_msg(MSGT_DECAUDIO, MSGL_V, "isrc: '%s'\n", metadata->data.cue_sheet.tracks[i].isrc); - mp_msg(MSGT_DECAUDIO, MSGL_V, "type: %s\n", metadata->data.cue_sheet.tracks[i].type?"non-audio":"audio"); - mp_msg(MSGT_DECAUDIO, MSGL_V, "pre_emphasis: %s\n", metadata->data.cue_sheet.tracks[i].pre_emphasis?"true":"false"); - mp_msg(MSGT_DECAUDIO, MSGL_V, "num_indices: %hhu\n", metadata->data.cue_sheet.tracks[i].num_indices); - for (j = 0; j < metadata->data.cue_sheet.tracks[i].num_indices; j++) - { - mp_msg(MSGT_DECAUDIO, MSGL_V, "index[%d]:\n", j); - mp_msg(MSGT_DECAUDIO, MSGL_V, "offset:%llu\n", metadata->data.cue_sheet.tracks[i].indices[j].offset); - mp_msg(MSGT_DECAUDIO, MSGL_V, "number:%hhu\n", metadata->data.cue_sheet.tracks[i].indices[j].number); - } - } - break; - default: if (metadata->type >= FLAC__METADATA_TYPE_UNDEFINED) - mp_msg(MSGT_DECAUDIO, MSGL_V, "UNKNOWN block (%u bytes):\n", metadata->length); - else - mp_msg(MSGT_DECAUDIO, MSGL_V, "Strange block: UNKNOWN #%d < FLAC__METADATA_TYPE_UNDEFINED (%u bytes):\n", metadata->type, metadata->length); - for (i = 0; i < (metadata->length)/8; i++) - { - for(j = 0; j < 8; j++) - mp_msg(MSGT_DECAUDIO, MSGL_V, "%c", (unsigned char)metadata->data.unknown.data[i*8+j]<0x20?'.':metadata->data.unknown.data[i*8+j]); - mp_msg(MSGT_DECAUDIO, MSGL_V, " | "); - for(j = 0; j < 8; j++) - mp_msg(MSGT_DECAUDIO, MSGL_V, "%#02hhx ", metadata->data.unknown.data[i*8+j]); - mp_msg(MSGT_DECAUDIO, MSGL_V, "\n"); - } - if (metadata->length-i*8 != 0) - { - for(j = 0; j < metadata->length-i*8; j++) - mp_msg(MSGT_DECAUDIO, MSGL_V, "%c", (unsigned char)metadata->data.unknown.data[i*8+j]<0x20?'.':metadata->data.unknown.data[i*8+j]); - for(; j <8; j++) - mp_msg(MSGT_DECAUDIO, MSGL_V, " "); - mp_msg(MSGT_DECAUDIO, MSGL_V, " | "); - for(j = 0; j < metadata->length-i*8; j++) - mp_msg(MSGT_DECAUDIO, MSGL_V, "%#02hhx ", metadata->data.unknown.data[i*8+j]); - mp_msg(MSGT_DECAUDIO, MSGL_V, "\n"); - } - break; - } -} - -void flac_error_callback(const FLAC__StreamDecoder *decoder, FLAC__StreamDecoderErrorStatus status, void *client_data) -{ - if (status != FLAC__STREAM_DECODER_ERROR_STATUS_LOST_SYNC) - mp_msg(MSGT_DECAUDIO, MSGL_ERR, "\nError callback called (%s)!!!\n", FLAC__StreamDecoderErrorStatusString[status]); -} - -static int preinit(sh_audio_t *sh){ - // there are default values set for buffering, but you can override them: - - sh->audio_out_minsize=8*4*65535; // due to specs: we assume max 8 channels, - // 4 bytes/sample and 65535 samples/frame - // So allocating 2Mbytes buffer :) - - // minimum input buffer size (set only if you need input buffering) - // (should be the max compressed frame size) - sh->audio_in_minsize=2048; // Default: 0 (no input buffer) - - // if you set audio_in_minsize non-zero, the buffer will be allocated - // before the init() call by the core, and you can access it via - // pointer: sh->audio_in_buffer - // it will free'd after uninit(), so you don't have to use malloc/free here! - - return 1; // return values: 1=OK 0=ERROR -} - -static int init(sh_audio_t *sh_audio){ - flac_struct_t *context = (flac_struct_t*)calloc(sizeof(flac_struct_t), 1); - - sh_audio->context = context; - context->sh = sh_audio; - if (context == NULL) - { - mp_msg(MSGT_DECAUDIO, MSGL_FATAL, "flac_init: error allocating context.\n"); - return 0; - } - - context->flac_dec = FLAC__stream_decoder_new(); - if (context->flac_dec == NULL) - { - mp_msg(MSGT_DECAUDIO, MSGL_ERR, "flac_init: error allocaing FLAC decoder.\n"); - return 0; - } - - if (!FLAC__stream_decoder_set_client_data(context->flac_dec, context)) - { - mp_msg(MSGT_DECAUDIO, MSGL_ERR, "error setting private data for callbacks.\n"); - return 0; - } - - if (!FLAC__stream_decoder_set_read_callback(context->flac_dec, &flac_read_callback)) - { - mp_msg(MSGT_DECAUDIO, MSGL_ERR, "error setting read callback.\n"); - return 0; - } - - if (!FLAC__stream_decoder_set_write_callback(context->flac_dec, &flac_write_callback)) - { - mp_msg(MSGT_DECAUDIO, MSGL_ERR, "error setting write callback.\n"); - return 0; - } - - if (!FLAC__stream_decoder_set_metadata_callback(context->flac_dec, &flac_metadata_callback)) - { - mp_msg(MSGT_DECAUDIO, MSGL_ERR, "error setting metadata callback.\n"); - return 0; - } - - if (!FLAC__stream_decoder_set_error_callback(context->flac_dec, &flac_error_callback)) - { - mp_msg(MSGT_DECAUDIO, MSGL_ERR, "error setting error callback.\n"); - return 0; - } - - if (!FLAC__stream_decoder_set_metadata_respond_all(context->flac_dec)) - { - mp_msg(MSGT_DECAUDIO, MSGL_ERR, "error during setting metadata_respond_all.\n"); - return 0; - } - - if (FLAC__stream_decoder_init(context->flac_dec) != FLAC__STREAM_DECODER_SEARCH_FOR_METADATA) - { - mp_msg(MSGT_DECAUDIO, MSGL_ERR, "Error initializing decoder!\n"); - return 0; - } - - context->buf = NULL; - context->minlen = context->maxlen = 0; - context->replay_scale = 1.0; - - FLAC__stream_decoder_process_until_end_of_metadata(context->flac_dec); - - FLAC__replaygain_synthesis__init_dither_context(&(context->dither_context), sh_audio->samplesize * 8, noise_shaping); - - return 1; // return values: 1=OK 0=ERROR -} - -static void uninit(sh_audio_t *sh){ - // uninit the decoder etc... - FLAC__stream_decoder_finish(((flac_struct_t*)(sh->context))->flac_dec); - FLAC__stream_decoder_delete(((flac_struct_t*)(sh->context))->flac_dec); - // again: you don't have to free() a_in_buffer here! it's done by the core. -} - -static int decode_audio(sh_audio_t *sh_audio,unsigned char *buf,int minlen,int maxlen){ - FLAC__StreamDecoderState decstate; - FLAC__bool status; - - // audio decoding. the most important thing :) - // parameters you get: - // buf = pointer to the output buffer, you have to store uncompressed - // samples there - // minlen = requested minimum size (in bytes!) of output. it's just a - // _recommendation_, you can decode more or less, it just tell you that - // the caller process needs 'minlen' bytes. if it gets less, it will - // call decode_audio() again. - // maxlen = maximum size (bytes) of output. you MUST NOT write more to the - // buffer, it's the upper-most limit! - // note: maxlen will be always greater or equal to sh->audio_out_minsize - -// Store params in private context for callback: - ((flac_struct_t*)(sh_audio->context))->buf = buf; - ((flac_struct_t*)(sh_audio->context))->minlen = minlen; - ((flac_struct_t*)(sh_audio->context))->maxlen = maxlen; - ((flac_struct_t*)(sh_audio->context))->written = 0; - - status = FLAC__stream_decoder_process_single(((flac_struct_t*)(sh_audio->context))->flac_dec); - decstate = FLAC__stream_decoder_get_state(((flac_struct_t*)(sh_audio->context))->flac_dec); - if (!status || ( - decstate != FLAC__STREAM_DECODER_SEARCH_FOR_METADATA && - decstate != FLAC__STREAM_DECODER_READ_METADATA && - decstate != FLAC__STREAM_DECODER_SEARCH_FOR_FRAME_SYNC && - decstate != FLAC__STREAM_DECODER_READ_FRAME - )) - { - if (decstate == FLAC__STREAM_DECODER_END_OF_STREAM) - { - /* return what we have decoded */ - if (((flac_struct_t*)(sh_audio->context))->written != 0) - return ((flac_struct_t*)(sh_audio->context))->written; - mp_msg(MSGT_DECAUDIO, MSGL_V, "End of stream.\n"); - return -1; - } - mp_msg(MSGT_DECAUDIO, MSGL_WARN, "process_single problem: returned %s, state is %s!\n", status?"true":"false", FLAC__StreamDecoderStateString[decstate]); - FLAC__stream_decoder_flush(((flac_struct_t*)(sh_audio->context))->flac_dec); - return -1; - } - - - return ((flac_struct_t*)(sh_audio->context))->written; // return value: number of _bytes_ written to output buffer, - // or -1 for EOF (or uncorrectable error) -} - -static int control(sh_audio_t *sh,int cmd,void* arg, ...){ - switch(cmd){ - case ADCTRL_RESYNC_STREAM: - // it is called once after seeking, to resync. - // Note: sh_audio->a_in_buffer_len=0; is done _before_ this call! - FLAC__stream_decoder_flush (((flac_struct_t*)(sh->context))->flac_dec); - return CONTROL_TRUE; - case ADCTRL_SKIP_FRAME: - // it is called to skip (jump over) small amount (1/10 sec or 1 frame) - // of audio data - used to sync audio to video after seeking - // if you don't return CONTROL_TRUE, it will defaults to: - // ds_fill_buffer(sh_audio->ds); // skip 1 demux packet - ((flac_struct_t*)(sh->context))->buf = NULL; - ((flac_struct_t*)(sh->context))->minlen = - ((flac_struct_t*)(sh->context))->maxlen = 0; - FLAC__stream_decoder_process_single(((flac_struct_t*)(sh->context))->flac_dec); - return CONTROL_TRUE; - } - return CONTROL_UNKNOWN; -} -#endif