Mercurial > libavcodec.hg
annotate wmv2.c @ 2497:69adfbbdcdeb libavcodec
- samples from mplayer ftp in the "adv" profile seem to have profile=2,
which isn't the advanced one; and indeed, using adv. profile parser fails.
Using normal parser works, and that's what is done
- attempt at taking care of stride for NORM2 bitplane decoding
- duplication of much code from msmpeg4.c; this code isn't yet used, but
goes down as far as the block layer (mainly Transform Type stuff, the
remains are wild editing without checking). Unusable yet, and lacks the AC
decoding (but a step further in bitstream parsing)
patch by anonymous
author | michael |
---|---|
date | Fri, 04 Feb 2005 02:20:38 +0000 |
parents | 81a9f883a17a |
children | e25782262d7d |
rev | line source |
---|---|
936 | 1 /* |
2 * Copyright (c) 2002 The FFmpeg Project. | |
3 * | |
4 * This library is free software; you can redistribute it and/or | |
5 * modify it under the terms of the GNU Lesser General Public | |
6 * License as published by the Free Software Foundation; either | |
7 * version 2 of the License, or (at your option) any later version. | |
8 * | |
9 * This library is distributed in the hope that it will be useful, | |
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of | |
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |
12 * Lesser General Public License for more details. | |
13 * | |
14 * You should have received a copy of the GNU Lesser General Public | |
15 * License along with this library; if not, write to the Free Software | |
16 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | |
17 * | |
18 */ | |
19 | |
1106 | 20 /** |
21 * @file wmv2.c | |
22 * wmv2 codec. | |
23 */ | |
24 | |
936 | 25 #include "simple_idct.h" |
26 | |
27 #define SKIP_TYPE_NONE 0 | |
28 #define SKIP_TYPE_MPEG 1 | |
29 #define SKIP_TYPE_ROW 2 | |
30 #define SKIP_TYPE_COL 3 | |
31 | |
32 | |
33 typedef struct Wmv2Context{ | |
34 MpegEncContext s; | |
35 int j_type_bit; | |
36 int j_type; | |
37 int flag3; | |
38 int flag63; | |
39 int abt_flag; | |
40 int abt_type; | |
41 int abt_type_table[6]; | |
42 int per_mb_abt; | |
43 int per_block_abt; | |
44 int mspel_bit; | |
45 int cbp_table_index; | |
46 int top_left_mv_flag; | |
47 int per_mb_rl_bit; | |
48 int skip_type; | |
49 int hshift; | |
50 | |
51 ScanTable abt_scantable[2]; | |
52 DCTELEM abt_block2[6][64] __align8; | |
53 }Wmv2Context; | |
54 | |
55 static void wmv2_common_init(Wmv2Context * w){ | |
56 MpegEncContext * const s= &w->s; | |
57 | |
1273 | 58 ff_init_scantable(s->dsp.idct_permutation, &w->abt_scantable[0], wmv2_scantableA); |
59 ff_init_scantable(s->dsp.idct_permutation, &w->abt_scantable[1], wmv2_scantableB); | |
936 | 60 } |
61 | |
2024
f65d87bfdd5a
some of the warning fixes by (Michael Roitzsch <mroi at users dot sourceforge dot net>)
michael
parents:
1943
diff
changeset
|
62 #ifdef CONFIG_ENCODERS |
f65d87bfdd5a
some of the warning fixes by (Michael Roitzsch <mroi at users dot sourceforge dot net>)
michael
parents:
1943
diff
changeset
|
63 |
936 | 64 static int encode_ext_header(Wmv2Context *w){ |
65 MpegEncContext * const s= &w->s; | |
66 PutBitContext pb; | |
67 int code; | |
68 | |
1524 | 69 init_put_bits(&pb, s->avctx->extradata, s->avctx->extradata_size); |
936 | 70 |
1126
77ccf7fe3bd0
per context frame_rate_base, this should finally fix frame_rate related av sync issues
michaelni
parents:
1106
diff
changeset
|
71 put_bits(&pb, 5, s->avctx->frame_rate / s->avctx->frame_rate_base); //yes 29.97 -> 29 |
936 | 72 put_bits(&pb, 11, FFMIN(s->bit_rate/1024, 2047)); |
73 | |
74 put_bits(&pb, 1, w->mspel_bit=1); | |
75 put_bits(&pb, 1, w->flag3=1); | |
76 put_bits(&pb, 1, w->abt_flag=1); | |
77 put_bits(&pb, 1, w->j_type_bit=1); | |
78 put_bits(&pb, 1, w->top_left_mv_flag=0); | |
79 put_bits(&pb, 1, w->per_mb_rl_bit=1); | |
80 put_bits(&pb, 3, code=1); | |
81 | |
82 flush_put_bits(&pb); | |
83 | |
84 s->slice_height = s->mb_height / code; | |
85 | |
86 return 0; | |
87 } | |
88 | |
89 static int wmv2_encode_init(AVCodecContext *avctx){ | |
90 Wmv2Context * const w= avctx->priv_data; | |
91 | |
92 if(MPV_encode_init(avctx) < 0) | |
93 return -1; | |
94 | |
95 wmv2_common_init(w); | |
96 | |
97 avctx->extradata_size= 4; | |
98 avctx->extradata= av_mallocz(avctx->extradata_size + 10); | |
99 encode_ext_header(w); | |
100 | |
101 return 0; | |
102 } | |
103 | |
104 static int wmv2_encode_end(AVCodecContext *avctx){ | |
105 | |
106 if(MPV_encode_end(avctx) < 0) | |
107 return -1; | |
108 | |
109 avctx->extradata_size= 0; | |
110 av_freep(&avctx->extradata); | |
111 | |
112 return 0; | |
113 } | |
114 | |
115 int ff_wmv2_encode_picture_header(MpegEncContext * s, int picture_number) | |
116 { | |
117 Wmv2Context * const w= (Wmv2Context*)s; | |
118 | |
119 put_bits(&s->pb, 1, s->pict_type - 1); | |
120 if(s->pict_type == I_TYPE){ | |
121 put_bits(&s->pb, 7, 0); | |
122 } | |
123 put_bits(&s->pb, 5, s->qscale); | |
124 | |
125 s->dc_table_index = 1; | |
126 s->mv_table_index = 1; /* only if P frame */ | |
127 // s->use_skip_mb_code = 1; /* only if P frame */ | |
128 s->per_mb_rl_table = 0; | |
129 s->mspel= 0; | |
130 w->per_mb_abt=0; | |
131 w->abt_type=0; | |
132 w->j_type=0; | |
133 | |
1163 | 134 assert(s->flipflop_rounding); |
135 | |
936 | 136 if (s->pict_type == I_TYPE) { |
1163 | 137 assert(s->no_rounding==1); |
936 | 138 if(w->j_type_bit) put_bits(&s->pb, 1, w->j_type); |
139 | |
140 if(w->per_mb_rl_bit) put_bits(&s->pb, 1, s->per_mb_rl_table); | |
141 | |
142 if(!s->per_mb_rl_table){ | |
143 code012(&s->pb, s->rl_chroma_table_index); | |
144 code012(&s->pb, s->rl_table_index); | |
145 } | |
146 | |
147 put_bits(&s->pb, 1, s->dc_table_index); | |
148 | |
149 s->inter_intra_pred= 0; | |
150 }else{ | |
151 int cbp_index; | |
152 | |
153 put_bits(&s->pb, 2, SKIP_TYPE_NONE); | |
154 | |
155 code012(&s->pb, cbp_index=0); | |
156 if(s->qscale <= 10){ | |
157 int map[3]= {0,2,1}; | |
158 w->cbp_table_index= map[cbp_index]; | |
159 }else if(s->qscale <= 20){ | |
160 int map[3]= {1,0,2}; | |
161 w->cbp_table_index= map[cbp_index]; | |
162 }else{ | |
163 int map[3]= {2,1,0}; | |
164 w->cbp_table_index= map[cbp_index]; | |
165 } | |
166 | |
167 if(w->mspel_bit) put_bits(&s->pb, 1, s->mspel); | |
168 | |
169 if(w->abt_flag){ | |
170 put_bits(&s->pb, 1, w->per_mb_abt^1); | |
171 if(!w->per_mb_abt){ | |
172 code012(&s->pb, w->abt_type); | |
173 } | |
174 } | |
175 | |
176 if(w->per_mb_rl_bit) put_bits(&s->pb, 1, s->per_mb_rl_table); | |
177 | |
178 if(!s->per_mb_rl_table){ | |
179 code012(&s->pb, s->rl_table_index); | |
180 s->rl_chroma_table_index = s->rl_table_index; | |
181 } | |
182 put_bits(&s->pb, 1, s->dc_table_index); | |
183 put_bits(&s->pb, 1, s->mv_table_index); | |
184 | |
1943 | 185 s->inter_intra_pred= 0;//(s->width*s->height < 320*240 && s->bit_rate<=II_BITRATE); |
936 | 186 } |
187 s->esc3_level_length= 0; | |
188 s->esc3_run_length= 0; | |
189 | |
190 return 0; | |
191 } | |
192 | |
193 // nearly idential to wmv1 but thats just because we dont use the useless M$ crap features | |
194 // its duplicated here in case someone wants to add support for these carp features | |
195 void ff_wmv2_encode_mb(MpegEncContext * s, | |
196 DCTELEM block[6][64], | |
197 int motion_x, int motion_y) | |
198 { | |
199 Wmv2Context * const w= (Wmv2Context*)s; | |
200 int cbp, coded_cbp, i; | |
201 int pred_x, pred_y; | |
1064 | 202 uint8_t *coded_block; |
936 | 203 |
204 handle_slices(s); | |
205 | |
206 if (!s->mb_intra) { | |
207 /* compute cbp */ | |
208 set_stat(ST_INTER_MB); | |
209 cbp = 0; | |
210 for (i = 0; i < 6; i++) { | |
211 if (s->block_last_index[i] >= 0) | |
212 cbp |= 1 << (5 - i); | |
213 } | |
214 | |
215 put_bits(&s->pb, | |
216 wmv2_inter_table[w->cbp_table_index][cbp + 64][1], | |
217 wmv2_inter_table[w->cbp_table_index][cbp + 64][0]); | |
218 | |
219 /* motion vector */ | |
1938
e2501e6e7ff7
unify table indexing (motion_val,dc_val,ac_val,coded_block changed)
michael
parents:
1668
diff
changeset
|
220 h263_pred_motion(s, 0, 0, &pred_x, &pred_y); |
936 | 221 msmpeg4_encode_motion(s, motion_x - pred_x, |
222 motion_y - pred_y); | |
223 } else { | |
224 /* compute cbp */ | |
225 cbp = 0; | |
226 coded_cbp = 0; | |
227 for (i = 0; i < 6; i++) { | |
228 int val, pred; | |
229 val = (s->block_last_index[i] >= 1); | |
230 cbp |= val << (5 - i); | |
231 if (i < 4) { | |
232 /* predict value for close blocks only for luma */ | |
233 pred = coded_block_pred(s, i, &coded_block); | |
234 *coded_block = val; | |
235 val = val ^ pred; | |
236 } | |
237 coded_cbp |= val << (5 - i); | |
238 } | |
239 #if 0 | |
240 if (coded_cbp) | |
241 printf("cbp=%x %x\n", cbp, coded_cbp); | |
242 #endif | |
243 | |
244 if (s->pict_type == I_TYPE) { | |
245 set_stat(ST_INTRA_MB); | |
246 put_bits(&s->pb, | |
2474 | 247 ff_msmp4_mb_i_table[coded_cbp][1], ff_msmp4_mb_i_table[coded_cbp][0]); |
936 | 248 } else { |
249 put_bits(&s->pb, | |
250 wmv2_inter_table[w->cbp_table_index][cbp][1], | |
251 wmv2_inter_table[w->cbp_table_index][cbp][0]); | |
252 } | |
253 set_stat(ST_INTRA_MB); | |
254 put_bits(&s->pb, 1, 0); /* no AC prediction yet */ | |
255 if(s->inter_intra_pred){ | |
256 s->h263_aic_dir=0; | |
257 put_bits(&s->pb, table_inter_intra[s->h263_aic_dir][1], table_inter_intra[s->h263_aic_dir][0]); | |
258 } | |
259 } | |
260 | |
261 for (i = 0; i < 6; i++) { | |
262 msmpeg4_encode_block(s, block[i], i); | |
263 } | |
264 } | |
1070
6da5ae9ee199
more #ifdef CONFIG_ENCODERS patch by (Wolfgang Hesseler <qv at multimediaware dot com>) with modifications by me (s/WOLFGANG/CONFIG_ENCODERS/ and some other fixes)
michaelni
parents:
1064
diff
changeset
|
265 #endif //CONFIG_ENCODERS |
936 | 266 |
267 static void parse_mb_skip(Wmv2Context * w){ | |
268 int mb_x, mb_y; | |
269 MpegEncContext * const s= &w->s; | |
1177
fea03d2c4946
simplified adressing of most mb based arrays (mb_x + mb_y*s->mb_stride) now instead of mb_x + mb_y*mb_width and 1+mb_x + (1+mb_y)*(mb_width+2) and ... mixture
michaelni
parents:
1163
diff
changeset
|
270 uint32_t * const mb_type= s->current_picture_ptr->mb_type; |
936 | 271 |
272 w->skip_type= get_bits(&s->gb, 2); | |
273 switch(w->skip_type){ | |
274 case SKIP_TYPE_NONE: | |
275 for(mb_y=0; mb_y<s->mb_height; mb_y++){ | |
276 for(mb_x=0; mb_x<s->mb_width; mb_x++){ | |
1177
fea03d2c4946
simplified adressing of most mb based arrays (mb_x + mb_y*s->mb_stride) now instead of mb_x + mb_y*mb_width and 1+mb_x + (1+mb_y)*(mb_width+2) and ... mixture
michaelni
parents:
1163
diff
changeset
|
277 mb_type[mb_y*s->mb_stride + mb_x]= MB_TYPE_16x16 | MB_TYPE_L0; |
936 | 278 } |
279 } | |
280 break; | |
281 case SKIP_TYPE_MPEG: | |
282 for(mb_y=0; mb_y<s->mb_height; mb_y++){ | |
283 for(mb_x=0; mb_x<s->mb_width; mb_x++){ | |
1177
fea03d2c4946
simplified adressing of most mb based arrays (mb_x + mb_y*s->mb_stride) now instead of mb_x + mb_y*mb_width and 1+mb_x + (1+mb_y)*(mb_width+2) and ... mixture
michaelni
parents:
1163
diff
changeset
|
284 mb_type[mb_y*s->mb_stride + mb_x]= (get_bits1(&s->gb) ? MB_TYPE_SKIP : 0) | MB_TYPE_16x16 | MB_TYPE_L0; |
936 | 285 } |
286 } | |
287 break; | |
288 case SKIP_TYPE_ROW: | |
289 for(mb_y=0; mb_y<s->mb_height; mb_y++){ | |
290 if(get_bits1(&s->gb)){ | |
291 for(mb_x=0; mb_x<s->mb_width; mb_x++){ | |
1177
fea03d2c4946
simplified adressing of most mb based arrays (mb_x + mb_y*s->mb_stride) now instead of mb_x + mb_y*mb_width and 1+mb_x + (1+mb_y)*(mb_width+2) and ... mixture
michaelni
parents:
1163
diff
changeset
|
292 mb_type[mb_y*s->mb_stride + mb_x]= MB_TYPE_SKIP | MB_TYPE_16x16 | MB_TYPE_L0; |
936 | 293 } |
294 }else{ | |
295 for(mb_x=0; mb_x<s->mb_width; mb_x++){ | |
1177
fea03d2c4946
simplified adressing of most mb based arrays (mb_x + mb_y*s->mb_stride) now instead of mb_x + mb_y*mb_width and 1+mb_x + (1+mb_y)*(mb_width+2) and ... mixture
michaelni
parents:
1163
diff
changeset
|
296 mb_type[mb_y*s->mb_stride + mb_x]= (get_bits1(&s->gb) ? MB_TYPE_SKIP : 0) | MB_TYPE_16x16 | MB_TYPE_L0; |
936 | 297 } |
298 } | |
299 } | |
300 break; | |
301 case SKIP_TYPE_COL: | |
302 for(mb_x=0; mb_x<s->mb_width; mb_x++){ | |
303 if(get_bits1(&s->gb)){ | |
304 for(mb_y=0; mb_y<s->mb_height; mb_y++){ | |
1177
fea03d2c4946
simplified adressing of most mb based arrays (mb_x + mb_y*s->mb_stride) now instead of mb_x + mb_y*mb_width and 1+mb_x + (1+mb_y)*(mb_width+2) and ... mixture
michaelni
parents:
1163
diff
changeset
|
305 mb_type[mb_y*s->mb_stride + mb_x]= MB_TYPE_SKIP | MB_TYPE_16x16 | MB_TYPE_L0; |
936 | 306 } |
307 }else{ | |
308 for(mb_y=0; mb_y<s->mb_height; mb_y++){ | |
1177
fea03d2c4946
simplified adressing of most mb based arrays (mb_x + mb_y*s->mb_stride) now instead of mb_x + mb_y*mb_width and 1+mb_x + (1+mb_y)*(mb_width+2) and ... mixture
michaelni
parents:
1163
diff
changeset
|
309 mb_type[mb_y*s->mb_stride + mb_x]= (get_bits1(&s->gb) ? MB_TYPE_SKIP : 0) | MB_TYPE_16x16 | MB_TYPE_L0; |
936 | 310 } |
311 } | |
312 } | |
313 break; | |
314 } | |
315 } | |
316 | |
317 static int decode_ext_header(Wmv2Context *w){ | |
318 MpegEncContext * const s= &w->s; | |
319 GetBitContext gb; | |
320 int fps; | |
321 int code; | |
322 | |
323 if(s->avctx->extradata_size<4) return -1; | |
324 | |
1025
1f9afd8b9131
GetBitContext.size is allways multiplied by 8 -> use size_in_bits to avoid useless *8 in a few inner loops
michaelni
parents:
983
diff
changeset
|
325 init_get_bits(&gb, s->avctx->extradata, s->avctx->extradata_size*8); |
936 | 326 |
327 fps = get_bits(&gb, 5); | |
328 s->bit_rate = get_bits(&gb, 11)*1024; | |
329 w->mspel_bit = get_bits1(&gb); | |
330 w->flag3 = get_bits1(&gb); | |
331 w->abt_flag = get_bits1(&gb); | |
332 w->j_type_bit = get_bits1(&gb); | |
333 w->top_left_mv_flag= get_bits1(&gb); | |
334 w->per_mb_rl_bit = get_bits1(&gb); | |
335 code = get_bits(&gb, 3); | |
336 | |
337 if(code==0) return -1; | |
1092 | 338 |
936 | 339 s->slice_height = s->mb_height / code; |
340 | |
341 if(s->avctx->debug&FF_DEBUG_PICT_INFO){ | |
1598
932d306bf1dc
av_log() patch by (Michel Bardiaux <mbardiaux at peaktime dot be>)
michael
parents:
1524
diff
changeset
|
342 av_log(s->avctx, AV_LOG_DEBUG, "fps:%d, br:%d, qpbit:%d, abt_flag:%d, j_type_bit:%d, tl_mv_flag:%d, mbrl_bit:%d, code:%d, flag3:%d, slices:%d\n", |
983 | 343 fps, s->bit_rate, w->mspel_bit, w->abt_flag, w->j_type_bit, w->top_left_mv_flag, w->per_mb_rl_bit, code, w->flag3, |
344 code); | |
936 | 345 } |
346 return 0; | |
347 } | |
348 | |
349 int ff_wmv2_decode_picture_header(MpegEncContext * s) | |
350 { | |
351 Wmv2Context * const w= (Wmv2Context*)s; | |
1183 | 352 int code; |
936 | 353 |
354 #if 0 | |
355 { | |
356 int i; | |
357 for(i=0; i<s->gb.size*8; i++) | |
358 printf("%d", get_bits1(&s->gb)); | |
359 // get_bits1(&s->gb); | |
360 printf("END\n"); | |
361 return -1; | |
362 } | |
363 #endif | |
364 if(s->picture_number==0) | |
365 decode_ext_header(w); | |
366 | |
367 s->pict_type = get_bits(&s->gb, 1) + 1; | |
368 if(s->pict_type == I_TYPE){ | |
369 code = get_bits(&s->gb, 7); | |
1598
932d306bf1dc
av_log() patch by (Michel Bardiaux <mbardiaux at peaktime dot be>)
michael
parents:
1524
diff
changeset
|
370 av_log(s->avctx, AV_LOG_ERROR, "I7:%X/\n", code); |
936 | 371 } |
1651 | 372 s->chroma_qscale= s->qscale = get_bits(&s->gb, 5); |
1183 | 373 if(s->qscale < 0) |
374 return -1; | |
375 | |
376 return 0; | |
377 } | |
378 | |
379 int ff_wmv2_decode_secondary_picture_header(MpegEncContext * s) | |
380 { | |
381 Wmv2Context * const w= (Wmv2Context*)s; | |
936 | 382 |
383 if (s->pict_type == I_TYPE) { | |
384 if(w->j_type_bit) w->j_type= get_bits1(&s->gb); | |
385 else w->j_type= 0; //FIXME check | |
386 | |
387 if(!w->j_type){ | |
388 if(w->per_mb_rl_bit) s->per_mb_rl_table= get_bits1(&s->gb); | |
389 else s->per_mb_rl_table= 0; | |
390 | |
391 if(!s->per_mb_rl_table){ | |
392 s->rl_chroma_table_index = decode012(&s->gb); | |
393 s->rl_table_index = decode012(&s->gb); | |
394 } | |
395 | |
396 s->dc_table_index = get_bits1(&s->gb); | |
397 } | |
398 s->inter_intra_pred= 0; | |
399 s->no_rounding = 1; | |
400 if(s->avctx->debug&FF_DEBUG_PICT_INFO){ | |
1598
932d306bf1dc
av_log() patch by (Michel Bardiaux <mbardiaux at peaktime dot be>)
michael
parents:
1524
diff
changeset
|
401 av_log(s->avctx, AV_LOG_DEBUG, "qscale:%d rlc:%d rl:%d dc:%d mbrl:%d j_type:%d \n", |
936 | 402 s->qscale, |
403 s->rl_chroma_table_index, | |
404 s->rl_table_index, | |
405 s->dc_table_index, | |
406 s->per_mb_rl_table, | |
407 w->j_type); | |
408 } | |
409 }else{ | |
410 int cbp_index; | |
411 w->j_type=0; | |
412 | |
413 parse_mb_skip(w); | |
414 cbp_index= decode012(&s->gb); | |
415 if(s->qscale <= 10){ | |
416 int map[3]= {0,2,1}; | |
417 w->cbp_table_index= map[cbp_index]; | |
418 }else if(s->qscale <= 20){ | |
419 int map[3]= {1,0,2}; | |
420 w->cbp_table_index= map[cbp_index]; | |
421 }else{ | |
422 int map[3]= {2,1,0}; | |
423 w->cbp_table_index= map[cbp_index]; | |
424 } | |
425 | |
426 if(w->mspel_bit) s->mspel= get_bits1(&s->gb); | |
427 else s->mspel= 0; //FIXME check | |
428 | |
429 if(w->abt_flag){ | |
430 w->per_mb_abt= get_bits1(&s->gb)^1; | |
431 if(!w->per_mb_abt){ | |
432 w->abt_type= decode012(&s->gb); | |
433 } | |
434 } | |
435 | |
436 if(w->per_mb_rl_bit) s->per_mb_rl_table= get_bits1(&s->gb); | |
437 else s->per_mb_rl_table= 0; | |
438 | |
439 if(!s->per_mb_rl_table){ | |
440 s->rl_table_index = decode012(&s->gb); | |
441 s->rl_chroma_table_index = s->rl_table_index; | |
442 } | |
443 | |
444 s->dc_table_index = get_bits1(&s->gb); | |
445 s->mv_table_index = get_bits1(&s->gb); | |
446 | |
1943 | 447 s->inter_intra_pred= 0;//(s->width*s->height < 320*240 && s->bit_rate<=II_BITRATE); |
936 | 448 s->no_rounding ^= 1; |
449 | |
450 if(s->avctx->debug&FF_DEBUG_PICT_INFO){ | |
1598
932d306bf1dc
av_log() patch by (Michel Bardiaux <mbardiaux at peaktime dot be>)
michael
parents:
1524
diff
changeset
|
451 av_log(s->avctx, AV_LOG_DEBUG, "rl:%d rlc:%d dc:%d mv:%d mbrl:%d qp:%d mspel:%d per_mb_abt:%d abt_type:%d cbp:%d ii:%d\n", |
936 | 452 s->rl_table_index, |
453 s->rl_chroma_table_index, | |
454 s->dc_table_index, | |
455 s->mv_table_index, | |
456 s->per_mb_rl_table, | |
457 s->qscale, | |
458 s->mspel, | |
459 w->per_mb_abt, | |
460 w->abt_type, | |
461 w->cbp_table_index, | |
462 s->inter_intra_pred); | |
463 } | |
464 } | |
465 s->esc3_level_length= 0; | |
466 s->esc3_run_length= 0; | |
467 | |
468 s->picture_number++; //FIXME ? | |
469 | |
470 | |
471 // if(w->j_type) | |
472 // return wmv2_decode_j_picture(w); //FIXME | |
473 | |
474 if(w->j_type){ | |
1598
932d306bf1dc
av_log() patch by (Michel Bardiaux <mbardiaux at peaktime dot be>)
michael
parents:
1524
diff
changeset
|
475 av_log(s->avctx, AV_LOG_ERROR, "J-type picture isnt supported\n"); |
936 | 476 return -1; |
477 } | |
478 | |
479 return 0; | |
480 } | |
481 | |
482 static inline int wmv2_decode_motion(Wmv2Context *w, int *mx_ptr, int *my_ptr){ | |
483 MpegEncContext * const s= &w->s; | |
484 int ret; | |
485 | |
486 ret= msmpeg4_decode_motion(s, mx_ptr, my_ptr); | |
487 | |
488 if(ret<0) return -1; | |
489 | |
490 if((((*mx_ptr)|(*my_ptr)) & 1) && s->mspel) | |
491 w->hshift= get_bits1(&s->gb); | |
492 else | |
493 w->hshift= 0; | |
494 | |
495 //printf("%d %d ", *mx_ptr, *my_ptr); | |
496 | |
497 return 0; | |
498 } | |
499 | |
500 static int16_t *wmv2_pred_motion(Wmv2Context *w, int *px, int *py){ | |
501 MpegEncContext * const s= &w->s; | |
502 int xy, wrap, diff, type; | |
1064 | 503 int16_t *A, *B, *C, *mot_val; |
936 | 504 |
1938
e2501e6e7ff7
unify table indexing (motion_val,dc_val,ac_val,coded_block changed)
michael
parents:
1668
diff
changeset
|
505 wrap = s->b8_stride; |
936 | 506 xy = s->block_index[0]; |
507 | |
1668
30746f429df6
move motion_val & mb_type to AVFrame patch by (Wolfgang Hesseler <qv at multimediaware dot com>)
michael
parents:
1651
diff
changeset
|
508 mot_val = s->current_picture.motion_val[0][xy]; |
936 | 509 |
1668
30746f429df6
move motion_val & mb_type to AVFrame patch by (Wolfgang Hesseler <qv at multimediaware dot com>)
michael
parents:
1651
diff
changeset
|
510 A = s->current_picture.motion_val[0][xy - 1]; |
30746f429df6
move motion_val & mb_type to AVFrame patch by (Wolfgang Hesseler <qv at multimediaware dot com>)
michael
parents:
1651
diff
changeset
|
511 B = s->current_picture.motion_val[0][xy - wrap]; |
30746f429df6
move motion_val & mb_type to AVFrame patch by (Wolfgang Hesseler <qv at multimediaware dot com>)
michael
parents:
1651
diff
changeset
|
512 C = s->current_picture.motion_val[0][xy + 2 - wrap]; |
936 | 513 |
514 diff= FFMAX(ABS(A[0] - B[0]), ABS(A[1] - B[1])); | |
515 | |
1043 | 516 if(s->mb_x && !s->first_slice_line && !s->mspel && w->top_left_mv_flag && diff >= 8) |
936 | 517 type= get_bits1(&s->gb); |
518 else | |
519 type= 2; | |
520 | |
521 if(type == 0){ | |
522 *px= A[0]; | |
523 *py= A[1]; | |
524 }else if(type == 1){ | |
525 *px= B[0]; | |
526 *py= B[1]; | |
527 }else{ | |
528 /* special case for first (slice) line */ | |
529 if (s->first_slice_line) { | |
530 *px = A[0]; | |
531 *py = A[1]; | |
532 } else { | |
533 *px = mid_pred(A[0], B[0], C[0]); | |
534 *py = mid_pred(A[1], B[1], C[1]); | |
535 } | |
536 } | |
537 | |
538 return mot_val; | |
539 } | |
540 | |
541 static inline int wmv2_decode_inter_block(Wmv2Context *w, DCTELEM *block, int n, int cbp){ | |
542 MpegEncContext * const s= &w->s; | |
543 static const int sub_cbp_table[3]= {2,3,1}; | |
544 int sub_cbp; | |
545 | |
546 if(!cbp){ | |
547 s->block_last_index[n] = -1; | |
548 | |
549 return 0; | |
550 } | |
551 | |
552 if(w->per_block_abt) | |
553 w->abt_type= decode012(&s->gb); | |
554 #if 0 | |
555 if(w->per_block_abt) | |
556 printf("B%d", w->abt_type); | |
557 #endif | |
558 w->abt_type_table[n]= w->abt_type; | |
559 | |
560 if(w->abt_type){ | |
561 // const uint8_t *scantable= w->abt_scantable[w->abt_type-1].permutated; | |
562 const uint8_t *scantable= w->abt_scantable[w->abt_type-1].scantable; | |
563 // const uint8_t *scantable= w->abt_type-1 ? w->abt_scantable[1].permutated : w->abt_scantable[0].scantable; | |
564 | |
565 sub_cbp= sub_cbp_table[ decode012(&s->gb) ]; | |
566 // printf("S%d", sub_cbp); | |
567 | |
568 if(sub_cbp&1){ | |
569 if (msmpeg4_decode_block(s, block, n, 1, scantable) < 0) | |
570 return -1; | |
571 } | |
572 | |
573 if(sub_cbp&2){ | |
574 if (msmpeg4_decode_block(s, w->abt_block2[n], n, 1, scantable) < 0) | |
575 return -1; | |
576 } | |
577 s->block_last_index[n] = 63; | |
578 | |
579 return 0; | |
580 }else{ | |
581 return msmpeg4_decode_block(s, block, n, 1, s->inter_scantable.permutated); | |
582 } | |
583 } | |
584 | |
585 static void wmv2_add_block(Wmv2Context *w, DCTELEM *block1, uint8_t *dst, int stride, int n){ | |
586 MpegEncContext * const s= &w->s; | |
1064 | 587 |
936 | 588 switch(w->abt_type_table[n]){ |
589 case 0: | |
590 if (s->block_last_index[n] >= 0) { | |
1092 | 591 s->dsp.idct_add (dst, stride, block1); |
936 | 592 } |
593 break; | |
594 case 1: | |
595 simple_idct84_add(dst , stride, block1); | |
596 simple_idct84_add(dst + 4*stride, stride, w->abt_block2[n]); | |
597 memset(w->abt_block2[n], 0, 64*sizeof(DCTELEM)); | |
598 break; | |
599 case 2: | |
600 simple_idct48_add(dst , stride, block1); | |
601 simple_idct48_add(dst + 4 , stride, w->abt_block2[n]); | |
602 memset(w->abt_block2[n], 0, 64*sizeof(DCTELEM)); | |
603 break; | |
604 default: | |
1598
932d306bf1dc
av_log() patch by (Michel Bardiaux <mbardiaux at peaktime dot be>)
michael
parents:
1524
diff
changeset
|
605 av_log(s->avctx, AV_LOG_ERROR, "internal error in WMV2 abt\n"); |
936 | 606 } |
607 } | |
608 | |
609 void ff_wmv2_add_mb(MpegEncContext *s, DCTELEM block1[6][64], uint8_t *dest_y, uint8_t *dest_cb, uint8_t *dest_cr){ | |
610 Wmv2Context * const w= (Wmv2Context*)s; | |
611 | |
612 wmv2_add_block(w, block1[0], dest_y , s->linesize, 0); | |
613 wmv2_add_block(w, block1[1], dest_y + 8 , s->linesize, 1); | |
614 wmv2_add_block(w, block1[2], dest_y + 8*s->linesize, s->linesize, 2); | |
615 wmv2_add_block(w, block1[3], dest_y + 8 + 8*s->linesize, s->linesize, 3); | |
616 | |
617 if(s->flags&CODEC_FLAG_GRAY) return; | |
618 | |
619 wmv2_add_block(w, block1[4], dest_cb , s->uvlinesize, 4); | |
620 wmv2_add_block(w, block1[5], dest_cr , s->uvlinesize, 5); | |
621 } | |
622 | |
623 void ff_mspel_motion(MpegEncContext *s, | |
1064 | 624 uint8_t *dest_y, uint8_t *dest_cb, uint8_t *dest_cr, |
625 uint8_t **ref_picture, op_pixels_func (*pix_op)[4], | |
936 | 626 int motion_x, int motion_y, int h) |
627 { | |
628 Wmv2Context * const w= (Wmv2Context*)s; | |
1064 | 629 uint8_t *ptr; |
936 | 630 int dxy, offset, mx, my, src_x, src_y, v_edge_pos, linesize, uvlinesize; |
631 int emu=0; | |
632 | |
633 dxy = ((motion_y & 1) << 1) | (motion_x & 1); | |
634 dxy = 2*dxy + w->hshift; | |
635 src_x = s->mb_x * 16 + (motion_x >> 1); | |
636 src_y = s->mb_y * 16 + (motion_y >> 1); | |
637 | |
638 /* WARNING: do no forget half pels */ | |
639 v_edge_pos = s->v_edge_pos; | |
640 src_x = clip(src_x, -16, s->width); | |
641 src_y = clip(src_y, -16, s->height); | |
642 linesize = s->linesize; | |
643 uvlinesize = s->uvlinesize; | |
644 ptr = ref_picture[0] + (src_y * linesize) + src_x; | |
645 | |
646 if(s->flags&CODEC_FLAG_EMU_EDGE){ | |
647 if(src_x<1 || src_y<1 || src_x + 17 >= s->h_edge_pos | |
648 || src_y + h+1 >= v_edge_pos){ | |
1318 | 649 ff_emulated_edge_mc(s->edge_emu_buffer, ptr - 1 - s->linesize, s->linesize, 19, 19, |
936 | 650 src_x-1, src_y-1, s->h_edge_pos, s->v_edge_pos); |
651 ptr= s->edge_emu_buffer + 1 + s->linesize; | |
652 emu=1; | |
653 } | |
654 } | |
655 | |
656 s->dsp.put_mspel_pixels_tab[dxy](dest_y , ptr , linesize); | |
657 s->dsp.put_mspel_pixels_tab[dxy](dest_y+8 , ptr+8 , linesize); | |
658 s->dsp.put_mspel_pixels_tab[dxy](dest_y +8*linesize, ptr +8*linesize, linesize); | |
659 s->dsp.put_mspel_pixels_tab[dxy](dest_y+8+8*linesize, ptr+8+8*linesize, linesize); | |
660 | |
661 if(s->flags&CODEC_FLAG_GRAY) return; | |
662 | |
663 if (s->out_format == FMT_H263) { | |
664 dxy = 0; | |
665 if ((motion_x & 3) != 0) | |
666 dxy |= 1; | |
667 if ((motion_y & 3) != 0) | |
668 dxy |= 2; | |
669 mx = motion_x >> 2; | |
670 my = motion_y >> 2; | |
671 } else { | |
672 mx = motion_x / 2; | |
673 my = motion_y / 2; | |
674 dxy = ((my & 1) << 1) | (mx & 1); | |
675 mx >>= 1; | |
676 my >>= 1; | |
677 } | |
678 | |
679 src_x = s->mb_x * 8 + mx; | |
680 src_y = s->mb_y * 8 + my; | |
681 src_x = clip(src_x, -8, s->width >> 1); | |
682 if (src_x == (s->width >> 1)) | |
683 dxy &= ~1; | |
684 src_y = clip(src_y, -8, s->height >> 1); | |
685 if (src_y == (s->height >> 1)) | |
686 dxy &= ~2; | |
687 offset = (src_y * uvlinesize) + src_x; | |
688 ptr = ref_picture[1] + offset; | |
689 if(emu){ | |
1317
26c44d2433c1
make ff_emulated_edge_mc() independant of MpegEncContext
michaelni
parents:
1273
diff
changeset
|
690 ff_emulated_edge_mc(s->edge_emu_buffer, ptr, s->uvlinesize, 9, 9, |
936 | 691 src_x, src_y, s->h_edge_pos>>1, s->v_edge_pos>>1); |
692 ptr= s->edge_emu_buffer; | |
693 } | |
694 pix_op[1][dxy](dest_cb, ptr, uvlinesize, h >> 1); | |
695 | |
696 ptr = ref_picture[2] + offset; | |
697 if(emu){ | |
1317
26c44d2433c1
make ff_emulated_edge_mc() independant of MpegEncContext
michaelni
parents:
1273
diff
changeset
|
698 ff_emulated_edge_mc(s->edge_emu_buffer, ptr, s->uvlinesize, 9, 9, |
936 | 699 src_x, src_y, s->h_edge_pos>>1, s->v_edge_pos>>1); |
700 ptr= s->edge_emu_buffer; | |
701 } | |
702 pix_op[1][dxy](dest_cr, ptr, uvlinesize, h >> 1); | |
703 } | |
704 | |
705 | |
706 static int wmv2_decode_mb(MpegEncContext *s, DCTELEM block[6][64]) | |
707 { | |
708 Wmv2Context * const w= (Wmv2Context*)s; | |
709 int cbp, code, i; | |
1064 | 710 uint8_t *coded_val; |
936 | 711 |
712 if(w->j_type) return 0; | |
713 | |
714 if (s->pict_type == P_TYPE) { | |
1177
fea03d2c4946
simplified adressing of most mb based arrays (mb_x + mb_y*s->mb_stride) now instead of mb_x + mb_y*mb_width and 1+mb_x + (1+mb_y)*(mb_width+2) and ... mixture
michaelni
parents:
1163
diff
changeset
|
715 if(IS_SKIP(s->current_picture.mb_type[s->mb_y * s->mb_stride + s->mb_x])){ |
936 | 716 /* skip mb */ |
717 s->mb_intra = 0; | |
718 for(i=0;i<6;i++) | |
719 s->block_last_index[i] = -1; | |
720 s->mv_dir = MV_DIR_FORWARD; | |
721 s->mv_type = MV_TYPE_16X16; | |
722 s->mv[0][0][0] = 0; | |
723 s->mv[0][0][1] = 0; | |
724 s->mb_skiped = 1; | |
1185 | 725 w->hshift=0; |
936 | 726 return 0; |
727 } | |
728 | |
729 code = get_vlc2(&s->gb, mb_non_intra_vlc[w->cbp_table_index].table, MB_NON_INTRA_VLC_BITS, 3); | |
730 if (code < 0) | |
731 return -1; | |
732 s->mb_intra = (~code & 0x40) >> 6; | |
733 | |
734 cbp = code & 0x3f; | |
735 } else { | |
736 s->mb_intra = 1; | |
2474 | 737 code = get_vlc2(&s->gb, ff_msmp4_mb_i_vlc.table, MB_INTRA_VLC_BITS, 2); |
936 | 738 if (code < 0){ |
1598
932d306bf1dc
av_log() patch by (Michel Bardiaux <mbardiaux at peaktime dot be>)
michael
parents:
1524
diff
changeset
|
739 av_log(s->avctx, AV_LOG_ERROR, "II-cbp illegal at %d %d\n", s->mb_x, s->mb_y); |
936 | 740 return -1; |
741 } | |
742 /* predict coded block pattern */ | |
743 cbp = 0; | |
744 for(i=0;i<6;i++) { | |
745 int val = ((code >> (5 - i)) & 1); | |
746 if (i < 4) { | |
747 int pred = coded_block_pred(s, i, &coded_val); | |
748 val = val ^ pred; | |
749 *coded_val = val; | |
750 } | |
751 cbp |= val << (5 - i); | |
752 } | |
753 } | |
754 | |
755 if (!s->mb_intra) { | |
756 int mx, my; | |
757 //printf("P at %d %d\n", s->mb_x, s->mb_y); | |
758 wmv2_pred_motion(w, &mx, &my); | |
759 | |
760 if(cbp){ | |
761 if(s->per_mb_rl_table){ | |
762 s->rl_table_index = decode012(&s->gb); | |
763 s->rl_chroma_table_index = s->rl_table_index; | |
764 } | |
765 | |
766 if(w->abt_flag && w->per_mb_abt){ | |
767 w->per_block_abt= get_bits1(&s->gb); | |
768 if(!w->per_block_abt) | |
769 w->abt_type= decode012(&s->gb); | |
770 }else | |
771 w->per_block_abt=0; | |
772 } | |
773 | |
774 if (wmv2_decode_motion(w, &mx, &my) < 0) | |
775 return -1; | |
776 | |
777 s->mv_dir = MV_DIR_FORWARD; | |
778 s->mv_type = MV_TYPE_16X16; | |
779 s->mv[0][0][0] = mx; | |
780 s->mv[0][0][1] = my; | |
781 | |
782 for (i = 0; i < 6; i++) { | |
783 if (wmv2_decode_inter_block(w, block[i], i, (cbp >> (5 - i)) & 1) < 0) | |
784 { | |
1598
932d306bf1dc
av_log() patch by (Michel Bardiaux <mbardiaux at peaktime dot be>)
michael
parents:
1524
diff
changeset
|
785 av_log(s->avctx, AV_LOG_ERROR, "\nerror while decoding inter block: %d x %d (%d)\n", s->mb_x, s->mb_y, i); |
936 | 786 return -1; |
787 } | |
788 } | |
789 } else { | |
790 //if(s->pict_type==P_TYPE) | |
791 // printf("%d%d ", s->inter_intra_pred, cbp); | |
792 //printf("I at %d %d %d %06X\n", s->mb_x, s->mb_y, ((cbp&3)? 1 : 0) +((cbp&0x3C)? 2 : 0), show_bits(&s->gb, 24)); | |
793 s->ac_pred = get_bits1(&s->gb); | |
794 if(s->inter_intra_pred){ | |
795 s->h263_aic_dir= get_vlc2(&s->gb, inter_intra_vlc.table, INTER_INTRA_VLC_BITS, 1); | |
796 // printf("%d%d %d %d/", s->ac_pred, s->h263_aic_dir, s->mb_x, s->mb_y); | |
797 } | |
798 if(s->per_mb_rl_table && cbp){ | |
799 s->rl_table_index = decode012(&s->gb); | |
800 s->rl_chroma_table_index = s->rl_table_index; | |
801 } | |
802 | |
803 for (i = 0; i < 6; i++) { | |
804 if (msmpeg4_decode_block(s, block[i], i, (cbp >> (5 - i)) & 1, NULL) < 0) | |
805 { | |
1598
932d306bf1dc
av_log() patch by (Michel Bardiaux <mbardiaux at peaktime dot be>)
michael
parents:
1524
diff
changeset
|
806 av_log(s->avctx, AV_LOG_ERROR, "\nerror while decoding intra block: %d x %d (%d)\n", s->mb_x, s->mb_y, i); |
936 | 807 return -1; |
808 } | |
809 } | |
810 } | |
811 | |
812 return 0; | |
813 } | |
814 | |
815 static int wmv2_decode_init(AVCodecContext *avctx){ | |
816 Wmv2Context * const w= avctx->priv_data; | |
817 | |
818 if(ff_h263_decode_init(avctx) < 0) | |
819 return -1; | |
820 | |
821 wmv2_common_init(w); | |
822 | |
823 return 0; | |
824 } | |
825 | |
826 AVCodec wmv2_decoder = { | |
827 "wmv2", | |
828 CODEC_TYPE_VIDEO, | |
829 CODEC_ID_WMV2, | |
830 sizeof(Wmv2Context), | |
831 wmv2_decode_init, | |
832 NULL, | |
833 ff_h263_decode_end, | |
834 ff_h263_decode_frame, | |
835 CODEC_CAP_DRAW_HORIZ_BAND | CODEC_CAP_DR1, | |
836 }; | |
837 | |
1070
6da5ae9ee199
more #ifdef CONFIG_ENCODERS patch by (Wolfgang Hesseler <qv at multimediaware dot com>) with modifications by me (s/WOLFGANG/CONFIG_ENCODERS/ and some other fixes)
michaelni
parents:
1064
diff
changeset
|
838 #ifdef CONFIG_ENCODERS |
936 | 839 AVCodec wmv2_encoder = { |
840 "wmv2", | |
841 CODEC_TYPE_VIDEO, | |
842 CODEC_ID_WMV2, | |
843 sizeof(Wmv2Context), | |
844 wmv2_encode_init, | |
845 MPV_encode_picture, | |
846 MPV_encode_end, | |
847 }; | |
1070
6da5ae9ee199
more #ifdef CONFIG_ENCODERS patch by (Wolfgang Hesseler <qv at multimediaware dot com>) with modifications by me (s/WOLFGANG/CONFIG_ENCODERS/ and some other fixes)
michaelni
parents:
1064
diff
changeset
|
848 #endif |