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