]> git.sesse.net Git - ffmpeg/blob - libavcodec/msmpeg4.c
hevc: reduce variable scope
[ffmpeg] / 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 "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
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->idsp.idct_permutation, &s->intra_scantable,   ff_wmv1_scantable[1]);
140         ff_init_scantable(s->idsp.idct_permutation, &s->intra_h_scantable, ff_wmv1_scantable[2]);
141         ff_init_scantable(s->idsp.idct_permutation, &s->intra_v_scantable, ff_wmv1_scantable[3]);
142         ff_init_scantable(s->idsp.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     /* Divisions are costly everywhere; optimize the most common case. */
246     if (scale == 8) {
247         a = (a + (8 >> 1)) / 8;
248         b = (b + (8 >> 1)) / 8;
249         c = (c + (8 >> 1)) / 8;
250     } else {
251         a = FASTDIV((a + (scale >> 1)), scale);
252         b = FASTDIV((b + (scale >> 1)), scale);
253         c = FASTDIV((c + (scale >> 1)), scale);
254     }
255 #endif
256     /* XXX: WARNING: they did not choose the same test as MPEG4. This
257        is very important ! */
258     if(s->msmpeg4_version>3){
259         if(s->inter_intra_pred){
260             uint8_t *dest;
261             int wrap;
262
263             if(n==1){
264                 pred=a;
265                 *dir_ptr = 0;
266             }else if(n==2){
267                 pred=c;
268                 *dir_ptr = 1;
269             }else if(n==3){
270                 if (abs(a - b) < abs(b - c)) {
271                     pred = c;
272                     *dir_ptr = 1;
273                 } else {
274                     pred = a;
275                     *dir_ptr = 0;
276                 }
277             }else{
278                 if(n<4){
279                     wrap= s->linesize;
280                     dest= s->current_picture.f->data[0] + (((n >> 1) + 2*s->mb_y) * 8*  wrap ) + ((n & 1) + 2*s->mb_x) * 8;
281                 }else{
282                     wrap= s->uvlinesize;
283                     dest= s->current_picture.f->data[n - 3] + (s->mb_y * 8 * wrap) + s->mb_x * 8;
284                 }
285                 if(s->mb_x==0) a= (1024 + (scale>>1))/scale;
286                 else           a= get_dc(dest-8, wrap, scale*8);
287                 if(s->mb_y==0) c= (1024 + (scale>>1))/scale;
288                 else           c= get_dc(dest-8*wrap, wrap, scale*8);
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