audio: add af_lavrresample, remove old resampling filtersmaster
authorStefano Pigozzi <[email protected]>
Sat, 9 Mar 2013 08:30:26 +0000 (9 09:30 +0100)
committerUoti Urpala <[email protected]>
Wed, 9 Oct 2013 20:43:25 +0000 (9 23:43 +0300)
Remove `af_resample` and `af_lavcresample`. The former is a mess while
the latter uses an API that was long deprecated in libavcodec and is
now removed. Add new filter af_lavrresample which uses libavresample.
`af_lavrresample` has roughly the same features and structure as
`af_lavcresample` had.

Libavresample is now a mandatory dependency. Change configure script
accordingly and remove #ifdefs in other code.

13 files changed:
DOCS/man/en/af.rst
DOCS/man/en/options.rst
Makefile
configure
etc/example.conf
libaf/af.c
libaf/af.h
libaf/af_lavcac3enc.c
libaf/af_lavcresample.c [deleted file]
libaf/af_lavrresample.c [new file with mode: 0644]
libaf/af_resample.c [deleted file]
libaf/af_resample_template.c [deleted file]
libmpcodecs/ad_ffmpeg.c

index 1822a44..f4891e7 100644 (file)
@@ -27,55 +27,26 @@ filter list.
 
 Available filters are:
 
-resample[=srate[:sloppy[:type]]]
-    Changes the sample rate of the audio stream. Can be used if you have a
-    fixed frequency sound card or if you are stuck with an old sound card that
-    is only capable of max 44.1kHz. This filter is automatically enabled if
-    necessary. It only supports 16-bit integer and float in native-endian
-    format as input.
-
-    <srate>
-        output sample frequency in Hz. The valid range for this parameter is
-        8000 to 192000. If the input and output sample frequency are the same
-        or if this parameter is omitted the filter is automatically unloaded.
-        A high sample frequency normally improves the audio quality,
-        especially when used in combination with other filters.
-    <sloppy>
-        Allow (1) or disallow (0) the output frequency to differ slightly from
-        the frequency given by <srate> (default: 1). Can be used if the
-        startup of the playback is extremely slow.
-    <type>
-        Select which resampling method to use.
-
-        :0: linear interpolation (fast, poor quality especially when
-            upsampling)
-        :1: polyphase filterbank and integer processing
-        :2: polyphase filterbank and floating point processing
-            (slow, best quality)
-
-    *EXAMPLE*:
-
-    ``mplayer --af=resample=44100:0:0``
-        would set the output frequency of the resample filter to 44100Hz using
-        exact output frequency scaling and linear interpolation.
-
-lavcresample[=srate[:length[:linear[:count[:cutoff]]]]]
+lavrresample[=option1:option2:...]
     Changes the sample rate of the audio stream to an integer <srate> in Hz.
-    It only supports the 16-bit native-endian format.
 
-    <srate>
-        the output sample rate
-    <length>
+    This filter is automatically inserted if the audio output device does not
+    support the sample rate of the file played. It only supports the
+    16-bit integer native-endian format.
+
+    srate=<srate>
+        the output sample rate (defaut: 44100)
+    length=<length>
         length of the filter with respect to the lower sampling rate (default:
         16)
-    <linear>
-        if 1 then filters will be linearly interpolated between polyphase
-        entries
-    <count>
+    phase_shift=<count>
         log2 of the number of polyphase entries (..., 10->1024, 11->2048,
         12->4096, ...) (default: 10->1024)
-    <cutoff>
+    cutoff=<cutoff>
         cutoff frequency (0.0-1.0), default set depending upon filter length
+    linear
+        if set then filters will be linearly interpolated between polyphase
+        entries (default: no)
 
 lavcac3enc[=tospdif[:bitrate[:minchn]]]
     Encode multi-channel audio to AC-3 at runtime using libavcodec. Supports
index a6f5d0d..0689a39 100644 (file)
 --srate=<Hz>
     Select the output sample rate to be used (of course sound cards have
     limits on this). If the sample frequency selected is different from that
-    of the current media, the resample or lavcresample audio filter will be
-    inserted into the audio filter layer to compensate for the difference. The
-    type of resampling can be controlled by the ``--af-adv`` option.
+    of the current media, the lavrresample audio filter will be inserted into
+    the audio filter layer to compensate for the difference. The type of
+    resampling can be controlled by the ``--af-adv`` option.
 
 --ss=<time>
     Seek to given time position.
index 371de28..56d50f7 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -224,9 +224,8 @@ SRCS_COMMON = asxparser.c \
               libaf/af_hrtf.c \
               libaf/af_karaoke.c \
               libaf/af_lavcac3enc.c \
-              libaf/af_lavcresample.c \
+              libaf/af_lavrresample.c \
               libaf/af_pan.c \
-              libaf/af_resample.c \
               libaf/af_scaletempo.c \
               libaf/af_sinesuppress.c \
               libaf/af_stats.c \
index 95a5ae8..60fd308 100755 (executable)
--- a/configure
+++ b/configure
@@ -336,7 +336,6 @@ Optional features:
   --disable-libass       disable subtitle rendering with libass [autodetect]
   --enable-rpath         enable runtime linker path for extra libs [disabled]
   --disable-libpostproc  disable postprocess filter (vf_pp) [autodetect]
-  --disable-libavresample disable libavresample (sample format conversion) [autodetect]
 
 Codecs:
   --enable-gif              enable GIF support [autodetect]
@@ -613,7 +612,6 @@ _w32threads=auto
 _ass=auto
 _rpath=no
 libpostproc=auto
-libavresample=auto
 _asmalign_pot=auto
 _stream_cache=yes
 _priority=no
@@ -917,8 +915,6 @@ for ac_option do
   --disable-rpath)      _rpath=no       ;;
   --enable-libpostproc) libpostproc=yes ;;
   --disable-libpostproc) libpostproc=no ;;
-  --enable-libavresample) libavresample=yes ;;
-  --disable-libavresample) libavresample=no ;;
 
   --enable-enca)        _enca=yes       ;;
   --disable-enca)       _enca=no        ;;
@@ -4733,7 +4729,7 @@ fi
 echores "$_lcms2"
 
 
-all_libav_libs="libavutil > 51.21.0:libavcodec >= 54.25.0:libavformat > 53.20.0:libswscale >= 2.0.0"
+all_libav_libs="libavutil > 51.21.0:libavcodec >= 54.25.0:libavformat > 53.20.0:libswscale >= 2.0.0:libavresample >= 1.0.0"
 echocheck "Libav ($all_libav_libs)"
 if test "$ffmpeg" = auto ; then
   IFS=":"   # shell should not be used for programming
@@ -4757,20 +4753,6 @@ else
 fi
 echores "$libpostproc"
 
-echocheck "libavresample >= 1.0.0"
-if test "$libavresample" = auto ; then
-    libavresample=no
-    if pkg_config_add "libavresample >= 1.0.0" ; then
-        libavresample=yes
-    fi
-fi
-if test "$libavresample" = yes ; then
-    def_libavresample='#define CONFIG_LIBAVRESAMPLE 1'
-else
-    def_libavresample='#undef CONFIG_LIBAVRESAMPLE'
-fi
-echores "$libavresample"
-
 echocheck "libdv-0.9.5+"
 if test "$_libdv" = auto ; then
   _libdv=no
