xref: /third_party/ffmpeg/libavcodec/msmpeg4.c (revision cabdff1a)
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. */
55static 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
107static 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
117av_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 */
163int 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
189static 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 */
203int 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