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

📄 dct.c

📁 T264是中国的视频编码自由组织合力开发的264编解码程序
💻 C
字号:
/*****************************************************************************
 *
 *  T264 AVC CODEC
 *
 *  Copyright(C) 2004-2005 llcc <lcgate1@yahoo.com.cn>
 *               2004-2005 visionany <visionany@yahoo.com.cn>
 *
 *  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., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
 *
 ****************************************************************************/

#include "stdio.h"
#include "T264.h"

#define Q_BITS          15
#define DQ_BITS         6
#define DQ_ROUND        (1<<(DQ_BITS-1))

//////////////////////////////////////////////////////
// static var
DECLARE_ALIGNED2_MATRIX_H(quant, 6, 4 * 4, int16_t, CACHE_SIZE) = 
{
    13107, 8066, 13107, 8066, 8066, 5243, 8066, 5243,    13107, 8066, 13107, 8066, 8066, 5243, 8066, 5243,    11916, 7490, 11916, 7490, 7490, 4660, 7490, 4660,    11916, 7490, 11916, 7490, 7490, 4660, 7490, 4660,    10082, 6554, 10082, 6554, 6554, 4194, 6554, 4194,    10082, 6554, 10082, 6554, 6554, 4194, 6554, 4194,     9362, 5825,  9362, 5825, 5825, 3647, 5825, 3647,     9362, 5825,  9362, 5825, 5825, 3647, 5825, 3647,     8192, 5243,  8192, 5243, 5243, 3355, 5243, 3355,     8192, 5243,  8192, 5243, 5243, 3355, 5243, 3355,     7282, 4559,  7282, 4559, 4559, 2893, 4559, 2893,     7282, 4559,  7282, 4559, 4559, 2893, 4559, 2893};

DECLARE_ALIGNED2_MATRIX_H(dequant, 6, 4 * 4, int16_t, CACHE_SIZE) = 
{
    10, 13, 10, 13, 13, 16, 13, 16, 10, 13, 10, 13, 13, 16, 13, 16,    11, 14, 11, 14, 14, 18, 14, 18, 11, 14, 11, 14, 14, 18, 14, 18,    13, 16, 13, 16, 16, 20, 16, 20, 13, 16, 13, 16, 16, 20, 16, 20,    14, 18, 14, 18, 18, 23, 18, 23, 14, 18, 14, 18, 18, 23, 18, 23,    16, 20, 16, 20, 20, 25, 20, 25, 16, 20, 16, 20, 20, 25, 20, 25,    18, 23, 18, 23, 23, 29, 23, 29, 18, 23, 18, 23, 23, 29, 23, 29};

//////////////////////////////////////////////////////
// DCT & IDCT
void 
dct4x4_c(int16_t* data)
{
    int32_t i;
    int16_t s[4];

    //
    // horizontal
    //
    for(i = 0 ; i < 4 ; i ++)
    {
        s[0] = data[i * 4 + 0] + data[i * 4 + 3];
        s[3] = data[i * 4 + 0] - data[i * 4 + 3];
        s[1] = data[i * 4 + 1] + data[i * 4 + 2];
        s[2] = data[i * 4 + 1] - data[i * 4 + 2];

        data[i * 4 + 0] = s[0] + s[1];
        data[i * 4 + 2] = s[0] - s[1];
        data[i * 4 + 1] = (s[3] << 1) + s[2];
        data[i * 4 + 3] = s[3] - (s[2] << 1);
    }

    //
    // vertical
    //
    for(i = 0 ; i < 4 ; i ++)
    {
        s[0] = data[0 * 4 + i] + data[3 * 4 + i];
        s[3] = data[0 * 4 + i] - data[3 * 4 + i];
        s[1] = data[1 * 4 + i] + data[2 * 4 + i];
        s[2] = data[1 * 4 + i] - data[2 * 4 + i];

        data[0 * 4 + i] = s[0] + s[1];
        data[2 * 4 + i] = s[0] - s[1];
        data[1 * 4 + i] = (s[3] << 1) + s[2];
        data[3 * 4 + i] = s[3] - (s[2] << 1);
    }
}

