www.pudn.com > T264-src-0.02.zip > dct.c


/***************************************************************************** 
 * 
 *  T264 AVC CODEC 
 * 
 *  Copyright(C) 2004-2005 llcc  
 *               2004-2005 visionany  
 * 
 *  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; 
    } 
}