Commit | Line | Data |
---|---|---|
2ba45a60 DM |
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 "h263.h" | |
23 | #include "intrax8.h" | |
24 | #include "mathops.h" | |
25 | #include "mpegutils.h" | |
26 | #include "mpegvideo.h" | |
27 | #include "msmpeg4.h" | |
28 | #include "msmpeg4data.h" | |
29 | #include "wmv2.h" | |
30 | ||
31 | ||
32 | static void parse_mb_skip(Wmv2Context *w) | |
33 | { | |
34 | int mb_x, mb_y; | |
35 | MpegEncContext *const s = &w->s; | |
36 | uint32_t *const mb_type = s->current_picture_ptr->mb_type; | |
37 | ||
38 | w->skip_type = get_bits(&s->gb, 2); | |
39 | switch (w->skip_type) { | |
40 | case SKIP_TYPE_NONE: | |
41 | for (mb_y = 0; mb_y < s->mb_height; mb_y++) | |
42 | for (mb_x = 0; mb_x < s->mb_width; mb_x++) | |
43 | mb_type[mb_y * s->mb_stride + mb_x] = | |
44 | MB_TYPE_16x16 | MB_TYPE_L0; | |
45 | break; | |
46 | case SKIP_TYPE_MPEG: | |
47 | for (mb_y = 0; mb_y < s->mb_height; mb_y++) | |
48 | for (mb_x = 0; mb_x < s->mb_width; mb_x++) | |
49 | mb_type[mb_y * s->mb_stride + mb_x] = | |
50 | (get_bits1(&s->gb) ? MB_TYPE_SKIP : 0) | MB_TYPE_16x16 | MB_TYPE_L0; | |
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] = | |
57 | MB_TYPE_SKIP | MB_TYPE_16x16 | MB_TYPE_L0; | |
58 | } else { | |
59 | for (mb_x = 0; mb_x < s->mb_width; mb_x++) | |
60 | mb_type[mb_y * s->mb_stride + mb_x] = | |
61 | (get_bits1(&s->gb) ? MB_TYPE_SKIP : 0) | MB_TYPE_16x16 | MB_TYPE_L0; | |
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] = | |
70 | MB_TYPE_SKIP | MB_TYPE_16x16 | MB_TYPE_L0; | |
71 | } else { | |
72 | for (mb_y = 0; mb_y < s->mb_height; mb_y++) | |
73 | mb_type[mb_y * s->mb_stride + mb_x] = | |
74 | (get_bits1(&s->gb) ? MB_TYPE_SKIP : 0) | MB_TYPE_16x16 | MB_TYPE_L0; | |
75 | } | |
76 | } | |
77 | break; | |
78 | } | |
79 | } | |
80 | ||
81 | static int decode_ext_header(Wmv2Context *w) | |
82 | { | |
83 | MpegEncContext *const s = &w->s; | |
84 | GetBitContext gb; | |
85 | int fps; | |
86 | int code; | |
87 | ||
88 | if (s->avctx->extradata_size < 4) | |
89 | return -1; | |
90 | ||
91 | init_get_bits(&gb, s->avctx->extradata, 32); | |
92 | ||
93 | fps = get_bits(&gb, 5); | |
94 | s->bit_rate = get_bits(&gb, 11) * 1024; | |
95 | w->mspel_bit = get_bits1(&gb); | |
96 | s->loop_filter = get_bits1(&gb); | |
97 | w->abt_flag = get_bits1(&gb); | |
98 | w->j_type_bit = get_bits1(&gb); | |
99 | w->top_left_mv_flag = get_bits1(&gb); | |
100 | w->per_mb_rl_bit = get_bits1(&gb); | |
101 | code = get_bits(&gb, 3); | |
102 | ||
103 | if (code == 0) | |
104 | return -1; | |
105 | ||
106 | s->slice_height = s->mb_height / code; | |
107 | ||
108 | if (s->avctx->debug & FF_DEBUG_PICT_INFO) | |
109 | av_log(s->avctx, AV_LOG_DEBUG, | |
110 | "fps:%d, br:%d, qpbit:%d, abt_flag:%d, j_type_bit:%d, " | |
111 | "tl_mv_flag:%d, mbrl_bit:%d, code:%d, loop_filter:%d, " | |
112 | "slices:%d\n", | |
113 | fps, s->bit_rate, w->mspel_bit, w->abt_flag, w->j_type_bit, | |
114 | w->top_left_mv_flag, w->per_mb_rl_bit, code, s->loop_filter, | |
115 | code); | |
116 | return 0; | |
117 | } | |
118 | ||
119 | int ff_wmv2_decode_picture_header(MpegEncContext *s) | |
120 | { | |
121 | Wmv2Context *const w = (Wmv2Context *) s; | |
122 | int code; | |
123 | ||
124 | if (s->picture_number == 0) | |
125 | decode_ext_header(w); | |
126 | ||
127 | s->pict_type = get_bits1(&s->gb) + 1; | |
128 | if (s->pict_type == AV_PICTURE_TYPE_I) { | |
129 | code = get_bits(&s->gb, 7); | |
130 | av_log(s->avctx, AV_LOG_DEBUG, "I7:%X/\n", code); | |
131 | } | |
132 | s->chroma_qscale = s->qscale = get_bits(&s->gb, 5); | |
133 | if (s->qscale <= 0) | |
134 | return -1; | |
135 | ||
136 | return 0; | |
137 | } | |
138 | ||
139 | int ff_wmv2_decode_secondary_picture_header(MpegEncContext *s) | |
140 | { | |
141 | Wmv2Context *const w = (Wmv2Context *) s; | |
142 | ||
143 | if (s->pict_type == AV_PICTURE_TYPE_I) { | |
144 | if (w->j_type_bit) | |
145 | w->j_type = get_bits1(&s->gb); | |
146 | else | |
147 | w->j_type = 0; // FIXME check | |
148 | ||
149 | if (!w->j_type) { | |
150 | if (w->per_mb_rl_bit) | |
151 | s->per_mb_rl_table = get_bits1(&s->gb); | |
152 | else | |
153 | 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, | |
166 | "qscale:%d rlc:%d rl:%d dc:%d mbrl:%d j_type:%d \n", | |
167 | s->qscale, s->rl_chroma_table_index, s->rl_table_index, | |
168 | s->dc_table_index, s->per_mb_rl_table, w->j_type); | |
169 | } | |
170 | } else { | |
171 | int cbp_index; | |
172 | w->j_type = 0; | |
173 | ||
174 | parse_mb_skip(w); | |
175 | cbp_index = decode012(&s->gb); | |
176 | if (s->qscale <= 10) { | |
177 | int map[3] = { 0, 2, 1 }; | |
178 | w->cbp_table_index = map[cbp_index]; | |
179 | } else if (s->qscale <= 20) { | |
180 | int map[3] = { 1, 0, 2 }; | |
181 | w->cbp_table_index = map[cbp_index]; | |
182 | } else { | |
183 | int map[3] = {2,1,0}; | |
184 | w->cbp_table_index = map[cbp_index]; | |
185 | } | |
186 | ||
187 | if (w->mspel_bit) | |
188 | s->mspel = get_bits1(&s->gb); | |
189 | else | |
190 | s->mspel = 0; // FIXME check | |
191 | ||
192 | if (w->abt_flag) { | |
193 | w->per_mb_abt = get_bits1(&s->gb) ^ 1; | |
194 | if (!w->per_mb_abt) | |
195 | w->abt_type = decode012(&s->gb); | |
196 | } | |
197 | ||
198 | if (w->per_mb_rl_bit) | |
199 | s->per_mb_rl_table = get_bits1(&s->gb); | |
200 | else | |
201 | 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, | |
216 | "rl:%d rlc:%d dc:%d mv:%d mbrl:%d qp:%d mspel:%d " | |
217 | "per_mb_abt:%d abt_type:%d cbp:%d ii:%d\n", | |
218 | s->rl_table_index, s->rl_chroma_table_index, | |
219 | s->dc_table_index, s->mv_table_index, | |
220 | s->per_mb_rl_table, s->qscale, s->mspel, | |
221 | w->per_mb_abt, w->abt_type, w->cbp_table_index, | |
222 | s->inter_intra_pred); | |
223 | } | |
224 | } | |
225 | s->esc3_level_length = 0; | |
226 | s->esc3_run_length = 0; | |
227 | s->picture_number++; // FIXME ? | |
228 | ||
229 | if (w->j_type) { | |
230 | ff_intrax8_decode_picture(&w->x8, 2 * s->qscale, (s->qscale - 1) | 1); | |
231 | return 1; | |
232 | } | |
233 | ||
234 | return 0; | |
235 | } | |
236 | ||
237 | static inline int wmv2_decode_motion(Wmv2Context *w, int *mx_ptr, int *my_ptr) | |
238 | { | |
239 | MpegEncContext *const s = &w->s; | |
240 | int ret; | |
241 | ||
242 | ret = ff_msmpeg4_decode_motion(s, mx_ptr, my_ptr); | |
243 | ||
244 | if (ret < 0) | |
245 | return -1; | |
246 | ||
247 | if ((((*mx_ptr) | (*my_ptr)) & 1) && s->mspel) | |
248 | w->hshift = get_bits1(&s->gb); | |
249 | else | |
250 | w->hshift = 0; | |
251 | ||
252 | return 0; | |
253 | } | |
254 | ||
255 | static int16_t *wmv2_pred_motion(Wmv2Context *w, int *px, int *py) | |
256 | { | |
257 | MpegEncContext *const s = &w->s; | |
258 | int xy, wrap, diff, type; | |
259 | int16_t *A, *B, *C, *mot_val; | |
260 | ||
261 | wrap = s->b8_stride; | |
262 | xy = s->block_index[0]; | |
263 | ||
264 | mot_val = s->current_picture.motion_val[0][xy]; | |
265 | ||
266 | A = s->current_picture.motion_val[0][xy - 1]; | |
267 | B = s->current_picture.motion_val[0][xy - wrap]; | |
268 | C = s->current_picture.motion_val[0][xy + 2 - wrap]; | |
269 | ||
270 | if (s->mb_x && !s->first_slice_line && !s->mspel && w->top_left_mv_flag) | |
271 | diff = FFMAX(FFABS(A[0] - B[0]), FFABS(A[1] - B[1])); | |
272 | else | |
273 | diff = 0; | |
274 | ||
275 | if (diff >= 8) | |
276 | type = get_bits1(&s->gb); | |
277 | else | |
278 | type = 2; | |
279 | ||
280 | if (type == 0) { | |
281 | *px = A[0]; | |
282 | *py = A[1]; | |
283 | } else if (type == 1) { | |
284 | *px = B[0]; | |
285 | *py = B[1]; | |
286 | } else { | |
287 | /* special case for first (slice) line */ | |
288 | if (s->first_slice_line) { | |
289 | *px = A[0]; | |
290 | *py = A[1]; | |
291 | } else { | |
292 | *px = mid_pred(A[0], B[0], C[0]); | |
293 | *py = mid_pred(A[1], B[1], C[1]); | |
294 | } | |
295 | } | |
296 | ||
297 | return mot_val; | |
298 | } | |
299 | ||
300 | static inline int wmv2_decode_inter_block(Wmv2Context *w, int16_t *block, | |
301 | int n, int cbp) | |
302 | { | |
303 | MpegEncContext *const s = &w->s; | |
304 | static const int sub_cbp_table[3] = { 2, 3, 1 }; | |
305 | int sub_cbp; | |
306 | ||
307 | if (!cbp) { | |
308 | s->block_last_index[n] = -1; | |
309 | return 0; | |
310 | } | |
311 | ||
312 | if (w->per_block_abt) | |
313 | w->abt_type = decode012(&s->gb); | |
314 | w->abt_type_table[n] = w->abt_type; | |
315 | ||
316 | if (w->abt_type) { | |
317 | // const uint8_t *scantable = w->abt_scantable[w->abt_type - 1].permutated; | |
318 | const uint8_t *scantable = w->abt_scantable[w->abt_type - 1].scantable; | |
319 | // const uint8_t *scantable = w->abt_type - 1 ? w->abt_scantable[1].permutated : w->abt_scantable[0].scantable; | |
320 | ||
321 | sub_cbp = sub_cbp_table[decode012(&s->gb)]; | |
322 | ||
323 | if (sub_cbp & 1) | |
324 | if (ff_msmpeg4_decode_block(s, block, n, 1, scantable) < 0) | |
325 | return -1; | |
326 | ||
327 | if (sub_cbp & 2) | |
328 | if (ff_msmpeg4_decode_block(s, w->abt_block2[n], n, 1, scantable) < 0) | |
329 | return -1; | |
330 | ||
331 | s->block_last_index[n] = 63; | |
332 | ||
333 | return 0; | |
334 | } else { | |
335 | return ff_msmpeg4_decode_block(s, block, n, 1, | |
336 | s->inter_scantable.permutated); | |
337 | } | |
338 | } | |
339 | ||
340 | int ff_wmv2_decode_mb(MpegEncContext *s, int16_t block[6][64]) | |
341 | { | |
342 | Wmv2Context *const w = (Wmv2Context *) s; | |
343 | int cbp, code, i; | |
344 | uint8_t *coded_val; | |
345 | ||
346 | if (w->j_type) | |
347 | return 0; | |
348 | ||
349 | if (s->pict_type == AV_PICTURE_TYPE_P) { | |
350 | if (IS_SKIP(s->current_picture.mb_type[s->mb_y * s->mb_stride + s->mb_x])) { | |
351 | /* skip mb */ | |
352 | s->mb_intra = 0; | |
353 | for (i = 0; i < 6; i++) | |
354 | s->block_last_index[i] = -1; | |
355 | s->mv_dir = MV_DIR_FORWARD; | |
356 | s->mv_type = MV_TYPE_16X16; | |
357 | s->mv[0][0][0] = 0; | |
358 | s->mv[0][0][1] = 0; | |
359 | s->mb_skipped = 1; | |
360 | w->hshift = 0; | |
361 | return 0; | |
362 | } | |
363 | ||
364 | code = get_vlc2(&s->gb, ff_mb_non_intra_vlc[w->cbp_table_index].table, | |
365 | MB_NON_INTRA_VLC_BITS, 3); | |
366 | if (code < 0) | |
367 | return -1; | |
368 | s->mb_intra = (~code & 0x40) >> 6; | |
369 | ||
370 | cbp = code & 0x3f; | |
371 | } else { | |
372 | s->mb_intra = 1; | |
373 | code = get_vlc2(&s->gb, ff_msmp4_mb_i_vlc.table, MB_INTRA_VLC_BITS, 2); | |
374 | if (code < 0) { | |
375 | av_log(s->avctx, AV_LOG_ERROR, | |
376 | "II-cbp illegal at %d %d\n", s->mb_x, s->mb_y); | |
377 | return -1; | |
378 | } | |
379 | /* predict coded block pattern */ | |
380 | cbp = 0; | |
381 | for (i = 0; i < 6; i++) { | |
382 | int val = ((code >> (5 - i)) & 1); | |
383 | if (i < 4) { | |
384 | int pred = ff_msmpeg4_coded_block_pred(s, i, &coded_val); | |
385 | val = val ^ pred; | |
386 | *coded_val = val; | |
387 | } | |
388 | cbp |= val << (5 - i); | |
389 | } | |
390 | } | |
391 | ||
392 | if (!s->mb_intra) { | |
393 | int mx, my; | |
394 | wmv2_pred_motion(w, &mx, &my); | |
395 | ||
396 | if (cbp) { | |
397 | s->bdsp.clear_blocks(s->block[0]); | |
398 | if (s->per_mb_rl_table) { | |
399 | s->rl_table_index = decode012(&s->gb); | |
400 | s->rl_chroma_table_index = s->rl_table_index; | |
401 | } | |
402 | ||
403 | if (w->abt_flag && w->per_mb_abt) { | |
404 | w->per_block_abt = get_bits1(&s->gb); | |
405 | if (!w->per_block_abt) | |
406 | w->abt_type = decode012(&s->gb); | |
407 | } else | |
408 | w->per_block_abt = 0; | |
409 | } | |
410 | ||
411 | if (wmv2_decode_motion(w, &mx, &my) < 0) | |
412 | return -1; | |
413 | ||
414 | s->mv_dir = MV_DIR_FORWARD; | |
415 | s->mv_type = MV_TYPE_16X16; | |
416 | s->mv[0][0][0] = mx; | |
417 | s->mv[0][0][1] = my; | |
418 | ||
419 | for (i = 0; i < 6; i++) { | |
420 | if (wmv2_decode_inter_block(w, block[i], i, (cbp >> (5 - i)) & 1) < 0) { | |
421 | av_log(s->avctx, AV_LOG_ERROR, | |
422 | "\nerror while decoding inter block: %d x %d (%d)\n", | |
423 | s->mb_x, s->mb_y, i); | |
424 | return -1; | |
425 | } | |
426 | } | |
427 | } else { | |
428 | if (s->pict_type == AV_PICTURE_TYPE_P) | |
429 | av_dlog(s->avctx, "%d%d ", s->inter_intra_pred, cbp); | |
430 | av_dlog(s->avctx, "I at %d %d %d %06X\n", s->mb_x, s->mb_y, | |
431 | ((cbp & 3) ? 1 : 0) + ((cbp & 0x3C) ? 2 : 0), | |
432 | show_bits(&s->gb, 24)); | |
433 | s->ac_pred = get_bits1(&s->gb); | |
434 | if (s->inter_intra_pred) { | |
435 | s->h263_aic_dir = get_vlc2(&s->gb, ff_inter_intra_vlc.table, | |
436 | INTER_INTRA_VLC_BITS, 1); | |
437 | av_dlog(s->avctx, "%d%d %d %d/", | |
438 | s->ac_pred, s->h263_aic_dir, s->mb_x, s->mb_y); | |
439 | } | |
440 | if (s->per_mb_rl_table && cbp) { | |
441 | s->rl_table_index = decode012(&s->gb); | |
442 | s->rl_chroma_table_index = s->rl_table_index; | |
443 | } | |
444 | ||
445 | s->bdsp.clear_blocks(s->block[0]); | |
446 | for (i = 0; i < 6; i++) { | |
447 | if (ff_msmpeg4_decode_block(s, block[i], i, (cbp >> (5 - i)) & 1, NULL) < 0) { | |
448 | av_log(s->avctx, AV_LOG_ERROR, | |
449 | "\nerror while decoding intra block: %d x %d (%d)\n", | |
450 | s->mb_x, s->mb_y, i); | |
451 | return -1; | |
452 | } | |
453 | } | |
454 | } | |
455 | ||
456 | return 0; | |
457 | } | |
458 | ||
459 | static av_cold int wmv2_decode_init(AVCodecContext *avctx) | |
460 | { | |
461 | Wmv2Context *const w = avctx->priv_data; | |
462 | ||
463 | avctx->flags |= CODEC_FLAG_EMU_EDGE; | |
464 | ||
465 | if (ff_msmpeg4_decode_init(avctx) < 0) | |
466 | return -1; | |
467 | ||
468 | ff_wmv2_common_init(w); | |
469 | ||
470 | ff_intrax8_common_init(&w->x8, &w->s); | |
471 | ||
472 | return 0; | |
473 | } | |
474 | ||
475 | static av_cold int wmv2_decode_end(AVCodecContext *avctx) | |
476 | { | |
477 | Wmv2Context *w = avctx->priv_data; | |
478 | ||
479 | ff_intrax8_common_end(&w->x8); | |
480 | return ff_h263_decode_end(avctx); | |
481 | } | |
482 | ||
483 | AVCodec ff_wmv2_decoder = { | |
484 | .name = "wmv2", | |
485 | .long_name = NULL_IF_CONFIG_SMALL("Windows Media Video 8"), | |
486 | .type = AVMEDIA_TYPE_VIDEO, | |
487 | .id = AV_CODEC_ID_WMV2, | |
488 | .priv_data_size = sizeof(Wmv2Context), | |
489 | .init = wmv2_decode_init, | |
490 | .close = wmv2_decode_end, | |
491 | .decode = ff_h263_decode_frame, | |
492 | .capabilities = CODEC_CAP_DRAW_HORIZ_BAND | CODEC_CAP_DR1, | |
493 | .pix_fmts = (const enum AVPixelFormat[]) { AV_PIX_FMT_YUV420P, | |
494 | AV_PIX_FMT_NONE }, | |
495 | }; |