FFmpeg
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 "config.h"
31 
32 #include "libavutil/thread.h"
33 #if ARCH_X86
34 #include "libavutil/x86/asm.h"
35 #endif
36 
37 #include "avcodec.h"
38 #include "idctdsp.h"
39 #include "mpegvideo.h"
40 #include "msmpeg4.h"
41 #include "mpeg4videodata.h"
42 #include "msmpeg4data.h"
43 #include "msmpeg4_vc1_data.h"
44 #include "mpegvideodata.h"
45 
46 /*
47  * You can also call this codec: MPEG-4 with a twist!
48  *
49  * TODO:
50  * - (encoding) select best mv table (two choices)
51  * - (encoding) select best vlc/dc table
52  */
53 
54 /* This table is practically identical to the one from H.263
55  * except that it is inverted. */
57 {
58  for (int level = -256; level < 256; level++) {
59  int uni_code, uni_len;
60  int size, v, l;
61  /* find number of bits */
62  size = 0;
63  v = abs(level);
64  while (v) {
65  v >>= 1;
66  size++;
67  }
68 
69  if (level < 0)
70  l = (-level) ^ ((1 << size) - 1);
71  else
72  l = level;
73 
74  /* luminance H.263 */
75  uni_code = ff_mpeg4_DCtab_lum[size][0];
76  uni_len = ff_mpeg4_DCtab_lum[size][1];
77  uni_code ^= (1 << uni_len) - 1; //M$ does not like compatibility
78 
79  if (size > 0) {
80  uni_code <<= size; uni_code |= l;
81  uni_len += size;
82  if (size > 8) {
83  uni_code <<= 1; uni_code |= 1;
84  uni_len++;
85  }
86  }
87  ff_v2_dc_lum_table[level + 256][0] = uni_code;
88  ff_v2_dc_lum_table[level + 256][1] = uni_len;
89 
90  /* chrominance H.263 */
91  uni_code = ff_mpeg4_DCtab_chrom[size][0];
92  uni_len = ff_mpeg4_DCtab_chrom[size][1];
93  uni_code ^= (1 << uni_len) - 1; //M$ does not like compatibility
94 
95  if (size > 0) {
96  uni_code <<= size; uni_code |= l;
97  uni_len +=size;
98  if (size > 8) {
99  uni_code <<= 1; uni_code |= 1;
100  uni_len++;
101  }
102  }
103  ff_v2_dc_chroma_table[level + 256][0] = uni_code;
104  ff_v2_dc_chroma_table[level + 256][1] = uni_len;
105  }
106 }
107 
109 {
110  static uint8_t rl_table_store[NB_RL_TABLES][2][2 * MAX_RUN + MAX_LEVEL + 3];
111 
112  for (int i = 0; i < NB_RL_TABLES; i++)
113  ff_rl_init(&ff_rl_table[i], rl_table_store[i]);
114 
116 }
117 
119 {
120  static AVOnce init_static_once = AV_ONCE_INIT;
121 
122  switch(s->msmpeg4_version){
123  case 1:
124  case 2:
125  s->y_dc_scale_table=
126  s->c_dc_scale_table= ff_mpeg1_dc_scale_table;
127  break;
128  case 3:
129  if(s->workaround_bugs){
130  s->y_dc_scale_table= ff_old_ff_y_dc_scale_table;
131  s->c_dc_scale_table= ff_wmv1_c_dc_scale_table;
132  } else{
133  s->y_dc_scale_table= ff_mpeg4_y_dc_scale_table;
134  s->c_dc_scale_table= ff_mpeg4_c_dc_scale_table;
135  }
136  break;
137  case 4:
138  case 5:
139  s->y_dc_scale_table= ff_wmv1_y_dc_scale_table;
140  s->c_dc_scale_table= ff_wmv1_c_dc_scale_table;
141  break;
142  }
143 
144  if(s->msmpeg4_version>=4){
145  ff_init_scantable(s->idsp.idct_permutation, &s->intra_scantable, ff_wmv1_scantable[1]);
146  ff_init_scantable(s->idsp.idct_permutation, &s->inter_scantable, ff_wmv1_scantable[0]);
147  ff_permute_scantable(s->permutated_intra_h_scantable, ff_wmv1_scantable[2],
148  s->idsp.idct_permutation);
149  ff_permute_scantable(s->permutated_intra_v_scantable, ff_wmv1_scantable[3],
150  s->idsp.idct_permutation);
151  }
152  //Note the default tables are set in common_init in mpegvideo.c
153 
154  ff_thread_once(&init_static_once, msmpeg4_common_init_static);
155 }
156 
157 /* predict coded block */
158 int ff_msmpeg4_coded_block_pred(MpegEncContext * s, int n, uint8_t **coded_block_ptr)
159 {
160  int xy, wrap, pred, a, b, c;
161 
162  xy = s->block_index[n];
163  wrap = s->b8_stride;
164 
165  /* B C
166  * A X
167  */
168  a = s->coded_block[xy - 1 ];
169  b = s->coded_block[xy - 1 - wrap];
170  c = s->coded_block[xy - wrap];
171 
172  if (b == c) {
173  pred = a;
174  } else {
175  pred = c;
176  }
177 
178  /* store value */
179  *coded_block_ptr = &s->coded_block[xy];
180 
181  return pred;
182 }
183 
184 static int get_dc(uint8_t *src, int stride, int scale, int block_size)
185 {
186  int y;
187  int sum=0;
188  for(y=0; y<block_size; y++){
189  int x;
190  for(x=0; x<block_size; x++){
191  sum+=src[x + y*stride];
192  }
193  }
194  return FASTDIV((sum + (scale>>1)), scale);
195 }
196 
197 /* dir = 0: left, dir = 1: top prediction */
199  int16_t **dc_val_ptr, int *dir_ptr)
200 {
201  int a, b, c, wrap, pred, scale;
202  int16_t *dc_val;
203 
204  /* find prediction */
205  if (n < 4) {
206  scale = s->y_dc_scale;
207  } else {
208  scale = s->c_dc_scale;
209  }
210 
211  wrap = s->block_wrap[n];
212  dc_val= s->dc_val[0] + s->block_index[n];
213 
214  /* B C
215  * A X
216  */
217  a = dc_val[ - 1];
218  b = dc_val[ - 1 - wrap];
219  c = dc_val[ - wrap];
220 
221  if(s->first_slice_line && (n&2)==0 && s->msmpeg4_version<4){
222  b=c=1024;
223  }
224 
225  /* XXX: the following solution consumes divisions, but it does not
226  necessitate to modify mpegvideo.c. The problem comes from the
227  fact they decided to store the quantized DC (which would lead
228  to problems if Q could vary !) */
229 #if ARCH_X86 && HAVE_7REGS && HAVE_EBX_AVAILABLE
230  __asm__ volatile(
231  "movl %3, %%eax \n\t"
232  "shrl $1, %%eax \n\t"
233  "addl %%eax, %2 \n\t"
234  "addl %%eax, %1 \n\t"
235  "addl %0, %%eax \n\t"
236  "imull %4 \n\t"
237  "movl %%edx, %0 \n\t"
238  "movl %1, %%eax \n\t"
239  "imull %4 \n\t"
240  "movl %%edx, %1 \n\t"
241  "movl %2, %%eax \n\t"
242  "imull %4 \n\t"
243  "movl %%edx, %2 \n\t"
244  : "+b" (a), "+c" (b), "+D" (c)
245  : "g" (scale), "S" (ff_inverse[scale])
246  : "%eax", "%edx"
247  );
248 #else
249  /* Divisions are costly everywhere; optimize the most common case. */
250  if (scale == 8) {
251  a = (a + (8 >> 1)) / 8;
252  b = (b + (8 >> 1)) / 8;
253  c = (c + (8 >> 1)) / 8;
254  } else {
255  a = FASTDIV((a + (scale >> 1)), scale);
256  b = FASTDIV((b + (scale >> 1)), scale);
257  c = FASTDIV((c + (scale >> 1)), scale);
258  }
259 #endif
260  /* XXX: WARNING: they did not choose the same test as MPEG-4. This
261  is very important ! */
262  if(s->msmpeg4_version>3){
263  if(s->inter_intra_pred){
264  uint8_t *dest;
265  int wrap;
266 
267  if(n==1){
268  pred=a;
269  *dir_ptr = 0;
270  }else if(n==2){
271  pred=c;
272  *dir_ptr = 1;
273  }else if(n==3){
274  if (abs(a - b) < abs(b - c)) {
275  pred = c;
276  *dir_ptr = 1;
277  } else {
278  pred = a;
279  *dir_ptr = 0;
280  }
281  }else{
282  int bs = 8 >> s->avctx->lowres;
283  if(n<4){
284  wrap= s->linesize;
285  dest= s->current_picture.f->data[0] + (((n >> 1) + 2*s->mb_y) * bs* wrap ) + ((n & 1) + 2*s->mb_x) * bs;
286  }else{
287  wrap= s->uvlinesize;
288  dest= s->current_picture.f->data[n - 3] + (s->mb_y * bs * wrap) + s->mb_x * bs;
289  }
290  if(s->mb_x==0) a= (1024 + (scale>>1))/scale;
291  else a= get_dc(dest-bs, wrap, scale*8>>(2*s->avctx->lowres), bs);
292  if(s->mb_y==0) c= (1024 + (scale>>1))/scale;
293  else c= get_dc(dest-bs*wrap, wrap, scale*8>>(2*s->avctx->lowres), bs);
294 
295  if (s->h263_aic_dir==0) {
296  pred= a;
297  *dir_ptr = 0;
298  }else if (s->h263_aic_dir==1) {
299  if(n==0){
300  pred= c;
301  *dir_ptr = 1;
302  }else{
303  pred= a;
304  *dir_ptr = 0;
305  }
306  }else if (s->h263_aic_dir==2) {
307  if(n==0){
308  pred= a;
309  *dir_ptr = 0;
310  }else{
311  pred= c;
312  *dir_ptr = 1;
313  }
314  } else {
315  pred= c;
316  *dir_ptr = 1;
317  }
318  }
319  }else{
320  if (abs(a - b) < abs(b - c)) {
321  pred = c;
322  *dir_ptr = 1;
323  } else {
324  pred = a;
325  *dir_ptr = 0;
326  }
327  }
328  }else{
329  if (abs(a - b) <= abs(b - c)) {
330  pred = c;
331  *dir_ptr = 1;
332  } else {
333  pred = a;
334  *dir_ptr = 0;
335  }
336  }
337 
338  /* update predictor */
339  *dc_val_ptr = &dc_val[0];
340  return pred;
341 }
342 
level
uint8_t level
Definition: svq3.c:205
thread.h
MAX_RUN
#define MAX_RUN
Definition: rl.h:35
ff_msmpeg4_common_init
av_cold void ff_msmpeg4_common_init(MpegEncContext *s)
Definition: msmpeg4.c:118
b
#define b
Definition: input.c:41
mpegvideo.h
ff_rl_table
RLTable ff_rl_table[NB_RL_TABLES]
Definition: msmpeg4data.c:441
ff_inverse
const uint32_t ff_inverse[257]
Definition: mathtables.c:27
ff_permute_scantable
av_cold void ff_permute_scantable(uint8_t dst[64], const uint8_t src[64], const uint8_t permutation[64])
Definition: idctdsp.c:30
ff_mpeg4_DCtab_chrom
const uint8_t ff_mpeg4_DCtab_chrom[13][2]
Definition: mpeg4data.h:40
wrap
#define wrap(func)
Definition: neontest.h:65
NB_RL_TABLES
#define NB_RL_TABLES
Definition: msmpeg4data.h:51
ff_thread_once
static int ff_thread_once(char *control, void(*routine)(void))
Definition: thread.h:205
av_cold
#define av_cold
Definition: attributes.h:90
msmpeg4data.h
s
#define s(width, name)
Definition: cbs_vp9.c:198
ff_mpeg1_dc_scale_table
static const uint8_t *const ff_mpeg1_dc_scale_table
Definition: mpegvideodata.h:32
ff_rl_init
av_cold void ff_rl_init(RLTable *rl, uint8_t static_store[2][2 *MAX_RUN+MAX_LEVEL+3])
Initialize index_run, max_level and max_run from n, last, table_vlc, table_run and table_level.
Definition: rl.c:44
ff_mpeg4_DCtab_lum
const uint8_t ff_mpeg4_DCtab_lum[13][2]
Definition: mpeg4data.h:34
AV_ONCE_INIT
#define AV_ONCE_INIT
Definition: thread.h:203
ff_v2_dc_lum_table
uint32_t ff_v2_dc_lum_table[512][2]
Definition: msmpeg4data.c:35
get_dc
static int get_dc(uint8_t *src, int stride, int scale, int block_size)
Definition: msmpeg4.c:184
ff_v2_dc_chroma_table
uint32_t ff_v2_dc_chroma_table[512][2]
Definition: msmpeg4data.c:36
abs
#define abs(x)
Definition: cuda_runtime.h:35
FASTDIV
#define FASTDIV(a, b)
Definition: mathops.h:214
AVOnce
#define AVOnce
Definition: thread.h:202
c
Undefined Behavior In the C some operations are like signed integer dereferencing freed accessing outside allocated Undefined Behavior must not occur in a C it is not safe even if the output of undefined operations is unused The unsafety may seem nit picking but Optimizing compilers have in fact optimized code on the assumption that no undefined Behavior occurs Optimizing code based on wrong assumptions can and has in some cases lead to effects beyond the output of computations The signed integer overflow problem in speed critical code Code which is highly optimized and works with signed integers sometimes has the problem that often the output of the computation does not c
Definition: undefined.txt:32
MAX_LEVEL
#define MAX_LEVEL
Definition: rl.h:36
ff_mpeg4_y_dc_scale_table
const uint8_t ff_mpeg4_y_dc_scale_table[32]
Definition: mpeg4data.h:356
size
int size
Definition: twinvq_data.h:10344
asm.h
a
The reader does not expect b to be semantically here and if the code is changed by maybe adding a a division or other the signedness will almost certainly be mistaken To avoid this confusion a new type was SUINT is the C unsigned type but it holds a signed int to use the same example SUINT a
Definition: undefined.txt:41
ff_msmpeg4_pred_dc
int ff_msmpeg4_pred_dc(MpegEncContext *s, int n, int16_t **dc_val_ptr, int *dir_ptr)
Definition: msmpeg4.c:198
mpegvideodata.h
ff_init_scantable
av_cold void ff_init_scantable(const uint8_t *permutation, ScanTable *st, const uint8_t *src_scantable)
Definition: mpegvideo.c:322
i
#define i(width, name, range_min, range_max)
Definition: cbs_h2645.c:256
msmpeg4_common_init_static
static av_cold void msmpeg4_common_init_static(void)
Definition: msmpeg4.c:108
idctdsp.h
avcodec.h
stride
#define stride
Definition: h264pred_template.c:537
msmpeg4.h
__asm__
__asm__(".macro parse_r var r\n\t" "\\var = -1\n\t" _IFC_REG(0) _IFC_REG(1) _IFC_REG(2) _IFC_REG(3) _IFC_REG(4) _IFC_REG(5) _IFC_REG(6) _IFC_REG(7) _IFC_REG(8) _IFC_REG(9) _IFC_REG(10) _IFC_REG(11) _IFC_REG(12) _IFC_REG(13) _IFC_REG(14) _IFC_REG(15) _IFC_REG(16) _IFC_REG(17) _IFC_REG(18) _IFC_REG(19) _IFC_REG(20) _IFC_REG(21) _IFC_REG(22) _IFC_REG(23) _IFC_REG(24) _IFC_REG(25) _IFC_REG(26) _IFC_REG(27) _IFC_REG(28) _IFC_REG(29) _IFC_REG(30) _IFC_REG(31) ".iflt \\var\n\t" ".error \"Unable to parse register name \\r\"\n\t" ".endif\n\t" ".endm")
pred
static const float pred[4]
Definition: siprdata.h:259
ff_old_ff_y_dc_scale_table
const uint8_t ff_old_ff_y_dc_scale_table[32]
Definition: msmpeg4data.c:1642
msmpeg4_vc1_data.h
ff_mpeg4_c_dc_scale_table
const uint8_t ff_mpeg4_c_dc_scale_table[32]
Definition: mpeg4data.h:360
ff_wmv1_y_dc_scale_table
const uint8_t ff_wmv1_y_dc_scale_table[32]
Definition: msmpeg4data.c:1633
scale
static void scale(int *out, const int *in, const int w, const int h, const int shift)
Definition: intra.c:291
init_h263_dc_for_msmpeg4
static av_cold void init_h263_dc_for_msmpeg4(void)
Definition: msmpeg4.c:56
mpeg4videodata.h
src
INIT_CLIP pixel * src
Definition: h264pred_template.c:418
ff_wmv1_c_dc_scale_table
const uint8_t ff_wmv1_c_dc_scale_table[32]
Definition: msmpeg4data.c:1637
MpegEncContext
MpegEncContext.
Definition: mpegvideo.h:73
ff_wmv1_scantable
const uint8_t ff_wmv1_scantable[WMV1_SCANTABLE_COUNT][64]
Definition: msmpeg4_vc1_data.c:220
ff_msmpeg4_coded_block_pred
int ff_msmpeg4_coded_block_pred(MpegEncContext *s, int n, uint8_t **coded_block_ptr)
Definition: msmpeg4.c:158