summaryrefslogtreecommitdiffstats
path: root/libaf
diff options
context:
space:
mode:
authormichael <michael@b3059339-0415-0410-9bf9-f77b7e298cf2>2004-10-21 03:32:31 +0000
committermichael <michael@b3059339-0415-0410-9bf9-f77b7e298cf2>2004-10-21 03:32:31 +0000
commit7981c2e20b4fff03657d78dc7b63a8f5064ee9bc (patch)
tree96e85fab7bfc5cea34a5a117083b9a1a5c3e40f2 /libaf
parent05e19b3333de6332a9952ab6bf94a29de067656e (diff)
downloadmpv-7981c2e20b4fff03657d78dc7b63a8f5064ee9bc.tar.bz2
mpv-7981c2e20b4fff03657d78dc7b63a8f5064ee9bc.tar.xz
libavcodec resampling ...
libaf doesnt seem to support planar audio, so we need to convert it :( git-svn-id: svn://svn.mplayerhq.hu/mplayer/trunk@13714 b3059339-0415-0410-9bf9-f77b7e298cf2
Diffstat (limited to 'libaf')
-rw-r--r--libaf/Makefile2
-rw-r--r--libaf/af.c4
-rw-r--r--libaf/af_lavcresample.c155
3 files changed, 160 insertions, 1 deletions
diff --git a/libaf/Makefile b/libaf/Makefile
index 188a0cee0a..3eacc3b7f6 100644
--- a/libaf/Makefile
+++ b/libaf/Makefile
@@ -2,7 +2,7 @@ include ../config.mak
LIBNAME = libaf.a
-SRCS=af.c af_mp.c af_dummy.c af_delay.c af_channels.c af_format.c af_resample.c window.c filter.c af_volume.c af_equalizer.c af_tools.c af_comp.c af_gate.c af_pan.c af_surround.c af_sub.c af_export.c af_volnorm.c af_extrastereo.c
+SRCS=af.c af_mp.c af_dummy.c af_delay.c af_channels.c af_format.c af_resample.c window.c filter.c af_volume.c af_equalizer.c af_tools.c af_comp.c af_gate.c af_pan.c af_surround.c af_sub.c af_export.c af_volnorm.c af_extrastereo.c af_lavcresample.c
OBJS=$(SRCS:.c=.o)
diff --git a/libaf/af.c b/libaf/af.c
index c0dcd7d78a..9189ce0b37 100644
--- a/libaf/af.c
+++ b/libaf/af.c
@@ -25,6 +25,7 @@ extern af_info_t af_info_sub;
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_lavcresample;
static af_info_t* filter_list[]={
&af_info_dummy,
@@ -44,6 +45,9 @@ static af_info_t* filter_list[]={
#endif
&af_info_volnorm,
&af_info_extrastereo,
+#ifdef USE_LIBAVCODEC
+ &af_info_lavcresample,
+#endif
NULL
};
diff --git a/libaf/af_lavcresample.c b/libaf/af_lavcresample.c
new file mode 100644
index 0000000000..e033c7e225
--- /dev/null
+++ b/libaf/af_lavcresample.c
@@ -0,0 +1,155 @@
+// Copyright (c) 2004 Michael Niedermayer <michaelni@gmx.at>
+// #inlcude <GPL_v2.h>
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <inttypes.h>
+
+#include "../config.h"
+#include "af.h"
+
+#ifdef USE_LIBAVCODEC
+
+#include "../libavcodec/avcodec.h"
+#include "../libavcodec/rational.h"
+
+#define CHANS 6
+
+// Data for specific instances of this filter
+typedef struct af_resample_s{
+ struct AVResampleContext *avrctx;
+ int16_t *in[CHANS];
+ int in_alloc;
+ int index;
+
+ int filter_length;
+ int linear;
+ int phase_shift;
+}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;
+
+ switch(cmd){
+ case AF_CONTROL_REINIT:
+ if((af->data->rate == data->rate) || (af->data->rate == 0))
+ return AF_DETACH;
+
+ if(data->format != (AF_FORMAT_SI | AF_FORMAT_NE) || data->nch > CHANS)
+ return AF_ERROR;
+
+ af->data->nch = data->nch;
+ af->data->format = AF_FORMAT_SI | AF_FORMAT_NE;
+ af->data->bps = 2;
+ af->mul.n = af->data->rate;
+ af->mul.d = data->rate;
+ af->delay = 500*s->filter_length/(double)min(af->mul.n, af->mul.d);
+
+ if(s->avrctx) av_resample_close(s->avrctx);
+ s->avrctx= av_resample_init(af->mul.n, /*in_rate*/af->mul.d, s->filter_length, s->phase_shift, s->linear);
+
+ return AF_OK;
+ case AF_CONTROL_COMMAND_LINE:{
+ sscanf((char*)arg,"%d:%d:%d:%d", &af->data->rate, &s->filter_length, &s->linear, &s->phase_shift);
+ 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);
+ if(af->setup){
+ af_resample_t *s = af->setup;
+ if(s->avrctx) av_resample_close(s->avrctx);
+ 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;
+ 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.n) / af->mul.d + 10;
+ int16_t tmp[CHANS][out_len];
+
+ if(AF_OK != RESIZE_LOCAL_BUFFER(af,data))
+ return NULL;
+
+ out= (int16_t*)af->data->audio;
+
+ 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)); //FIXME free this maybe ;)
+ }
+ }
+
+ 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));
+ }
+
+ 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 open(af_instance_t* af){
+ af->control=control;
+ af->uninit=uninit;
+ af->play=play;
+ af->mul.n=1;
+ af->mul.d=1;
+ af->data=calloc(1,sizeof(af_data_t));
+ af->setup=calloc(1,sizeof(af_resample_t));
+ ((af_resample_t*)af->setup)->filter_length= 16;
+ ((af_resample_t*)af->setup)->phase_shift= 10;
+// ((af_resample_t*)af->setup)->setup = RSMP_INT | FREQ_SLOPPY;
+ return AF_OK;
+}
+
+af_info_t af_info_lavcresample = {
+ "Sample frequency conversion using libavcodec",
+ "lavcresample",
+ "Michael Niedermayer",
+ "",
+ AF_FLAGS_REENTRANT,
+ open
+};
+#endif