void 
dct4x4dc_c(int16_t* data)
{
    int32_t i;
    int16_t s[4];

    for(i = 0 ; i < 4 ; i ++)
    {
        s[0] = data[i * 4 + 0] + data[i * 4 + 3];
        s[3] = data[i * 4 + 0] - data[i * 4 + 3];
        s[1] = data[i * 4 + 1] + data[i * 4 + 2];
        s[2] = data[i * 4 + 1] - data[i * 4 + 2];

        data[i * 4 + 0] = s[0] + s[1];
        data[i * 4 + 2] = s[0] - s[1];
        data[i * 4 + 1] = s[3] + s[2];
        data[i * 4 + 3] = s[3] - s[2];
    }

    for(i = 0 ; i < 4 ; i ++)
    {
        s[0] = data[0 * 4 + i] + data[3 * 4 + i];
        s[3] = data[0 * 4 + i] - data[3 * 4 + i];
        s[1] = data[1 * 4 + i] + data[2 * 4 + i];
        s[2] = data[1 * 4 + i] - data[2 * 4 + i];

        data[0 * 4 + i] = (s[0] + s[1] + 1) >> 1;
        data[2 * 4 + i] = (s[0] - s[1] + 1) >> 1;
        data[1 * 4 + i] = (s[3] + s[2] + 1) >> 1;
        data[3 * 4 + i] = (s[3] - s[2] + 1) >> 1;
    }
}

void 
dct2x2dc_c(int16_t* data)
{   
    int16_t s[4];

    s[0] = data[0];
    s[1] = data[1];
    s[2] = data[2];
    s[3] = data[3];

    data[0] = s[0] + s[2] + s[1] + s[3];
    data[1] = s[0] + s[2] - s[1] - s[3];
    data[2] = s[0] - s[2] + s[1] - s[3];
    data[3] = s[0] - s[2] - s[1] + s[3];
}

void
idct4x4_c(int16_t* data)
{
    int32_t i;
    int16_t s[4];

    for (i = 0; i < 4; i ++)
    {
        s[0] = data[i * 4 + 0] + data[i * 4 + 2];
        s[1] = data[i * 4 + 0] - data[i * 4 + 2];
        s[2] = (data[i * 4 + 1] >> 1) - data[i * 4 + 3];
        s[3] = data[i * 4 + 1] + (data[i * 4 + 3] >> 1);

        data[i * 4 + 0] = s[0] + s[3];
        data[i * 4 + 3] = s[0] - s[3];
        data[i * 4 + 1] = s[1] + s[2];
        data[i * 4 + 2] = s[1] - s[2];
    }

    for (i = 0; i < 4; i ++)
    {
        s[0] = data[0 * 4 + i] + data[2 * 4 + i];
        s[1] = data[0 * 4 + i] - data[2 * 4 + i];
        s[2] = (data[1 * 4 + i] >> 1) - data[3 * 4 + i];
        s[3] = data[1 * 4 + i] + (data[3 * 4 + i] >> 1);

        data[0 * 4 + i] = (s[0] + s[3] + 32) >> 6;
        data[3 * 4 + i] = (s[0] - s[3] + 32) >> 6;
        data[1 * 4 + i] = (s[1] + s[2] + 32) >> 6;
        data[2 * 4 + i] = (s[1] - s[2] + 32) >> 6;
    }
}

void 
idct4x4dc_c(int16_t* data)
{
    int32_t i;
    int16_t s[4];

    for (i = 0; i < 4; i ++)
    {
        s[0] = data[i * 4 + 0] + data[i * 4 + 2];
        s[1] = data[i * 4 + 0] - data[i * 4 + 2];
        s[2] = data[i * 4 + 1] - data[i * 4 + 3];
        s[3] = data[i * 4 + 1] + data[i * 4 + 3];

        data[i * 4 + 0] = s[0] + s[3];
        data[i * 4 + 3] = s[0] - s[3];
        data[i * 4 + 1] = s[1] + s[2];
        data[i * 4 + 2] = s[1] - s[2];
    }

    for (i = 0; i < 4; i ++)
    {
        s[0] = data[0 * 4 + i] + data[2 * 4 + i];
        s[1] = data[0 * 4 + i] - data[2 * 4 + i];
        s[2] = data[1 * 4 + i] - data[3 * 4 + i];
        s[3] = data[1 * 4 + i] + data[3 * 4 + i];

        data[0 * 4 + i] = s[0] + s[3];
        data[3 * 4 + i] = s[0] - s[3];
        data[1 * 4 + i] = s[1] + s[2];
        data[2 * 4 + i] = s[1] - s[2];
    }
}

