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