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