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