Libav
msmpeg4.c
Go to the documentation of this file.
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 
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. */
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 
105 {
106  static int initialized=0;
107 
108  switch(s->msmpeg4_version){
109  case 1:
110  case 2:
111  s->y_dc_scale_table=
113  break;
114  case 3:
115  if(s->workaround_bugs){
118  } else{
121  }
122  break;
123  case 4:
124  case 5:
127  break;
128 #if CONFIG_VC1_DECODER
129  case 6:
132  break;
133 #endif
134 
135  }
136 
137 
138  if(s->msmpeg4_version>=4){
143  }
144  //Note the default tables are set in common_init in mpegvideo.c
145 
146  if(!initialized){
147  initialized=1;
148 
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 */
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