51 |
|
|
52 |
#include <stdio.h> |
#include <stdio.h> |
53 |
#include <stdlib.h> |
#include <stdlib.h> |
54 |
|
#include <string.h> |
55 |
|
|
56 |
#include "../portab.h" |
#include "../portab.h" |
57 |
#include "../global.h" |
#include "../global.h" |
58 |
#include "bitstream.h" |
#include "bitstream.h" |
1269 |
|
|
1270 |
} |
} |
1271 |
|
|
1272 |
|
|
1273 |
|
|
1274 |
|
|
1275 |
|
|
1276 |
|
|
1277 |
|
|
1278 |
|
/************************************************************************ |
1279 |
|
* Trellis based R-D optimal quantization * |
1280 |
|
* not really "bitstream" or "mbcoding" related, but needs VLC tables * |
1281 |
|
* * |
1282 |
|
************************************************************************/ |
1283 |
|
|
1284 |
|
|
1285 |
|
int __inline |
1286 |
|
RunLevel_CalcBits_inter(const int16_t run, int16_t level) |
1287 |
|
{ |
1288 |
|
const int esc_length = 30; |
1289 |
|
|
1290 |
|
if (!((level+32) & -64)) |
1291 |
|
return coeff_VLC[0][0][level+32][run].len; |
1292 |
|
else |
1293 |
|
return esc_length; |
1294 |
|
} |
1295 |
|
|
1296 |
|
int __inline |
1297 |
|
RunLevelLast_CalcBits_inter(const int16_t run, const int16_t level) |
1298 |
|
{ |
1299 |
|
const int esc_length = 30; |
1300 |
|
|
1301 |
|
if (!((level+32) & -64)) |
1302 |
|
return coeff_VLC[0][1][level+32][run].len; |
1303 |
|
else |
1304 |
|
return esc_length; |
1305 |
|
} |
1306 |
|
|
1307 |
|
|
1308 |
|
int __inline |
1309 |
|
RunLevel_CalcBits_intra(const int16_t run, int16_t level) |
1310 |
|
{ |
1311 |
|
const int esc_length = 30; |
1312 |
|
int bits; |
1313 |
|
|
1314 |
|
level = abs(level); |
1315 |
|
if (!(level & -64)) { |
1316 |
|
bits = coeff_VLC[1][0][level][run].len; |
1317 |
|
if (bits!=128) |
1318 |
|
return bits; |
1319 |
|
} |
1320 |
|
return esc_length; |
1321 |
|
} |
1322 |
|
|
1323 |
|
int __inline |
1324 |
|
RunLevelLast_CalcBits_intra(const int16_t run, int16_t level) |
1325 |
|
{ |
1326 |
|
const int esc_length = 30; |
1327 |
|
int bits; |
1328 |
|
|
1329 |
|
level = abs(level); |
1330 |
|
if (!(level & -64)) { |
1331 |
|
bits = coeff_VLC[1][1][level][run].len; |
1332 |
|
if (bits!=128) |
1333 |
|
return bits; |
1334 |
|
} |
1335 |
|
return esc_length; |
1336 |
|
} |
1337 |
|
|
1338 |
|
/* based on ffmpeg's trellis quant, thanks! */ |
1339 |
|
/* (C) 2003 Michael Niedermayer <michaelni@gmx.at> */ |
1340 |
|
|
1341 |
|
int |
1342 |
|
dct_quantize_trellis_inter_h263_c (int16_t *qcoeff, const int16_t *data, int quant) |
1343 |
|
{ |
1344 |
|
|
1345 |
|
/* input: original quantized DCT coefficients (to calc distorion)*/ |
1346 |
|
/* already quantized DCT coefficients */ |
1347 |
|
/* quantizer */ |
1348 |
|
/* output: modified table of quantized DCT coefficients */ |
1349 |
|
|
1350 |
|
/* maybe combining quantize&Trellis would be faster (even that it disables MMX quant) */ |
1351 |
|
|
1352 |
|
int run_tab[65]; |
1353 |
|
int level_tab[65]; |
1354 |
|
int score_tab[65]; |
1355 |
|
int last_run = 0; |
1356 |
|
int last_level = 0; |
1357 |
|
int last_score = 0; |
1358 |
|
int last_i = 0; |
1359 |
|
int coeff[64]; |
1360 |
|
int coeff_count[64]; /* is a table useful for this 0-1 (or 1-2) table? */ |
1361 |
|
int last_non_zero, i; |
1362 |
|
|
1363 |
|
const uint16_t *const zigzag = &scan_tables[0][0]; |
1364 |
|
/* ordinary zigzag order, so it's not INTERLACE compatible, yet */ |
1365 |
|
|
1366 |
|
const int qmul = 2*quant; |
1367 |
|
const int qadd = ((quant-1)|1); |
1368 |
|
|
1369 |
|
/* quant is not needed anymore after this */ |
1370 |
|
|
1371 |
|
int score_limit = 0; |
1372 |
|
int left_limit = 0; |
1373 |
|
|
1374 |
|
const int lambda = (quant * quant * 123 + 64) >> 7; // default lagrangian |
1375 |
|
|
1376 |
|
/* control lambda through a ENVIRONMENT variable (for automatic optmization) */ |
1377 |
|
|
1378 |
|
/* |
1379 |
|
const int lfact=123; // better control of the lagrangian lambda |
1380 |
|
int lambda = (quant * quant * 123 + 64) >> 7; // default lagrangian |
1381 |
|
|
1382 |
|
const char * const trellis_lambda = getenv("TRELLIS_LAMBDA"); |
1383 |
|
if(trellis_lambda) |
1384 |
|
lfact = atoi(trellis_lambda); |
1385 |
|
if (lfact < 1) |
1386 |
|
lfact = 123; // why this value? Who knows? But 123 seems better than 109 = 0.85<<7 |
1387 |
|
|
1388 |
|
lambda = (quant * quant * lfact + 64) >> 7; // lagrangian |
1389 |
|
*/ |
1390 |
|
|
1391 |
|
last_non_zero = -1; |
1392 |
|
for (i = 0; i < 64; i++) |
1393 |
|
{ |
1394 |
|
const int level = qcoeff[zigzag[i]]; |
1395 |
|
|
1396 |
|
if (level) { |
1397 |
|
last_non_zero = i; |
1398 |
|
|
1399 |
|
if (level>0) { |
1400 |
|
if (level==1) { |
1401 |
|
coeff[i] = 1; |
1402 |
|
coeff_count[i] = 0; |
1403 |
|
} else { |
1404 |
|
coeff[i] = level; |
1405 |
|
coeff_count[i] = 1; |
1406 |
|
} |
1407 |
|
} else { |
1408 |
|
if (level==-1) { |
1409 |
|
coeff[i] = -1; |
1410 |
|
coeff_count[i] = 0; |
1411 |
|
} else { |
1412 |
|
coeff[i] = level+1; // because we check coeff[i] and coeff[i]-1 |
1413 |
|
coeff_count[i] = 1; |
1414 |
|
} |
1415 |
|
} |
1416 |
|
} else { |
1417 |
|
coeff[i] = ((data[zigzag[i]]>>31)|1); /* +- 1 because of gap */ |
1418 |
|
coeff_count[i] = 0; |
1419 |
|
} |
1420 |
|
} |
1421 |
|
|
1422 |
|
if (last_non_zero < 0) |
1423 |
|
return last_non_zero; |
1424 |
|
|
1425 |
|
score_tab[0] = 0; |
1426 |
|
|
1427 |
|
for (i = 0; i <= last_non_zero; i++) { |
1428 |
|
int level, run, j; |
1429 |
|
const int dct_coeff = data[zigzag[i]]; |
1430 |
|
const int zero_distortion = dct_coeff * dct_coeff; |
1431 |
|
int best_score = 256 * 256 * 256 * 120; |
1432 |
|
|
1433 |
|
int distortion; |
1434 |
|
int dequant_err; |
1435 |
|
|
1436 |
|
last_score += zero_distortion; |
1437 |
|
|
1438 |
|
|
1439 |
|
/****************** level loop unrolled: first check coeff[i] *********/ |
1440 |
|
level = coeff[i]; |
1441 |
|
|
1442 |
|
if (level > 0) // coeff[i]==0 is not possible here |
1443 |
|
dequant_err = level * qmul + qadd - dct_coeff; |
1444 |
|
else |
1445 |
|
dequant_err = level * qmul - qadd - dct_coeff; |
1446 |
|
|
1447 |
|
distortion = dequant_err*dequant_err; |
1448 |
|
|
1449 |
|
for (run = 0; run <= i - left_limit; run++) { |
1450 |
|
|
1451 |
|
int score = distortion + lambda*RunLevel_CalcBits_inter(run, level) + score_tab[i - run]; |
1452 |
|
|
1453 |
|
if (score < best_score) |
1454 |
|
{ |
1455 |
|
best_score = score_tab[i + 1] = score; |
1456 |
|
run_tab[i + 1] = run; |
1457 |
|
level_tab[i + 1] = level; |
1458 |
|
} |
1459 |
|
} |
1460 |
|
|
1461 |
|
for (run = 0; run <= i - left_limit; run++) { |
1462 |
|
int score = distortion + lambda*RunLevelLast_CalcBits_inter(run, level) + score_tab[i - run]; |
1463 |
|
|
1464 |
|
if (score < last_score) |
1465 |
|
{ |
1466 |
|
last_score = score; |
1467 |
|
last_run = run; |
1468 |
|
last_level = level; |
1469 |
|
last_i = i + 1; |
1470 |
|
} |
1471 |
|
} |
1472 |
|
|
1473 |
|
/****************** level loop unrolled: if possible, check coeff[i]-1 *********/ |
1474 |
|
|
1475 |
|
if (coeff_count[i]) { |
1476 |
|
|
1477 |
|
level--; |
1478 |
|
dequant_err -= qmul; |
1479 |
|
distortion = dequant_err*dequant_err; |
1480 |
|
|
1481 |
|
for (run = 0; run <= i - left_limit; run++) { |
1482 |
|
int score = distortion + lambda*RunLevel_CalcBits_inter(run, level) + score_tab[i-run]; |
1483 |
|
|
1484 |
|
if (score < best_score) |
1485 |
|
{ |
1486 |
|
best_score = score_tab[i + 1] = score; |
1487 |
|
run_tab[i + 1] = run; |
1488 |
|
level_tab[i + 1] = level; |
1489 |
|
} |
1490 |
|
} |
1491 |
|
|
1492 |
|
for (run = 0; run <= i - left_limit; run++) { |
1493 |
|
int score = distortion + lambda*RunLevelLast_CalcBits_inter(run, level) + score_tab[i-run]; |
1494 |
|
|
1495 |
|
if (score < last_score) |
1496 |
|
{ |
1497 |
|
last_score = score; |
1498 |
|
last_run = run; |
1499 |
|
last_level = level; |
1500 |
|
last_i = i + 1; |
1501 |
|
} |
1502 |
|
|
1503 |
|
} |
1504 |
|
} // of check coeff[i]-1 |
1505 |
|
|
1506 |
|
|
1507 |
|
/****************** checking coeff[i]-2 doesn't isn't supported *********/ |
1508 |
|
|
1509 |
|
/****************** add distorsion for higher RUN (-> coeff[i]==0) *******/ |
1510 |
|
for (j = left_limit; j <= i; j++) |
1511 |
|
score_tab[j] += zero_distortion; |
1512 |
|
|
1513 |
|
score_limit += zero_distortion; |
1514 |
|
|
1515 |
|
if (score_tab[i + 1] < score_limit) |
1516 |
|
score_limit = score_tab[i + 1]; |
1517 |
|
|
1518 |
|
// there is a vlc code in mpeg4 which is 1 bit shorter then another one with a shorter run and the same level |
1519 |
|
// so we finalize only if we have no chance of getting lower than score_limit + 1*lambda anymore |
1520 |
|
|
1521 |
|
while (score_tab[left_limit] > score_limit + lambda) |
1522 |
|
left_limit++; |
1523 |
|
|
1524 |
|
|
1525 |
|
} // end of (i=0;i<=last_non_zero;i++) |
1526 |
|
|
1527 |
|
|
1528 |
|
last_score = 256 * 256 * 256 * 120; |
1529 |
|
for (i = left_limit; i <= last_non_zero + 1; i++) |
1530 |
|
{ |
1531 |
|
int score = score_tab[i]; |
1532 |
|
if (i) |
1533 |
|
score += 2*lambda; /* coded block means 2 extra bits (roughly) */ |
1534 |
|
|
1535 |
|
if (score < last_score) |
1536 |
|
{ |
1537 |
|
last_score = score; |
1538 |
|
last_i = i; |
1539 |
|
last_level = level_tab[i]; |
1540 |
|
last_run = run_tab[i]; |
1541 |
|
} |
1542 |
|
} |
1543 |
|
|
1544 |
|
last_non_zero = last_i - 1; |
1545 |
|
if (last_non_zero < 0) |
1546 |
|
return last_non_zero; |
1547 |
|
|
1548 |
|
i = last_i; |
1549 |
|
|
1550 |
|
memset(qcoeff,0x00,64*sizeof(int16_t)); |
1551 |
|
|
1552 |
|
qcoeff[zigzag[last_non_zero]] = last_level; |
1553 |
|
i -= last_run + 1; |
1554 |
|
|
1555 |
|
for (; i > 0; i -= run_tab[i] + 1) |
1556 |
|
{ |
1557 |
|
qcoeff[zigzag[i-1]] = level_tab[i]; |
1558 |
|
} |
1559 |
|
|
1560 |
|
return last_non_zero; |
1561 |
|
} |
1562 |
|
|
1563 |
|
int |
1564 |
|
dct_quantize_trellis_inter_mpeg_c (int16_t *qcoeff, const int16_t *data, int quant) |
1565 |
|
{ return 64; } |
1566 |
|
|
1567 |
|
|
1568 |
|
|
1569 |
|
|
1570 |
|
|
1571 |
/***************************************************************************** |
/***************************************************************************** |
1572 |
* VLC tables and other constant arrays |
* VLC tables and other constant arrays |
1573 |
****************************************************************************/ |
****************************************************************************/ |