blob: 920f50f32cdfb6a70db95846b017cd5144cbf6e1
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 | static av_cold void init_h263_dc_for_msmpeg4(void) |
53 | { |
54 | int level, uni_code, uni_len; |
55 | |
56 | if(ff_v2_dc_chroma_table[255 + 256][1]) |
57 | return; |
58 | |
59 | for(level=-256; level<256; level++){ |
60 | int size, v, l; |
61 | /* find number of bits */ |
62 | size = 0; |
63 | v = abs(level); |
64 | while (v) { |
65 | v >>= 1; |
66 | size++; |
67 | } |
68 | |
69 | if (level < 0) |
70 | l= (-level) ^ ((1 << size) - 1); |
71 | else |
72 | l= level; |
73 | |
74 | /* luminance H.263 */ |
75 | uni_code= ff_mpeg4_DCtab_lum[size][0]; |
76 | uni_len = ff_mpeg4_DCtab_lum[size][1]; |
77 | uni_code ^= (1<<uni_len)-1; //M$ does not like compatibility |
78 | |
79 | if (size > 0) { |
80 | uni_code<<=size; uni_code|=l; |
81 | uni_len+=size; |
82 | if (size > 8){ |
83 | uni_code<<=1; uni_code|=1; |
84 | uni_len++; |
85 | } |
86 | } |
87 | ff_v2_dc_lum_table[level + 256][0] = uni_code; |
88 | ff_v2_dc_lum_table[level + 256][1] = uni_len; |
89 | |
90 | /* chrominance H.263 */ |
91 | uni_code= ff_mpeg4_DCtab_chrom[size][0]; |
92 | uni_len = ff_mpeg4_DCtab_chrom[size][1]; |
93 | uni_code ^= (1<<uni_len)-1; //M$ does not like compatibility |
94 | |
95 | if (size > 0) { |
96 | uni_code<<=size; uni_code|=l; |
97 | uni_len+=size; |
98 | if (size > 8){ |
99 | uni_code<<=1; uni_code|=1; |
100 | uni_len++; |
101 | } |
102 | } |
103 | ff_v2_dc_chroma_table[level + 256][0] = uni_code; |
104 | ff_v2_dc_chroma_table[level + 256][1] = uni_len; |
105 | |
106 | } |
107 | } |
108 | |
109 | av_cold void ff_msmpeg4_common_init(MpegEncContext *s) |
110 | { |
111 | switch(s->msmpeg4_version){ |
112 | case 1: |
113 | case 2: |
114 | s->y_dc_scale_table= |
115 | s->c_dc_scale_table= ff_mpeg1_dc_scale_table; |
116 | break; |
117 | case 3: |
118 | if(s->workaround_bugs){ |
119 | s->y_dc_scale_table= ff_old_ff_y_dc_scale_table; |
120 | s->c_dc_scale_table= ff_wmv1_c_dc_scale_table; |
121 | } else{ |
122 | s->y_dc_scale_table= ff_mpeg4_y_dc_scale_table; |
123 | s->c_dc_scale_table= ff_mpeg4_c_dc_scale_table; |
124 | } |
125 | break; |
126 | case 4: |
127 | case 5: |
128 | s->y_dc_scale_table= ff_wmv1_y_dc_scale_table; |
129 | s->c_dc_scale_table= ff_wmv1_c_dc_scale_table; |
130 | break; |
131 | #if CONFIG_VC1_DECODER |
132 | case 6: |
133 | s->y_dc_scale_table= ff_wmv3_dc_scale_table; |
134 | s->c_dc_scale_table= ff_wmv3_dc_scale_table; |
135 | break; |
136 | #endif |
137 | |
138 | } |
139 | |
140 | |
141 | if(s->msmpeg4_version>=4){ |
142 | ff_init_scantable(s->idsp.idct_permutation, &s->intra_scantable, ff_wmv1_scantable[1]); |
143 | ff_init_scantable(s->idsp.idct_permutation, &s->intra_h_scantable, ff_wmv1_scantable[2]); |
144 | ff_init_scantable(s->idsp.idct_permutation, &s->intra_v_scantable, ff_wmv1_scantable[3]); |
145 | 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 | init_h263_dc_for_msmpeg4(); |
150 | } |
151 | |
152 | /* predict coded block */ |
153 | 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 | xy = s->block_index[n]; |
158 | wrap = s->b8_stride; |
159 | |
160 | /* B C |
161 | * A X |
162 | */ |
163 | a = s->coded_block[xy - 1 ]; |
164 | b = s->coded_block[xy - 1 - wrap]; |
165 | c = s->coded_block[xy - wrap]; |
166 | |
167 | if (b == c) { |
168 | pred = a; |
169 | } else { |
170 | pred = c; |
171 | } |
172 | |
173 | /* store value */ |
174 | *coded_block_ptr = &s->coded_block[xy]; |
175 | |
176 | 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 | 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 | if (n < 4) { |
201 | scale = s->y_dc_scale; |
202 | } else { |
203 | scale = s->c_dc_scale; |
204 | } |
205 | |
206 | wrap = s->block_wrap[n]; |
207 | dc_val= s->dc_val[0] + s->block_index[n]; |
208 | |
209 | /* B C |
210 | * A X |
211 | */ |
212 | a = dc_val[ - 1]; |
213 | b = dc_val[ - 1 - wrap]; |
214 | c = dc_val[ - wrap]; |
215 | |
216 | if(s->first_slice_line && (n&2)==0 && s->msmpeg4_version<4){ |
217 | 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 | __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 | : "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 | if(s->msmpeg4_version>3){ |
258 | 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 | if (abs(a - b) < abs(b - c)) { |
316 | pred = c; |
317 | *dir_ptr = 1; |
318 | } else { |
319 | pred = a; |
320 | *dir_ptr = 0; |
321 | } |
322 | } |
323 | }else{ |
324 | if (abs(a - b) <= abs(b - c)) { |
325 | pred = c; |
326 | *dir_ptr = 1; |
327 | } else { |
328 | pred = a; |
329 | *dir_ptr = 0; |
330 | } |
331 | } |
332 | |
333 | /* update predictor */ |
334 | *dc_val_ptr = &dc_val[0]; |
335 | return pred; |
336 | } |
337 | |
338 |