@@ -5356,7 +5338,6 @@ LIBMAD = $_mad
 LCMS2 = $_lcms2
 LIBNUT = $_libnut
 LIBPOSTPROC = $libpostproc
-LIBAVRESAMPLE = $libavresample
 LIBSMBCLIENT = $_smb
 LIBQUVI = $_libquvi
 LIBTHEORA = $_theora
@@ -5579,7 +5560,6 @@ $def_xvid
 $def_zlib
 
 $def_libpostproc
-$def_libavresample
 $def_libnut
 
 
index 9e243d0..aed8b24 100644 (file)
@@ -58,8 +58,8 @@
 # Specify the mixer device.
 #mixer = /dev/mixer
 
-# Resample the sound to 44100Hz with the lavcresample audio filter.
-#af=lavcresample=44100
+# Resample the sound to 44100Hz with the lavrresample audio filter.
+#af=lavrresample=44100
 
 # Output audio to S/PDIF
 #ao=alsa:device=spdif
index e401572..434943b 100644 (file)
@@ -29,7 +29,6 @@ extern af_info_t af_info_dummy;
 extern af_info_t af_info_delay;
 extern af_info_t af_info_channels;
 extern af_info_t af_info_format;
-extern af_info_t af_info_resample;
 extern af_info_t af_info_volume;
 extern af_info_t af_info_equalizer;
 extern af_info_t af_info_gate;
@@ -41,7 +40,7 @@ extern af_info_t af_info_export;
 extern af_info_t af_info_volnorm;
 extern af_info_t af_info_extrastereo;
 extern af_info_t af_info_lavcac3enc;
-extern af_info_t af_info_lavcresample;
+extern af_info_t af_info_lavrresample;
 extern af_info_t af_info_sweep;
 extern af_info_t af_info_hrtf;
 extern af_info_t af_info_ladspa;
