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