FFmpeg
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
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 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 "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 #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. */
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 
109 {
110  switch(s->msmpeg4_version){
111  case 1:
112  case 2:
113  s->y_dc_scale_table=
115  break;
116  case 3:
117  if(s->workaround_bugs){
120  } else{
123  }
124  break;
125  case 4:
126  case 5:
129  break;
130 #if CONFIG_VC1_DECODER
131  case 6:
134  break;
135 #endif
136 
137  }
138 
139 
140  if(s->msmpeg4_version>=4){
145  }
146  //Note the default tables are set in common_init in mpegvideo.c
147 
149 }
150 
151 /* predict coded block */
152 int 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 
178 static 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 */
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