Go to most recent revision | Details | Last modification | View Log | RSS feed
Rev | Author | Line No. | Line |
---|---|---|---|
4349 | Serge | 1 | /* |
2 | * Copyright (c) 2002 The FFmpeg Project |
||
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 "mpegvideo.h" |
||
23 | #include "h263.h" |
||
24 | #include "mathops.h" |
||
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 |
||
40 | for(mb_x=0; 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 |
||
47 | for(mb_x=0; 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 |
||
54 | if(get_bits1(&s->gb)){ |
||
55 | for(mb_x=0; 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 |
||
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 |
||
67 | if(get_bits1(&s->gb)){ |
||
68 | for(mb_y=0; 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 |
||
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, 32); |
||
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(s->picture_number==0) |
||
119 | decode_ext_header(w); |
||
120 | |||
121 | s->pict_type = get_bits1(&s->gb) + 1; |
||
122 | if(s->pict_type == AV_PICTURE_TYPE_I){ |
||
123 | code = get_bits(&s->gb, 7); |
||
124 | av_log(s->avctx, AV_LOG_DEBUG, "I7:%X/\n", code); |
||
125 | } |
||
126 | s->chroma_qscale= s->qscale = get_bits(&s->gb, 5); |
||
127 | if(s->qscale <= 0) |
||
128 | return -1; |
||
129 | |||
130 | return 0; |
||
131 | } |
||
132 | |||
133 | int ff_wmv2_decode_secondary_picture_header(MpegEncContext * s) |
||
134 | { |
||
135 | Wmv2Context * const w= (Wmv2Context*)s; |
||
136 | |||
137 | if (s->pict_type == AV_PICTURE_TYPE_I) { |
||
138 | if(w->j_type_bit) w->j_type= get_bits1(&s->gb); |
||
139 | else w->j_type= 0; //FIXME check |
||
140 | |||
141 | if(!w->j_type){ |
||
142 | if(w->per_mb_rl_bit) s->per_mb_rl_table= get_bits1(&s->gb); |
||
143 | else s->per_mb_rl_table= 0; |
||
144 | |||
145 | if(!s->per_mb_rl_table){ |
||
146 | s->rl_chroma_table_index = decode012(&s->gb); |
||
147 | s->rl_table_index = decode012(&s->gb); |
||
148 | } |
||
149 | |||
150 | s->dc_table_index = get_bits1(&s->gb); |
||
151 | } |
||
152 | s->inter_intra_pred= 0; |
||
153 | s->no_rounding = 1; |
||
154 | if(s->avctx->debug&FF_DEBUG_PICT_INFO){ |
||
155 | av_log(s->avctx, AV_LOG_DEBUG, "qscale:%d rlc:%d rl:%d dc:%d mbrl:%d j_type:%d \n", |
||
156 | s->qscale, |
||
157 | s->rl_chroma_table_index, |
||
158 | s->rl_table_index, |
||
159 | s->dc_table_index, |
||
160 | s->per_mb_rl_table, |
||
161 | w->j_type); |
||
162 | } |
||
163 | }else{ |
||
164 | int cbp_index; |
||
165 | w->j_type=0; |
||
166 | |||
167 | parse_mb_skip(w); |
||
168 | cbp_index= decode012(&s->gb); |
||
169 | if(s->qscale <= 10){ |
||
170 | int map[3]= {0,2,1}; |
||
171 | w->cbp_table_index= map[cbp_index]; |
||
172 | }else if(s->qscale <= 20){ |
||
173 | int map[3]= {1,0,2}; |
||
174 | w->cbp_table_index= map[cbp_index]; |
||
175 | }else{ |
||
176 | int map[3]= {2,1,0}; |
||
177 | w->cbp_table_index= map[cbp_index]; |
||
178 | } |
||
179 | |||
180 | if(w->mspel_bit) s->mspel= get_bits1(&s->gb); |
||
181 | else s->mspel= 0; //FIXME check |
||
182 | |||
183 | if(w->abt_flag){ |
||
184 | w->per_mb_abt= get_bits1(&s->gb)^1; |
||
185 | if(!w->per_mb_abt){ |
||
186 | w->abt_type= decode012(&s->gb); |
||
187 | } |
||
188 | } |
||
189 | |||
190 | if(w->per_mb_rl_bit) s->per_mb_rl_table= get_bits1(&s->gb); |
||
191 | else s->per_mb_rl_table= 0; |
||
192 | |||
193 | if(!s->per_mb_rl_table){ |
||
194 | s->rl_table_index = decode012(&s->gb); |
||
195 | s->rl_chroma_table_index = s->rl_table_index; |
||
196 | } |
||
197 | |||
198 | s->dc_table_index = get_bits1(&s->gb); |
||
199 | s->mv_table_index = get_bits1(&s->gb); |
||
200 | |||
201 | s->inter_intra_pred= 0;//(s->width*s->height < 320*240 && s->bit_rate<=II_BITRATE); |
||
202 | s->no_rounding ^= 1; |
||
203 | |||
204 | if(s->avctx->debug&FF_DEBUG_PICT_INFO){ |
||
205 | 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", |
||
206 | s->rl_table_index, |
||
207 | s->rl_chroma_table_index, |
||
208 | s->dc_table_index, |
||
209 | s->mv_table_index, |
||
210 | s->per_mb_rl_table, |
||
211 | s->qscale, |
||
212 | s->mspel, |
||
213 | w->per_mb_abt, |
||
214 | w->abt_type, |
||
215 | w->cbp_table_index, |
||
216 | s->inter_intra_pred); |
||
217 | } |
||
218 | } |
||
219 | s->esc3_level_length= 0; |
||
220 | s->esc3_run_length= 0; |
||
221 | |||
222 | s->picture_number++; //FIXME ? |
||
223 | |||
224 | |||
225 | if(w->j_type){ |
||
226 | ff_intrax8_decode_picture(&w->x8, 2*s->qscale, (s->qscale-1)|1 ); |
||
227 | return 1; |
||
228 | } |
||
229 | |||
230 | return 0; |
||
231 | } |
||
232 | |||
233 | static inline int wmv2_decode_motion(Wmv2Context *w, int *mx_ptr, int *my_ptr){ |
||
234 | MpegEncContext * const s= &w->s; |
||
235 | int ret; |
||
236 | |||
237 | ret= ff_msmpeg4_decode_motion(s, mx_ptr, my_ptr); |
||
238 | |||
239 | if(ret<0) return -1; |
||
240 | |||
241 | if((((*mx_ptr)|(*my_ptr)) & 1) && s->mspel) |
||
242 | w->hshift= get_bits1(&s->gb); |
||
243 | else |
||
244 | w->hshift= 0; |
||
245 | |||
246 | return 0; |
||
247 | } |
||
248 | |||
249 | static int16_t *wmv2_pred_motion(Wmv2Context *w, int *px, int *py){ |
||
250 | MpegEncContext * const s= &w->s; |
||
251 | int xy, wrap, diff, type; |
||
252 | int16_t *A, *B, *C, *mot_val; |
||
253 | |||
254 | wrap = s->b8_stride; |
||
255 | xy = s->block_index[0]; |
||
256 | |||
257 | mot_val = s->current_picture.motion_val[0][xy]; |
||
258 | |||
259 | A = s->current_picture.motion_val[0][xy - 1]; |
||
260 | B = s->current_picture.motion_val[0][xy - wrap]; |
||
261 | C = s->current_picture.motion_val[0][xy + 2 - wrap]; |
||
262 | |||
263 | if(s->mb_x && !s->first_slice_line && !s->mspel && w->top_left_mv_flag) |
||
264 | diff= FFMAX(FFABS(A[0] - B[0]), FFABS(A[1] - B[1])); |
||
265 | else |
||
266 | diff=0; |
||
267 | |||
268 | if(diff >= 8) |
||
269 | type= get_bits1(&s->gb); |
||
270 | else |
||
271 | type= 2; |
||
272 | |||
273 | if(type == 0){ |
||
274 | *px= A[0]; |
||
275 | *py= A[1]; |
||
276 | }else if(type == 1){ |
||
277 | *px= B[0]; |
||
278 | *py= B[1]; |
||
279 | }else{ |
||
280 | /* special case for first (slice) line */ |
||
281 | if (s->first_slice_line) { |
||
282 | *px = A[0]; |
||
283 | *py = A[1]; |
||
284 | } else { |
||
285 | *px = mid_pred(A[0], B[0], C[0]); |
||
286 | *py = mid_pred(A[1], B[1], C[1]); |
||
287 | } |
||
288 | } |
||
289 | |||
290 | return mot_val; |
||
291 | } |
||
292 | |||
293 | static inline int wmv2_decode_inter_block(Wmv2Context *w, int16_t *block, int n, int cbp){ |
||
294 | MpegEncContext * const s= &w->s; |
||
295 | static const int sub_cbp_table[3]= {2,3,1}; |
||
296 | int sub_cbp; |
||
297 | |||
298 | if(!cbp){ |
||
299 | s->block_last_index[n] = -1; |
||
300 | |||
301 | return 0; |
||
302 | } |
||
303 | |||
304 | if(w->per_block_abt) |
||
305 | w->abt_type= decode012(&s->gb); |
||
306 | w->abt_type_table[n]= w->abt_type; |
||
307 | |||
308 | if(w->abt_type){ |
||
309 | // const uint8_t *scantable= w->abt_scantable[w->abt_type-1].permutated; |
||
310 | const uint8_t *scantable= w->abt_scantable[w->abt_type-1].scantable; |
||
311 | // const uint8_t *scantable= w->abt_type-1 ? w->abt_scantable[1].permutated : w->abt_scantable[0].scantable; |
||
312 | |||
313 | sub_cbp= sub_cbp_table[ decode012(&s->gb) ]; |
||
314 | |||
315 | if(sub_cbp&1){ |
||
316 | if (ff_msmpeg4_decode_block(s, block, n, 1, scantable) < 0) |
||
317 | return -1; |
||
318 | } |
||
319 | |||
320 | if(sub_cbp&2){ |
||
321 | if (ff_msmpeg4_decode_block(s, w->abt_block2[n], n, 1, scantable) < 0) |
||
322 | return -1; |
||
323 | } |
||
324 | s->block_last_index[n] = 63; |
||
325 | |||
326 | return 0; |
||
327 | }else{ |
||
328 | return ff_msmpeg4_decode_block(s, block, n, 1, s->inter_scantable.permutated); |
||
329 | } |
||
330 | } |
||
331 | |||
332 | |||
333 | int ff_wmv2_decode_mb(MpegEncContext *s, int16_t block[6][64]) |
||
334 | { |
||
335 | Wmv2Context * const w= (Wmv2Context*)s; |
||
336 | int cbp, code, i; |
||
337 | uint8_t *coded_val; |
||
338 | |||
339 | if(w->j_type) return 0; |
||
340 | |||
341 | if (s->pict_type == AV_PICTURE_TYPE_P) { |
||
342 | if (IS_SKIP(s->current_picture.mb_type[s->mb_y * s->mb_stride + s->mb_x])) { |
||
343 | /* skip mb */ |
||
344 | s->mb_intra = 0; |
||
345 | for(i=0;i<6;i++) |
||
346 | s->block_last_index[i] = -1; |
||
347 | s->mv_dir = MV_DIR_FORWARD; |
||
348 | s->mv_type = MV_TYPE_16X16; |
||
349 | s->mv[0][0][0] = 0; |
||
350 | s->mv[0][0][1] = 0; |
||
351 | s->mb_skipped = 1; |
||
352 | w->hshift=0; |
||
353 | return 0; |
||
354 | } |
||
355 | |||
356 | code = get_vlc2(&s->gb, ff_mb_non_intra_vlc[w->cbp_table_index].table, MB_NON_INTRA_VLC_BITS, 3); |
||
357 | if (code < 0) |
||
358 | return -1; |
||
359 | s->mb_intra = (~code & 0x40) >> 6; |
||
360 | |||
361 | cbp = code & 0x3f; |
||
362 | } else { |
||
363 | s->mb_intra = 1; |
||
364 | code = get_vlc2(&s->gb, ff_msmp4_mb_i_vlc.table, MB_INTRA_VLC_BITS, 2); |
||
365 | if (code < 0){ |
||
366 | av_log(s->avctx, AV_LOG_ERROR, "II-cbp illegal at %d %d\n", s->mb_x, s->mb_y); |
||
367 | return -1; |
||
368 | } |
||
369 | /* predict coded block pattern */ |
||
370 | cbp = 0; |
||
371 | for(i=0;i<6;i++) { |
||
372 | int val = ((code >> (5 - i)) & 1); |
||
373 | if (i < 4) { |
||
374 | int pred = ff_msmpeg4_coded_block_pred(s, i, &coded_val); |
||
375 | val = val ^ pred; |
||
376 | *coded_val = val; |
||
377 | } |
||
378 | cbp |= val << (5 - i); |
||
379 | } |
||
380 | } |
||
381 | |||
382 | if (!s->mb_intra) { |
||
383 | int mx, my; |
||
384 | wmv2_pred_motion(w, &mx, &my); |
||
385 | |||
386 | if(cbp){ |
||
387 | s->dsp.clear_blocks(s->block[0]); |
||
388 | if(s->per_mb_rl_table){ |
||
389 | s->rl_table_index = decode012(&s->gb); |
||
390 | s->rl_chroma_table_index = s->rl_table_index; |
||
391 | } |
||
392 | |||
393 | if(w->abt_flag && w->per_mb_abt){ |
||
394 | w->per_block_abt= get_bits1(&s->gb); |
||
395 | if(!w->per_block_abt) |
||
396 | w->abt_type= decode012(&s->gb); |
||
397 | }else |
||
398 | w->per_block_abt=0; |
||
399 | } |
||
400 | |||
401 | if (wmv2_decode_motion(w, &mx, &my) < 0) |
||
402 | return -1; |
||
403 | |||
404 | s->mv_dir = MV_DIR_FORWARD; |
||
405 | s->mv_type = MV_TYPE_16X16; |
||
406 | s->mv[0][0][0] = mx; |
||
407 | s->mv[0][0][1] = my; |
||
408 | |||
409 | for (i = 0; i < 6; i++) { |
||
410 | if (wmv2_decode_inter_block(w, block[i], i, (cbp >> (5 - i)) & 1) < 0) |
||
411 | { |
||
412 | av_log(s->avctx, AV_LOG_ERROR, "\nerror while decoding inter block: %d x %d (%d)\n", s->mb_x, s->mb_y, i); |
||
413 | return -1; |
||
414 | } |
||
415 | } |
||
416 | } else { |
||
417 | if (s->pict_type==AV_PICTURE_TYPE_P) |
||
418 | av_dlog(s->avctx, "%d%d ", s->inter_intra_pred, cbp); |
||
419 | av_dlog(s->avctx, "I at %d %d %d %06X\n", s->mb_x, s->mb_y, |
||
420 | ((cbp & 3) ? 1 : 0) +((cbp & 0x3C)? 2 : 0), |
||
421 | show_bits(&s->gb, 24)); |
||
422 | s->ac_pred = get_bits1(&s->gb); |
||
423 | if(s->inter_intra_pred){ |
||
424 | s->h263_aic_dir= get_vlc2(&s->gb, ff_inter_intra_vlc.table, INTER_INTRA_VLC_BITS, 1); |
||
425 | av_dlog(s->avctx, "%d%d %d %d/", |
||
426 | s->ac_pred, s->h263_aic_dir, s->mb_x, s->mb_y); |
||
427 | } |
||
428 | if(s->per_mb_rl_table && cbp){ |
||
429 | s->rl_table_index = decode012(&s->gb); |
||
430 | s->rl_chroma_table_index = s->rl_table_index; |
||
431 | } |
||
432 | |||
433 | s->dsp.clear_blocks(s->block[0]); |
||
434 | for (i = 0; i < 6; i++) { |
||
435 | if (ff_msmpeg4_decode_block(s, block[i], i, (cbp >> (5 - i)) & 1, NULL) < 0) |
||
436 | { |
||
437 | av_log(s->avctx, AV_LOG_ERROR, "\nerror while decoding intra block: %d x %d (%d)\n", s->mb_x, s->mb_y, i); |
||
438 | return -1; |
||
439 | } |
||
440 | } |
||
441 | } |
||
442 | |||
443 | return 0; |
||
444 | } |
||
445 | |||
446 | static av_cold int wmv2_decode_init(AVCodecContext *avctx){ |
||
447 | Wmv2Context * const w= avctx->priv_data; |
||
448 | |||
449 | avctx->flags |= CODEC_FLAG_EMU_EDGE; |
||
450 | |||
451 | if(ff_msmpeg4_decode_init(avctx) < 0) |
||
452 | return -1; |
||
453 | |||
454 | ff_wmv2_common_init(w); |
||
455 | |||
456 | ff_intrax8_common_init(&w->x8,&w->s); |
||
457 | |||
458 | return 0; |
||
459 | } |
||
460 | |||
461 | static av_cold int wmv2_decode_end(AVCodecContext *avctx) |
||
462 | { |
||
463 | Wmv2Context *w = avctx->priv_data; |
||
464 | |||
465 | ff_intrax8_common_end(&w->x8); |
||
466 | return ff_h263_decode_end(avctx); |
||
467 | } |
||
468 | |||
469 | AVCodec ff_wmv2_decoder = { |
||
470 | .name = "wmv2", |
||
471 | .long_name = NULL_IF_CONFIG_SMALL("Windows Media Video 8"), |
||
472 | .type = AVMEDIA_TYPE_VIDEO, |
||
473 | .id = AV_CODEC_ID_WMV2, |
||
474 | .priv_data_size = sizeof(Wmv2Context), |
||
475 | .init = wmv2_decode_init, |
||
476 | .close = wmv2_decode_end, |
||
477 | .decode = ff_h263_decode_frame, |
||
478 | .capabilities = CODEC_CAP_DRAW_HORIZ_BAND | CODEC_CAP_DR1, |
||
479 | .pix_fmts = ff_pixfmt_list_420, |
||
480 | };>>>>>>><>>6;i++)>>>6;i++) |