Mercurial > mplayer.hg
changeset 13713:28bb0f15ac91
libavcodec resampling ...
libaf doesnt seem to support planar audio, so we need to convert it :(
author | michael |
---|---|
date | Thu, 21 Oct 2004 03:32:31 +0000 |
parents | f6ef5a0ad7e4 |
children | 3995da1d8d68 |
files | libaf/Makefile libaf/af.c libaf/af_lavcresample.c |
diffstat | 3 files changed, 160 insertions(+), 1 deletions(-) [+] |
line wrap: on
line diff
--- a/libaf/Makefile Wed Oct 20 23:33:31 2004 +0000 +++ b/libaf/Makefile Thu Oct 21 03:32:31 2004 +0000 @@ -2,7 +2,7 @@ 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)
--- a/libaf/af.c Wed Oct 20 23:33:31 2004 +0000 +++ b/libaf/af.c Thu Oct 21 03:32:31 2004 +0000 @@ -25,6 +25,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_lavcresample; static af_info_t* filter_list[]={ &af_info_dummy, @@ -44,6 +45,9 @@ #endif &af_info_volnorm, &af_info_extrastereo, +#ifdef USE_LIBAVCODEC + &af_info_lavcresample, +#endif NULL };
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/libaf/af_lavcresample.c Thu Oct 21 03:32:31 2004 +0000 @@ -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