1 |
|
|
/* |
2 |
|
|
* MSMPEG4 backend for encoder and decoder |
3 |
|
|
* Copyright (c) 2001 Fabrice Bellard |
4 |
|
|
* Copyright (c) 2002-2004 Michael Niedermayer <michaelni@gmx.at> |
5 |
|
|
* |
6 |
|
|
* msmpeg4v1 & v2 stuff by Michael Niedermayer <michaelni@gmx.at> |
7 |
|
|
* |
8 |
|
|
* This file is part of FFmpeg. |
9 |
|
|
* |
10 |
|
|
* FFmpeg is free software; you can redistribute it and/or |
11 |
|
|
* modify it under the terms of the GNU Lesser General Public |
12 |
|
|
* License as published by the Free Software Foundation; either |
13 |
|
|
* version 2.1 of the License, or (at your option) any later version. |
14 |
|
|
* |
15 |
|
|
* FFmpeg is distributed in the hope that it will be useful, |
16 |
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of |
17 |
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
18 |
|
|
* Lesser General Public License for more details. |
19 |
|
|
* |
20 |
|
|
* You should have received a copy of the GNU Lesser General Public |
21 |
|
|
* License along with FFmpeg; if not, write to the Free Software |
22 |
|
|
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA |
23 |
|
|
*/ |
24 |
|
|
|
25 |
|
|
/** |
26 |
|
|
* @file |
27 |
|
|
* MSMPEG4 backend for encoder and decoder |
28 |
|
|
*/ |
29 |
|
|
|
30 |
|
|
#include "avcodec.h" |
31 |
|
|
#include "idctdsp.h" |
32 |
|
|
#include "mpegvideo.h" |
33 |
|
|
#include "msmpeg4.h" |
34 |
|
|
#include "libavutil/x86/asm.h" |
35 |
|
|
#include "h263.h" |
36 |
|
|
#include "mpeg4video.h" |
37 |
|
|
#include "msmpeg4data.h" |
38 |
|
|
#include "mpegvideodata.h" |
39 |
|
|
#include "vc1data.h" |
40 |
|
|
#include "libavutil/imgutils.h" |
41 |
|
|
|
42 |
|
|
/* |
43 |
|
|
* You can also call this codec: MPEG-4 with a twist! |
44 |
|
|
* |
45 |
|
|
* TODO: |
46 |
|
|
* - (encoding) select best mv table (two choices) |
47 |
|
|
* - (encoding) select best vlc/dc table |
48 |
|
|
*/ |
49 |
|
|
|
50 |
|
|
/* This table is practically identical to the one from H.263 |
51 |
|
|
* except that it is inverted. */ |
52 |
|
104 |
static av_cold void init_h263_dc_for_msmpeg4(void) |
53 |
|
|
{ |
54 |
|
|
int level, uni_code, uni_len; |
55 |
|
|
|
56 |
✓✓ |
104 |
if(ff_v2_dc_chroma_table[255 + 256][1]) |
57 |
|
44 |
return; |
58 |
|
|
|
59 |
✓✓ |
30780 |
for(level=-256; level<256; level++){ |
60 |
|
|
int size, v, l; |
61 |
|
|
/* find number of bits */ |
62 |
|
30720 |
size = 0; |
63 |
|
30720 |
v = abs(level); |
64 |
✓✓ |
246420 |
while (v) { |
65 |
|
215700 |
v >>= 1; |
66 |
|
215700 |
size++; |
67 |
|
|
} |
68 |
|
|
|
69 |
✓✓ |
30720 |
if (level < 0) |
70 |
|
15360 |
l= (-level) ^ ((1 << size) - 1); |
71 |
|
|
else |
72 |
|
15360 |
l= level; |
73 |
|
|
|
74 |
|
|
/* luminance H.263 */ |
75 |
|
30720 |
uni_code= ff_mpeg4_DCtab_lum[size][0]; |
76 |
|
30720 |
uni_len = ff_mpeg4_DCtab_lum[size][1]; |
77 |
|
30720 |
uni_code ^= (1<<uni_len)-1; //M$ does not like compatibility |
78 |
|
|
|
79 |
✓✓ |
30720 |
if (size > 0) { |
80 |
|
30660 |
uni_code<<=size; uni_code|=l; |
81 |
|
30660 |
uni_len+=size; |
82 |
✓✓ |
30660 |
if (size > 8){ |
83 |
|
60 |
uni_code<<=1; uni_code|=1; |
84 |
|
60 |
uni_len++; |
85 |
|
|
} |
86 |
|
|
} |
87 |
|
30720 |
ff_v2_dc_lum_table[level + 256][0] = uni_code; |
88 |
|
30720 |
ff_v2_dc_lum_table[level + 256][1] = uni_len; |
89 |
|
|
|
90 |
|
|
/* chrominance H.263 */ |
91 |
|
30720 |
uni_code= ff_mpeg4_DCtab_chrom[size][0]; |
92 |
|
30720 |
uni_len = ff_mpeg4_DCtab_chrom[size][1]; |
93 |
|
30720 |
uni_code ^= (1<<uni_len)-1; //M$ does not like compatibility |
94 |
|
|
|
95 |
✓✓ |
30720 |
if (size > 0) { |
96 |
|
30660 |
uni_code<<=size; uni_code|=l; |
97 |
|
30660 |
uni_len+=size; |
98 |
✓✓ |
30660 |
if (size > 8){ |
99 |
|
60 |
uni_code<<=1; uni_code|=1; |
100 |
|
60 |
uni_len++; |
101 |
|
|
} |
102 |
|
|
} |
103 |
|
30720 |
ff_v2_dc_chroma_table[level + 256][0] = uni_code; |
104 |
|
30720 |
ff_v2_dc_chroma_table[level + 256][1] = uni_len; |
105 |
|
|
|
106 |
|
|
} |
107 |
|
|
} |
108 |
|
|
|
109 |
|
104 |
av_cold void ff_msmpeg4_common_init(MpegEncContext *s) |
110 |
|
|
{ |
111 |
✓✓✓✓ ✗ |
104 |
switch(s->msmpeg4_version){ |
112 |
|
15 |
case 1: |
113 |
|
|
case 2: |
114 |
|
15 |
s->y_dc_scale_table= |
115 |
|
15 |
s->c_dc_scale_table= ff_mpeg1_dc_scale_table; |
116 |
|
15 |
break; |
117 |
|
18 |
case 3: |
118 |
✓✓ |
18 |
if(s->workaround_bugs){ |
119 |
|
13 |
s->y_dc_scale_table= ff_old_ff_y_dc_scale_table; |
120 |
|
13 |
s->c_dc_scale_table= ff_wmv1_c_dc_scale_table; |
121 |
|
|
} else{ |
122 |
|
5 |
s->y_dc_scale_table= ff_mpeg4_y_dc_scale_table; |
123 |
|
5 |
s->c_dc_scale_table= ff_mpeg4_c_dc_scale_table; |
124 |
|
|
} |
125 |
|
18 |
break; |
126 |
|
29 |
case 4: |
127 |
|
|
case 5: |
128 |
|
29 |
s->y_dc_scale_table= ff_wmv1_y_dc_scale_table; |
129 |
|
29 |
s->c_dc_scale_table= ff_wmv1_c_dc_scale_table; |
130 |
|
29 |
break; |
131 |
|
|
#if CONFIG_VC1_DECODER |
132 |
|
42 |
case 6: |
133 |
|
42 |
s->y_dc_scale_table= ff_wmv3_dc_scale_table; |
134 |
|
42 |
s->c_dc_scale_table= ff_wmv3_dc_scale_table; |
135 |
|
42 |
break; |
136 |
|
|
#endif |
137 |
|
|
|
138 |
|
|
} |
139 |
|
|
|
140 |
|
|
|
141 |
✓✓ |
104 |
if(s->msmpeg4_version>=4){ |
142 |
|
71 |
ff_init_scantable(s->idsp.idct_permutation, &s->intra_scantable, ff_wmv1_scantable[1]); |
143 |
|
71 |
ff_init_scantable(s->idsp.idct_permutation, &s->intra_h_scantable, ff_wmv1_scantable[2]); |
144 |
|
71 |
ff_init_scantable(s->idsp.idct_permutation, &s->intra_v_scantable, ff_wmv1_scantable[3]); |
145 |
|
71 |
ff_init_scantable(s->idsp.idct_permutation, &s->inter_scantable, ff_wmv1_scantable[0]); |
146 |
|
|
} |
147 |
|
|
//Note the default tables are set in common_init in mpegvideo.c |
148 |
|
|
|
149 |
|
104 |
init_h263_dc_for_msmpeg4(); |
150 |
|
104 |
} |
151 |
|
|
|
152 |
|
|
/* predict coded block */ |
153 |
|
222472 |
int ff_msmpeg4_coded_block_pred(MpegEncContext * s, int n, uint8_t **coded_block_ptr) |
154 |
|
|
{ |
155 |
|
|
int xy, wrap, pred, a, b, c; |
156 |
|
|
|
157 |
|
222472 |
xy = s->block_index[n]; |
158 |
|
222472 |
wrap = s->b8_stride; |
159 |
|
|
|
160 |
|
|
/* B C |
161 |
|
|
* A X |
162 |
|
|
*/ |
163 |
|
222472 |
a = s->coded_block[xy - 1 ]; |
164 |
|
222472 |
b = s->coded_block[xy - 1 - wrap]; |
165 |
|
222472 |
c = s->coded_block[xy - wrap]; |
166 |
|
|
|
167 |
✓✓ |
222472 |
if (b == c) { |
168 |
|
194858 |
pred = a; |
169 |
|
|
} else { |
170 |
|
27614 |
pred = c; |
171 |
|
|
} |
172 |
|
|
|
173 |
|
|
/* store value */ |
174 |
|
222472 |
*coded_block_ptr = &s->coded_block[xy]; |
175 |
|
|
|
176 |
|
222472 |
return pred; |
177 |
|
|
} |
178 |
|
|
|
179 |
|
|
static int get_dc(uint8_t *src, int stride, int scale, int block_size) |
180 |
|
|
{ |
181 |
|
|
int y; |
182 |
|
|
int sum=0; |
183 |
|
|
for(y=0; y<block_size; y++){ |
184 |
|
|
int x; |
185 |
|
|
for(x=0; x<block_size; x++){ |
186 |
|
|
sum+=src[x + y*stride]; |
187 |
|
|
} |
188 |
|
|
} |
189 |
|
|
return FASTDIV((sum + (scale>>1)), scale); |
190 |
|
|
} |
191 |
|
|
|
192 |
|
|
/* dir = 0: left, dir = 1: top prediction */ |
193 |
|
433272 |
int ff_msmpeg4_pred_dc(MpegEncContext *s, int n, |
194 |
|
|
int16_t **dc_val_ptr, int *dir_ptr) |
195 |
|
|
{ |
196 |
|
|
int a, b, c, wrap, pred, scale; |
197 |
|
|
int16_t *dc_val; |
198 |
|
|
|
199 |
|
|
/* find prediction */ |
200 |
✓✓ |
433272 |
if (n < 4) { |
201 |
|
288848 |
scale = s->y_dc_scale; |
202 |
|
|
} else { |
203 |
|
144424 |
scale = s->c_dc_scale; |
204 |
|
|
} |
205 |
|
|
|
206 |
|
433272 |
wrap = s->block_wrap[n]; |
207 |
|
433272 |
dc_val= s->dc_val[0] + s->block_index[n]; |
208 |
|
|
|
209 |
|
|
/* B C |
210 |
|
|
* A X |
211 |
|
|
*/ |
212 |
|
433272 |
a = dc_val[ - 1]; |
213 |
|
433272 |
b = dc_val[ - 1 - wrap]; |
214 |
|
433272 |
c = dc_val[ - wrap]; |
215 |
|
|
|
216 |
✓✓✓✓ ✓✓ |
433272 |
if(s->first_slice_line && (n&2)==0 && s->msmpeg4_version<4){ |
217 |
|
6624 |
b=c=1024; |
218 |
|
|
} |
219 |
|
|
|
220 |
|
|
/* XXX: the following solution consumes divisions, but it does not |
221 |
|
|
necessitate to modify mpegvideo.c. The problem comes from the |
222 |
|
|
fact they decided to store the quantized DC (which would lead |
223 |
|
|
to problems if Q could vary !) */ |
224 |
|
|
#if ARCH_X86 && HAVE_7REGS && HAVE_EBX_AVAILABLE |
225 |
|
433272 |
__asm__ volatile( |
226 |
|
|
"movl %3, %%eax \n\t" |
227 |
|
|
"shrl $1, %%eax \n\t" |
228 |
|
|
"addl %%eax, %2 \n\t" |
229 |
|
|
"addl %%eax, %1 \n\t" |
230 |
|
|
"addl %0, %%eax \n\t" |
231 |
|
|
"imull %4 \n\t" |
232 |
|
|
"movl %%edx, %0 \n\t" |
233 |
|
|
"movl %1, %%eax \n\t" |
234 |
|
|
"imull %4 \n\t" |
235 |
|
|
"movl %%edx, %1 \n\t" |
236 |
|
|
"movl %2, %%eax \n\t" |
237 |
|
|
"imull %4 \n\t" |
238 |
|
|
"movl %%edx, %2 \n\t" |
239 |
|
|
: "+b" (a), "+c" (b), "+D" (c) |
240 |
|
433272 |
: "g" (scale), "S" (ff_inverse[scale]) |
241 |
|
|
: "%eax", "%edx" |
242 |
|
|
); |
243 |
|
|
#else |
244 |
|
|
/* Divisions are costly everywhere; optimize the most common case. */ |
245 |
|
|
if (scale == 8) { |
246 |
|
|
a = (a + (8 >> 1)) / 8; |
247 |
|
|
b = (b + (8 >> 1)) / 8; |
248 |
|
|
c = (c + (8 >> 1)) / 8; |
249 |
|
|
} else { |
250 |
|
|
a = FASTDIV((a + (scale >> 1)), scale); |
251 |
|
|
b = FASTDIV((b + (scale >> 1)), scale); |
252 |
|
|
c = FASTDIV((c + (scale >> 1)), scale); |
253 |
|
|
} |
254 |
|
|
#endif |
255 |
|
|
/* XXX: WARNING: they did not choose the same test as MPEG-4. This |
256 |
|
|
is very important ! */ |
257 |
✓✓ |
433272 |
if(s->msmpeg4_version>3){ |
258 |
✗✓ |
212484 |
if(s->inter_intra_pred){ |
259 |
|
|
uint8_t *dest; |
260 |
|
|
int wrap; |
261 |
|
|
|
262 |
|
|
if(n==1){ |
263 |
|
|
pred=a; |
264 |
|
|
*dir_ptr = 0; |
265 |
|
|
}else if(n==2){ |
266 |
|
|
pred=c; |
267 |
|
|
*dir_ptr = 1; |
268 |
|
|
}else if(n==3){ |
269 |
|
|
if (abs(a - b) < abs(b - c)) { |
270 |
|
|
pred = c; |
271 |
|
|
*dir_ptr = 1; |
272 |
|
|
} else { |
273 |
|
|
pred = a; |
274 |
|
|
*dir_ptr = 0; |
275 |
|
|
} |
276 |
|
|
}else{ |
277 |
|
|
int bs = 8 >> s->avctx->lowres; |
278 |
|
|
if(n<4){ |
279 |
|
|
wrap= s->linesize; |
280 |
|
|
dest= s->current_picture.f->data[0] + (((n >> 1) + 2*s->mb_y) * bs* wrap ) + ((n & 1) + 2*s->mb_x) * bs; |
281 |
|
|
}else{ |
282 |
|
|
wrap= s->uvlinesize; |
283 |
|
|
dest= s->current_picture.f->data[n - 3] + (s->mb_y * bs * wrap) + s->mb_x * bs; |
284 |
|
|
} |
285 |
|
|
if(s->mb_x==0) a= (1024 + (scale>>1))/scale; |
286 |
|
|
else a= get_dc(dest-bs, wrap, scale*8>>(2*s->avctx->lowres), bs); |
287 |
|
|
if(s->mb_y==0) c= (1024 + (scale>>1))/scale; |
288 |
|
|
else c= get_dc(dest-bs*wrap, wrap, scale*8>>(2*s->avctx->lowres), bs); |
289 |
|
|
|
290 |
|
|
if (s->h263_aic_dir==0) { |
291 |
|
|
pred= a; |
292 |
|
|
*dir_ptr = 0; |
293 |
|
|
}else if (s->h263_aic_dir==1) { |
294 |
|
|
if(n==0){ |
295 |
|
|
pred= c; |
296 |
|
|
*dir_ptr = 1; |
297 |
|
|
}else{ |
298 |
|
|
pred= a; |
299 |
|
|
*dir_ptr = 0; |
300 |
|
|
} |
301 |
|
|
}else if (s->h263_aic_dir==2) { |
302 |
|
|
if(n==0){ |
303 |
|
|
pred= a; |
304 |
|
|
*dir_ptr = 0; |
305 |
|
|
}else{ |
306 |
|
|
pred= c; |
307 |
|
|
*dir_ptr = 1; |
308 |
|
|
} |
309 |
|
|
} else { |
310 |
|
|
pred= c; |
311 |
|
|
*dir_ptr = 1; |
312 |
|
|
} |
313 |
|
|
} |
314 |
|
|
}else{ |
315 |
✓✓ |
212484 |
if (abs(a - b) < abs(b - c)) { |
316 |
|
86305 |
pred = c; |
317 |
|
86305 |
*dir_ptr = 1; |
318 |
|
|
} else { |
319 |
|
126179 |
pred = a; |
320 |
|
126179 |
*dir_ptr = 0; |
321 |
|
|
} |
322 |
|
|
} |
323 |
|
|
}else{ |
324 |
✓✓ |
220788 |
if (abs(a - b) <= abs(b - c)) { |
325 |
|
116422 |
pred = c; |
326 |
|
116422 |
*dir_ptr = 1; |
327 |
|
|
} else { |
328 |
|
104366 |
pred = a; |
329 |
|
104366 |
*dir_ptr = 0; |
330 |
|
|
} |
331 |
|
|
} |
332 |
|
|
|
333 |
|
|
/* update predictor */ |
334 |
|
433272 |
*dc_val_ptr = &dc_val[0]; |
335 |
|
433272 |
return pred; |
336 |
|
|
} |
337 |
|
|
|