2 * Copyright (c) 2004 Michael Niedermayer <michaelni@gmx.at>
4 * This file is part of MPlayer.
6 * MPlayer is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
11 * MPlayer is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
16 * You should have received a copy of the GNU General Public License along
17 * with MPlayer; if not, write to the Free Software Foundation, Inc.,
18 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
28 #include "libavcodec/avcodec.h"
29 #include "libavutil/rational.h"
31 // Data for specific instances of this filter
32 typedef struct af_resample_s
{
33 struct AVResampleContext
*avrctx
;
52 // Initialization and runtime control
53 static int control(struct af_instance_s
* af
, int cmd
, void* arg
)
55 af_resample_t
* s
= (af_resample_t
*)af
->setup
;
56 af_data_t
*data
= (af_data_t
*)arg
;
57 int out_rate
, test_output_res
; // helpers for checking input format
60 case AF_CONTROL_REINIT
:
61 if((af
->data
->rate
== data
->rate
) || (af
->data
->rate
== 0))
64 af
->data
->nch
= data
->nch
;
65 if (af
->data
->nch
> AF_NCH
) af
->data
->nch
= AF_NCH
;
66 af
->data
->format
= AF_FORMAT_S16_NE
;
68 af
->mul
= (double)af
->data
->rate
/ data
->rate
;
69 af
->delay
= af
->data
->nch
* s
->filter_length
/ min(af
->mul
, 1); // *bps*.5
71 if (s
->ctx_out_rate
!= af
->data
->rate
|| s
->ctx_in_rate
!= data
->rate
|| s
->ctx_filter_size
!= s
->filter_length
||
72 s
->ctx_phase_shift
!= s
->phase_shift
|| s
->ctx_linear
!= s
->linear
|| s
->ctx_cutoff
!= s
->cutoff
) {
73 if(s
->avrctx
) av_resample_close(s
->avrctx
);
74 s
->avrctx
= av_resample_init(af
->data
->rate
, /*in_rate*/data
->rate
, s
->filter_length
, s
->phase_shift
, s
->linear
, s
->cutoff
);
75 s
->ctx_out_rate
= af
->data
->rate
;
76 s
->ctx_in_rate
= data
->rate
;
77 s
->ctx_filter_size
= s
->filter_length
;
78 s
->ctx_phase_shift
= s
->phase_shift
;
79 s
->ctx_linear
= s
->linear
;
80 s
->ctx_cutoff
= s
->cutoff
;
83 // hack to make af_test_output ignore the samplerate change
84 out_rate
= af
->data
->rate
;
85 af
->data
->rate
= data
->rate
;
86 test_output_res
= af_test_output(af
, (af_data_t
*)arg
);
87 af
->data
->rate
= out_rate
;
88 return test_output_res
;
89 case AF_CONTROL_COMMAND_LINE
:{
91 sscanf((char*)arg
,"%d:%d:%d:%d:%lf", &af
->data
->rate
, &s
->filter_length
, &s
->linear
, &s
->phase_shift
, &s
->cutoff
);
92 if(s
->cutoff
<= 0.0) s
->cutoff
= max(1.0 - 6.5/(s
->filter_length
+8), 0.80);
95 case AF_CONTROL_RESAMPLE_RATE
| AF_CONTROL_SET
:
96 af
->data
->rate
= *(int*)arg
;
103 static void uninit(struct af_instance_s
* af
)
106 free(af
->data
->audio
);
110 af_resample_t
*s
= af
->setup
;
111 if(s
->avrctx
) av_resample_close(s
->avrctx
);
112 for (i
=0; i
< AF_NCH
; i
++)
118 // Filter data through filter
119 static af_data_t
* play(struct af_instance_s
* af
, af_data_t
* data
)
121 af_resample_t
*s
= af
->setup
;
122 int i
, j
, consumed
, ret
;
123 int16_t *in
= (int16_t*)data
->audio
;
125 int chans
= data
->nch
;
126 int in_len
= data
->len
/(2*chans
);
127 int out_len
= in_len
* af
->mul
+ 10;
128 int16_t tmp
[AF_NCH
][out_len
];
130 if(AF_OK
!= RESIZE_LOCAL_BUFFER(af
,data
))
133 out
= (int16_t*)af
->data
->audio
;
135 out_len
= min(out_len
, af
->data
->len
/(2*chans
));
137 if(s
->in_alloc
< in_len
+ s
->index
){
138 s
->in_alloc
= in_len
+ s
->index
;
139 for(i
=0; i
<chans
; i
++){
140 s
->in
[i
]= realloc(s
->in
[i
], s
->in_alloc
*sizeof(int16_t));
145 memcpy(&s
->in
[0][s
->index
], in
, in_len
* sizeof(int16_t));
147 for(j
=0; j
<in_len
; j
++){
148 s
->in
[0][j
+ s
->index
]= *(in
++);
149 s
->in
[1][j
+ s
->index
]= *(in
++);
152 for(j
=0; j
<in_len
; j
++){
153 for(i
=0; i
<chans
; i
++){
154 s
->in
[i
][j
+ s
->index
]= *(in
++);
160 for(i
=0; i
<chans
; i
++){
161 ret
= av_resample(s
->avrctx
, tmp
[i
], s
->in
[i
], &consumed
, in_len
, out_len
, i
+1 == chans
);
165 s
->index
= in_len
- consumed
;
166 for(i
=0; i
<chans
; i
++){
167 memmove(s
->in
[i
], s
->in
[i
] + consumed
, s
->index
*sizeof(int16_t));
171 memcpy(out
, tmp
[0], out_len
*sizeof(int16_t));
173 for(j
=0; j
<out_len
; j
++){
178 for(j
=0; j
<out_len
; j
++){
179 for(i
=0; i
<chans
; i
++){
185 data
->audio
= af
->data
->audio
;
186 data
->len
= out_len
*chans
*2;
187 data
->rate
= af
->data
->rate
;
191 static int af_open(af_instance_t
* af
){
192 af_resample_t
*s
= calloc(1,sizeof(af_resample_t
));
197 af
->data
=calloc(1,sizeof(af_data_t
));
198 s
->filter_length
= 16;
199 s
->cutoff
= max(1.0 - 6.5/(s
->filter_length
+8), 0.80);
201 // s->setup = RSMP_INT | FREQ_SLOPPY;
206 af_info_t af_info_lavcresample
= {
207 "Sample frequency conversion using libavcodec",
209 "Michael Niedermayer",