⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 block.c

📁 VLC Player Source Code
💻 C
📖 第 1 页 / 共 2 页
字号:
/***************************************************************************** * block.c: MPEG2 video transrating module ***************************************************************************** * Copyright (C) 2003-2004 the VideoLAN team * Copyright (C) 2003 Antoine Missout * Copyright (C) 2000-2003 Michel Lespinasse <walken@zoy.org> * Copyright (C) 1999-2000 Aaron Holtzman <aholtzma@ess.engr.uvic.ca> * $Id: 67e6332caab2e32f3ca95d3244d56611bda2afbe $ * * Authors: Christophe Massiot <massiot@via.ecp.fr> *          Laurent Aimar <fenrir@via.ecp.fr> *          Antoine Missout *          Michel Lespinasse <walken@zoy.org> *          Aaron Holtzman <aholtzma@ess.engr.uvic.ca> * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA. *****************************************************************************//***************************************************************************** * Preamble *****************************************************************************/#define NDEBUG 1#include <assert.h>#include <math.h>#ifdef HAVE_CONFIG_H# include "config.h"#endif#include <vlc_common.h>#include <vlc_sout.h>#include <vlc_codec.h>#include "transrate.h"/**************************************************************************** * transrater, code from M2VRequantizer http://www.metakine.com/ ****************************************************************************//////---- begin ext mpeg code#include "getvlc.h"#include "putvlc.h"static inline int saturate( int i_value ){    if ( i_value > 2047 )        return 2047;    if ( i_value < -2048 )        return -2048;    return i_value;}static int64_t get_score( const RunLevel *blk, RunLevel *new_blk, int i_qscale, int i_qscale_new ){    int64_t score = 0;    int i1 = -1, i2 = -1;    while ( new_blk->level )    {        int new_level = new_blk->level;        int level = blk->level;    if ( i1 > 64 || i2 > 64 || !blk->run || !new_blk->run ) return score;        if ( i1 + blk->run == i2 + new_blk->run )        {            int64_t tmp = saturate(level * i_qscale)                            - saturate(new_level * i_qscale_new);            i1 += blk->run;            i2 += new_blk->run;            score += tmp * tmp;            blk++;            new_blk++;        }        else        {            int64_t tmp = saturate(level * i_qscale);            i1 += blk->run;            score += tmp * tmp;            blk++;        }    }    while ( blk->level )    {        int level = blk->level;        int64_t tmp = saturate(level * i_qscale);        i1 += blk->run;        score += tmp * tmp;        blk++;    }    return score;}static void change_qscale( const RunLevel *blk, RunLevel *new_blk, int i_qscale, int i_qscale_new, int intra ){    int i = 0, li = 0;    int rounding;    if ( intra )        rounding = i_qscale_new / 3;    else        rounding = i_qscale_new / 6;    while ( blk->level )    {        int level = blk->level > 0 ? blk->level : -blk->level;        int new_level = saturate(level * i_qscale) / i_qscale_new;        i += blk->run;        if ( new_level )        {            new_blk->run = i - li;            new_blk->level = blk->level > 0 ? new_level : -new_level;            new_blk++;            li = i;        }        blk++;    }    new_blk->level = 0;}static const uint8_t non_linear_mquant_table[32] ={    0, 1, 2, 3, 4, 5, 6, 7,    8,10,12,14,16,18,20,22,    24,28,32,36,40,44,48,52,    56,64,72,80,88,96,104,112};static const uint8_t map_non_linear_mquant[113] ={    0,1,2,3,4,5,6,7,8,8,9,9,10,10,11,11,12,12,13,13,14,14,15,15,16,16,    16,17,17,17,18,18,18,18,19,19,19,19,20,20,20,20,21,21,21,21,22,22,    22,22,23,23,23,23,24,24,24,24,24,24,24,25,25,25,25,25,25,25,26,26,    26,26,26,26,26,26,27,27,27,27,27,27,27,27,28,28,28,28,28,28,28,29,    29,29,29,29,29,29,29,29,29,30,30,30,30,30,30,30,31,31,31,31,31};int scale_quant( transrate_t *tr, double qrate ){    int i_quant = (int)floor( tr->quantizer_scale * qrate + 0.5 );    if ( tr->q_scale_type )    {        if ( i_quant < 1 )            i_quant = 1;        if ( i_quant > 112 )            i_quant = 112;        i_quant = non_linear_mquant_table[map_non_linear_mquant[i_quant]];    }    else    {        if ( i_quant < 2 )            i_quant = 2;        if ( i_quant > 62 )            i_quant = 62;        i_quant = (i_quant / 2) * 2; // Must be *even*    }    return i_quant;}int increment_quant( transrate_t *tr, int i_quant ){    if ( tr->q_scale_type )    {        assert( i_quant >= 1 && i_quant <= 112 );        i_quant = map_non_linear_mquant[i_quant] + 1;        if ( i_quant > 31 )            i_quant = 31;        i_quant = non_linear_mquant_table[i_quant];    }    else    {        assert(!(i_quant & 1));        i_quant += 2;        if ( i_quant > 62 )            i_quant = 62;    }    return i_quant;}static int decrement_quant( transrate_t *tr, int i_quant ){    if ( tr->q_scale_type )    {        assert( i_quant >= 1 && i_quant <= 112 );        i_quant = map_non_linear_mquant[i_quant] - 1;        if ( i_quant < 1 )            i_quant = 1;        i_quant = non_linear_mquant_table[i_quant];    }    else    {        assert(!(i_quant & 1));        i_quant -= 2;        if ( i_quant < 2 )            i_quant = 2;    }    return i_quant;}static void quantize_block( transrate_t *tr, RunLevel *new_blk, int intra ){    RunLevel old_blk[65];    RunLevel *blk = old_blk;    const uint8_t *old_matrix, *new_matrix;    int i = 0, li = 0;    memcpy( blk, new_blk, 65 * sizeof(RunLevel) );    if ( intra )    {        old_matrix = tr->intra_quantizer_matrix;        new_matrix = mpeg4_default_intra_matrix;    }    else    {        old_matrix = tr->non_intra_quantizer_matrix;        new_matrix = mpeg4_default_non_intra_matrix;    }    while ( blk->level )    {        int level = blk->level > 0 ? blk->level : -blk->level;        int new_level = (level * old_matrix[i] + new_matrix[i]/2)                            / new_matrix[i];        i += blk->run;        if (new_level)        {            new_blk->run = i - li;            new_blk->level = blk->level > 0 ? new_level : -new_level;            new_blk++;            li = i;        }        blk++;    }    new_blk->level = 0;}int transrate_mb( transrate_t *tr, RunLevel blk[6][65], RunLevel new_blk[6][65],                  int i_cbp, int intra ){    int i_qscale = tr->quantizer_scale;    int i_guessed_qscale = tr->new_quantizer_scale;    int64_t i_last_error = 0;    int i_last_qscale;    int i_last_qscale_same_error = 0;    int i_direction = 0;    int i_new_cbp;    int i_nb_blocks = 0;    int i_nb_coeffs = 0;    int i;    for ( i = 0; i < 6; i++ )    {        if ( i_cbp & (1 << (5 - i)) )        {            RunLevel *cur_blk = blk[i];            i_nb_blocks++;            while ( cur_blk->level )            {                cur_blk++;                i_nb_coeffs++;            }        }    }    /* See if we can change quantizer scale */    for ( ; ; )    {        int64_t i_error = 0;        i_new_cbp = 0;        for ( i = 0; i < 6; i++ )        {            if ( i_cbp & (1 << (5 - i)) )            {                int64_t i_block_error;                change_qscale( blk[i], new_blk[i], i_qscale, i_guessed_qscale,                               intra );                i_block_error = get_score( blk[i], new_blk[i],                                           i_qscale, i_guessed_qscale );                if ( i > 3 ) i_block_error *= 4;                if ( i_block_error > i_error )                    i_error = i_block_error;                if ( new_blk[i]->level )                    i_new_cbp |= (1 << (5 - i));            }        }        if ( i_error >= (int64_t)tr->i_minimum_error                && i_error <= (int64_t)tr->i_admissible_error )        {            break;        }        if ( i_nb_coeffs <= 15 && i_error <= (int64_t)tr->i_admissible_error )        {            /* There is no interest in changing the qscale (takes up 5 bits             * we won't regain) */            break;        }        if ( !i_direction )        {            if ( i_error > (int64_t)tr->i_admissible_error )            {                i_direction = -1;                i_last_qscale = i_guessed_qscale;                i_guessed_qscale = decrement_quant( tr, i_guessed_qscale );            }            else            {                i_direction = +1;                i_last_qscale = i_guessed_qscale;                i_guessed_qscale = increment_quant( tr, i_guessed_qscale );                i_last_error = i_error;                i_last_qscale_same_error = i_last_qscale;            }            if ( i_guessed_qscale == i_last_qscale )                break;        }        else if ( i_direction < 0 )        {            if ( i_error > (int64_t)tr->i_admissible_error )            {                i_last_qscale = i_guessed_qscale;                i_guessed_qscale = decrement_quant( tr, i_guessed_qscale );                if ( i_guessed_qscale == i_last_qscale )                    break;            }            else            {                break;            }        }        else        {            if ( i_error < (int64_t)tr->i_minimum_error )            {                i_last_qscale = i_guessed_qscale;                i_guessed_qscale = increment_quant( tr, i_guessed_qscale );                if ( i_error > i_last_error )                {                    i_last_error = i_error;                    i_last_qscale_same_error = i_last_qscale;                }                if ( i_guessed_qscale == i_last_qscale )                {                    if ( i_last_error == i_error )                    {                        i_guessed_qscale = i_last_qscale_same_error;                        if ( i_guessed_qscale == i_qscale )                        {                            memcpy( new_blk, blk, sizeof(RunLevel)*65*6 );                            i_new_cbp = i_cbp;                        }                        else                        {                            i_new_cbp = 0;                            for ( i = 0; i < 6; i++ )                            {                                if ( i_cbp & (1 << (5 - i)) )                                {                                    change_qscale( blk[i], new_blk[i],                                                   i_qscale, i_guessed_qscale,                                                   intra );                                    if ( new_blk[i]->level )                                        i_new_cbp |= (1 << (5 - i));                                }                            }                        }                    }                    break;                }            }            else            {                if ( i_error > (int64_t)tr->i_admissible_error                        || i_last_error == i_error )                {                    i_guessed_qscale = i_last_qscale_same_error;                    if ( i_guessed_qscale == i_qscale )                    {                        memcpy( new_blk, blk, sizeof(RunLevel)*65*6 );                        i_new_cbp = i_cbp;                    }                    else                    {                        i_new_cbp = 0;                        for ( i = 0; i < 6; i++ )                        {                            if ( i_cbp & (1 << (5 - i)) )

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -