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
17 * along with MPlayer; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
29 #ifdef USE_LIBAVCODEC_SO
30 #include <ffmpeg/avcodec.h>
31 #include <ffmpeg/rational.h>
37 // Data for specific instances of this filter
38 typedef struct af_resample_s
{
39 struct AVResampleContext
*avrctx
;
51 // Initialization and runtime control
52 static int control(struct af_instance_s
* af
, int cmd
, void* arg
)
54 af_resample_t
* s
= (af_resample_t
*)af
->setup
;
55 af_data_t
*data
= (af_data_t
*)arg
;
56 int out_rate
, test_output_res
; // helpers for checking input format
59 case AF_CONTROL_REINIT
:
60 if((af
->data
->rate
== data
->rate
) || (af
->data
->rate
== 0))
63 af
->data
->nch
= data
->nch
;
64 if (af
->data
->nch
> AF_NCH
) af
->data
->nch
= AF_NCH
;
65 af
->data
->format
= AF_FORMAT_S16_NE
;
67 af
->mul
= (double)af
->data
->rate
/ data
->rate
;
68 af
->delay
= af
->data
->nch
* s
->filter_length
/ min(af
->mul
, 1); // *bps*.5
70 if(s
->avrctx
) av_resample_close(s
->avrctx
);
71 s
->avrctx
= av_resample_init(af
->data
->rate
, /*in_rate*/data
->rate
, s
->filter_length
, s
->phase_shift
, s
->linear
, s
->cutoff
);
73 // hack to make af_test_output ignore the samplerate change
74 out_rate
= af
->data
->rate
;
75 af
->data
->rate
= data
->rate
;
76 test_output_res
= af_test_output(af
, (af_data_t
*)arg
);
77 af
->data
->rate
= out_rate
;
78 return test_output_res
;
79 case AF_CONTROL_COMMAND_LINE
:{
81 sscanf((char*)arg
,"%d:%d:%d:%d:%lf", &af
->data
->rate
, &s
->filter_length
, &s
->linear
, &s
->phase_shift
, &s
->cutoff
);
82 if(s
->cutoff
<= 0.0) s
->cutoff
= max(1.0 - 6.5/(s
->filter_length
+8), 0.80);
85 case AF_CONTROL_RESAMPLE_RATE
| AF_CONTROL_SET
:
86 af
->data
->rate
= *(int*)arg
;
93 static void uninit(struct af_instance_s
* af
)
96 free(af
->data
->audio
);
100 af_resample_t
*s
= af
->setup
;
101 if(s
->avrctx
) av_resample_close(s
->avrctx
);
102 for (i
=0; i
< AF_NCH
; i
++)
108 // Filter data through filter
109 static af_data_t
* play(struct af_instance_s
* af
, af_data_t
* data
)
111 af_resample_t
*s
= af
->setup
;
112 int i
, j
, consumed
, ret
;
113 int16_t *in
= (int16_t*)data
->audio
;
115 int chans
= data
->nch
;
116 int in_len
= data
->len
/(2*chans
);
117 int out_len
= in_len
* af
->mul
+ 10;
118 int16_t tmp
[AF_NCH
][out_len
];
120 if(AF_OK
!= RESIZE_LOCAL_BUFFER(af
,data
))
123 out
= (int16_t*)af
->data
->audio
;
125 out_len
= min(out_len
, af
->data
->len
/(2*chans
));
127 if(s
->in_alloc
< in_len
+ s
->index
){
128 s
->in_alloc
= in_len
+ s
->index
;
129 for(i
=0; i
<chans
; i
++){
130 s
->in
[i
]= realloc(s
->in
[i
], s
->in_alloc
*sizeof(int16_t));
135 memcpy(&s
->in
[0][s
->index
], in
, in_len
* sizeof(int16_t));
137 for(j
=0; j
<in_len
; j
++){
138 s
->in
[0][j
+ s
->index
]= *(in
++);
139 s
->in
[1][j
+ s
->index
]= *(in
++);
142 for(j
=0; j
<in_len
; j
++){
143 for(i
=0; i
<chans
; i
++){
144 s
->in
[i
][j
+ s
->index
]= *(in
++);
150 for(i
=0; i
<chans
; i
++){
151 ret
= av_resample(s
->avrctx
, tmp
[i
], s
->in
[i
], &consumed
, in_len
, out_len
, i
+1 == chans
);
155 s
->index
= in_len
- consumed
;
156 for(i
=0; i
<chans
; i
++){
157 memmove(s
->in
[i
], s
->in
[i
] + consumed
, s
->index
*sizeof(int16_t));
161 memcpy(out
, tmp
[0], out_len
*sizeof(int16_t));
163 for(j
=0; j
<out_len
; j
++){
168 for(j
=0; j
<out_len
; j
++){
169 for(i
=0; i
<chans
; i
++){
175 data
->audio
= af
->data
->audio
;
176 data
->len
= out_len
*chans
*2;
177 data
->rate
= af
->data
->rate
;
181 static int af_open(af_instance_t
* af
){
182 af_resample_t
*s
= calloc(1,sizeof(af_resample_t
));
187 af
->data
=calloc(1,sizeof(af_data_t
));
188 s
->filter_length
= 16;
189 s
->cutoff
= max(1.0 - 6.5/(s
->filter_length
+8), 0.80);
191 // s->setup = RSMP_INT | FREQ_SLOPPY;
196 af_info_t af_info_lavcresample
= {
197 "Sample frequency conversion using libavcodec",
199 "Michael Niedermayer",