yading@10
|
1 /*
|
yading@10
|
2 * MSMPEG4 backend for encoder and decoder
|
yading@10
|
3 * Copyright (c) 2001 Fabrice Bellard
|
yading@10
|
4 * Copyright (c) 2002-2004 Michael Niedermayer <michaelni@gmx.at>
|
yading@10
|
5 *
|
yading@10
|
6 * msmpeg4v1 & v2 stuff by Michael Niedermayer <michaelni@gmx.at>
|
yading@10
|
7 *
|
yading@10
|
8 * This file is part of FFmpeg.
|
yading@10
|
9 *
|
yading@10
|
10 * FFmpeg is free software; you can redistribute it and/or
|
yading@10
|
11 * modify it under the terms of the GNU Lesser General Public
|
yading@10
|
12 * License as published by the Free Software Foundation; either
|
yading@10
|
13 * version 2.1 of the License, or (at your option) any later version.
|
yading@10
|
14 *
|
yading@10
|
15 * FFmpeg is distributed in the hope that it will be useful,
|
yading@10
|
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
|
yading@10
|
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
yading@10
|
18 * Lesser General Public License for more details.
|
yading@10
|
19 *
|
yading@10
|
20 * You should have received a copy of the GNU Lesser General Public
|
yading@10
|
21 * License along with FFmpeg; if not, write to the Free Software
|
yading@10
|
22 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
yading@10
|
23 */
|
yading@10
|
24
|
yading@10
|
25 /**
|
yading@10
|
26 * @file
|
yading@10
|
27 * MSMPEG4 backend for encoder and decoder
|
yading@10
|
28 */
|
yading@10
|
29
|
yading@10
|
30 #include "avcodec.h"
|
yading@10
|
31 #include "dsputil.h"
|
yading@10
|
32 #include "mpegvideo.h"
|
yading@10
|
33 #include "msmpeg4.h"
|
yading@10
|
34 #include "libavutil/x86/asm.h"
|
yading@10
|
35 #include "h263.h"
|
yading@10
|
36 #include "mpeg4video.h"
|
yading@10
|
37 #include "msmpeg4data.h"
|
yading@10
|
38 #include "vc1data.h"
|
yading@10
|
39 #include "libavutil/imgutils.h"
|
yading@10
|
40
|
yading@10
|
41 /*
|
yading@10
|
42 * You can also call this codec : MPEG4 with a twist !
|
yading@10
|
43 *
|
yading@10
|
44 * TODO:
|
yading@10
|
45 * - (encoding) select best mv table (two choices)
|
yading@10
|
46 * - (encoding) select best vlc/dc table
|
yading@10
|
47 */
|
yading@10
|
48 //#define DEBUG
|
yading@10
|
49
|
yading@10
|
50 /* This table is practically identical to the one from h263
|
yading@10
|
51 * except that it is inverted. */
|
yading@10
|
52 static av_cold void init_h263_dc_for_msmpeg4(void)
|
yading@10
|
53 {
|
yading@10
|
54 int level, uni_code, uni_len;
|
yading@10
|
55
|
yading@10
|
56 if(ff_v2_dc_chroma_table[255 + 256][1])
|
yading@10
|
57 return;
|
yading@10
|
58
|
yading@10
|
59 for(level=-256; level<256; level++){
|
yading@10
|
60 int size, v, l;
|
yading@10
|
61 /* find number of bits */
|
yading@10
|
62 size = 0;
|
yading@10
|
63 v = abs(level);
|
yading@10
|
64 while (v) {
|
yading@10
|
65 v >>= 1;
|
yading@10
|
66 size++;
|
yading@10
|
67 }
|
yading@10
|
68
|
yading@10
|
69 if (level < 0)
|
yading@10
|
70 l= (-level) ^ ((1 << size) - 1);
|
yading@10
|
71 else
|
yading@10
|
72 l= level;
|
yading@10
|
73
|
yading@10
|
74 /* luminance h263 */
|
yading@10
|
75 uni_code= ff_mpeg4_DCtab_lum[size][0];
|
yading@10
|
76 uni_len = ff_mpeg4_DCtab_lum[size][1];
|
yading@10
|
77 uni_code ^= (1<<uni_len)-1; //M$ does not like compatibility
|
yading@10
|
78
|
yading@10
|
79 if (size > 0) {
|
yading@10
|
80 uni_code<<=size; uni_code|=l;
|
yading@10
|
81 uni_len+=size;
|
yading@10
|
82 if (size > 8){
|
yading@10
|
83 uni_code<<=1; uni_code|=1;
|
yading@10
|
84 uni_len++;
|
yading@10
|
85 }
|
yading@10
|
86 }
|
yading@10
|
87 ff_v2_dc_lum_table[level + 256][0] = uni_code;
|
yading@10
|
88 ff_v2_dc_lum_table[level + 256][1] = uni_len;
|
yading@10
|
89
|
yading@10
|
90 /* chrominance h263 */
|
yading@10
|
91 uni_code= ff_mpeg4_DCtab_chrom[size][0];
|
yading@10
|
92 uni_len = ff_mpeg4_DCtab_chrom[size][1];
|
yading@10
|
93 uni_code ^= (1<<uni_len)-1; //M$ does not like compatibility
|
yading@10
|
94
|
yading@10
|
95 if (size > 0) {
|
yading@10
|
96 uni_code<<=size; uni_code|=l;
|
yading@10
|
97 uni_len+=size;
|
yading@10
|
98 if (size > 8){
|
yading@10
|
99 uni_code<<=1; uni_code|=1;
|
yading@10
|
100 uni_len++;
|
yading@10
|
101 }
|
yading@10
|
102 }
|
yading@10
|
103 ff_v2_dc_chroma_table[level + 256][0] = uni_code;
|
yading@10
|
104 ff_v2_dc_chroma_table[level + 256][1] = uni_len;
|
yading@10
|
105
|
yading@10
|
106 }
|
yading@10
|
107 }
|
yading@10
|
108
|
yading@10
|
109 av_cold void ff_msmpeg4_common_init(MpegEncContext *s)
|
yading@10
|
110 {
|
yading@10
|
111 switch(s->msmpeg4_version){
|
yading@10
|
112 case 1:
|
yading@10
|
113 case 2:
|
yading@10
|
114 s->y_dc_scale_table=
|
yading@10
|
115 s->c_dc_scale_table= ff_mpeg1_dc_scale_table;
|
yading@10
|
116 break;
|
yading@10
|
117 case 3:
|
yading@10
|
118 if(s->workaround_bugs){
|
yading@10
|
119 s->y_dc_scale_table= ff_old_ff_y_dc_scale_table;
|
yading@10
|
120 s->c_dc_scale_table= ff_wmv1_c_dc_scale_table;
|
yading@10
|
121 } else{
|
yading@10
|
122 s->y_dc_scale_table= ff_mpeg4_y_dc_scale_table;
|
yading@10
|
123 s->c_dc_scale_table= ff_mpeg4_c_dc_scale_table;
|
yading@10
|
124 }
|
yading@10
|
125 break;
|
yading@10
|
126 case 4:
|
yading@10
|
127 case 5:
|
yading@10
|
128 s->y_dc_scale_table= ff_wmv1_y_dc_scale_table;
|
yading@10
|
129 s->c_dc_scale_table= ff_wmv1_c_dc_scale_table;
|
yading@10
|
130 break;
|
yading@10
|
131 #if CONFIG_VC1_DECODER
|
yading@10
|
132 case 6:
|
yading@10
|
133 s->y_dc_scale_table= ff_wmv3_dc_scale_table;
|
yading@10
|
134 s->c_dc_scale_table= ff_wmv3_dc_scale_table;
|
yading@10
|
135 break;
|
yading@10
|
136 #endif
|
yading@10
|
137
|
yading@10
|
138 }
|
yading@10
|
139
|
yading@10
|
140
|
yading@10
|
141 if(s->msmpeg4_version>=4){
|
yading@10
|
142 ff_init_scantable(s->dsp.idct_permutation, &s->intra_scantable , ff_wmv1_scantable[1]);
|
yading@10
|
143 ff_init_scantable(s->dsp.idct_permutation, &s->intra_h_scantable, ff_wmv1_scantable[2]);
|
yading@10
|
144 ff_init_scantable(s->dsp.idct_permutation, &s->intra_v_scantable, ff_wmv1_scantable[3]);
|
yading@10
|
145 ff_init_scantable(s->dsp.idct_permutation, &s->inter_scantable , ff_wmv1_scantable[0]);
|
yading@10
|
146 }
|
yading@10
|
147 //Note the default tables are set in common_init in mpegvideo.c
|
yading@10
|
148
|
yading@10
|
149 init_h263_dc_for_msmpeg4();
|
yading@10
|
150 }
|
yading@10
|
151
|
yading@10
|
152 /* predict coded block */
|
yading@10
|
153 int ff_msmpeg4_coded_block_pred(MpegEncContext * s, int n, uint8_t **coded_block_ptr)
|
yading@10
|
154 {
|
yading@10
|
155 int xy, wrap, pred, a, b, c;
|
yading@10
|
156
|
yading@10
|
157 xy = s->block_index[n];
|
yading@10
|
158 wrap = s->b8_stride;
|
yading@10
|
159
|
yading@10
|
160 /* B C
|
yading@10
|
161 * A X
|
yading@10
|
162 */
|
yading@10
|
163 a = s->coded_block[xy - 1 ];
|
yading@10
|
164 b = s->coded_block[xy - 1 - wrap];
|
yading@10
|
165 c = s->coded_block[xy - wrap];
|
yading@10
|
166
|
yading@10
|
167 if (b == c) {
|
yading@10
|
168 pred = a;
|
yading@10
|
169 } else {
|
yading@10
|
170 pred = c;
|
yading@10
|
171 }
|
yading@10
|
172
|
yading@10
|
173 /* store value */
|
yading@10
|
174 *coded_block_ptr = &s->coded_block[xy];
|
yading@10
|
175
|
yading@10
|
176 return pred;
|
yading@10
|
177 }
|
yading@10
|
178
|
yading@10
|
179 static int get_dc(uint8_t *src, int stride, int scale)
|
yading@10
|
180 {
|
yading@10
|
181 int y;
|
yading@10
|
182 int sum=0;
|
yading@10
|
183 for(y=0; y<8; y++){
|
yading@10
|
184 int x;
|
yading@10
|
185 for(x=0; x<8; x++){
|
yading@10
|
186 sum+=src[x + y*stride];
|
yading@10
|
187 }
|
yading@10
|
188 }
|
yading@10
|
189 return FASTDIV((sum + (scale>>1)), scale);
|
yading@10
|
190 }
|
yading@10
|
191
|
yading@10
|
192 /* dir = 0: left, dir = 1: top prediction */
|
yading@10
|
193 int ff_msmpeg4_pred_dc(MpegEncContext *s, int n,
|
yading@10
|
194 int16_t **dc_val_ptr, int *dir_ptr)
|
yading@10
|
195 {
|
yading@10
|
196 int a, b, c, wrap, pred, scale;
|
yading@10
|
197 int16_t *dc_val;
|
yading@10
|
198
|
yading@10
|
199 /* find prediction */
|
yading@10
|
200 if (n < 4) {
|
yading@10
|
201 scale = s->y_dc_scale;
|
yading@10
|
202 } else {
|
yading@10
|
203 scale = s->c_dc_scale;
|
yading@10
|
204 }
|
yading@10
|
205
|
yading@10
|
206 wrap = s->block_wrap[n];
|
yading@10
|
207 dc_val= s->dc_val[0] + s->block_index[n];
|
yading@10
|
208
|
yading@10
|
209 /* B C
|
yading@10
|
210 * A X
|
yading@10
|
211 */
|
yading@10
|
212 a = dc_val[ - 1];
|
yading@10
|
213 b = dc_val[ - 1 - wrap];
|
yading@10
|
214 c = dc_val[ - wrap];
|
yading@10
|
215
|
yading@10
|
216 if(s->first_slice_line && (n&2)==0 && s->msmpeg4_version<4){
|
yading@10
|
217 b=c=1024;
|
yading@10
|
218 }
|
yading@10
|
219
|
yading@10
|
220 /* XXX: the following solution consumes divisions, but it does not
|
yading@10
|
221 necessitate to modify mpegvideo.c. The problem comes from the
|
yading@10
|
222 fact they decided to store the quantized DC (which would lead
|
yading@10
|
223 to problems if Q could vary !) */
|
yading@10
|
224 #if ARCH_X86 && HAVE_7REGS && HAVE_EBX_AVAILABLE
|
yading@10
|
225 __asm__ volatile(
|
yading@10
|
226 "movl %3, %%eax \n\t"
|
yading@10
|
227 "shrl $1, %%eax \n\t"
|
yading@10
|
228 "addl %%eax, %2 \n\t"
|
yading@10
|
229 "addl %%eax, %1 \n\t"
|
yading@10
|
230 "addl %0, %%eax \n\t"
|
yading@10
|
231 "imull %4 \n\t"
|
yading@10
|
232 "movl %%edx, %0 \n\t"
|
yading@10
|
233 "movl %1, %%eax \n\t"
|
yading@10
|
234 "imull %4 \n\t"
|
yading@10
|
235 "movl %%edx, %1 \n\t"
|
yading@10
|
236 "movl %2, %%eax \n\t"
|
yading@10
|
237 "imull %4 \n\t"
|
yading@10
|
238 "movl %%edx, %2 \n\t"
|
yading@10
|
239 : "+b" (a), "+c" (b), "+D" (c)
|
yading@10
|
240 : "g" (scale), "S" (ff_inverse[scale])
|
yading@10
|
241 : "%eax", "%edx"
|
yading@10
|
242 );
|
yading@10
|
243 #else
|
yading@10
|
244 /* #elif ARCH_ALPHA */
|
yading@10
|
245 /* Divisions are extremely costly on Alpha; optimize the most
|
yading@10
|
246 common case. But they are costly everywhere...
|
yading@10
|
247 */
|
yading@10
|
248 if (scale == 8) {
|
yading@10
|
249 a = (a + (8 >> 1)) / 8;
|
yading@10
|
250 b = (b + (8 >> 1)) / 8;
|
yading@10
|
251 c = (c + (8 >> 1)) / 8;
|
yading@10
|
252 } else {
|
yading@10
|
253 a = FASTDIV((a + (scale >> 1)), scale);
|
yading@10
|
254 b = FASTDIV((b + (scale >> 1)), scale);
|
yading@10
|
255 c = FASTDIV((c + (scale >> 1)), scale);
|
yading@10
|
256 }
|
yading@10
|
257 #endif
|
yading@10
|
258 /* XXX: WARNING: they did not choose the same test as MPEG4. This
|
yading@10
|
259 is very important ! */
|
yading@10
|
260 if(s->msmpeg4_version>3){
|
yading@10
|
261 if(s->inter_intra_pred){
|
yading@10
|
262 uint8_t *dest;
|
yading@10
|
263 int wrap;
|
yading@10
|
264
|
yading@10
|
265 if(n==1){
|
yading@10
|
266 pred=a;
|
yading@10
|
267 *dir_ptr = 0;
|
yading@10
|
268 }else if(n==2){
|
yading@10
|
269 pred=c;
|
yading@10
|
270 *dir_ptr = 1;
|
yading@10
|
271 }else if(n==3){
|
yading@10
|
272 if (abs(a - b) < abs(b - c)) {
|
yading@10
|
273 pred = c;
|
yading@10
|
274 *dir_ptr = 1;
|
yading@10
|
275 } else {
|
yading@10
|
276 pred = a;
|
yading@10
|
277 *dir_ptr = 0;
|
yading@10
|
278 }
|
yading@10
|
279 }else{
|
yading@10
|
280 if(n<4){
|
yading@10
|
281 wrap= s->linesize;
|
yading@10
|
282 dest= s->current_picture.f.data[0] + (((n >> 1) + 2*s->mb_y) * 8* wrap ) + ((n & 1) + 2*s->mb_x) * 8;
|
yading@10
|
283 }else{
|
yading@10
|
284 wrap= s->uvlinesize;
|
yading@10
|
285 dest= s->current_picture.f.data[n - 3] + (s->mb_y * 8 * wrap) + s->mb_x * 8;
|
yading@10
|
286 }
|
yading@10
|
287 if(s->mb_x==0) a= (1024 + (scale>>1))/scale;
|
yading@10
|
288 else a= get_dc(dest-8, wrap, scale*8);
|
yading@10
|
289 if(s->mb_y==0) c= (1024 + (scale>>1))/scale;
|
yading@10
|
290 else c= get_dc(dest-8*wrap, wrap, scale*8);
|
yading@10
|
291
|
yading@10
|
292 if (s->h263_aic_dir==0) {
|
yading@10
|
293 pred= a;
|
yading@10
|
294 *dir_ptr = 0;
|
yading@10
|
295 }else if (s->h263_aic_dir==1) {
|
yading@10
|
296 if(n==0){
|
yading@10
|
297 pred= c;
|
yading@10
|
298 *dir_ptr = 1;
|
yading@10
|
299 }else{
|
yading@10
|
300 pred= a;
|
yading@10
|
301 *dir_ptr = 0;
|
yading@10
|
302 }
|
yading@10
|
303 }else if (s->h263_aic_dir==2) {
|
yading@10
|
304 if(n==0){
|
yading@10
|
305 pred= a;
|
yading@10
|
306 *dir_ptr = 0;
|
yading@10
|
307 }else{
|
yading@10
|
308 pred= c;
|
yading@10
|
309 *dir_ptr = 1;
|
yading@10
|
310 }
|
yading@10
|
311 } else {
|
yading@10
|
312 pred= c;
|
yading@10
|
313 *dir_ptr = 1;
|
yading@10
|
314 }
|
yading@10
|
315 }
|
yading@10
|
316 }else{
|
yading@10
|
317 if (abs(a - b) < abs(b - c)) {
|
yading@10
|
318 pred = c;
|
yading@10
|
319 *dir_ptr = 1;
|
yading@10
|
320 } else {
|
yading@10
|
321 pred = a;
|
yading@10
|
322 *dir_ptr = 0;
|
yading@10
|
323 }
|
yading@10
|
324 }
|
yading@10
|
325 }else{
|
yading@10
|
326 if (abs(a - b) <= abs(b - c)) {
|
yading@10
|
327 pred = c;
|
yading@10
|
328 *dir_ptr = 1;
|
yading@10
|
329 } else {
|
yading@10
|
330 pred = a;
|
yading@10
|
331 *dir_ptr = 0;
|
yading@10
|
332 }
|
yading@10
|
333 }
|
yading@10
|
334
|
yading@10
|
335 /* update predictor */
|
yading@10
|
336 *dc_val_ptr = &dc_val[0];
|
yading@10
|
337 return pred;
|
yading@10
|
338 }
|
yading@10
|
339
|