@@ -57,7 +56,6 @@ static af_info_t* filter_list[]={
    &af_info_delay,
    &af_info_channels,
    &af_info_format,
-   &af_info_resample,
    &af_info_volume,
    &af_info_equalizer,
    &af_info_gate,
@@ -71,7 +69,7 @@ static af_info_t* filter_list[]={
    &af_info_volnorm,
    &af_info_extrastereo,
    &af_info_lavcac3enc,
-   &af_info_lavcresample,
+   &af_info_lavrresample,
    &af_info_sweep,
    &af_info_hrtf,
 #ifdef CONFIG_LADSPA
@@ -528,9 +526,7 @@ int af_init(af_stream_t* s)
       af = af_control_any_rev(s, AF_CONTROL_RESAMPLE_RATE | AF_CONTROL_SET,
                &(s->output.rate));
       if (!af) {
-        char *resampler = "resample";
-        if ((AF_INIT_TYPE_MASK & s->cfg.force) == AF_INIT_SLOW)
-          resampler = "lavcresample";
+        char *resampler = "lavrresample";
        if((AF_INIT_TYPE_MASK & s->cfg.force) == AF_INIT_SLOW){
          if(!strcmp(s->first->info->name,"format"))
            af = af_append(s,s->first,resampler);
@@ -547,16 +543,6 @@ int af_init(af_stream_t* s)
       if(!af || (AF_OK != af->control(af,AF_CONTROL_RESAMPLE_RATE | AF_CONTROL_SET,
                                      &(s->output.rate))))
        return -1;
-      // Use lin int if the user wants fast
-      if ((AF_INIT_TYPE_MASK & s->cfg.force) == AF_INIT_FAST) {
-        char args[32];
-       sprintf(args, "%d", s->output.rate);
-       if (strcmp(resampler, "lavcresample") == 0)
-         strcat(args, ":1");
-       else
-            strcat(args, ":0:0");
-       af->control(af, AF_CONTROL_COMMAND_LINE, args);
-      }
       }
       if(AF_OK != af_reinit(s,af))
        return -1;
index ceca34c..175687f 100644 (file)
@@ -37,8 +37,7 @@ struct af_instance_s;
 #endif
 
 // Audio data chunk
-typedef struct af_data_s
-{
+typedef struct af_data {
   void* audio;  // data buffer
   int len;      // buffer length
   int rate;    // sample rate
@@ -54,8 +53,7 @@ typedef struct af_data_s
 
 /* Audio filter information not specific for current instance, but for
    a specific filter */
-typedef struct af_info_s
-{
+typedef struct af_info {
   const char *info;
   const char *name;
   const char *author;
index 2aa69e6..c54cc3e 100644 (file)
 #include <libavutil/mem.h>
 #include <libavutil/opt.h>
 #include <libavutil/samplefmt.h>
+#include <libavresample/avresample.h>
 
 #include "config.h"
 #include "af.h"
 #include "reorder_ch.h"
 
-#ifdef CONFIG_LIBAVRESAMPLE
-#include <libavresample/avresample.h>
-#endif
 
 #define AC3_MAX_CHANNELS 6
 #define AC3_MAX_CODED_FRAME_SIZE 3840
@@ -52,11 +50,9 @@ const uint16_t ac3_bitrate_tab[19] = {
 
 // Data for specific instances of this filter
 typedef struct af_ac3enc_s {
-#ifdef CONFIG_LIBAVRESAMPLE
     AVAudioResampleContext *avr;
     uint8_t *resample_buf[AC3_MAX_CHANNELS];
     int linesize;
-#endif
     AVFrame *frame;
     struct AVCodec        *lavc_acodec;
     struct AVCodecContext *lavc_actx;
@@ -115,7 +111,6 @@ static int control(struct af_instance_s *af, int cmd, void *arg)
 
             avcodec_close(s->lavc_actx);
 
-#ifdef CONFIG_LIBAVRESAMPLE
             if (s->avr) {
                 uint64_t ch_layout =
                     av_get_default_channel_layout(af->data->nch);
@@ -154,7 +149,6 @@ static int control(struct af_instance_s *af, int cmd, void *arg)
                     return AF_ERROR;
                 }
             }
-#endif
 
             // Put sample parameters
             s->lavc_actx->channels = af->data->nch;
@@ -223,10 +217,8 @@ static void uninit(struct af_instance_s* af)
 #else
         av_freep(&s->frame);
 #endif
-#ifdef CONFIG_LIBAVRESAMPLE
         avresample_free(&s->avr);
         av_freep(&s->resample_buf[0]);
-#endif
         free(s->pending_data);
         free(s);
     }
@@ -250,7 +242,6 @@ static int encode_data(af_ac3enc_t *s, uint8_t *src, uint8_t *dst, int dst_len)
     s->frame->data[0]     = src;
     s->frame->linesize[0] = total_samples * bps;
 
-#ifdef CONFIG_LIBAVRESAMPLE
     if (s->avr) {
         ret = avresample_convert(s->avr, s->resample_buf, s->linesize,
                                  AC3_FRAME_SIZE, &src, total_samples * bps,
@@ -268,7 +259,6 @@ static int encode_data(af_ac3enc_t *s, uint8_t *src, uint8_t *dst, int dst_len)
         memcpy(s->frame->data, s->resample_buf, sizeof(s->resample_buf));
         s->frame->linesize[0] = s->linesize;
     }
-#endif
 
     av_init_packet(&pkt);
     pkt.data = dst;
@@ -408,10 +398,7 @@ static int af_open(af_instance_t* af){
                    "support expected sample formats!\n");
             return AF_ERROR;
         }
-        enum AVSampleFormat fmt_packed = fmts[i];
-#ifdef CONFIG_LIBAVRESAMPLE
-        fmt_packed = av_get_packed_sample_fmt(fmt_packed);
-#endif
+        enum AVSampleFormat fmt_packed = av_get_packed_sample_fmt(fmts[i]);
         if (fmt_packed == AV_SAMPLE_FMT_S16) {
             s->in_sampleformat = AF_FORMAT_S16_NE;
             s->lavc_actx->sample_fmt = fmts[i];
@@ -423,15 +410,9 @@ static int af_open(af_instance_t* af){
         }
     }
     if (av_sample_fmt_is_planar(s->lavc_actx->sample_fmt)) {
-#ifdef CONFIG_LIBAVRESAMPLE
         s->avr = avresample_alloc_context();
         if (!s->avr)
             abort();
-#else
-        mp_msg(MSGT_AFILTER, MSGL_ERR, "Libavresample is required for this "
-               "filter to work with this libavcodec version.\n");
-        return AF_ERROR;
-#endif
     }
     char buf[100];
     mp_msg(MSGT_AFILTER, MSGL_V, "[af_lavcac3enc]: in sample format: %s\n",
diff --git a/libaf/af_lavcresample.c b/libaf/af_lavcresample.c
deleted file mode 100644 (file)
index f1483ac..0000000
+++ /dev/null
@@ -1,213 +0,0 @@
-/*
- * Copyright (c) 2004 Michael Niedermayer <[email protected]>
- *
- * This file is part of MPlayer.
- *
- * MPlayer 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.
- *
- * MPlayer 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 MPlayer; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
- */
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <inttypes.h>
-
-#include "config.h"
-#include "af.h"
-#include "libavcodec/avcodec.h"
-#include "libavutil/rational.h"
-
-// Data for specific instances of this filter
-typedef struct af_resample_s{
-    struct AVResampleContext *avrctx;
-    int16_t *in[AF_NCH];
-    int in_alloc;
-    int index;
-
-    int filter_length;
-    int linear;
-    int phase_shift;
-    double cutoff;
-
-    int ctx_out_rate;
-    int ctx_in_rate;
-    int ctx_filter_size;
-    int ctx_phase_shift;
-    int ctx_linear;
-    double ctx_cutoff;
-}af_resample_t;
-
-
-// Initialization and runtime control
-static int control(struct af_instance_s* af, int cmd, void* arg)
-{
-  af_resample_t* s   = (af_resample_t*)af->setup;
-  af_data_t *data= (af_data_t*)arg;
-  int out_rate, test_output_res; // helpers for checking input format
-
-  switch(cmd){
-  case AF_CONTROL_REINIT:
-    if((af->data->rate == data->rate) || (af->data->rate == 0))
-        return AF_DETACH;
-
-    af->data->nch    = data->nch;
-    if (af->data->nch > AF_NCH) af->data->nch = AF_NCH;
-    af->data->format = AF_FORMAT_S16_NE;
-    af->data->bps    = 2;
-    af->mul = (double)af->data->rate / data->rate;
-    af->delay = af->data->nch * s->filter_length / min(af->mul, 1); // *bps*.5
-
-    if (s->ctx_out_rate != af->data->rate || s->ctx_in_rate != data->rate || s->ctx_filter_size != s->filter_length ||
-        s->ctx_phase_shift != s->phase_shift || s->ctx_linear != s->linear || s->ctx_cutoff != s->cutoff) {
-        if(s->avrctx) av_resample_close(s->avrctx);
-        s->avrctx= av_resample_init(af->data->rate, /*in_rate*/data->rate, s->filter_length, s->phase_shift, s->linear, s->cutoff);
-        s->ctx_out_rate    = af->data->rate;
-        s->ctx_in_rate     = data->rate;
-        s->ctx_filter_size = s->filter_length;
-        s->ctx_phase_shift = s->phase_shift;
-        s->ctx_linear      = s->linear;
-        s->ctx_cutoff      = s->cutoff;
-    }
-
-    // hack to make af_test_output ignore the samplerate change
-    out_rate = af->data->rate;
-    af->data->rate = data->rate;
-    test_output_res = af_test_output(af, (af_data_t*)arg);
-    af->data->rate = out_rate;
-    return test_output_res;
-  case AF_CONTROL_COMMAND_LINE:{
-    s->cutoff= 0.0;
-    sscanf((char*)arg,"%d:%d:%d:%d:%lf", &af->data->rate, &s->filter_length, &s->linear, &s->phase_shift, &s->cutoff);
-    if(s->cutoff <= 0.0) s->cutoff= max(1.0 - 6.5/(s->filter_length+8), 0.80);
-    return AF_OK;
-  }
-  case AF_CONTROL_RESAMPLE_RATE | AF_CONTROL_SET:
-    af->data->rate = *(int*)arg;
-    return AF_OK;
-  }
-  return AF_UNKNOWN;
-}
-
-// Deallocate memory
-static void uninit(struct af_instance_s* af)
-{
-    if(af->data)
-        free(af->data->audio);
-    free(af->data);
-    if(af->setup){
-        int i;
-        af_resample_t *s = af->setup;
-        if(s->avrctx) av_resample_close(s->avrctx);
-        for (i=0; i < AF_NCH; i++)
-            free(s->in[i]);
-        free(s);
-    }
-}
-
-// Filter data through filter
-static af_data_t* play(struct af_instance_s* af, af_data_t* data)
-{
-  af_resample_t *s = af->setup;
-  int i, j, consumed, ret = 0;
-  int16_t *in = (int16_t*)data->audio;
-  int16_t *out;
-  int chans   = data->nch;
-  int in_len  = data->len/(2*chans);
-  int out_len = in_len * af->mul + 10;
-  int16_t tmp[AF_NCH][out_len];
-
-  if(AF_OK != RESIZE_LOCAL_BUFFER(af,data))
-      return NULL;
-
-  out= (int16_t*)af->data->audio;
-
-  out_len= min(out_len, af->data->len/(2*chans));
-
-  if(s->in_alloc < in_len + s->index){
-      s->in_alloc= in_len + s->index;
-      for(i=0; i<chans; i++){
-          s->in[i]= realloc(s->in[i], s->in_alloc*sizeof(int16_t));
-      }
-  }
-
-  if(chans==1){
-      memcpy(&s->in[0][s->index], in, in_len * sizeof(int16_t));
-  }else if(chans==2){
-      for(j=0; j<in_len; j++){
-          s->in[0][j + s->index]= *(in++);
-          s->in[1][j + s->index]= *(in++);
-      }
-  }else{
-      for(j=0; j<in_len; j++){
-          for(i=0; i<chans; i++){
-              s->in[i][j + s->index]= *(in++);
-          }
-      }
-  }
-  in_len += s->index;
-
-  for(i=0; i<chans; i++){
-      ret= av_resample(s->avrctx, tmp[i], s->in[i], &consumed, in_len, out_len, i+1 == chans);
-  }
-  out_len= ret;
-
-  s->index= in_len - consumed;
-  for(i=0; i<chans; i++){
-      memmove(s->in[i], s->in[i] + consumed, s->index*sizeof(int16_t));
-  }
-
-  if(chans==1){
-      memcpy(out, tmp[0], out_len*sizeof(int16_t));
-  }else if(chans==2){
-      for(j=0; j<out_len; j++){
-          *(out++)= tmp[0][j];
-          *(out++)= tmp[1][j];
-      }
-  }else{
-      for(j=0; j<out_len; j++){
-          for(i=0; i<chans; i++){
-              *(out++)= tmp[i][j];
-          }
-      }
-  }
-
-  data->audio = af->data->audio;
-  data->len   = out_len*chans*2;
-  data->rate  = af->data->rate;
-  return data;
-}
-
-static int af_open(af_instance_t* af){
-  af_resample_t *s = calloc(1,sizeof(af_resample_t));
-  af->control=control;
-  af->uninit=uninit;
-  af->play=play;
-  af->mul=1;
-  af->data=calloc(1,sizeof(af_data_t));
-  s->filter_length= 16;
-  s->cutoff= max(1.0 - 6.5/(s->filter_length+8), 0.80);
-  s->phase_shift= 10;
-//  s->setup = RSMP_INT | FREQ_SLOPPY;
-  af->setup=s;
-  return AF_OK;
-}
-
-af_info_t af_info_lavcresample = {
-  "Sample frequency conversion using libavcodec",
-  "lavcresample",
-  "Michael Niedermayer",
-  "",
-  AF_FLAGS_REENTRANT,
-  af_open
-};
diff --git a/libaf/af_lavrresample.c b/libaf/af_lavrresample.c
new file mode 100644 (file)
index 0000000..1185e15
--- /dev/null
@@ -0,0 +1,254 @@
+/*
+ * Copyright (c) 2004 Michael Niedermayer <[email protected]>
+ * Copyright (c) 2013 Stefano Pigozzi <[email protected]>
+ * Copyright (c) 2013 Uoti Urpala <[email protected]>
+ *
+ * This file is part of mplayer2.
+ *
+ * mplayer2 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.
+ *
+ * mplayer2 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 mplayer2.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <inttypes.h>
+#include <stdbool.h>
+
+#include <libavutil/common.h>
+#include <libavutil/opt.h>
+#include <libavutil/samplefmt.h>
+#include <libavutil/mathematics.h>
+#include <libavresample/avresample.h>
+
+#include "talloc.h"
+#include "config.h"
+
+#include "mp_msg.h"
+#include "subopt-helper.h"
+#include "af.h"
+
+struct af_resample_opts {
+    int filter_size;
+    int phase_shift;
+    int linear;
+    double cutoff;
+
+    int out_rate;
+    int in_rate;
+};
+
+struct af_resample {
+    struct AVAudioResampleContext *avrctx;
+    struct af_resample_opts ctx;   // opts in the context
+    struct af_resample_opts opts;  // opts requested by the user
+};
+
+static double af_resample_default_cutoff(int filter_size)
+{
+    return FFMAX(1.0 - 6.5 / (filter_size + 8), 0.80);
+}
+
+static bool needs_lavrctx_reconfigure(struct af_resample *s,
+                                      struct af_data *in,
+                                      struct af_data *out)
+{
+    return s->ctx.out_rate    != out->rate ||
+           s->ctx.in_rate     != in->rate ||
+           s->ctx.filter_size != s->opts.filter_size ||
+           s->ctx.phase_shift != s->opts.phase_shift ||
+           s->ctx.linear      != s->opts.linear ||
+           s->ctx.cutoff      != s->opts.cutoff;
+
+}
+
+#define ctx_opt_set_int(a,b) av_opt_set_int(s->avrctx, (a), (b), 0)
+#define ctx_opt_set_dbl(a,b) av_opt_set_double(s->avrctx, (a), (b), 0)
+
+static int control(struct af_instance_s *af, int cmd, void *arg)
+{
+    struct af_resample *s = af->setup;
+    struct af_data *in    = arg;
+    struct af_data *out   = af->data;
+
+    switch (cmd) {
+    case AF_CONTROL_REINIT: {
+        if ((out->rate == in->rate) || (out->rate == 0))
+            return AF_DETACH;
+
+        out->nch    = FFMIN(in->nch, AF_NCH);
+        out->format = AF_FORMAT_S16_NE;
+        out->bps    = 2;
+        af->mul     = (double) out->rate / in->rate;
+        af->delay   = out->nch * s->opts.filter_size / FFMIN(af->mul, 1);
+
+        if (needs_lavrctx_reconfigure(s, in, out)) {
+            if (s->avrctx)
+                avresample_close(s->avrctx);
+
+            s->ctx.out_rate    = out->rate;
+            s->ctx.in_rate     = in->rate;
+            s->ctx.filter_size = s->opts.filter_size;
+            s->ctx.phase_shift = s->opts.phase_shift;
+            s->ctx.linear      = s->opts.linear;
+            s->ctx.cutoff      = s->opts.cutoff;
+
+            int ch_layout = av_get_default_channel_layout(out->nch);
+
+            ctx_opt_set_int("in_channel_layout",  ch_layout);
+            ctx_opt_set_int("out_channel_layout", ch_layout);
+
+            ctx_opt_set_int("in_sample_rate",     s->ctx.in_rate);
+            ctx_opt_set_int("out_sample_rate",    s->ctx.out_rate);
+
+            ctx_opt_set_int("in_sample_fmt",      AV_SAMPLE_FMT_S16);
+            ctx_opt_set_int("out_sample_fmt",     AV_SAMPLE_FMT_S16);
+
+            ctx_opt_set_int("filter_size",        s->ctx.filter_size);
+            ctx_opt_set_int("phase_shift",        s->ctx.phase_shift);
+            ctx_opt_set_int("linear_interp",      s->ctx.linear);
+
+            ctx_opt_set_dbl("cutoff",             s->ctx.cutoff);
+
+            if (avresample_open(s->avrctx) < 0) {
+                mp_msg(MSGT_AFILTER, MSGL_ERR, "[lavrresample] Cannot open "
+                       "Libavresample Context. \n");
+                return AF_ERROR;
+            }
+        }
+
+        int out_rate, test_output_res;
+        // hack to make af_test_output ignore the samplerate change
+        out_rate  = out->rate;
+        out->rate = in->rate;
+        test_output_res = af_test_output(af, in);
+        out->rate = out_rate;
+        return test_output_res;
+    }
+    case AF_CONTROL_COMMAND_LINE: {
+        s->opts.cutoff = 0.0;
+
+        const opt_t subopts[] = {
+            {"srate",        OPT_ARG_INT,    &out->rate, NULL},
+            {"filter_size",  OPT_ARG_INT,    &s->opts.filter_size, NULL},
+            {"phase_shift",  OPT_ARG_INT,    &s->opts.phase_shift, NULL},
+            {"linear",       OPT_ARG_BOOL,   &s->opts.linear, NULL},
+            {"cutoff",       OPT_ARG_FLOAT,  &s->opts.cutoff, NULL},
+        };
+
+        if (subopt_parse(arg, subopts) != 0) {
+            mp_msg(MSGT_AFILTER, MSGL_ERR, "[lavrresample] Invalid option "
+                   "specified.\n");
+            return AF_ERROR;
+        }
+
+        if (s->opts.cutoff <= 0.0)
+            s->opts.cutoff = af_resample_default_cutoff(s->opts.filter_size);
+        return AF_OK;
+    }
+    case AF_CONTROL_RESAMPLE_RATE | AF_CONTROL_SET:
+        out->rate = *(int *)arg;
+        return AF_OK;
+    }
+    return AF_UNKNOWN;
+}
+
+#undef ctx_opt_set_int
+#undef ctx_opt_set_dbl
+
+static void uninit(struct af_instance_s *af)
+{
+    if (af->setup) {
+        struct af_resample *s = af->setup;
+        if (s->avrctx)
+            avresample_close(s->avrctx);
+        talloc_free(af->setup);
+    }
+}
+
+static struct af_data *play(struct af_instance_s *af, struct af_data *data)
+{
+    struct af_resample *s = af->setup;
+    struct af_data *in    = data;
+    struct af_data *out   = af->data;
+
+
+    int in_size     = data->len;
+    int in_samples  = in_size / (data->bps * data->nch);
+    int out_samples = avresample_available(s->avrctx) +
+        av_rescale_rnd(avresample_get_delay(s->avrctx) + in_samples,
+                       s->ctx.out_rate, s->ctx.in_rate, AV_ROUND_UP);
+    int out_size    = out->bps * out_samples * out->nch;
+
+    if (talloc_get_size(out->audio) < out_size)
+        out->audio = talloc_realloc_size(out, out->audio, out_size);
+
+    af->delay = out->bps * av_rescale_rnd(avresample_get_delay(s->avrctx),
+                                          s->ctx.out_rate, s->ctx.in_rate,
+                                          AV_ROUND_UP);
+
+    out_samples = avresample_convert(s->avrctx,
+            (uint8_t **) &out->audio, out_size, out_samples,
+            (uint8_t **) &in->audio,  in_size,  in_samples);
+
+    out_size  = out->bps * out_samples * out->nch;
+    in->audio = out->audio;
+    in->len   = out_size;
+    in->rate  = s->ctx.out_rate;
+    return data;
+}
+
+static int af_open(struct af_instance_s *af)
+{
+    struct af_resample *s = talloc_zero(NULL, struct af_resample);
+
+    af->control = control;
+    af->uninit  = uninit;
+    af->play    = play;
+    af->mul     = 1;
+    af->data    = talloc_zero(s, struct af_data);
+
+    af->data->rate   = 44100;
+
+    int default_filter_size = 16;
+    s->opts = (struct af_resample_opts) {
+        .linear      = 0,
+        .filter_size = default_filter_size,
+        .cutoff      = af_resample_default_cutoff(default_filter_size),
+        .phase_shift = 10,
+    };
+
+    s->avrctx = avresample_alloc_context();
+    af->setup = s;
+
+    if (s->avrctx) {
+        return AF_OK;
+    } else {
+        mp_msg(MSGT_AFILTER, MSGL_ERR, "[lavrresample] Cannot initialize "
+               "libavresample context. \n");
+        uninit(af);
+        return AF_ERROR;
+    }
+}
+
+struct af_info af_info_lavrresample = {
+    "Sample frequency conversion using libavresample",
+    "lavrresample",
+    "Stefano Pigozzi (based on Michael Niedermayer's lavcresample)",
+    "",
+    AF_FLAGS_REENTRANT,
+    af_open
+};
+#warning don't use subopt / positional arguments
+#warning use lavr default option values
+#warning support float and other data types
diff --git a/libaf/af_resample.c b/libaf/af_resample.c
deleted file mode 100644 (file)
index 6809c48..0000000
+++ /dev/null
@@ -1,394 +0,0 @@
-/*
- * This audio filter changes the sample rate.
- *
- * Copyright (C) 2002 Anders Johansson [email protected]
- *
- * This file is part of MPlayer.
- *
- * MPlayer 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.
- *
- * MPlayer 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 MPlayer; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
- */
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <inttypes.h>
-
-#include "libavutil/common.h"
-#include "libavutil/mathematics.h"
-#include "af.h"
-#include "dsp.h"
-
-/* Below definition selects the length of each poly phase component.
-   Valid definitions are L8 and L16, where the number denotes the
-   length of the filter. This definition affects the computational
-   complexity (see play()), the performance (see filter.h) and the
-   memory usage. The filter length is chosen to 8 if the machine is
-   slow and to 16 if the machine is fast and has MMX.
-*/
-
-#if !HAVE_MMX // This machine is slow
-#define L8
-#else
-#define L16
-#endif
-
-#include "af_resample_template.c"
-
-// Filtering types
-#define RSMP_LIN       (0<<0)  // Linear interpolation
-#define RSMP_INT       (1<<0)  // 16 bit integer
-#define RSMP_FLOAT     (2<<0)  // 32 bit floating point
-#define RSMP_MASK      (3<<0)
-
-// Defines for sloppy or exact resampling
-#define FREQ_SLOPPY    (0<<2)
-#define FREQ_EXACT     (1<<2)
-#define FREQ_MASK      (1<<2)
-
-// Accuracy for linear interpolation
-#define STEPACCURACY 32
-
-// local data
-typedef struct af_resample_s
-{
-  void*        w;      // Current filter weights
-  void**       xq;     // Circular buffers
-  uint32_t     xi;     // Index for circular buffers
-  uint32_t     wi;     // Index for w
-  uint32_t     i;      // Number of new samples to put in x queue
-  uint32_t     dn;     // Down sampling factor
-  uint32_t     up;     // Up sampling factor
-  uint64_t     step;   // Step size for linear interpolation
-  uint64_t     pt;     // Pointer remainder for linear interpolation
-  int          setup;  // Setup parameters cmdline or through postcreate
-} af_resample_t;
-
-// Fast linear interpolation resample with modest audio quality
-static int linint(af_data_t* c,af_data_t* l, af_resample_t* s)
-{
-  uint32_t     len   = 0;              // Number of input samples
-  uint32_t     nch   = l->nch;         // Words pre transfer
-  uint64_t     step  = s->step;
-  int16_t*     in16  = ((int16_t*)c->audio);
-  int16_t*     out16 = ((int16_t*)l->audio);
-  int32_t*     in32  = ((int32_t*)c->audio);
-  int32_t*     out32 = ((int32_t*)l->audio);
-  uint64_t     end   = ((((uint64_t)c->len)/2LL)<<STEPACCURACY);
-  uint64_t     pt    = s->pt;
-  uint16_t     tmp;
-
-  switch (nch){
-  case 1:
-    while(pt < end){
-      out16[len++]=in16[pt>>STEPACCURACY];
-      pt+=step;
-    }
-    s->pt=pt & ((1LL<<STEPACCURACY)-1);
-    break;
-  case 2:
-    end/=2;
-    while(pt < end){
-      out32[len++]=in32[pt>>STEPACCURACY];
-      pt+=step;
-    }
-    len=(len<<1);
-    s->pt=pt & ((1LL<<STEPACCURACY)-1);
-    break;
-  default:
-    end /=nch;
-    while(pt < end){
-      tmp=nch;
-      do {
-       tmp--;
-       out16[len+tmp]=in16[tmp+(pt>>STEPACCURACY)*nch];
-      } while (tmp);
-      len+=nch;
-      pt+=step;
-    }
-    s->pt=pt & ((1LL<<STEPACCURACY)-1);
-  }
-  return len;
-}
-
-/* Determine resampling type and format */
-static int set_types(struct af_instance_s* af, af_data_t* data)
-{
-  af_resample_t* s = af->setup;
-  int rv = AF_OK;
-  float rd = 0;
-
-  // Make sure this filter isn't redundant
-  if((af->data->rate == data->rate) || (af->data->rate == 0))
-    return AF_DETACH;
-  /* If sloppy and small resampling difference (2%) */
-  rd = abs((float)af->data->rate - (float)data->rate)/(float)data->rate;
-  if((((s->setup & FREQ_MASK) == FREQ_SLOPPY) && (rd < 0.02) &&
-      (data->format != (AF_FORMAT_FLOAT_NE))) ||
-     ((s->setup & RSMP_MASK) == RSMP_LIN)){
-    s->setup = (s->setup & ~RSMP_MASK) | RSMP_LIN;
-    af->data->format = AF_FORMAT_S16_NE;
-    af->data->bps    = 2;
-    mp_msg(MSGT_AFILTER, MSGL_V, "[resample] Using linear interpolation. \n");
-  }
-  else{
-    /* If the input format is float or if float is explicitly selected
-       use float, otherwise use int */
-    if((data->format == (AF_FORMAT_FLOAT_NE)) ||
-       ((s->setup & RSMP_MASK) == RSMP_FLOAT)){
-      s->setup = (s->setup & ~RSMP_MASK) | RSMP_FLOAT;
-      af->data->format = AF_FORMAT_FLOAT_NE;
-      af->data->bps    = 4;
-    }
-    else{
-      s->setup = (s->setup & ~RSMP_MASK) | RSMP_INT;
-      af->data->format = AF_FORMAT_S16_NE;
-      af->data->bps    = 2;
-    }
-    mp_msg(MSGT_AFILTER, MSGL_V, "[resample] Using %s processing and %s frequecy"
-          " conversion.\n",
-          ((s->setup & RSMP_MASK) == RSMP_FLOAT)?"floating point":"integer",
-          ((s->setup & FREQ_MASK) == FREQ_SLOPPY)?"inexact":"exact");
-  }
-
-  if(af->data->format != data->format || af->data->bps != data->bps)
-    rv = AF_FALSE;
-  data->format = af->data->format;
-  data->bps = af->data->bps;
-  af->data->nch = data->nch;
-  return rv;
-}
-
-// Initialization and runtime control
-static int control(struct af_instance_s* af, int cmd, void* arg)
-{
-  switch(cmd){
-  case AF_CONTROL_REINIT:{
-    af_resample_t* s   = af->setup;
-    af_data_t*            n   = arg; // New configuration
-    int            i,d = 0;
-    int           rv  = AF_OK;
-
-    // Free space for circular buffers
-    if(s->xq){
-      free(s->xq[0]);
-      free(s->xq);
-      s->xq = NULL;
-    }
-
-    if(AF_DETACH == (rv = set_types(af,n)))
-      return AF_DETACH;
-
-    // If linear interpolation
-    if((s->setup & RSMP_MASK) == RSMP_LIN){
-      s->pt=0LL;
-      s->step=((uint64_t)n->rate<<STEPACCURACY)/(uint64_t)af->data->rate+1LL;
-      mp_msg(MSGT_AFILTER, MSGL_DBG2, "[resample] Linear interpolation step: 0x%016"PRIX64".\n",
-            s->step);
-      af->mul = (double)af->data->rate / n->rate;
-      return rv;
-    }
-
-    // Calculate up and down sampling factors
-    d=av_gcd(af->data->rate,n->rate);
-
-    // If sloppy resampling is enabled limit the upsampling factor
-    if(((s->setup & FREQ_MASK) == FREQ_SLOPPY) && (af->data->rate/d > 5000)){
-      int up=af->data->rate/2;
-      int dn=n->rate/2;
-      int m=2;
-      while(af->data->rate/(d*m) > 5000){
-       d=av_gcd(up,dn);
-       up/=2; dn/=2; m*=2;
-      }
-      d*=m;
-    }
-
-    // Create space for circular buffers
-    s->xq = malloc(n->nch*sizeof(void*));
-    s->xq[0] = calloc(n->nch, 2*L*af->data->bps);
-    for(i=1;i<n->nch;i++)
-      s->xq[i] = (uint8_t *)s->xq[i-1] + 2*L*af->data->bps;
-    s->xi = 0;
-
-    // Check if the design needs to be redone
-    if(s->up != af->data->rate/d || s->dn != n->rate/d){
-      float* w;
-      float* wt;
-      float fc;
-      int j;
-      s->up = af->data->rate/d;
-      s->dn = n->rate/d;
-      s->wi = 0;
-      s->i = 0;
-
-      // Calculate cutoff frequency for filter
-      fc = 1/(float)(max(s->up,s->dn));
-      // Allocate space for polyphase filter bank and prototype filter
-      w = malloc(sizeof(float) * s->up *L);
-      free(s->w);
-      s->w = malloc(L*s->up*af->data->bps);
-
-      // Design prototype filter type using Kaiser window with beta = 10
-      if(NULL == w || NULL == s->w ||
-        -1 == af_filter_design_fir(s->up*L, w, &fc, LP|KAISER , 10.0)){
-       mp_msg(MSGT_AFILTER, MSGL_ERR, "[resample] Unable to design prototype filter.\n");
-       return AF_ERROR;
-      }
-      // Copy data from prototype to polyphase filter
-      wt=w;
-      for(j=0;j<L;j++){//Columns
-       for(i=0;i<s->up;i++){//Rows
-         if((s->setup & RSMP_MASK) == RSMP_INT){
-           float t=(float)s->up*32767.0*(*wt);
-           ((int16_t*)s->w)[i*L+j] = (int16_t)((t>=0.0)?(t+0.5):(t-0.5));
-         }
-         else
-           ((float*)s->w)[i*L+j] = (float)s->up*(*wt);
-         wt++;
-       }
-      }
-      free(w);
-      mp_msg(MSGT_AFILTER, MSGL_V, "[resample] New filter designed up: %i "
-            "down: %i\n", s->up, s->dn);
-    }
-
-    // Set multiplier and delay
-    af->delay = 0; // not set correctly, but shouldn't be too large anyway
-    af->mul = (double)s->up / s->dn;
-    return rv;
-  }
-  case AF_CONTROL_COMMAND_LINE:{
-    af_resample_t* s   = af->setup;
-    int rate=0;
-    int type=RSMP_INT;
-    int sloppy=1;
-    sscanf((char*)arg,"%i:%i:%i", &rate, &sloppy, &type);
-    s->setup = (sloppy?FREQ_SLOPPY:FREQ_EXACT) |
-      (clamp(type,RSMP_LIN,RSMP_FLOAT));
-    return af->control(af,AF_CONTROL_RESAMPLE_RATE | AF_CONTROL_SET, &rate);
-  }
-  case AF_CONTROL_POST_CREATE:
-    if((((af_cfg_t*)arg)->force & AF_INIT_FORMAT_MASK) == AF_INIT_FLOAT)
-      ((af_resample_t*)af->setup)->setup = RSMP_FLOAT;
-    return AF_OK;
-  case AF_CONTROL_RESAMPLE_RATE | AF_CONTROL_SET:
-    // Reinit must be called after this function has been called
-
-    // Sanity check
-    if(((int*)arg)[0] < 8000 || ((int*)arg)[0] > 192000){
-      mp_msg(MSGT_AFILTER, MSGL_ERR, "[resample] The output sample frequency "
-            "must be between 8kHz and 192kHz. Current value is %i \n",
-            ((int*)arg)[0]);
-      return AF_ERROR;
-    }
-
-    af->data->rate=((int*)arg)[0];
-    mp_msg(MSGT_AFILTER, MSGL_V, "[resample] Changing sample rate "
-          "to %iHz\n",af->data->rate);
-    return AF_OK;
-  }
-  return AF_UNKNOWN;
-}
-
-// Deallocate memory
-static void uninit(struct af_instance_s* af)
-{
-  af_resample_t *s = af->setup;
-  if (s) {
-    if (s->xq) free(s->xq[0]);
-    free(s->xq);
-    free(s->w);
-    free(s);
-  }
-  if(af->data)
-    free(af->data->audio);
-  free(af->data);
-}
-
-// Filter data through filter
-static af_data_t* play(struct af_instance_s* af, af_data_t* data)
-{
-  int           len = 0;        // Length of output data
-  af_data_t*     c   = data;    // Current working data
-  af_data_t*     l   = af->data; // Local data
-  af_resample_t* s   = af->setup;
-
-  if(AF_OK != RESIZE_LOCAL_BUFFER(af,data))
-    return NULL;
-
-  // Run resampling
-  switch(s->setup & RSMP_MASK){
-  case(RSMP_INT):
-# define FORMAT_I 1
-    if(s->up>s->dn){
-#     define UP
-#     include "af_resample_template.c"
-#     undef UP
-    }
-    else{
-#     define DN
-#     include "af_resample_template.c"
-#     undef DN
-    }
-    break;
-  case(RSMP_FLOAT):
-# undef FORMAT_I
-# define FORMAT_F 1
-    if(s->up>s->dn){
-#     define UP
-#     include "af_resample_template.c"
-#     undef UP
-    }
-    else{
-#     define DN
-#     include "af_resample_template.c"
-#     undef DN
-    }
-    break;
-  case(RSMP_LIN):
-    len = linint(c, l, s);
-    break;
-  }
-
-  // Set output data
-  c->audio = l->audio;
-  c->len   = len*l->bps;
-  c->rate  = l->rate;
-
-  return c;
-}
-
-// Allocate memory and set function pointers
-static int af_open(af_instance_t* af){
-  af->control=control;
-  af->uninit=uninit;
-  af->play=play;
-  af->mul=1;
-  af->data=calloc(1,sizeof(af_data_t));
-  af->setup=calloc(1,sizeof(af_resample_t));
-  if(af->data == NULL || af->setup == NULL)
-    return AF_ERROR;
-  ((af_resample_t*)af->setup)->setup = RSMP_INT | FREQ_SLOPPY;
-  return AF_OK;
-}
-
-// Description of this plugin
-af_info_t af_info_resample = {
-  "Sample frequency conversion",
-  "resample",
-  "Anders",
-  "",
-  AF_FLAGS_REENTRANT,
-  af_open
-};
diff --git a/libaf/af_resample_template.c b/libaf/af_resample_template.c
deleted file mode 100644 (file)
index 4d4c592..0000000
+++ /dev/null
@@ -1,171 +0,0 @@
-/*
- * Copyright (C) 2002 Anders Johansson [email protected]
- *
- * This file is part of MPlayer.
- *
- * MPlayer 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.
- *
- * MPlayer 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 MPlayer; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
- */
-
-/* This file contains the resampling engine, the sample format is
-   controlled by the FORMAT parameter, the filter length by the L
-   parameter and the resampling type by UP and DN. This file should
-   only be included by af_resample.c
-*/
-
-#undef L
-#undef SHIFT
-#undef FORMAT
-#undef FIR
-#undef ADDQUE
-
-/* The length Lxx definition selects the length of each poly phase
-   component. Valid definitions are L8 and L16 where the number
-   defines the nuber of taps. This definition affects the
-   computational complexity, the performance and the memory usage.
-*/
-
-/* The FORMAT_x parameter selects the sample format type currently
-   float and int16 are supported. Thes two formats are selected by
-   defining eiter FORMAT_F or FORMAT_I. The advantage of using float
-   is that the amplitude and therefore the SNR isn't affected by the
-   filtering, the disadvantage is that it is a lot slower.
-*/
-
-#if defined(FORMAT_I)
-#define SHIFT >>16
-#define FORMAT int16_t
-#else
-#define SHIFT
-#define FORMAT float
-#endif
-
-// Short filter
-#if defined(L8)
-
-#define L      8       // Filter length
-// Unrolled loop to speed up execution
-#define FIR(x,w,y) \
-  (y[0])  = ( w[0]*x[0]+w[1]*x[1]+w[2]*x[2]+w[3]*x[3] \
-            + w[4]*x[4]+w[5]*x[5]+w[6]*x[6]+w[7]*x[7] ) SHIFT
-
-
-
-#else  /* L8/L16 */
-
-#define L      16
-// Unrolled loop to speed up execution
-#define FIR(x,w,y) \
-  y[0] = ( w[0] *x[0] +w[1] *x[1] +w[2] *x[2] +w[3] *x[3] \
-         + w[4] *x[4] +w[5] *x[5] +w[6] *x[6] +w[7] *x[7] \
-         + w[8] *x[8] +w[9] *x[9] +w[10]*x[10]+w[11]*x[11] \
-         + w[12]*x[12]+w[13]*x[13]+w[14]*x[14]+w[15]*x[15] ) SHIFT
-
-#endif /* L8/L16 */
-
-// Macro to add data to circular que
-#define ADDQUE(xi,xq,in)\
-  xq[xi]=xq[(xi)+L]=*(in);\
-  xi=((xi)-1)&(L-1);
-
-#if defined(UP)
-
-  uint32_t             ci    = l->nch;         // Index for channels
-  uint32_t             nch   = l->nch;         // Number of channels
-  uint32_t             inc   = s->up/s->dn;
-  uint32_t             level = s->up%s->dn;
-  uint32_t             up    = s->up;
-  uint32_t             dn    = s->dn;
-  uint32_t             ns    = c->len/l->bps;
-  register FORMAT*     w     = s->w;
-
-  register uint32_t    wi    = 0;
-  register uint32_t    xi    = 0;
-
-  // Index current channel
-  while(ci--){
-    // Temporary pointers
-    register FORMAT*   x     = s->xq[ci];
-    register FORMAT*   in    = ((FORMAT*)c->audio)+ci;
-    register FORMAT*   out   = ((FORMAT*)l->audio)+ci;
-    FORMAT*            end   = in+ns; // Block loop end
-    wi = s->wi; xi = s->xi;
-
-    while(in < end){
-      register uint32_t        i = inc;
-      if(wi<level) i++;
-
-      ADDQUE(xi,x,in);
-      in+=nch;
-      while(i--){
-       // Run the FIR filter
-       FIR((&x[xi]),(&w[wi*L]),out);
-       len++; out+=nch;
-       // Update wi to point at the correct polyphase component
-       wi=(wi+dn)%up;
-      }
-    }
-
-  }
-  // Save values that needs to be kept for next time
-  s->wi = wi;
-  s->xi = xi;
-#endif /* UP */
-
-#if defined(DN) /* DN */
-  uint32_t             ci    = l->nch;         // Index for channels
-  uint32_t             nch   = l->nch;         // Number of channels
-  uint32_t             inc   = s->dn/s->up;
-  uint32_t             level = s->dn%s->up;
-  uint32_t             up    = s->up;
-  uint32_t             dn    = s->dn;
-  uint32_t             ns    = c->len/l->bps;
-  FORMAT*              w     = s->w;
-
-  register int32_t     i     = 0;
-  register uint32_t    wi    = 0;
-  register uint32_t    xi    = 0;
-
-  // Index current channel
-  while(ci--){
-    // Temporary pointers
-    register FORMAT*   x     = s->xq[ci];
-    register FORMAT*   in    = ((FORMAT*)c->audio)+ci;
-    register FORMAT*   out   = ((FORMAT*)l->audio)+ci;
-    register FORMAT*   end   = in+ns;    // Block loop end
-    i = s->i; wi = s->wi; xi = s->xi;
-
-    while(in < end){
-
-      ADDQUE(xi,x,in);
-      in+=nch;
-      if((--i)<=0){
-       // Run the FIR filter
-       FIR((&x[xi]),(&w[wi*L]),out);
-       len++;  out+=nch;
-
-       // Update wi to point at the correct polyphase component
-       wi=(wi+dn)%up;
-
-       // Insert i number of new samples in queue
-       i = inc;
-       if(wi<level) i++;
-      }
-    }
-  }
-  // Save values that needs to be kept for next time
-  s->wi = wi;
-  s->xi = xi;
-  s->i = i;
-#endif /* DN */
index 166a790..0aea120 100644 (file)
@@ -26,6 +26,7 @@
 #include <libavutil/audioconvert.h>
 #include <libavutil/opt.h>
 #include <libavutil/samplefmt.h>
+#include <libavresample/avresample.h>
 
 #include "talloc.h"
 
 
 #include "mpbswap.h"
 
-#ifdef CONFIG_LIBAVRESAMPLE
-#include <libavresample/avresample.h>
-#endif
-
 static const ad_info_t info =
 {
     "libavcodec audio decoders",
@@ -62,14 +59,12 @@ struct priv {
     int unitsize;
     int previous_data_left;  // input demuxer packet data
 
-#ifdef CONFIG_LIBAVRESAMPLE
     AVAudioResampleContext *avr;
     enum AVSampleFormat resample_fmt;
     enum AVSampleFormat out_fmt;
     int resample_channels;
     uint8_t *resample_buf;
     uint64_t resample_buf_size;
-#endif
 };
 
 static int preinit(sh_audio_t *sh)
@@ -104,17 +99,6 @@ static int setup_format(sh_audio_t *sh_audio)
 
     int sample_format = sample_fmt_lavc2native(codec->sample_fmt);
     if (sample_format == AF_FORMAT_UNKNOWN) {
-#ifndef CONFIG_LIBAVRESAMPLE
-        if (av_sample_fmt_is_planar(codec->sample_fmt))
-            mp_msg(MSGT_DECAUDIO, MSGL_ERR,
-                   "The player has been compiled without libavresample "
-                   "support,\nwhich is needed with this libavcodec decoder "
-                   "version.\nCompile with libavresample enabled to make "
-                   "audio decoding work!\n");
-        else
-            mp_msg(MSGT_DECAUDIO, MSGL_ERR, "Unsupported sample format\n");
-        goto error;
-#else
         if (priv->avr && (priv->resample_fmt      != codec->sample_fmt ||
                           priv->resample_channels != codec->channels))
             avresample_free(&priv->avr);
@@ -167,7 +151,6 @@ static int setup_format(sh_audio_t *sh_audio)
             sample_format = sh_audio->sample_format;
     } else if (priv->avr) {
         avresample_free(&priv->avr);
-#endif
     }
 
     bool broken_srate        = false;
@@ -195,9 +178,7 @@ static int setup_format(sh_audio_t *sh_audio)
     }
     return 0;
 error:
-#ifdef CONFIG_LIBAVRESAMPLE
     avresample_free(&priv->avr);
-#endif
     return -1;
 }
 
@@ -329,9 +310,7 @@ static void uninit(sh_audio_t *sh)
         av_freep(&lavc_context->extradata);
         av_freep(&lavc_context);
     }
-#ifdef CONFIG_LIBAVRESAMPLE
     avresample_free(&ctx->avr);
-#endif
 #if LIBAVCODEC_VERSION_INT >= (54 << 16 | 28 << 8)
     avcodec_free_frame(&ctx->avframe);
 #else
@@ -417,7 +396,6 @@ static int decode_new_packet(struct sh_audio *sh)
     if (format_result < 0)
         return format_result;
 
-#ifdef CONFIG_LIBAVRESAMPLE
     if (priv->avr) {
         int ret;
         uint64_t needed_size = av_samples_get_buffer_size(
@@ -445,9 +423,7 @@ static int decode_new_packet(struct sh_audio *sh)
 
         priv->output = priv->resample_buf;
         priv->output_left = priv->unitsize * ret;
-    } else
-#endif
-    {
+    } else {
         uint64_t unitsize = av_get_bytes_per_sample(avctx->sample_fmt) *
                             (uint64_t)avctx->channels;
         if (unitsize > 100000)