void 
idct2x2dc_c(int16_t* data)
{
    int16_t s[4];

    s[0] = data[0];
    s[1] = data[1];
    s[2] = data[2];
    s[3] = data[3];

    data[0] = s[0] + s[2] + s[1] + s[3];
    data[1] = s[0] + s[2] - s[1] - s[3];
    data[2] = s[0] - s[2] + s[1] - s[3];
    data[3] = s[0] - s[2] - s[1] + s[3];
}

///////////////////////////////////////////////////////////
// Quant & IQuant
void
quant4x4_c(int16_t* data, const int32_t Qp, int32_t is_intra)
{
    const int32_t qbits    = 15 + Qp / 6;
    const int32_t mf_index = Qp % 6;
    int32_t i;
    const int32_t f = (1 << qbits) / (is_intra ? 3 : 6);

    for(i = 0 ; i < 16 ; i ++)
    {
        if (data[i] > 0)
            data[i] = (data[i] * quant[mf_index][i] + f) >> qbits;
        else
            data[i] = -((-(data[i] * quant[mf_index][i]) + f) >> qbits);
    }
}

void
quant4x4dc_c(int16_t* data, const int32_t Qp)
{
    const int32_t qbits    = 15 + Qp / 6;
    const int32_t mf_index = Qp % 6;
    const int32_t mf00 = quant[mf_index][0];
    const int32_t f2 = (2 << qbits) / 3;	// Only 16x16 intra mode
    int32_t i;

    for(i = 0 ; i < 16 ; i ++)
    {
        if (data[i] > 0)
            data[i] = (data[i] * mf00 + f2) >> (qbits + 1);
        else
            data[i] = -((-(data[i] * mf00) + f2) >> (qbits + 1));
    }
}

void
quant2x2dc_c(int16_t* data, const int32_t Qp, int32_t is_intra)
{
    const int32_t qbits    = 15 + Qp / 6;
    const int32_t mf_index = Qp % 6;
    const int32_t mf00 = quant[mf_index][0];
    const int32_t f2 = (2 << qbits) / (is_intra ? 3 : 6);
    int32_t i;

    for(i = 0 ; i < 4 ; i ++)
    {
        if (data[i] > 0)
            data[i] = (data[i] * mf00 + f2) >> (qbits + 1);
        else
            data[i] = -((-(data[i] * mf00) + f2) >> (qbits + 1));
    }
}

void
iquant4x4_c(int16_t* data, const int32_t Qp)
{
    const int32_t qbits = Qp / 6;
    const int32_t index_mf = Qp % 6;
    int32_t i;

    for(i = 0 ; i < 16 ; i ++)
    {
        data[i] = (data[i] * dequant[index_mf][i]) << qbits;
    }    
}

void
iquant4x4dc_c(int16_t* data, const int32_t Qp)
{
    const int32_t qbits = Qp / 6 - 2;
    int32_t i;

    if (qbits >= 0)
    {
        const int32_t mf_index = Qp % 6;
        const int32_t dmf = dequant[mf_index][0] << qbits;
        for(i = 0 ; i < 16 ; i ++)
        {
            data[i] = data[i] * dmf;
        }
    }
    else
    {
        const int32_t dmf = dequant[Qp % 6][0];
        const int32_t t2  = 1 << (1 + qbits);
        for(i = 0 ; i < 16 ; i ++)
        {
            data[i] = (data[i] * dmf + t2) >> (-qbits);
        }
    }
}

void
iquant2x2dc_c(int16_t* data, const int32_t Qp)
{
    const int32_t qbits = Qp / 6 - 1;

    if (qbits >= 0 )
    {
        const int32_t dmf = dequant[Qp % 6][0] << qbits;

        data[0] = data[0] * dmf;
        data[1] = data[1] * dmf;
        data[2] = data[2] * dmf;
        data[3] = data[3] * dmf;
    }
    else
    {
        const int32_t dmf = dequant[Qp % 6][0];

        data[0] = (data[0] * dmf) >> 1;
        data[1] = (data[1] * dmf) >> 1;
        data[2] = (data[2] * dmf) >> 1;
        data[3] = (data[3] * dmf) >> 1;
    }
}

⌨️ 快捷键说明

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