Commit | Line | Data |
---|---|---|
2ba45a60 DM |
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 "vc1data.h" | |
39 | #include "libavutil/imgutils.h" | |
40 | ||
41 | /* | |
42 | * You can also call this codec : MPEG4 with a twist ! | |
43 | * | |
44 | * TODO: | |
45 | * - (encoding) select best mv table (two choices) | |
46 | * - (encoding) select best vlc/dc table | |
47 | */ | |
48 | ||
49 | /* This table is practically identical to the one from h263 | |
50 | * except that it is inverted. */ | |
51 | static av_cold void init_h263_dc_for_msmpeg4(void) | |
52 | { | |
53 | int level, uni_code, uni_len; | |
54 | ||
55 | if(ff_v2_dc_chroma_table[255 + 256][1]) | |
56 | return; | |
57 | ||
58 | for(level=-256; level<256; level++){ | |
59 | int size, v, l; | |
60 | /* find number of bits */ | |
61 | size = 0; | |
62 | v = abs(level); | |
63 | while (v) { | |
64 | v >>= 1; | |
65 | size++; | |
66 | } | |
67 | ||
68 | if (level < 0) | |
69 | l= (-level) ^ ((1 << size) - 1); | |
70 | else | |
71 | l= level; | |
72 | ||
73 | /* luminance h263 */ | |
74 | uni_code= ff_mpeg4_DCtab_lum[size][0]; | |
75 | uni_len = ff_mpeg4_DCtab_lum[size][1]; | |
76 | uni_code ^= (1<<uni_len)-1; //M$ does not like compatibility | |
77 | ||
78 | if (size > 0) { | |
79 | uni_code<<=size; uni_code|=l; | |
80 | uni_len+=size; | |
81 | if (size > 8){ | |
82 | uni_code<<=1; uni_code|=1; | |
83 | uni_len++; | |
84 | } | |
85 | } | |
86 | ff_v2_dc_lum_table[level + 256][0] = uni_code; | |
87 | ff_v2_dc_lum_table[level + 256][1] = uni_len; | |
88 | ||
89 | /* chrominance h263 */ | |
90 | uni_code= ff_mpeg4_DCtab_chrom[size][0]; | |
91 | uni_len = ff_mpeg4_DCtab_chrom[size][1]; | |
92 | uni_code ^= (1<<uni_len)-1; //M$ does not like compatibility | |
93 | ||
94 | if (size > 0) { | |
95 | uni_code<<=size; uni_code|=l; | |
96 | uni_len+=size; | |
97 | if (size > 8){ | |
98 | uni_code<<=1; uni_code|=1; | |
99 | uni_len++; | |
100 | } | |
101 | } | |
102 | ff_v2_dc_chroma_table[level + 256][0] = uni_code; | |
103 | ff_v2_dc_chroma_table[level + 256][1] = uni_len; | |
104 | ||
105 | } | |
106 | } | |
107 | ||
108 | av_cold void ff_msmpeg4_common_init(MpegEncContext *s) | |
109 | { | |
110 | switch(s->msmpeg4_version){ | |
111 | case 1: | |
112 | case 2: | |
113 | s->y_dc_scale_table= | |
114 | s->c_dc_scale_table= ff_mpeg1_dc_scale_table; | |
115 | break; | |
116 | case 3: | |
117 | if(s->workaround_bugs){ | |
118 | s->y_dc_scale_table= ff_old_ff_y_dc_scale_table; | |
119 | s->c_dc_scale_table= ff_wmv1_c_dc_scale_table; | |
120 | } else{ | |
121 | s->y_dc_scale_table= ff_mpeg4_y_dc_scale_table; | |
122 | s->c_dc_scale_table= ff_mpeg4_c_dc_scale_table; | |
123 | } | |
124 | break; | |
125 | case 4: | |
126 | case 5: | |
127 | s->y_dc_scale_table= ff_wmv1_y_dc_scale_table; | |
128 | s->c_dc_scale_table= ff_wmv1_c_dc_scale_table; | |
129 | break; | |
130 | #if CONFIG_VC1_DECODER | |
131 | case 6: | |
132 | s->y_dc_scale_table= ff_wmv3_dc_scale_table; | |
133 | s->c_dc_scale_table= ff_wmv3_dc_scale_table; | |
134 | break; | |
135 | #endif | |
136 | ||
137 | } | |
138 | ||
139 | ||
140 | if(s->msmpeg4_version>=4){ | |
141 | ff_init_scantable(s->idsp.idct_permutation, &s->intra_scantable, ff_wmv1_scantable[1]); | |
142 | ff_init_scantable(s->idsp.idct_permutation, &s->intra_h_scantable, ff_wmv1_scantable[2]); | |
143 | ff_init_scantable(s->idsp.idct_permutation, &s->intra_v_scantable, ff_wmv1_scantable[3]); | |
144 | ff_init_scantable(s->idsp.idct_permutation, &s->inter_scantable, ff_wmv1_scantable[0]); | |
145 | } | |
146 | //Note the default tables are set in common_init in mpegvideo.c | |
147 | ||
148 | init_h263_dc_for_msmpeg4(); | |
149 | } | |
150 | ||
151 | /* predict coded block */ | |
152 | int ff_msmpeg4_coded_block_pred(MpegEncContext * s, int n, uint8_t **coded_block_ptr) | |
153 | { | |
154 | int xy, wrap, pred, a, b, c; | |
155 | ||
156 | xy = s->block_index[n]; | |
157 | wrap = s->b8_stride; | |
158 | ||
159 | /* B C | |
160 | * A X | |
161 | */ | |
162 | a = s->coded_block[xy - 1 ]; | |
163 | b = s->coded_block[xy - 1 - wrap]; | |
164 | c = s->coded_block[xy - wrap]; | |
165 | ||
166 | if (b == c) { | |
167 | pred = a; | |
168 | } else { | |
169 | pred = c; | |
170 | } | |
171 | ||
172 | /* store value */ | |
173 | *coded_block_ptr = &s->coded_block[xy]; | |
174 | ||
175 | return pred; | |
176 | } | |
177 | ||
178 | static int get_dc(uint8_t *src, int stride, int scale, int block_size) | |
179 | { | |
180 | int y; | |
181 | int sum=0; | |
182 | for(y=0; y<block_size; y++){ | |
183 | int x; | |
184 | for(x=0; x<block_size; x++){ | |
185 | sum+=src[x + y*stride]; | |
186 | } | |
187 | } | |
188 | return FASTDIV((sum + (scale>>1)), scale); | |
189 | } | |
190 | ||
191 | /* dir = 0: left, dir = 1: top prediction */ | |
192 | int ff_msmpeg4_pred_dc(MpegEncContext *s, int n, | |
193 | int16_t **dc_val_ptr, int *dir_ptr) | |
194 | { | |
195 | int a, b, c, wrap, pred, scale; | |
196 | int16_t *dc_val; | |
197 | ||
198 | /* find prediction */ | |
199 | if (n < 4) { | |
200 | scale = s->y_dc_scale; | |
201 | } else { | |
202 | scale = s->c_dc_scale; | |
203 | } | |
204 | ||
205 | wrap = s->block_wrap[n]; | |
206 | dc_val= s->dc_val[0] + s->block_index[n]; | |
207 | ||
208 | /* B C | |
209 | * A X | |
210 | */ | |
211 | a = dc_val[ - 1]; | |
212 | b = dc_val[ - 1 - wrap]; | |
213 | c = dc_val[ - wrap]; | |
214 | ||
215 | if(s->first_slice_line && (n&2)==0 && s->msmpeg4_version<4){ | |
216 | b=c=1024; | |
217 | } | |
218 | ||
219 | /* XXX: the following solution consumes divisions, but it does not | |
220 | necessitate to modify mpegvideo.c. The problem comes from the | |
221 | fact they decided to store the quantized DC (which would lead | |
222 | to problems if Q could vary !) */ | |
223 | #if ARCH_X86 && HAVE_7REGS && HAVE_EBX_AVAILABLE | |
224 | __asm__ volatile( | |
225 | "movl %3, %%eax \n\t" | |
226 | "shrl $1, %%eax \n\t" | |
227 | "addl %%eax, %2 \n\t" | |
228 | "addl %%eax, %1 \n\t" | |
229 | "addl %0, %%eax \n\t" | |
230 | "imull %4 \n\t" | |
231 | "movl %%edx, %0 \n\t" | |
232 | "movl %1, %%eax \n\t" | |
233 | "imull %4 \n\t" | |
234 | "movl %%edx, %1 \n\t" | |
235 | "movl %2, %%eax \n\t" | |
236 | "imull %4 \n\t" | |
237 | "movl %%edx, %2 \n\t" | |
238 | : "+b" (a), "+c" (b), "+D" (c) | |
239 | : "g" (scale), "S" (ff_inverse[scale]) | |
240 | : "%eax", "%edx" | |
241 | ); | |
242 | #else | |
243 | /* Divisions are costly everywhere; optimize the most common case. */ | |
244 | if (scale == 8) { | |
245 | a = (a + (8 >> 1)) / 8; | |
246 | b = (b + (8 >> 1)) / 8; | |
247 | c = (c + (8 >> 1)) / 8; | |
248 | } else { | |
249 | a = FASTDIV((a + (scale >> 1)), scale); | |
250 | b = FASTDIV((b + (scale >> 1)), scale); | |
251 | c = FASTDIV((c + (scale >> 1)), scale); | |
252 | } | |
253 | #endif | |
254 | /* XXX: WARNING: they did not choose the same test as MPEG4. This | |
255 | is very important ! */ | |
256 | if(s->msmpeg4_version>3){ | |
257 | if(s->inter_intra_pred){ | |
258 | uint8_t *dest; | |
259 | int wrap; | |
260 | ||
261 | if(n==1){ | |
262 | pred=a; | |
263 | *dir_ptr = 0; | |
264 | }else if(n==2){ | |
265 | pred=c; | |
266 | *dir_ptr = 1; | |
267 | }else if(n==3){ | |
268 | if (abs(a - b) < abs(b - c)) { | |
269 | pred = c; | |
270 | *dir_ptr = 1; | |
271 | } else { | |
272 | pred = a; | |
273 | *dir_ptr = 0; | |
274 | } | |
275 | }else{ | |
276 | int bs = 8 >> s->avctx->lowres; | |
277 | if(n<4){ | |
278 | wrap= s->linesize; | |
279 | dest= s->current_picture.f->data[0] + (((n >> 1) + 2*s->mb_y) * bs* wrap ) + ((n & 1) + 2*s->mb_x) * bs; | |
280 | }else{ | |
281 | wrap= s->uvlinesize; | |
282 | dest= s->current_picture.f->data[n - 3] + (s->mb_y * bs * wrap) + s->mb_x * bs; | |
283 | } | |
284 | if(s->mb_x==0) a= (1024 + (scale>>1))/scale; | |
285 | else a= get_dc(dest-bs, wrap, scale*8>>(2*s->avctx->lowres), bs); | |
286 | if(s->mb_y==0) c= (1024 + (scale>>1))/scale; | |
287 | else c= get_dc(dest-bs*wrap, wrap, scale*8>>(2*s->avctx->lowres), bs); | |
288 | ||
289 | if (s->h263_aic_dir==0) { | |
290 | pred= a; | |
291 | *dir_ptr = 0; | |
292 | }else if (s->h263_aic_dir==1) { | |
293 | if(n==0){ | |
294 | pred= c; | |
295 | *dir_ptr = 1; | |
296 | }else{ | |
297 | pred= a; | |
298 | *dir_ptr = 0; | |
299 | } | |
300 | }else if (s->h263_aic_dir==2) { | |
301 | if(n==0){ | |
302 | pred= a; | |
303 | *dir_ptr = 0; | |
304 | }else{ | |
305 | pred= c; | |
306 | *dir_ptr = 1; | |
307 | } | |
308 | } else { | |
309 | pred= c; | |
310 | *dir_ptr = 1; | |
311 | } | |
312 | } | |
313 | }else{ | |
314 | if (abs(a - b) < abs(b - c)) { | |
315 | pred = c; | |
316 | *dir_ptr = 1; | |
317 | } else { | |
318 | pred = a; | |
319 | *dir_ptr = 0; | |
320 | } | |
321 | } | |
322 | }else{ | |
323 | if (abs(a - b) <= abs(b - c)) { | |
324 | pred = c; | |
325 | *dir_ptr = 1; | |
326 | } else { | |
327 | pred = a; | |
328 | *dir_ptr = 0; | |
329 | } | |
330 | } | |
331 | ||
332 | /* update predictor */ | |
333 | *dc_val_ptr = &dc_val[0]; | |
334 | return pred; | |
335 | } | |
336 |