Mercurial > libavcodec.hg
comparison vp3.c @ 1292:f7b3fa4bb7ae libavcodec
revising and fixing motion vectors, squished block unpacking bug that
led to memory stomps, added support for funky arbitrary dimensions
| author | tmmm |
|---|---|
| date | Sat, 31 May 2003 07:56:58 +0000 |
| parents | 8988af3ae1e8 |
| children | 1c05f4290517 |
comparison
equal
deleted
inserted
replaced
| 1291:384110c44dec | 1292:f7b3fa4bb7ae |
|---|---|
| 137 int coding_method; | 137 int coding_method; |
| 138 int coeff_count; | 138 int coeff_count; |
| 139 int last_coeff; | 139 int last_coeff; |
| 140 int motion_x; | 140 int motion_x; |
| 141 int motion_y; | 141 int motion_y; |
| 142 /* this indicates which ffmpeg put_pixels() function to use: | |
| 143 * 00b = no halfpel, 01b = x halfpel, 10b = y halfpel, 11b = both halfpel */ | |
| 144 int motion_halfpel_index; | |
| 145 /* address of first pixel taking into account which plane the fragment | 142 /* address of first pixel taking into account which plane the fragment |
| 146 * lives on as well as the plane stride */ | 143 * lives on as well as the plane stride */ |
| 147 int first_pixel; | 144 int first_pixel; |
| 148 /* this is the macroblock that the fragment belongs to */ | 145 /* this is the macroblock that the fragment belongs to */ |
| 149 int macroblock; | 146 int macroblock; |
| 814 s->coded_fragment_list_index = 0; | 811 s->coded_fragment_list_index = 0; |
| 815 for (i = 0; i < s->fragment_count; i++) { | 812 for (i = 0; i < s->fragment_count; i++) { |
| 816 memset(s->all_fragments[i].coeffs, 0, 64 * sizeof(DCTELEM)); | 813 memset(s->all_fragments[i].coeffs, 0, 64 * sizeof(DCTELEM)); |
| 817 s->all_fragments[i].coeff_count = 0; | 814 s->all_fragments[i].coeff_count = 0; |
| 818 s->all_fragments[i].last_coeff = 0; | 815 s->all_fragments[i].last_coeff = 0; |
| 816 s->all_fragments[i].motion_x = 0xbeef; | |
| 817 s->all_fragments[i].motion_y = 0xbeef; | |
| 819 } | 818 } |
| 820 } | 819 } |
| 821 | 820 |
| 822 /* | 821 /* |
| 823 * This function sets of the dequantization tables used for a particular | 822 * This function sets of the dequantization tables used for a particular |
| 1159 current_superblock + current_run - 1, | 1158 current_superblock + current_run - 1, |
| 1160 (bit) ? "partially coded" : "not coded"); | 1159 (bit) ? "partially coded" : "not coded"); |
| 1161 | 1160 |
| 1162 /* if any of the superblocks are not partially coded, flag | 1161 /* if any of the superblocks are not partially coded, flag |
| 1163 * a boolean to decode the list of fully-coded superblocks */ | 1162 * a boolean to decode the list of fully-coded superblocks */ |
| 1164 if (bit == 0) | 1163 if (bit == 0) { |
| 1165 decode_fully_flags = 1; | 1164 decode_fully_flags = 1; |
| 1166 } else { | 1165 } else { |
| 1167 | 1166 |
| 1168 /* make a note of the fact that there are partially coded | 1167 /* make a note of the fact that there are partially coded |
| 1169 * superblocks */ | 1168 * superblocks */ |
| 1170 decode_partial_blocks = 1; | 1169 decode_partial_blocks = 1; |
| 1171 | 1170 } |
| 1172 } | 1171 } |
| 1173 s->superblock_coding[current_superblock++] = | 1172 s->superblock_coding[current_superblock++] = |
| 1174 (bit) ? SB_PARTIALLY_CODED : SB_NOT_CODED; | 1173 (bit) ? SB_PARTIALLY_CODED : SB_NOT_CODED; |
| 1175 current_run--; | 1174 current_run--; |
| 1176 } | 1175 } |
| 1307 | 1306 |
| 1308 if (!first_c_fragment_seen) | 1307 if (!first_c_fragment_seen) |
| 1309 /* only Y fragments coded in this frame */ | 1308 /* only Y fragments coded in this frame */ |
| 1310 s->last_coded_y_fragment = s->coded_fragment_list_index - 1; | 1309 s->last_coded_y_fragment = s->coded_fragment_list_index - 1; |
| 1311 else | 1310 else |
| 1312 /* end the list of coded fragments */ | 1311 /* end the list of coded C fragments */ |
| 1313 s->last_coded_c_fragment = s->coded_fragment_list_index - 1; | 1312 s->last_coded_c_fragment = s->coded_fragment_list_index - 1; |
| 1314 | 1313 |
| 1315 debug_block_coding(" %d total coded fragments, y: %d -> %d, c: %d -> %d\n", | 1314 debug_block_coding(" %d total coded fragments, y: %d -> %d, c: %d -> %d\n", |
| 1316 s->coded_fragment_list_index, | 1315 s->coded_fragment_list_index, |
| 1317 s->first_coded_y_fragment, | 1316 s->first_coded_y_fragment, |
| 1405 | 1404 |
| 1406 return 0; | 1405 return 0; |
| 1407 } | 1406 } |
| 1408 | 1407 |
| 1409 /* | 1408 /* |
| 1410 * This function adjusts the components of a motion vector for the halfpel | |
| 1411 * motion grid. c_plane indicates whether the vector applies to the U or V | |
| 1412 * plane. The function returns the halfpel function index to be used in | |
| 1413 * ffmpeg's put_pixels[]() array of functions. | |
| 1414 */ | |
| 1415 static inline int adjust_vector(int *x, int *y, int c_plane) | |
| 1416 { | |
| 1417 int motion_halfpel_index = 0; | |
| 1418 int x_halfpel; | |
| 1419 int y_halfpel; | |
| 1420 | |
| 1421 if (!c_plane) { | |
| 1422 | |
| 1423 x_halfpel = *x & 1; | |
| 1424 motion_halfpel_index |= x_halfpel; | |
| 1425 if (*x >= 0) | |
| 1426 *x >>= 1; | |
| 1427 else | |
| 1428 *x = -( (-(*x) >> 1) + x_halfpel); | |
| 1429 | |
| 1430 y_halfpel = *y & 1; | |
| 1431 motion_halfpel_index |= (y_halfpel << 1); | |
| 1432 if (*y >= 0) | |
| 1433 *y >>= 1; | |
| 1434 else | |
| 1435 *y = -( (-(*y) >> 1) + y_halfpel); | |
| 1436 | |
| 1437 } else { | |
| 1438 | |
| 1439 x_halfpel = ((*x & 0x03) != 0); | |
| 1440 motion_halfpel_index |= x_halfpel; | |
| 1441 if (*x >= 0) | |
| 1442 *x >>= 2; | |
| 1443 else | |
| 1444 *x = -( (-(*x) >> 2) + x_halfpel); | |
| 1445 | |
| 1446 y_halfpel = ((*y & 0x03) != 0); | |
| 1447 motion_halfpel_index |= (y_halfpel << 1); | |
| 1448 if (*y >= 0) | |
| 1449 *y >>= 2; | |
| 1450 else | |
| 1451 *y = -( (-(*y) >> 2) + y_halfpel); | |
| 1452 | |
| 1453 } | |
| 1454 | |
| 1455 return motion_halfpel_index; | |
| 1456 } | |
| 1457 | |
| 1458 /* | |
| 1459 * This function unpacks all the motion vectors for the individual | 1409 * This function unpacks all the motion vectors for the individual |
| 1460 * macroblocks from the bitstream. | 1410 * macroblocks from the bitstream. |
| 1461 */ | 1411 */ |
| 1462 static int unpack_vectors(Vp3DecodeContext *s, GetBitContext *gb) | 1412 static int unpack_vectors(Vp3DecodeContext *s, GetBitContext *gb) |
| 1463 { | 1413 { |
| 1525 motion_x[k] = motion_x[0]; | 1475 motion_x[k] = motion_x[0]; |
| 1526 motion_y[k] = motion_y[0]; | 1476 motion_y[k] = motion_y[0]; |
| 1527 } | 1477 } |
| 1528 | 1478 |
| 1529 /* vector maintenance, only on MODE_INTER_PLUS_MV */ | 1479 /* vector maintenance, only on MODE_INTER_PLUS_MV */ |
| 1530 if (s->all_fragments[current_fragment].coding_method == | 1480 if (s->macroblock_coding[current_macroblock] == |
| 1531 MODE_INTER_PLUS_MV) { | 1481 MODE_INTER_PLUS_MV) { |
| 1532 prior_last_motion_x = last_motion_x; | 1482 prior_last_motion_x = last_motion_x; |
| 1533 prior_last_motion_y = last_motion_y; | 1483 prior_last_motion_y = last_motion_y; |
| 1534 last_motion_x = motion_x[0]; | 1484 last_motion_x = motion_x[0]; |
| 1535 last_motion_y = motion_y[0]; | 1485 last_motion_y = motion_y[0]; |
| 1612 } | 1562 } |
| 1613 | 1563 |
| 1614 /* assign the motion vectors to the correct fragments */ | 1564 /* assign the motion vectors to the correct fragments */ |
| 1615 debug_vectors(" vectors for macroblock starting @ fragment %d (coding method %d):\n", | 1565 debug_vectors(" vectors for macroblock starting @ fragment %d (coding method %d):\n", |
| 1616 current_fragment, | 1566 current_fragment, |
| 1617 s->all_fragments[current_fragment].coding_method); | 1567 s->macroblock_coding[current_macroblock]); |
| 1618 for (k = 0; k < 6; k++) { | 1568 for (k = 0; k < 6; k++) { |
| 1619 current_fragment = | 1569 current_fragment = |
| 1620 s->macroblock_fragments[current_macroblock * 6 + k]; | 1570 s->macroblock_fragments[current_macroblock * 6 + k]; |
| 1621 if (current_fragment == -1) | 1571 if (current_fragment == -1) |
| 1622 continue; | 1572 continue; |
| 1623 if (current_fragment >= s->fragment_count) { | 1573 if (current_fragment >= s->fragment_count) { |
| 1624 printf (" vp3:unpack_vectors(): bad fragment number (%d >= %d)\n", | 1574 printf (" vp3:unpack_vectors(): bad fragment number (%d >= %d)\n", |
| 1625 current_fragment, s->fragment_count); | 1575 current_fragment, s->fragment_count); |
| 1626 return 1; | 1576 return 1; |
| 1627 } | 1577 } |
| 1628 s->all_fragments[current_fragment].motion_halfpel_index = | |
| 1629 adjust_vector(&motion_x[k], &motion_y[k], | |
| 1630 ((k == 4) || (k == 5))); | |
| 1631 s->all_fragments[current_fragment].motion_x = motion_x[k]; | 1578 s->all_fragments[current_fragment].motion_x = motion_x[k]; |
| 1632 s->all_fragments[current_fragment].motion_y = motion_y[k]; | 1579 s->all_fragments[current_fragment].motion_y = motion_y[k]; |
| 1633 debug_vectors(" vector %d: fragment %d = (%d, %d), index %d\n", | 1580 debug_vectors(" vector %d: fragment %d = (%d, %d)\n", |
| 1634 k, current_fragment, motion_x[k], motion_y[k], | 1581 k, current_fragment, motion_x[k], motion_y[k]); |
| 1635 s->all_fragments[current_fragment].motion_halfpel_index); | |
| 1636 } | 1582 } |
| 1637 } | 1583 } |
| 1638 } | 1584 } |
| 1639 } | 1585 } |
| 1640 | 1586 |
| 2139 } | 2085 } |
| 2140 | 2086 |
| 2141 /* transform if this block was coded */ | 2087 /* transform if this block was coded */ |
| 2142 if (s->all_fragments[i].coding_method != MODE_COPY) { | 2088 if (s->all_fragments[i].coding_method != MODE_COPY) { |
| 2143 | 2089 |
| 2144 /* sort out the motion vector */ | |
| 2145 motion_x = s->all_fragments[i].motion_x; | |
| 2146 motion_y = s->all_fragments[i].motion_y; | |
| 2147 motion_halfpel_index = s->all_fragments[i].motion_halfpel_index; | |
| 2148 | |
| 2149 motion_source = s->all_fragments[i].first_pixel; | 2090 motion_source = s->all_fragments[i].first_pixel; |
| 2150 motion_source += motion_x; | 2091 motion_halfpel_index = 0; |
| 2151 motion_source += (motion_y * stride); | 2092 |
| 2152 | 2093 /* sort out the motion vector if this fragment is coded |
| 2153 /* if the are any problems with a motion vector, refuse | 2094 * using a motion vector method */ |
| 2154 * to render the block */ | 2095 if ((s->all_fragments[i].coding_method > MODE_INTRA) && |
| 2155 if ((motion_source < upper_motion_limit) || | 2096 (s->all_fragments[i].coding_method != MODE_USING_GOLDEN)) { |
| 2156 (motion_source > lower_motion_limit)) { | 2097 motion_x = s->all_fragments[i].motion_x; |
| 2157 // printf (" vp3: help! motion source (%d) out of range (%d..%d)\n", | 2098 motion_y = s->all_fragments[i].motion_y; |
| 2158 // motion_source, upper_motion_limit, lower_motion_limit); | 2099 if ((motion_x == 0xbeef) || (motion_y == 0xbeef)) |
| 2159 continue; | 2100 printf (" help! got beefy vector! (%X, %X)\n", motion_x, motion_y); |
| 2101 | |
| 2102 if (motion_x >= 0) { | |
| 2103 motion_halfpel_index = motion_x & 0x01; | |
| 2104 motion_source += (motion_x >> 1); | |
| 2105 } else { | |
| 2106 motion_x = -motion_x; | |
| 2107 motion_halfpel_index = motion_x & 0x01; | |
| 2108 motion_source -= ((motion_x + 1) >> 1); | |
| 2109 } | |
| 2110 | |
| 2111 // motion_y = -motion_y; | |
| 2112 if (motion_y >= 0) { | |
| 2113 motion_halfpel_index |= (motion_y & 0x01) << 1; | |
| 2114 motion_source += ((motion_y >> 1) * stride); | |
| 2115 } else { | |
| 2116 motion_y = -motion_y; | |
| 2117 motion_halfpel_index |= (motion_y & 0x01) << 1; | |
| 2118 motion_source -= (((motion_y + 1) >> 1) * stride); | |
| 2119 } | |
| 2120 | |
| 2121 /* if the are any problems with a motion vector, refuse | |
| 2122 * to render the block */ | |
| 2123 if ((motion_source < upper_motion_limit) || | |
| 2124 (motion_source > lower_motion_limit)) { | |
| 2125 // printf (" vp3: help! motion source (%d) out of range (%d..%d)\n", | |
| 2126 // motion_source, upper_motion_limit, lower_motion_limit); | |
| 2127 continue; | |
| 2128 } | |
| 2160 } | 2129 } |
| 2161 | 2130 |
| 2162 /* first, take care of copying a block from either the | 2131 /* first, take care of copying a block from either the |
| 2163 * previous or the golden frame */ | 2132 * previous or the golden frame */ |
| 2164 if ((s->all_fragments[i].coding_method == MODE_USING_GOLDEN) || | 2133 if ((s->all_fragments[i].coding_method == MODE_USING_GOLDEN) || |
| 2302 int c_height; | 2271 int c_height; |
| 2303 int y_superblock_count; | 2272 int y_superblock_count; |
| 2304 int c_superblock_count; | 2273 int c_superblock_count; |
| 2305 | 2274 |
| 2306 s->avctx = avctx; | 2275 s->avctx = avctx; |
| 2276 #if 0 | |
| 2307 s->width = avctx->width; | 2277 s->width = avctx->width; |
| 2308 s->height = avctx->height; | 2278 s->height = avctx->height; |
| 2279 #else | |
| 2280 s->width = (avctx->width + 15) & 0xFFFFFFF0; | |
| 2281 s->height = (avctx->height + 15) & 0xFFFFFFF0; | |
| 2282 #endif | |
| 2309 avctx->pix_fmt = PIX_FMT_YUV420P; | 2283 avctx->pix_fmt = PIX_FMT_YUV420P; |
| 2310 avctx->has_b_frames = 0; | 2284 avctx->has_b_frames = 0; |
| 2311 dsputil_init(&s->dsp, avctx); | 2285 dsputil_init(&s->dsp, avctx); |
| 2312 | 2286 |
| 2313 /* initialize to an impossible value which will force a recalculation | 2287 /* initialize to an impossible value which will force a recalculation |
| 2430 s->keyframe = get_bits(&gb, 1); | 2404 s->keyframe = get_bits(&gb, 1); |
| 2431 s->keyframe ^= 1; | 2405 s->keyframe ^= 1; |
| 2432 skip_bits(&gb, 1); | 2406 skip_bits(&gb, 1); |
| 2433 s->last_quality_index = s->quality_index; | 2407 s->last_quality_index = s->quality_index; |
| 2434 s->quality_index = get_bits(&gb, 6); | 2408 s->quality_index = get_bits(&gb, 6); |
| 2409 | |
| 2410 debug_vp3(" VP3 frame #%d: Q index = %d", counter, s->quality_index); | |
| 2411 counter++; | |
| 2412 | |
| 2435 if (s->quality_index != s->last_quality_index) | 2413 if (s->quality_index != s->last_quality_index) |
| 2436 init_dequantizer(s); | 2414 init_dequantizer(s); |
| 2437 | |
| 2438 debug_vp3(" VP3 frame #%d: Q index = %d", counter, s->quality_index); | |
| 2439 counter++; | |
| 2440 | 2415 |
| 2441 if (s->keyframe) { | 2416 if (s->keyframe) { |
| 2442 | 2417 |
| 2443 debug_vp3(", keyframe\n"); | 2418 debug_vp3(", keyframe\n"); |
| 2444 /* skip the other 2 header bytes for now */ | 2419 /* skip the other 2 header bytes for now */ |
| 2508 s->fragment_width / 2, s->fragment_height / 2); | 2483 s->fragment_width / 2, s->fragment_height / 2); |
| 2509 reverse_dc_prediction(s, s->v_fragment_start, | 2484 reverse_dc_prediction(s, s->v_fragment_start, |
| 2510 s->fragment_width / 2, s->fragment_height / 2); | 2485 s->fragment_width / 2, s->fragment_height / 2); |
| 2511 | 2486 |
| 2512 render_fragments(s, 0, s->width, s->height, 0); | 2487 render_fragments(s, 0, s->width, s->height, 0); |
| 2488 #if 1 | |
| 2513 render_fragments(s, s->u_fragment_start, s->width / 2, s->height / 2, 1); | 2489 render_fragments(s, s->u_fragment_start, s->width / 2, s->height / 2, 1); |
| 2514 render_fragments(s, s->v_fragment_start, s->width / 2, s->height / 2, 2); | 2490 render_fragments(s, s->v_fragment_start, s->width / 2, s->height / 2, 2); |
| 2491 #else | |
| 2492 memset(s->current_frame.data[1], 0x80, s->width * s->height / 4); | |
| 2493 memset(s->current_frame.data[2], 0x80, s->width * s->height / 4); | |
| 2494 #endif | |
| 2515 | 2495 |
| 2516 #if KEYFRAMES_ONLY | 2496 #if KEYFRAMES_ONLY |
| 2517 } | 2497 } |
| 2518 #endif | 2498 #endif |
| 2519 | 2499 |
