[svn] / branches / dev-api-4 / xvidcore / src / bitstream / mbcoding.c Repository:
ViewVC logotype

Diff of /branches/dev-api-4/xvidcore/src/bitstream/mbcoding.c

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

revision 994, Sun Apr 27 15:40:50 2003 UTC revision 995, Sun Apr 27 19:47:48 2003 UTC
# Line 51  Line 51 
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"
# Line 1267  Line 1269 
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   ****************************************************************************/   ****************************************************************************/

Legend:
Removed from v.994  
changed lines
  Added in v.995

No admin address has been configured
ViewVC Help
Powered by ViewVC 1.0.4