Mercurial > libavcodec.hg
annotate resample.c @ 2504:f12657081093 libavcodec
INTRA PCM macroblocks support patch by (Loic )lll+ffmpeg m4x org)
This patch adds the support for INTRA PCM macroblocks in CAVLC and CABAC
mode, the deblocking needed a small modification and so did the
intra4x4_pred_mode prediction.
With this patch, the 5 streams of the conformance suite containing INTRA
PCM macroblocks now decode entirely, 4 are completely corrects, 1 is
incorrect since the first B slice because of deblocking in B slice not
yet implemented.
The code is not optimized for speed, it is not necessary IPCM
macroblocks are rare, but it could be optimized for code size, if
someone want to do this, feel free.
author | michael |
---|---|
date | Mon, 07 Feb 2005 00:10:28 +0000 |
parents | de38526a1f3f |
children | e25782262d7d |
rev | line source |
---|---|
0 | 1 /* |
2 * Sample rate convertion for both audio and video | |
429 | 3 * Copyright (c) 2000 Fabrice Bellard. |
0 | 4 * |
429 | 5 * This library is free software; you can redistribute it and/or |
6 * modify it under the terms of the GNU Lesser General Public | |
7 * License as published by the Free Software Foundation; either | |
8 * version 2 of the License, or (at your option) any later version. | |
0 | 9 * |
429 | 10 * This library is distributed in the hope that it will be useful, |
0 | 11 * but WITHOUT ANY WARRANTY; without even the implied warranty of |
429 | 12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
13 * Lesser General Public License for more details. | |
0 | 14 * |
429 | 15 * You should have received a copy of the GNU Lesser General Public |
16 * License along with this library; if not, write to the Free Software | |
17 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | |
0 | 18 */ |
1106 | 19 |
20 /** | |
21 * @file resample.c | |
22 * Sample rate convertion for both audio and video. | |
23 */ | |
24 | |
64 | 25 #include "avcodec.h" |
1125
0980ae063f4e
restoring OS/2 compatibility patch by ("Slavik Gnatenko" <miracle9 at newmail dot ru>)
michaelni
parents:
1106
diff
changeset
|
26 |
2082
3dc9bbe1b152
polyphase kaiser windowed sinc and blackman nuttall windowed sinc audio resample filters
michael
parents:
1598
diff
changeset
|
27 struct AVResampleContext; |
0 | 28 |
29 struct ReSampleContext { | |
2082
3dc9bbe1b152
polyphase kaiser windowed sinc and blackman nuttall windowed sinc audio resample filters
michael
parents:
1598
diff
changeset
|
30 struct AVResampleContext *resample_context; |
3dc9bbe1b152
polyphase kaiser windowed sinc and blackman nuttall windowed sinc audio resample filters
michael
parents:
1598
diff
changeset
|
31 short *temp[2]; |
3dc9bbe1b152
polyphase kaiser windowed sinc and blackman nuttall windowed sinc audio resample filters
michael
parents:
1598
diff
changeset
|
32 int temp_len; |
0 | 33 float ratio; |
34 /* channel convert */ | |
35 int input_channels, output_channels, filter_channels; | |
36 }; | |
37 | |
38 /* n1: number of samples */ | |
39 static void stereo_to_mono(short *output, short *input, int n1) | |
40 { | |
41 short *p, *q; | |
42 int n = n1; | |
43 | |
44 p = input; | |
45 q = output; | |
46 while (n >= 4) { | |
47 q[0] = (p[0] + p[1]) >> 1; | |
48 q[1] = (p[2] + p[3]) >> 1; | |
49 q[2] = (p[4] + p[5]) >> 1; | |
50 q[3] = (p[6] + p[7]) >> 1; | |
51 q += 4; | |
52 p += 8; | |
53 n -= 4; | |
54 } | |
55 while (n > 0) { | |
56 q[0] = (p[0] + p[1]) >> 1; | |
57 q++; | |
58 p += 2; | |
59 n--; | |
60 } | |
61 } | |
62 | |
63 /* n1: number of samples */ | |
64 static void mono_to_stereo(short *output, short *input, int n1) | |
65 { | |
66 short *p, *q; | |
67 int n = n1; | |
68 int v; | |
69 | |
70 p = input; | |
71 q = output; | |
72 while (n >= 4) { | |
73 v = p[0]; q[0] = v; q[1] = v; | |
74 v = p[1]; q[2] = v; q[3] = v; | |
75 v = p[2]; q[4] = v; q[5] = v; | |
76 v = p[3]; q[6] = v; q[7] = v; | |
77 q += 8; | |
78 p += 4; | |
79 n -= 4; | |
80 } | |
81 while (n > 0) { | |
82 v = p[0]; q[0] = v; q[1] = v; | |
83 q += 2; | |
84 p += 1; | |
85 n--; | |
86 } | |
87 } | |
88 | |
89 /* XXX: should use more abstract 'N' channels system */ | |
90 static void stereo_split(short *output1, short *output2, short *input, int n) | |
91 { | |
92 int i; | |
93 | |
94 for(i=0;i<n;i++) { | |
95 *output1++ = *input++; | |
96 *output2++ = *input++; | |
97 } | |
98 } | |
99 | |
100 static void stereo_mux(short *output, short *input1, short *input2, int n) | |
101 { | |
102 int i; | |
103 | |
104 for(i=0;i<n;i++) { | |
105 *output++ = *input1++; | |
106 *output++ = *input2++; | |
107 } | |
108 } | |
109 | |
1408
4d67eb341a0c
AC3 encoding patch ba (Ross Martin <ffmpeg at ross dot interwrx dot com>)
michaelni
parents:
1128
diff
changeset
|
110 static void ac3_5p1_mux(short *output, short *input1, short *input2, int n) |
4d67eb341a0c
AC3 encoding patch ba (Ross Martin <ffmpeg at ross dot interwrx dot com>)
michaelni
parents:
1128
diff
changeset
|
111 { |
4d67eb341a0c
AC3 encoding patch ba (Ross Martin <ffmpeg at ross dot interwrx dot com>)
michaelni
parents:
1128
diff
changeset
|
112 int i; |
4d67eb341a0c
AC3 encoding patch ba (Ross Martin <ffmpeg at ross dot interwrx dot com>)
michaelni
parents:
1128
diff
changeset
|
113 short l,r; |
4d67eb341a0c
AC3 encoding patch ba (Ross Martin <ffmpeg at ross dot interwrx dot com>)
michaelni
parents:
1128
diff
changeset
|
114 |
4d67eb341a0c
AC3 encoding patch ba (Ross Martin <ffmpeg at ross dot interwrx dot com>)
michaelni
parents:
1128
diff
changeset
|
115 for(i=0;i<n;i++) { |
4d67eb341a0c
AC3 encoding patch ba (Ross Martin <ffmpeg at ross dot interwrx dot com>)
michaelni
parents:
1128
diff
changeset
|
116 l=*input1++; |
4d67eb341a0c
AC3 encoding patch ba (Ross Martin <ffmpeg at ross dot interwrx dot com>)
michaelni
parents:
1128
diff
changeset
|
117 r=*input2++; |
4d67eb341a0c
AC3 encoding patch ba (Ross Martin <ffmpeg at ross dot interwrx dot com>)
michaelni
parents:
1128
diff
changeset
|
118 *output++ = l; /* left */ |
4d67eb341a0c
AC3 encoding patch ba (Ross Martin <ffmpeg at ross dot interwrx dot com>)
michaelni
parents:
1128
diff
changeset
|
119 *output++ = (l/2)+(r/2); /* center */ |
4d67eb341a0c
AC3 encoding patch ba (Ross Martin <ffmpeg at ross dot interwrx dot com>)
michaelni
parents:
1128
diff
changeset
|
120 *output++ = r; /* right */ |
4d67eb341a0c
AC3 encoding patch ba (Ross Martin <ffmpeg at ross dot interwrx dot com>)
michaelni
parents:
1128
diff
changeset
|
121 *output++ = 0; /* left surround */ |
4d67eb341a0c
AC3 encoding patch ba (Ross Martin <ffmpeg at ross dot interwrx dot com>)
michaelni
parents:
1128
diff
changeset
|
122 *output++ = 0; /* right surroud */ |
4d67eb341a0c
AC3 encoding patch ba (Ross Martin <ffmpeg at ross dot interwrx dot com>)
michaelni
parents:
1128
diff
changeset
|
123 *output++ = 0; /* low freq */ |
4d67eb341a0c
AC3 encoding patch ba (Ross Martin <ffmpeg at ross dot interwrx dot com>)
michaelni
parents:
1128
diff
changeset
|
124 } |
4d67eb341a0c
AC3 encoding patch ba (Ross Martin <ffmpeg at ross dot interwrx dot com>)
michaelni
parents:
1128
diff
changeset
|
125 } |
4d67eb341a0c
AC3 encoding patch ba (Ross Martin <ffmpeg at ross dot interwrx dot com>)
michaelni
parents:
1128
diff
changeset
|
126 |
0 | 127 ReSampleContext *audio_resample_init(int output_channels, int input_channels, |
128 int output_rate, int input_rate) | |
129 { | |
130 ReSampleContext *s; | |
131 int i; | |
132 | |
1408
4d67eb341a0c
AC3 encoding patch ba (Ross Martin <ffmpeg at ross dot interwrx dot com>)
michaelni
parents:
1128
diff
changeset
|
133 if ( input_channels > 2) |
4d67eb341a0c
AC3 encoding patch ba (Ross Martin <ffmpeg at ross dot interwrx dot com>)
michaelni
parents:
1128
diff
changeset
|
134 { |
1598
932d306bf1dc
av_log() patch by (Michel Bardiaux <mbardiaux at peaktime dot be>)
michael
parents:
1446
diff
changeset
|
135 av_log(NULL, AV_LOG_ERROR, "Resampling with input channels greater than 2 unsupported."); |
1408
4d67eb341a0c
AC3 encoding patch ba (Ross Martin <ffmpeg at ross dot interwrx dot com>)
michaelni
parents:
1128
diff
changeset
|
136 return NULL; |
4d67eb341a0c
AC3 encoding patch ba (Ross Martin <ffmpeg at ross dot interwrx dot com>)
michaelni
parents:
1128
diff
changeset
|
137 } |
0 | 138 |
139 s = av_mallocz(sizeof(ReSampleContext)); | |
140 if (!s) | |
1408
4d67eb341a0c
AC3 encoding patch ba (Ross Martin <ffmpeg at ross dot interwrx dot com>)
michaelni
parents:
1128
diff
changeset
|
141 { |
1598
932d306bf1dc
av_log() patch by (Michel Bardiaux <mbardiaux at peaktime dot be>)
michael
parents:
1446
diff
changeset
|
142 av_log(NULL, AV_LOG_ERROR, "Can't allocate memory for resample context."); |
1408
4d67eb341a0c
AC3 encoding patch ba (Ross Martin <ffmpeg at ross dot interwrx dot com>)
michaelni
parents:
1128
diff
changeset
|
143 return NULL; |
4d67eb341a0c
AC3 encoding patch ba (Ross Martin <ffmpeg at ross dot interwrx dot com>)
michaelni
parents:
1128
diff
changeset
|
144 } |
0 | 145 |
146 s->ratio = (float)output_rate / (float)input_rate; | |
147 | |
148 s->input_channels = input_channels; | |
149 s->output_channels = output_channels; | |
150 | |
151 s->filter_channels = s->input_channels; | |
152 if (s->output_channels < s->filter_channels) | |
153 s->filter_channels = s->output_channels; | |
154 | |
1408
4d67eb341a0c
AC3 encoding patch ba (Ross Martin <ffmpeg at ross dot interwrx dot com>)
michaelni
parents:
1128
diff
changeset
|
155 /* |
4d67eb341a0c
AC3 encoding patch ba (Ross Martin <ffmpeg at ross dot interwrx dot com>)
michaelni
parents:
1128
diff
changeset
|
156 * ac3 output is the only case where filter_channels could be greater than 2. |
4d67eb341a0c
AC3 encoding patch ba (Ross Martin <ffmpeg at ross dot interwrx dot com>)
michaelni
parents:
1128
diff
changeset
|
157 * input channels can't be greater than 2, so resample the 2 channels and then |
4d67eb341a0c
AC3 encoding patch ba (Ross Martin <ffmpeg at ross dot interwrx dot com>)
michaelni
parents:
1128
diff
changeset
|
158 * expand to 6 channels after the resampling. |
4d67eb341a0c
AC3 encoding patch ba (Ross Martin <ffmpeg at ross dot interwrx dot com>)
michaelni
parents:
1128
diff
changeset
|
159 */ |
4d67eb341a0c
AC3 encoding patch ba (Ross Martin <ffmpeg at ross dot interwrx dot com>)
michaelni
parents:
1128
diff
changeset
|
160 if(s->filter_channels>2) |
4d67eb341a0c
AC3 encoding patch ba (Ross Martin <ffmpeg at ross dot interwrx dot com>)
michaelni
parents:
1128
diff
changeset
|
161 s->filter_channels = 2; |
4d67eb341a0c
AC3 encoding patch ba (Ross Martin <ffmpeg at ross dot interwrx dot com>)
michaelni
parents:
1128
diff
changeset
|
162 |
2308 | 163 s->resample_context= av_resample_init(output_rate, input_rate, 16, 10, 0, 1.0); |
2082
3dc9bbe1b152
polyphase kaiser windowed sinc and blackman nuttall windowed sinc audio resample filters
michael
parents:
1598
diff
changeset
|
164 |
0 | 165 return s; |
166 } | |
167 | |
168 /* resample audio. 'nb_samples' is the number of input samples */ | |
169 /* XXX: optimize it ! */ | |
170 int audio_resample(ReSampleContext *s, short *output, short *input, int nb_samples) | |
171 { | |
172 int i, nb_samples1; | |
64 | 173 short *bufin[2]; |
174 short *bufout[2]; | |
0 | 175 short *buftmp2[2], *buftmp3[2]; |
64 | 176 int lenout; |
0 | 177 |
2109 | 178 if (s->input_channels == s->output_channels && s->ratio == 1.0 && 0) { |
0 | 179 /* nothing to do */ |
180 memcpy(output, input, nb_samples * s->input_channels * sizeof(short)); | |
181 return nb_samples; | |
182 } | |
183 | |
64 | 184 /* XXX: move those malloc to resample init code */ |
2082
3dc9bbe1b152
polyphase kaiser windowed sinc and blackman nuttall windowed sinc audio resample filters
michael
parents:
1598
diff
changeset
|
185 for(i=0; i<s->filter_channels; i++){ |
3dc9bbe1b152
polyphase kaiser windowed sinc and blackman nuttall windowed sinc audio resample filters
michael
parents:
1598
diff
changeset
|
186 bufin[i]= (short*) av_malloc( (nb_samples + s->temp_len) * sizeof(short) ); |
3dc9bbe1b152
polyphase kaiser windowed sinc and blackman nuttall windowed sinc audio resample filters
michael
parents:
1598
diff
changeset
|
187 memcpy(bufin[i], s->temp[i], s->temp_len * sizeof(short)); |
3dc9bbe1b152
polyphase kaiser windowed sinc and blackman nuttall windowed sinc audio resample filters
michael
parents:
1598
diff
changeset
|
188 buftmp2[i] = bufin[i] + s->temp_len; |
3dc9bbe1b152
polyphase kaiser windowed sinc and blackman nuttall windowed sinc audio resample filters
michael
parents:
1598
diff
changeset
|
189 } |
64 | 190 |
191 /* make some zoom to avoid round pb */ | |
192 lenout= (int)(nb_samples * s->ratio) + 16; | |
396
fce0a2520551
removed useless header includes - use av memory functions
glantau
parents:
373
diff
changeset
|
193 bufout[0]= (short*) av_malloc( lenout * sizeof(short) ); |
fce0a2520551
removed useless header includes - use av memory functions
glantau
parents:
373
diff
changeset
|
194 bufout[1]= (short*) av_malloc( lenout * sizeof(short) ); |
64 | 195 |
0 | 196 if (s->input_channels == 2 && |
197 s->output_channels == 1) { | |
198 buftmp3[0] = output; | |
199 stereo_to_mono(buftmp2[0], input, nb_samples); | |
1408
4d67eb341a0c
AC3 encoding patch ba (Ross Martin <ffmpeg at ross dot interwrx dot com>)
michaelni
parents:
1128
diff
changeset
|
200 } else if (s->output_channels >= 2 && s->input_channels == 1) { |
0 | 201 buftmp3[0] = bufout[0]; |
2082
3dc9bbe1b152
polyphase kaiser windowed sinc and blackman nuttall windowed sinc audio resample filters
michael
parents:
1598
diff
changeset
|
202 memcpy(buftmp2[0], input, nb_samples*sizeof(short)); |
1408
4d67eb341a0c
AC3 encoding patch ba (Ross Martin <ffmpeg at ross dot interwrx dot com>)
michaelni
parents:
1128
diff
changeset
|
203 } else if (s->output_channels >= 2) { |
0 | 204 buftmp3[0] = bufout[0]; |
205 buftmp3[1] = bufout[1]; | |
206 stereo_split(buftmp2[0], buftmp2[1], input, nb_samples); | |
207 } else { | |
208 buftmp3[0] = output; | |
2082
3dc9bbe1b152
polyphase kaiser windowed sinc and blackman nuttall windowed sinc audio resample filters
michael
parents:
1598
diff
changeset
|
209 memcpy(buftmp2[0], input, nb_samples*sizeof(short)); |
0 | 210 } |
211 | |
2082
3dc9bbe1b152
polyphase kaiser windowed sinc and blackman nuttall windowed sinc audio resample filters
michael
parents:
1598
diff
changeset
|
212 nb_samples += s->temp_len; |
3dc9bbe1b152
polyphase kaiser windowed sinc and blackman nuttall windowed sinc audio resample filters
michael
parents:
1598
diff
changeset
|
213 |
0 | 214 /* resample each channel */ |
215 nb_samples1 = 0; /* avoid warning */ | |
216 for(i=0;i<s->filter_channels;i++) { | |
2082
3dc9bbe1b152
polyphase kaiser windowed sinc and blackman nuttall windowed sinc audio resample filters
michael
parents:
1598
diff
changeset
|
217 int consumed; |
3dc9bbe1b152
polyphase kaiser windowed sinc and blackman nuttall windowed sinc audio resample filters
michael
parents:
1598
diff
changeset
|
218 int is_last= i+1 == s->filter_channels; |
3dc9bbe1b152
polyphase kaiser windowed sinc and blackman nuttall windowed sinc audio resample filters
michael
parents:
1598
diff
changeset
|
219 |
3dc9bbe1b152
polyphase kaiser windowed sinc and blackman nuttall windowed sinc audio resample filters
michael
parents:
1598
diff
changeset
|
220 nb_samples1 = av_resample(s->resample_context, buftmp3[i], bufin[i], &consumed, nb_samples, lenout, is_last); |
3dc9bbe1b152
polyphase kaiser windowed sinc and blackman nuttall windowed sinc audio resample filters
michael
parents:
1598
diff
changeset
|
221 s->temp_len= nb_samples - consumed; |
3dc9bbe1b152
polyphase kaiser windowed sinc and blackman nuttall windowed sinc audio resample filters
michael
parents:
1598
diff
changeset
|
222 s->temp[i]= av_realloc(s->temp[i], s->temp_len*sizeof(short)); |
3dc9bbe1b152
polyphase kaiser windowed sinc and blackman nuttall windowed sinc audio resample filters
michael
parents:
1598
diff
changeset
|
223 memcpy(s->temp[i], bufin[i] + consumed, s->temp_len*sizeof(short)); |
0 | 224 } |
225 | |
226 if (s->output_channels == 2 && s->input_channels == 1) { | |
227 mono_to_stereo(output, buftmp3[0], nb_samples1); | |
228 } else if (s->output_channels == 2) { | |
229 stereo_mux(output, buftmp3[0], buftmp3[1], nb_samples1); | |
1408
4d67eb341a0c
AC3 encoding patch ba (Ross Martin <ffmpeg at ross dot interwrx dot com>)
michaelni
parents:
1128
diff
changeset
|
230 } else if (s->output_channels == 6) { |
4d67eb341a0c
AC3 encoding patch ba (Ross Martin <ffmpeg at ross dot interwrx dot com>)
michaelni
parents:
1128
diff
changeset
|
231 ac3_5p1_mux(output, buftmp3[0], buftmp3[1], nb_samples1); |
0 | 232 } |
233 | |
2084 | 234 for(i=0; i<s->filter_channels; i++) |
235 av_free(bufin[i]); | |
64 | 236 |
396
fce0a2520551
removed useless header includes - use av memory functions
glantau
parents:
373
diff
changeset
|
237 av_free(bufout[0]); |
fce0a2520551
removed useless header includes - use av memory functions
glantau
parents:
373
diff
changeset
|
238 av_free(bufout[1]); |
0 | 239 return nb_samples1; |
240 } | |
241 | |
242 void audio_resample_close(ReSampleContext *s) | |
243 { | |
2082
3dc9bbe1b152
polyphase kaiser windowed sinc and blackman nuttall windowed sinc audio resample filters
michael
parents:
1598
diff
changeset
|
244 av_resample_close(s->resample_context); |
3dc9bbe1b152
polyphase kaiser windowed sinc and blackman nuttall windowed sinc audio resample filters
michael
parents:
1598
diff
changeset
|
245 av_freep(&s->temp[0]); |
3dc9bbe1b152
polyphase kaiser windowed sinc and blackman nuttall windowed sinc audio resample filters
michael
parents:
1598
diff
changeset
|
246 av_freep(&s->temp[1]); |
396
fce0a2520551
removed useless header includes - use av memory functions
glantau
parents:
373
diff
changeset
|
247 av_free(s); |
0 | 248 } |