Mercurial > libavcodec.hg
annotate wmv2dec.c @ 8991:ca768cb2bfb6 libavcodec
Use last decoded SPS as current SPS in order to parse picture timing SEI
correctly. This works around an apparent H.264 standard deficiency.
Patch by Ivan Schreter, schreter gmx net
author | cehoyos |
---|---|
date | Fri, 20 Feb 2009 16:20:01 +0000 |
parents | 04423b2f6e0b |
children | 0f95e4f0a3f5 |
rev | line source |
---|---|
5939 | 1 /* |
8629
04423b2f6e0b
cosmetics: Remove pointless period after copyright statement non-sentences.
diego
parents:
8627
diff
changeset
|
2 * Copyright (c) 2002 The FFmpeg Project |
5939 | 3 * |
4 * This file is part of FFmpeg. | |
5 * | |
6 * FFmpeg is free software; you can redistribute it and/or | |
7 * modify it under the terms of the GNU Lesser General Public | |
8 * License as published by the Free Software Foundation; either | |
9 * version 2.1 of the License, or (at your option) any later version. | |
10 * | |
11 * FFmpeg is distributed in the hope that it will be useful, | |
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of | |
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |
14 * Lesser General Public License for more details. | |
15 * | |
16 * You should have received a copy of the GNU Lesser General Public | |
17 * License along with FFmpeg; if not, write to the Free Software | |
18 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA | |
19 */ | |
20 | |
21 #include "avcodec.h" | |
22 #include "dsputil.h" | |
23 #include "mpegvideo.h" | |
8627
d6bab465b82c
moves mid_pred() into mathops.h (with arch specific code split by directory)
aurel
parents:
7040
diff
changeset
|
24 #include "mathops.h" |
5939 | 25 #include "msmpeg4.h" |
26 #include "msmpeg4data.h" | |
27 #include "intrax8.h" | |
28 #include "wmv2.h" | |
29 | |
30 | |
31 static void parse_mb_skip(Wmv2Context * w){ | |
32 int mb_x, mb_y; | |
33 MpegEncContext * const s= &w->s; | |
34 uint32_t * const mb_type= s->current_picture_ptr->mb_type; | |
35 | |
36 w->skip_type= get_bits(&s->gb, 2); | |
37 switch(w->skip_type){ | |
38 case SKIP_TYPE_NONE: | |
39 for(mb_y=0; mb_y<s->mb_height; mb_y++){ | |
40 for(mb_x=0; mb_x<s->mb_width; mb_x++){ | |
41 mb_type[mb_y*s->mb_stride + mb_x]= MB_TYPE_16x16 | MB_TYPE_L0; | |
42 } | |
43 } | |
44 break; | |
45 case SKIP_TYPE_MPEG: | |
46 for(mb_y=0; mb_y<s->mb_height; mb_y++){ | |
47 for(mb_x=0; mb_x<s->mb_width; mb_x++){ | |
48 mb_type[mb_y*s->mb_stride + mb_x]= (get_bits1(&s->gb) ? MB_TYPE_SKIP : 0) | MB_TYPE_16x16 | MB_TYPE_L0; | |
49 } | |
50 } | |
51 break; | |
52 case SKIP_TYPE_ROW: | |
53 for(mb_y=0; mb_y<s->mb_height; mb_y++){ | |
54 if(get_bits1(&s->gb)){ | |
55 for(mb_x=0; mb_x<s->mb_width; mb_x++){ | |
56 mb_type[mb_y*s->mb_stride + mb_x]= MB_TYPE_SKIP | MB_TYPE_16x16 | MB_TYPE_L0; | |
57 } | |
58 }else{ | |
59 for(mb_x=0; mb_x<s->mb_width; mb_x++){ | |
60 mb_type[mb_y*s->mb_stride + mb_x]= (get_bits1(&s->gb) ? MB_TYPE_SKIP : 0) | MB_TYPE_16x16 | MB_TYPE_L0; | |
61 } | |
62 } | |
63 } | |
64 break; | |
65 case SKIP_TYPE_COL: | |
66 for(mb_x=0; mb_x<s->mb_width; mb_x++){ | |
67 if(get_bits1(&s->gb)){ | |
68 for(mb_y=0; mb_y<s->mb_height; mb_y++){ | |
69 mb_type[mb_y*s->mb_stride + mb_x]= MB_TYPE_SKIP | MB_TYPE_16x16 | MB_TYPE_L0; | |
70 } | |
71 }else{ | |
72 for(mb_y=0; mb_y<s->mb_height; mb_y++){ | |
73 mb_type[mb_y*s->mb_stride + mb_x]= (get_bits1(&s->gb) ? MB_TYPE_SKIP : 0) | MB_TYPE_16x16 | MB_TYPE_L0; | |
74 } | |
75 } | |
76 } | |
77 break; | |
78 } | |
79 } | |
80 | |
81 static int decode_ext_header(Wmv2Context *w){ | |
82 MpegEncContext * const s= &w->s; | |
83 GetBitContext gb; | |
84 int fps; | |
85 int code; | |
86 | |
87 if(s->avctx->extradata_size<4) return -1; | |
88 | |
89 init_get_bits(&gb, s->avctx->extradata, s->avctx->extradata_size*8); | |
90 | |
91 fps = get_bits(&gb, 5); | |
92 s->bit_rate = get_bits(&gb, 11)*1024; | |
93 w->mspel_bit = get_bits1(&gb); | |
94 s->loop_filter = get_bits1(&gb); | |
95 w->abt_flag = get_bits1(&gb); | |
96 w->j_type_bit = get_bits1(&gb); | |
97 w->top_left_mv_flag= get_bits1(&gb); | |
98 w->per_mb_rl_bit = get_bits1(&gb); | |
99 code = get_bits(&gb, 3); | |
100 | |
101 if(code==0) return -1; | |
102 | |
103 s->slice_height = s->mb_height / code; | |
104 | |
105 if(s->avctx->debug&FF_DEBUG_PICT_INFO){ | |
106 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, loop_filter:%d, slices:%d\n", | |
107 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, s->loop_filter, | |
108 code); | |
109 } | |
110 return 0; | |
111 } | |
112 | |
113 int ff_wmv2_decode_picture_header(MpegEncContext * s) | |
114 { | |
115 Wmv2Context * const w= (Wmv2Context*)s; | |
116 int code; | |
117 | |
118 #if 0 | |
119 { | |
120 int i; | |
121 for(i=0; i<s->gb.size*8; i++) | |
122 printf("%d", get_bits1(&s->gb)); | |
123 // get_bits1(&s->gb); | |
124 printf("END\n"); | |
125 return -1; | |
126 } | |
127 #endif | |
128 if(s->picture_number==0) | |
129 decode_ext_header(w); | |
130 | |
131 s->pict_type = get_bits1(&s->gb) + 1; | |
6481 | 132 if(s->pict_type == FF_I_TYPE){ |
5939 | 133 code = get_bits(&s->gb, 7); |
134 av_log(s->avctx, AV_LOG_DEBUG, "I7:%X/\n", code); | |
135 } | |
136 s->chroma_qscale= s->qscale = get_bits(&s->gb, 5); | |
6149 | 137 if(s->qscale <= 0) |
5939 | 138 return -1; |
139 | |
140 return 0; | |
141 } | |
142 | |
143 int ff_wmv2_decode_secondary_picture_header(MpegEncContext * s) | |
144 { | |
145 Wmv2Context * const w= (Wmv2Context*)s; | |
146 | |
6481 | 147 if (s->pict_type == FF_I_TYPE) { |
5939 | 148 if(w->j_type_bit) w->j_type= get_bits1(&s->gb); |
149 else w->j_type= 0; //FIXME check | |
150 | |
151 if(!w->j_type){ | |
152 if(w->per_mb_rl_bit) s->per_mb_rl_table= get_bits1(&s->gb); | |
153 else s->per_mb_rl_table= 0; | |
154 | |
155 if(!s->per_mb_rl_table){ | |
156 s->rl_chroma_table_index = decode012(&s->gb); | |
157 s->rl_table_index = decode012(&s->gb); | |
158 } | |
159 | |
160 s->dc_table_index = get_bits1(&s->gb); | |
161 } | |
162 s->inter_intra_pred= 0; | |
163 s->no_rounding = 1; | |
164 if(s->avctx->debug&FF_DEBUG_PICT_INFO){ | |
165 av_log(s->avctx, AV_LOG_DEBUG, "qscale:%d rlc:%d rl:%d dc:%d mbrl:%d j_type:%d \n", | |
166 s->qscale, | |
167 s->rl_chroma_table_index, | |
168 s->rl_table_index, | |
169 s->dc_table_index, | |
170 s->per_mb_rl_table, | |
171 w->j_type); | |
172 } | |
173 }else{ | |
174 int cbp_index; | |
175 w->j_type=0; | |
176 | |
177 parse_mb_skip(w); | |
178 cbp_index= decode012(&s->gb); | |
179 if(s->qscale <= 10){ | |
180 int map[3]= {0,2,1}; | |
181 w->cbp_table_index= map[cbp_index]; | |
182 }else if(s->qscale <= 20){ | |
183 int map[3]= {1,0,2}; | |
184 w->cbp_table_index= map[cbp_index]; | |
185 }else{ | |
186 int map[3]= {2,1,0}; | |
187 w->cbp_table_index= map[cbp_index]; | |
188 } | |
189 | |
190 if(w->mspel_bit) s->mspel= get_bits1(&s->gb); | |
191 else s->mspel= 0; //FIXME check | |
192 | |
193 if(w->abt_flag){ | |
194 w->per_mb_abt= get_bits1(&s->gb)^1; | |
195 if(!w->per_mb_abt){ | |
196 w->abt_type= decode012(&s->gb); | |
197 } | |
198 } | |
199 | |
200 if(w->per_mb_rl_bit) s->per_mb_rl_table= get_bits1(&s->gb); | |
201 else s->per_mb_rl_table= 0; | |
202 | |
203 if(!s->per_mb_rl_table){ | |
204 s->rl_table_index = decode012(&s->gb); | |
205 s->rl_chroma_table_index = s->rl_table_index; | |
206 } | |
207 | |
208 s->dc_table_index = get_bits1(&s->gb); | |
209 s->mv_table_index = get_bits1(&s->gb); | |
210 | |
211 s->inter_intra_pred= 0;//(s->width*s->height < 320*240 && s->bit_rate<=II_BITRATE); | |
212 s->no_rounding ^= 1; | |
213 | |
214 if(s->avctx->debug&FF_DEBUG_PICT_INFO){ | |
215 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", | |
216 s->rl_table_index, | |
217 s->rl_chroma_table_index, | |
218 s->dc_table_index, | |
219 s->mv_table_index, | |
220 s->per_mb_rl_table, | |
221 s->qscale, | |
222 s->mspel, | |
223 w->per_mb_abt, | |
224 w->abt_type, | |
225 w->cbp_table_index, | |
226 s->inter_intra_pred); | |
227 } | |
228 } | |
229 s->esc3_level_length= 0; | |
230 s->esc3_run_length= 0; | |
231 | |
232 s->picture_number++; //FIXME ? | |
233 | |
234 | |
235 if(w->j_type){ | |
236 ff_intrax8_decode_picture(&w->x8, 2*s->qscale, (s->qscale-1)|1 ); | |
237 return 1; | |
238 } | |
239 | |
240 return 0; | |
241 } | |
242 | |
243 static inline int wmv2_decode_motion(Wmv2Context *w, int *mx_ptr, int *my_ptr){ | |
244 MpegEncContext * const s= &w->s; | |
245 int ret; | |
246 | |
247 ret= ff_msmpeg4_decode_motion(s, mx_ptr, my_ptr); | |
248 | |
249 if(ret<0) return -1; | |
250 | |
251 if((((*mx_ptr)|(*my_ptr)) & 1) && s->mspel) | |
252 w->hshift= get_bits1(&s->gb); | |
253 else | |
254 w->hshift= 0; | |
255 | |
256 //printf("%d %d ", *mx_ptr, *my_ptr); | |
257 | |
258 return 0; | |
259 } | |
260 | |
261 static int16_t *wmv2_pred_motion(Wmv2Context *w, int *px, int *py){ | |
262 MpegEncContext * const s= &w->s; | |
263 int xy, wrap, diff, type; | |
264 int16_t *A, *B, *C, *mot_val; | |
265 | |
266 wrap = s->b8_stride; | |
267 xy = s->block_index[0]; | |
268 | |
269 mot_val = s->current_picture.motion_val[0][xy]; | |
270 | |
271 A = s->current_picture.motion_val[0][xy - 1]; | |
272 B = s->current_picture.motion_val[0][xy - wrap]; | |
273 C = s->current_picture.motion_val[0][xy + 2 - wrap]; | |
274 | |
275 if(s->mb_x && !s->first_slice_line && !s->mspel && w->top_left_mv_flag) | |
276 diff= FFMAX(FFABS(A[0] - B[0]), FFABS(A[1] - B[1])); | |
277 else | |
278 diff=0; | |
279 | |
280 if(diff >= 8) | |
281 type= get_bits1(&s->gb); | |
282 else | |
283 type= 2; | |
284 | |
285 if(type == 0){ | |
286 *px= A[0]; | |
287 *py= A[1]; | |
288 }else if(type == 1){ | |
289 *px= B[0]; | |
290 *py= B[1]; | |
291 }else{ | |
292 /* special case for first (slice) line */ | |
293 if (s->first_slice_line) { | |
294 *px = A[0]; | |
295 *py = A[1]; | |
296 } else { | |
297 *px = mid_pred(A[0], B[0], C[0]); | |
298 *py = mid_pred(A[1], B[1], C[1]); | |
299 } | |
300 } | |
301 | |
302 return mot_val; | |
303 } | |
304 | |
305 static inline int wmv2_decode_inter_block(Wmv2Context *w, DCTELEM *block, int n, int cbp){ | |
306 MpegEncContext * const s= &w->s; | |
307 static const int sub_cbp_table[3]= {2,3,1}; | |
308 int sub_cbp; | |
309 | |
310 if(!cbp){ | |
311 s->block_last_index[n] = -1; | |
312 | |
313 return 0; | |
314 } | |
315 | |
316 if(w->per_block_abt) | |
317 w->abt_type= decode012(&s->gb); | |
318 #if 0 | |
319 if(w->per_block_abt) | |
320 printf("B%d", w->abt_type); | |
321 #endif | |
322 w->abt_type_table[n]= w->abt_type; | |
323 | |
324 if(w->abt_type){ | |
325 // const uint8_t *scantable= w->abt_scantable[w->abt_type-1].permutated; | |
326 const uint8_t *scantable= w->abt_scantable[w->abt_type-1].scantable; | |
327 // const uint8_t *scantable= w->abt_type-1 ? w->abt_scantable[1].permutated : w->abt_scantable[0].scantable; | |
328 | |
329 sub_cbp= sub_cbp_table[ decode012(&s->gb) ]; | |
330 // printf("S%d", sub_cbp); | |
331 | |
332 if(sub_cbp&1){ | |
333 if (ff_msmpeg4_decode_block(s, block, n, 1, scantable) < 0) | |
334 return -1; | |
335 } | |
336 | |
337 if(sub_cbp&2){ | |
338 if (ff_msmpeg4_decode_block(s, w->abt_block2[n], n, 1, scantable) < 0) | |
339 return -1; | |
340 } | |
341 s->block_last_index[n] = 63; | |
342 | |
343 return 0; | |
344 }else{ | |
345 return ff_msmpeg4_decode_block(s, block, n, 1, s->inter_scantable.permutated); | |
346 } | |
347 } | |
348 | |
349 | |
350 int ff_wmv2_decode_mb(MpegEncContext *s, DCTELEM block[6][64]) | |
351 { | |
352 Wmv2Context * const w= (Wmv2Context*)s; | |
353 int cbp, code, i; | |
354 uint8_t *coded_val; | |
355 | |
356 if(w->j_type) return 0; | |
357 | |
6481 | 358 if (s->pict_type == FF_P_TYPE) { |
5939 | 359 if(IS_SKIP(s->current_picture.mb_type[s->mb_y * s->mb_stride + s->mb_x])){ |
360 /* skip mb */ | |
361 s->mb_intra = 0; | |
362 for(i=0;i<6;i++) | |
363 s->block_last_index[i] = -1; | |
364 s->mv_dir = MV_DIR_FORWARD; | |
365 s->mv_type = MV_TYPE_16X16; | |
366 s->mv[0][0][0] = 0; | |
367 s->mv[0][0][1] = 0; | |
368 s->mb_skipped = 1; | |
369 w->hshift=0; | |
370 return 0; | |
371 } | |
372 | |
373 code = get_vlc2(&s->gb, ff_mb_non_intra_vlc[w->cbp_table_index].table, MB_NON_INTRA_VLC_BITS, 3); | |
374 if (code < 0) | |
375 return -1; | |
376 s->mb_intra = (~code & 0x40) >> 6; | |
377 | |
378 cbp = code & 0x3f; | |
379 } else { | |
380 s->mb_intra = 1; | |
381 code = get_vlc2(&s->gb, ff_msmp4_mb_i_vlc.table, MB_INTRA_VLC_BITS, 2); | |
382 if (code < 0){ | |
383 av_log(s->avctx, AV_LOG_ERROR, "II-cbp illegal at %d %d\n", s->mb_x, s->mb_y); | |
384 return -1; | |
385 } | |
386 /* predict coded block pattern */ | |
387 cbp = 0; | |
388 for(i=0;i<6;i++) { | |
389 int val = ((code >> (5 - i)) & 1); | |
390 if (i < 4) { | |
391 int pred = ff_msmpeg4_coded_block_pred(s, i, &coded_val); | |
392 val = val ^ pred; | |
393 *coded_val = val; | |
394 } | |
395 cbp |= val << (5 - i); | |
396 } | |
397 } | |
398 | |
399 if (!s->mb_intra) { | |
400 int mx, my; | |
401 //printf("P at %d %d\n", s->mb_x, s->mb_y); | |
402 wmv2_pred_motion(w, &mx, &my); | |
403 | |
404 if(cbp){ | |
405 s->dsp.clear_blocks(s->block[0]); | |
406 if(s->per_mb_rl_table){ | |
407 s->rl_table_index = decode012(&s->gb); | |
408 s->rl_chroma_table_index = s->rl_table_index; | |
409 } | |
410 | |
411 if(w->abt_flag && w->per_mb_abt){ | |
412 w->per_block_abt= get_bits1(&s->gb); | |
413 if(!w->per_block_abt) | |
414 w->abt_type= decode012(&s->gb); | |
415 }else | |
416 w->per_block_abt=0; | |
417 } | |
418 | |
419 if (wmv2_decode_motion(w, &mx, &my) < 0) | |
420 return -1; | |
421 | |
422 s->mv_dir = MV_DIR_FORWARD; | |
423 s->mv_type = MV_TYPE_16X16; | |
424 s->mv[0][0][0] = mx; | |
425 s->mv[0][0][1] = my; | |
426 | |
427 for (i = 0; i < 6; i++) { | |
428 if (wmv2_decode_inter_block(w, block[i], i, (cbp >> (5 - i)) & 1) < 0) | |
429 { | |
430 av_log(s->avctx, AV_LOG_ERROR, "\nerror while decoding inter block: %d x %d (%d)\n", s->mb_x, s->mb_y, i); | |
431 return -1; | |
432 } | |
433 } | |
434 } else { | |
6481 | 435 //if(s->pict_type==FF_P_TYPE) |
5939 | 436 // printf("%d%d ", s->inter_intra_pred, cbp); |
437 //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)); | |
438 s->ac_pred = get_bits1(&s->gb); | |
439 if(s->inter_intra_pred){ | |
440 s->h263_aic_dir= get_vlc2(&s->gb, ff_inter_intra_vlc.table, INTER_INTRA_VLC_BITS, 1); | |
441 // printf("%d%d %d %d/", s->ac_pred, s->h263_aic_dir, s->mb_x, s->mb_y); | |
442 } | |
443 if(s->per_mb_rl_table && cbp){ | |
444 s->rl_table_index = decode012(&s->gb); | |
445 s->rl_chroma_table_index = s->rl_table_index; | |
446 } | |
447 | |
448 s->dsp.clear_blocks(s->block[0]); | |
449 for (i = 0; i < 6; i++) { | |
450 if (ff_msmpeg4_decode_block(s, block[i], i, (cbp >> (5 - i)) & 1, NULL) < 0) | |
451 { | |
452 av_log(s->avctx, AV_LOG_ERROR, "\nerror while decoding intra block: %d x %d (%d)\n", s->mb_x, s->mb_y, i); | |
453 return -1; | |
454 } | |
455 } | |
456 } | |
457 | |
458 return 0; | |
459 } | |
460 | |
6517
48759bfbd073
Apply 'cold' attribute to init/uninit functions in libavcodec
zuxy
parents:
6481
diff
changeset
|
461 static av_cold int wmv2_decode_init(AVCodecContext *avctx){ |
5939 | 462 Wmv2Context * const w= avctx->priv_data; |
463 | |
464 if(avctx->idct_algo==FF_IDCT_AUTO){ | |
465 avctx->idct_algo=FF_IDCT_WMV2; | |
466 } | |
467 | |
468 if(ff_h263_decode_init(avctx) < 0) | |
469 return -1; | |
470 | |
471 ff_wmv2_common_init(w); | |
472 | |
473 ff_intrax8_common_init(&w->x8,&w->s); | |
474 | |
475 return 0; | |
476 } | |
477 | |
6517
48759bfbd073
Apply 'cold' attribute to init/uninit functions in libavcodec
zuxy
parents:
6481
diff
changeset
|
478 static av_cold int wmv2_decode_end(AVCodecContext *avctx) |
6176
1d735690e172
Correctly clean up IntraX8Context upon codec close.
andoma
parents:
6149
diff
changeset
|
479 { |
1d735690e172
Correctly clean up IntraX8Context upon codec close.
andoma
parents:
6149
diff
changeset
|
480 Wmv2Context *w = avctx->priv_data; |
1d735690e172
Correctly clean up IntraX8Context upon codec close.
andoma
parents:
6149
diff
changeset
|
481 |
1d735690e172
Correctly clean up IntraX8Context upon codec close.
andoma
parents:
6149
diff
changeset
|
482 ff_intrax8_common_end(&w->x8); |
1d735690e172
Correctly clean up IntraX8Context upon codec close.
andoma
parents:
6149
diff
changeset
|
483 return ff_h263_decode_end(avctx); |
1d735690e172
Correctly clean up IntraX8Context upon codec close.
andoma
parents:
6149
diff
changeset
|
484 } |
1d735690e172
Correctly clean up IntraX8Context upon codec close.
andoma
parents:
6149
diff
changeset
|
485 |
5939 | 486 AVCodec wmv2_decoder = { |
487 "wmv2", | |
488 CODEC_TYPE_VIDEO, | |
489 CODEC_ID_WMV2, | |
490 sizeof(Wmv2Context), | |
491 wmv2_decode_init, | |
492 NULL, | |
6176
1d735690e172
Correctly clean up IntraX8Context upon codec close.
andoma
parents:
6149
diff
changeset
|
493 wmv2_decode_end, |
5939 | 494 ff_h263_decode_frame, |
495 CODEC_CAP_DRAW_HORIZ_BAND | CODEC_CAP_DR1, | |
7040
e943e1409077
Make AVCodec long_names definition conditional depending on CONFIG_SMALL.
stefano
parents:
6710
diff
changeset
|
496 .long_name = NULL_IF_CONFIG_SMALL("Windows Media Video 8"), |
5939 | 497 }; |