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 "libavutil/thread.h"
31 
32 #include "avcodec.h"
33 #include "idctdsp.h"
34 #include "mpegvideo.h"
35 #include "msmpeg4.h"
36 #include "libavutil/x86/asm.h"
37 #include "mpeg4videodata.h"
38 #include "msmpeg4data.h"
39 #include "mpegvideodata.h"
40 #include "vc1data.h"
41 #include "libavutil/imgutils.h"
42 
43 /*
44  * You can also call this codec: MPEG-4 with a twist!
45  *
46  * TODO:
47  * - (encoding) select best mv table (two choices)
48  * - (encoding) select best vlc/dc table
49  */
50 
51 /* This table is practically identical to the one from H.263
52  * except that it is inverted. */
54 {
55  for (int level = -256; level < 256; level++) {
56  int uni_code, uni_len;
57  int size, v, l;
58  /* find number of bits */
59  size = 0;
60  v = abs(level);
61  while (v) {
62  v >>= 1;
63  size++;
64  }
65 
66  if (level < 0)
67  l = (-level) ^ ((1 << size) - 1);
68  else
69  l = level;
70 
71  /* luminance H.263 */
72  uni_code = ff_mpeg4_DCtab_lum[size][0];
73  uni_len = ff_mpeg4_DCtab_lum[size][1];
74  uni_code ^= (1 << uni_len) - 1; //M$ does not like compatibility
75 
76  if (size > 0) {
77  uni_code <<= size; uni_code |= l;
78  uni_len += size;
79  if (size > 8) {
80  uni_code <<= 1; uni_code |= 1;
81  uni_len++;
82  }
83  }
84  ff_v2_dc_lum_table[level + 256][0] = uni_code;
85  ff_v2_dc_lum_table[level + 256][1] = uni_len;
86 
87  /* chrominance H.263 */
88  uni_code = ff_mpeg4_DCtab_chrom[size][0];
89  uni_len = ff_mpeg4_DCtab_chrom[size][1];
90  uni_code ^= (1 << uni_len) - 1; //M$ does not like compatibility
91 
92  if (size > 0) {
93  uni_code <<= size; uni_code |= l;
94  uni_len +=size;
95  if (size > 8) {
96  uni_code <<= 1; uni_code |= 1;
97  uni_len++;
98  }
99  }
100  ff_v2_dc_chroma_table[level + 256][0] = uni_code;
101  ff_v2_dc_chroma_table[level + 256][1] = uni_len;
102  }
103 }
104 
106 {
107  static uint8_t rl_table_store[NB_RL_TABLES][2][2 * MAX_RUN + MAX_LEVEL + 3];
108 
109  for (int i = 0; i < NB_RL_TABLES; i++)
110  ff_rl_init(&ff_rl_table[i], rl_table_store[i]);
111 
113 }
114 
116 {
117  static AVOnce init_static_once = AV_ONCE_INIT;
118 
119  switch(s->msmpeg4_version){
120  case 1:
121  case 2:
122  s->y_dc_scale_table=
123  s->c_dc_scale_table= ff_mpeg1_dc_scale_table;
124  break;
125  case 3:
126  if(s->workaround_bugs){
127  s->y_dc_scale_table= ff_old_ff_y_dc_scale_table;
128  s->c_dc_scale_table= ff_wmv1_c_dc_scale_table;
129  } else{
130  s->y_dc_scale_table= ff_mpeg4_y_dc_scale_table;
131  s->c_dc_scale_table= ff_mpeg4_c_dc_scale_table;
132  }
133  break;
134  case 4:
135  case 5:
136  s->y_dc_scale_table= ff_wmv1_y_dc_scale_table;
137  s->c_dc_scale_table= ff_wmv1_c_dc_scale_table;
138  break;
139 #if CONFIG_VC1_DECODER
140  case 6:
141  s->y_dc_scale_table= ff_wmv3_dc_scale_table;
142  s->c_dc_scale_table= ff_wmv3_dc_scale_table;
143  break;
144 #endif
145 
146  }
147 
148 
149  if(s->msmpeg4_version>=4){
150  ff_init_scantable(s->idsp.idct_permutation, &s->intra_scantable, ff_wmv1_scantable[1]);
151  ff_init_scantable(s->idsp.idct_permutation, &s->intra_h_scantable, ff_wmv1_scantable[2]);
152  ff_init_scantable(s->idsp.idct_permutation, &s->intra_v_scantable, ff_wmv1_scantable[3]);
153  ff_init_scantable(s->idsp.idct_permutation, &s->inter_scantable, ff_wmv1_scantable[0]);
154  }
155  //Note the default tables are set in common_init in mpegvideo.c
156 
157  ff_thread_once(&init_static_once, msmpeg4_common_init_static);
158 }
159 
160 /* predict coded block */
161 int ff_msmpeg4_coded_block_pred(MpegEncContext * s, int n, uint8_t **coded_block_ptr)
162 {
163  int xy, wrap, pred, a, b, c;
164 
165  xy = s->block_index[n];
166  wrap = s->b8_stride;
167 
168  /* B C
169  * A X
170  */
171  a = s->coded_block[xy - 1 ];
172  b = s->coded_block[xy - 1 - wrap];
173  c = s->coded_block[xy - wrap];
174 
175  if (b == c) {
176  pred = a;
177  } else {
178  pred = c;
179  }
180 
181  /* store value */
182  *coded_block_ptr = &s->coded_block[xy];
183 
184  return pred;
185 }
186 
187 static int get_dc(uint8_t *src, int stride, int scale, int block_size)
188 {
189  int y;
190  int sum=0;
191  for(y=0; y<block_size; y++){
192  int x;
193  for(x=0; x<block_size; x++){
194  sum+=src[x + y*stride];
195  }
196  }
197  return FASTDIV((sum + (scale>>1)), scale);
198 }
199 
200 /* dir = 0: left, dir = 1: top prediction */
202  int16_t **dc_val_ptr, int *dir_ptr)
203 {
204  int a, b, c, wrap, pred, scale;
205  int16_t *dc_val;
206 
207  /* find prediction */
208  if (n < 4) {
209  scale = s->y_dc_scale;
210  } else {
211  scale = s->c_dc_scale;
212  }
213 
214  wrap = s->block_wrap[n];
215  dc_val= s->dc_val[0] + s->block_index[n];
216 
217  /* B C
218  * A X
219  */
220  a = dc_val[ - 1];
221  b = dc_val[ - 1 - wrap];
222  c = dc_val[ - wrap];
223 
224  if(s->first_slice_line && (n&2)==0 && s->msmpeg4_version<4){
225  b=c=1024;
226  }
227 
228  /* XXX: the following solution consumes divisions, but it does not
229  necessitate to modify mpegvideo.c. The problem comes from the
230  fact they decided to store the quantized DC (which would lead
231  to problems if Q could vary !) */
232 #if ARCH_X86 && HAVE_7REGS && HAVE_EBX_AVAILABLE
233  __asm__ volatile(
234  "movl %3, %%eax \n\t"
235  "shrl $1, %%eax \n\t"
236  "addl %%eax, %2 \n\t"
237  "addl %%eax, %1 \n\t"
238  "addl %0, %%eax \n\t"
239  "imull %4 \n\t"
240  "movl %%edx, %0 \n\t"
241  "movl %1, %%eax \n\t"
242  "imull %4 \n\t"
243  "movl %%edx, %1 \n\t"
244  "movl %2, %%eax \n\t"
245  "imull %4 \n\t"
246  "movl %%edx, %2 \n\t"
247  : "+b" (a), "+c" (b), "+D" (c)
248  : "g" (scale), "S" (ff_inverse[scale])
249  : "%eax", "%edx"
250  );
251 #else
252  /* Divisions are costly everywhere; optimize the most common case. */
253  if (scale == 8) {
254  a = (a + (8 >> 1)) / 8;
255  b = (b + (8 >> 1)) / 8;
256  c = (c + (8 >> 1)) / 8;
257  } else {
258  a = FASTDIV((a + (scale >> 1)), scale);
259  b = FASTDIV((b + (scale >> 1)), scale);
260  c = FASTDIV((c + (scale >> 1)), scale);
261  }
262 #endif
263  /* XXX: WARNING: they did not choose the same test as MPEG-4. This
264  is very important ! */
265  if(s->msmpeg4_version>3){
266  if(s->inter_intra_pred){
267  uint8_t *dest;
268  int wrap;
269 
270  if(n==1){
271  pred=a;
272  *dir_ptr = 0;
273  }else if(n==2){
274  pred=c;
275  *dir_ptr = 1;
276  }else if(n==3){
277  if (abs(a - b) < abs(b - c)) {
278  pred = c;
279  *dir_ptr = 1;
280  } else {
281  pred = a;
282  *dir_ptr = 0;
283  }
284  }else{
285  int bs = 8 >> s->avctx->lowres;
286  if(n<4){
287  wrap= s->linesize;
288  dest= s->current_picture.f->data[0] + (((n >> 1) + 2*s->mb_y) * bs* wrap ) + ((n & 1) + 2*s->mb_x) * bs;
289  }else{
290  wrap= s->uvlinesize;
291  dest= s->current_picture.f->data[n - 3] + (s->mb_y * bs * wrap) + s->mb_x * bs;
292  }
293  if(s->mb_x==0) a= (1024 + (scale>>1))/scale;
294  else a= get_dc(dest-bs, wrap, scale*8>>(2*s->avctx->lowres), bs);
295  if(s->mb_y==0) c= (1024 + (scale>>1))/scale;
296  else c= get_dc(dest-bs*wrap, wrap, scale*8>>(2*s->avctx->lowres), bs);
297 
298  if (s->h263_aic_dir==0) {
299  pred= a;
300  *dir_ptr = 0;
301  }else if (s->h263_aic_dir==1) {
302  if(n==0){
303  pred= c;
304  *dir_ptr = 1;
305  }else{
306  pred= a;
307  *dir_ptr = 0;
308  }
309  }else if (s->h263_aic_dir==2) {
310  if(n==0){
311  pred= a;
312  *dir_ptr = 0;
313  }else{
314  pred= c;
315  *dir_ptr = 1;
316  }
317  } else {
318  pred= c;
319  *dir_ptr = 1;
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  }else{
332  if (abs(a - b) <= abs(b - c)) {
333  pred = c;
334  *dir_ptr = 1;
335  } else {
336  pred = a;
337  *dir_ptr = 0;
338  }
339  }
340 
341  /* update predictor */
342  *dc_val_ptr = &dc_val[0];
343  return pred;
344 }
345 
ff_init_scantable
av_cold void ff_init_scantable(uint8_t *permutation, ScanTable *st, const uint8_t *src_scantable)
Definition: idctdsp.c:29
level
uint8_t level
Definition: svq3.c:202
thread.h
ff_mpeg1_dc_scale_table
const uint8_t ff_mpeg1_dc_scale_table[128]
Definition: mpegvideodata.c:33
ff_wmv1_scantable
const uint8_t ff_wmv1_scantable[WMV1_SCANTABLE_COUNT][64]
Definition: msmpeg4data.c:1806
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:115
b
#define b
Definition: input.c:40
mpegvideo.h
ff_rl_table
RLTable ff_rl_table[NB_RL_TABLES]
Definition: msmpeg4data.c:600
ff_inverse
const uint32_t ff_inverse[257]
Definition: mathtables.c:27
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
scale
static av_always_inline float scale(float x, float s)
Definition: vf_v360.c:1388
NB_RL_TABLES
#define NB_RL_TABLES
Definition: msmpeg4data.h:59
ff_thread_once
static int ff_thread_once(char *control, void(*routine)(void))
Definition: thread.h:175
ff_wmv3_dc_scale_table
const uint8_t ff_wmv3_dc_scale_table[32]
Definition: vc1data.c:648
av_cold
#define av_cold
Definition: attributes.h:90
msmpeg4data.h
s
#define s(width, name)
Definition: cbs_vp9.c:257
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:27
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:173
ff_v2_dc_lum_table
uint32_t ff_v2_dc_lum_table[512][2]
Definition: msmpeg4data.c:34
get_dc
static int get_dc(uint8_t *src, int stride, int scale, int block_size)
Definition: msmpeg4.c:187
ff_v2_dc_chroma_table
uint32_t ff_v2_dc_chroma_table[512][2]
Definition: msmpeg4data.c:35
abs
#define abs(x)
Definition: cuda_runtime.h:35
FASTDIV
#define FASTDIV(a, b)
Definition: mathops.h:202
AVOnce
#define AVOnce
Definition: thread.h:172
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
vc1data.h
ff_msmpeg4_pred_dc
int ff_msmpeg4_pred_dc(MpegEncContext *s, int n, int16_t **dc_val_ptr, int *dir_ptr)
Definition: msmpeg4.c:201
mpegvideodata.h
i
#define i(width, name, range_min, range_max)
Definition: cbs_h2645.c:271
msmpeg4_common_init_static
static av_cold void msmpeg4_common_init_static(void)
Definition: msmpeg4.c:105
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:1801
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:1792
init_h263_dc_for_msmpeg4
static av_cold void init_h263_dc_for_msmpeg4(void)
Definition: msmpeg4.c:53
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:1796
imgutils.h
MpegEncContext
MpegEncContext.
Definition: mpegvideo.h:69
ff_msmpeg4_coded_block_pred
int ff_msmpeg4_coded_block_pred(MpegEncContext *s, int n, uint8_t **coded_block_ptr)
Definition: msmpeg4.c:161