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