FFmpeg
resample_template.c
Go to the documentation of this file.
1 /*
2  * audio resampling
3  * Copyright (c) 2004-2012 Michael Niedermayer <michaelni@gmx.at>
4  *
5  * This file is part of FFmpeg.
6  *
7  * FFmpeg is free software; you can redistribute it and/or
8  * modify it under the terms of the GNU Lesser General Public
9  * License as published by the Free Software Foundation; either
10  * version 2.1 of the License, or (at your option) any later version.
11  *
12  * FFmpeg is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15  * Lesser General Public License for more details.
16  *
17  * You should have received a copy of the GNU Lesser General Public
18  * License along with FFmpeg; if not, write to the Free Software
19  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
20  */
21 
22 /**
23  * @file
24  * audio resampling
25  * @author Michael Niedermayer <michaelni@gmx.at>
26  */
27 
28 // FELEM2U, a variant of FELEM2 which does not produce undefined overflow
29 
30 #if defined(TEMPLATE_RESAMPLE_DBL)
31 
32 # define RENAME(N) N ## _double
33 # define FILTER_SHIFT 0
34 # define DELEM double
35 # define FELEM double
36 # define FELEM2 double
37 # define FELEM2U double
38 # define FOFFSET 0
39 # define OUT(d, v) d = v
40 
41 #elif defined(TEMPLATE_RESAMPLE_FLT)
42 
43 # define RENAME(N) N ## _float
44 # define FILTER_SHIFT 0
45 # define DELEM float
46 # define FELEM float
47 # define FELEM2 float
48 # define FELEM2U float
49 # define FOFFSET 0
50 # define OUT(d, v) d = v
51 
52 #elif defined(TEMPLATE_RESAMPLE_S32)
53 
54 # define RENAME(N) N ## _int32
55 # define FILTER_SHIFT 30
56 # define DELEM int32_t
57 # define FELEM int32_t
58 # define FELEM2 int64_t
59 # define FELEM2U uint64_t
60 # define FELEM_MAX INT32_MAX
61 # define FELEM_MIN INT32_MIN
62 # define FOFFSET (1<<(FILTER_SHIFT-1))
63 # define OUT(d, v) (d) = av_clipl_int32((v)>>FILTER_SHIFT)
64 
65 #elif defined(TEMPLATE_RESAMPLE_S16)
66 
67 # define RENAME(N) N ## _int16
68 # define FILTER_SHIFT 15
69 # define DELEM int16_t
70 # define FELEM int16_t
71 # define FELEM2 int32_t
72 # define FELEM2U uint32_t
73 # define FELEML int64_t
74 # define FELEM_MAX INT16_MAX
75 # define FELEM_MIN INT16_MIN
76 # define FOFFSET (1<<(FILTER_SHIFT-1))
77 # define OUT(d, v) (d) = av_clip_int16((v)>>FILTER_SHIFT)
78 
79 #endif
80 
81 static void RENAME(resample_one)(void *dest, const void *source,
82  int dst_size, int64_t index2, int64_t incr)
83 {
84  DELEM *dst = dest;
85  const DELEM *src = source;
86  int dst_index;
87 
88  for (dst_index = 0; dst_index < dst_size; dst_index++) {
89  dst[dst_index] = src[index2 >> 32];
90  index2 += incr;
91  }
92 }
93 
95  void *dest, const void *source,
96  int n, int update_ctx)
97 {
98  DELEM *dst = dest;
99  const DELEM *src = source;
100  int dst_index;
101  int index= c->index;
102  int frac= c->frac;
103  int sample_index = 0;
104 
105  while (index >= c->phase_count) {
106  sample_index++;
107  index -= c->phase_count;
108  }
109 
110  for (dst_index = 0; dst_index < n; dst_index++) {
111  FELEM *filter = ((FELEM *) c->filter_bank) + c->filter_alloc * index;
112 
113  FELEM2 val = FOFFSET;
114  FELEM2 val2= 0;
115  int i;
116  for (i = 0; i + 1 < c->filter_length; i+=2) {
117  val += src[sample_index + i ] * (FELEM2)filter[i ];
118  val2 += src[sample_index + i + 1] * (FELEM2)filter[i + 1];
119  }
120  if (i < c->filter_length)
121  val += src[sample_index + i ] * (FELEM2)filter[i ];
122 #ifdef FELEML
123  OUT(dst[dst_index], val + (FELEML)val2);
124 #else
125  OUT(dst[dst_index], val + val2);
126 #endif
127 
128  frac += c->dst_incr_mod;
129  index += c->dst_incr_div;
130  if (frac >= c->src_incr) {
131  frac -= c->src_incr;
132  index++;
133  }
134 
135  while (index >= c->phase_count) {
136  sample_index++;
137  index -= c->phase_count;
138  }
139  }
140 
141  if(update_ctx){
142  c->frac= frac;
143  c->index= index;
144  }
145 
146  return sample_index;
147 }
148 
150  void *dest, const void *source,
151  int n, int update_ctx)
152 {
153  DELEM *dst = dest;
154  const DELEM *src = source;
155  int dst_index;
156  int index= c->index;
157  int frac= c->frac;
158  int sample_index = 0;
159 #if FILTER_SHIFT == 0
160  double inv_src_incr = 1.0 / c->src_incr;
161 #endif
162 
163  while (index >= c->phase_count) {
164  sample_index++;
165  index -= c->phase_count;
166  }
167 
168  for (dst_index = 0; dst_index < n; dst_index++) {
169  FELEM *filter = ((FELEM *) c->filter_bank) + c->filter_alloc * index;
170  FELEM2U val = FOFFSET, v2 = FOFFSET;
171 
172  int i;
173  for (i = 0; i < c->filter_length; i++) {
174  val += src[sample_index + i] * (FELEM2)filter[i];
175  v2 += src[sample_index + i] * (FELEM2)filter[i + c->filter_alloc];
176  }
177 #ifdef FELEML
178  val += (FELEM2)(v2 - val) * (FELEML) frac / c->src_incr;
179 #else
180 # if FILTER_SHIFT == 0
181  val += (FELEM2)(v2 - val) * inv_src_incr * frac;
182 # else
183  val += (FELEM2)(v2 - val) / c->src_incr * frac;
184 # endif
185 #endif
186  OUT(dst[dst_index], (FELEM2)val);
187 
188  frac += c->dst_incr_mod;
189  index += c->dst_incr_div;
190  if (frac >= c->src_incr) {
191  frac -= c->src_incr;
192  index++;
193  }
194 
195  while (index >= c->phase_count) {
196  sample_index++;
197  index -= c->phase_count;
198  }
199  }
200 
201  if(update_ctx){
202  c->frac= frac;
203  c->index= index;
204  }
205 
206  return sample_index;
207 }
208 
209 #undef RENAME
210 #undef FILTER_SHIFT
211 #undef DELEM
212 #undef FELEM
213 #undef FELEM2
214 #undef FELEM2U
215 #undef FELEML
216 #undef FELEM_MAX
217 #undef FELEM_MIN
218 #undef OUT
219 #undef FOFFSET
ResampleContext::resample_one
void(* resample_one)(void *dst, const void *src, int n, int64_t index, int64_t incr)
Definition: resample.h:54
ResampleContext::frac
int frac
Definition: resample.h:40
int64_t
long long int64_t
Definition: coverity.c:34
filter
void(* filter)(uint8_t *src, int stride, int qscale)
Definition: h263dsp.c:29
ResampleContext::resample_common
int(* resample_common)(struct ResampleContext *c, void *dst, const void *src, int n, int update_ctx)
Definition: resample.h:56
ResampleContext::filter_length
int filter_length
Definition: resample.h:33
val
static double val(void *priv, double ch)
Definition: aeval.c:77
resample_linear
static int resample_linear(AVFilterContext *ctx, void *arg, int job, int nb_jobs)
Definition: vf_perspective.c:355
ResampleContext
Definition: resample.h:30
index
int index
Definition: gxfenc.c:90
c
Undefined Behavior In the C some operations are like signed integer dereferencing freed accessing outside allocated Undefined Behavior must not occur in a C it is not safe even if the output of undefined operations is unused The unsafety may seem nit picking but Optimizing compilers have in fact optimized code on the assumption that no undefined Behavior occurs Optimizing code based on wrong assumptions can and has in some cases lead to effects beyond the output of computations The signed integer overflow problem in speed critical code Code which is highly optimized and works with signed integers sometimes has the problem that often the output of the computation does not c
Definition: undefined.txt:32
source
these buffered frames must be flushed immediately if a new input produces new the filter must not call request_frame to get more It must just process the frame or queue it The task of requesting more frames is left to the filter s request_frame method or the application If a filter has several the filter must be ready for frames arriving randomly on any input any filter with several inputs will most likely require some kind of queuing mechanism It is perfectly acceptable to have a limited queue and to drop frames when the inputs are too unbalanced request_frame For filters that do not use the this method is called when a frame is wanted on an output For a source
Definition: filter_design.txt:256
dst
uint8_t ptrdiff_t const uint8_t ptrdiff_t int intptr_t intptr_t int int16_t * dst
Definition: dsp.h:87
i
#define i(width, name, range_min, range_max)
Definition: cbs_h264.c:63
OUT
@ OUT
Definition: af_loudnorm.c:41
RENAME
#define RENAME(element)
Definition: ac3enc_template.c:44
src
#define src
Definition: vp8dsp.c:248