File: lowpassdct.cpp

package info (click to toggle)
x265 4.1-3
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid
  • size: 15,408 kB
  • sloc: asm: 187,063; cpp: 118,996; ansic: 741; makefile: 146; sh: 91; python: 11
file content (131 lines) | stat: -rw-r--r-- 4,401 bytes parent folder | download | duplicates (2)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
/*****************************************************************************
 * Copyright (C) 2017 
 *
 * Authors: Humberto Ribeiro Filho <mont3z.claro5@gmail.com>
 *
 * 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  02111, USA.
 *
 * This program is also available under a commercial proprietary license.
 * For more information, contact us at license @ x265.com.
 *****************************************************************************/

#include "common.h"
#include "primitives.h"

using namespace X265_NS;

/* standard dct transformations */
static dct_t* s_dct4x4;
static dct_t* s_dct8x8;
static dct_t* s_dct16x16;

static void lowPassDct8_c(const int16_t* src, int16_t* dst, intptr_t srcStride)
{
    ALIGN_VAR_32(int16_t, coef[4 * 4]);
    ALIGN_VAR_32(int16_t, avgBlock[4 * 4]);
    int16_t totalSum = 0;
    int16_t sum = 0;
    
    for (int i = 0; i < 4; i++)
        for (int j =0; j < 4; j++)
        {
            // Calculate average of 2x2 cells
            sum = src[2*i*srcStride + 2*j] + src[2*i*srcStride + 2*j + 1]
                    + src[(2*i+1)*srcStride + 2*j] + src[(2*i+1)*srcStride + 2*j + 1];
            avgBlock[i*4 + j] = sum >> 2;

            totalSum += sum; // use to calculate total block average
        }

    //dct4
    (*s_dct4x4)(avgBlock, coef, 4);
    memset(dst, 0, 64 * sizeof(int16_t));
    for (int i = 0; i < 4; i++)
    {
        memcpy(&dst[i * 8], &coef[i * 4], 4 * sizeof(int16_t));
    }

    // replace first coef with total block average
#if X265_DEPTH == 8
    dst[0] = totalSum << 1;
#else
    dst[0] = totalSum >> (X265_DEPTH - 9);
#endif
}

static void lowPassDct16_c(const int16_t* src, int16_t* dst, intptr_t srcStride)
{
    ALIGN_VAR_32(int16_t, coef[8 * 8]);
    ALIGN_VAR_32(int16_t, avgBlock[8 * 8]);
    int32_t totalSum = 0;
    int16_t sum = 0;
    for (int i = 0; i < 8; i++)
        for (int j =0; j < 8; j++)
        {
            sum = src[2*i*srcStride + 2*j] + src[2*i*srcStride + 2*j + 1]
                    + src[(2*i+1)*srcStride + 2*j] + src[(2*i+1)*srcStride + 2*j + 1];
            avgBlock[i*8 + j] = sum >> 2;

            totalSum += sum;
        }

    (*s_dct8x8)(avgBlock, coef, 8);
    memset(dst, 0, 256 * sizeof(int16_t));
    for (int i = 0; i < 8; i++)
    {
        memcpy(&dst[i * 16], &coef[i * 8], 8 * sizeof(int16_t));
    }
    dst[0] = static_cast<int16_t>(totalSum >> (1 + (X265_DEPTH - 8)));
}

static void lowPassDct32_c(const int16_t* src, int16_t* dst, intptr_t srcStride)
{
    ALIGN_VAR_32(int16_t, coef[16 * 16]);
    ALIGN_VAR_32(int16_t, avgBlock[16 * 16]);
    int32_t totalSum = 0;
    int16_t sum = 0;
    for (int i = 0; i < 16; i++)
        for (int j =0; j < 16; j++)
        {
            sum = src[2*i*srcStride + 2*j] + src[2*i*srcStride + 2*j + 1]
                    + src[(2*i+1)*srcStride + 2*j] + src[(2*i+1)*srcStride + 2*j + 1];
            avgBlock[i*16 + j] = sum >> 2;

            totalSum += sum;
        }

    (*s_dct16x16)(avgBlock, coef, 16);
    memset(dst, 0, 1024 * sizeof(int16_t));
    for (int i = 0; i < 16; i++)
    {
        memcpy(&dst[i * 32], &coef[i * 16], 16 * sizeof(int16_t));
    }
    dst[0] = static_cast<int16_t>(totalSum >> (3 + (X265_DEPTH - 8)));
}

namespace X265_NS {
// x265 private namespace

void setupLowPassPrimitives_c(EncoderPrimitives& p)
{
    s_dct4x4 = &(p.cu[BLOCK_4x4].standard_dct);
    s_dct8x8 = &(p.cu[BLOCK_8x8].standard_dct);
    s_dct16x16 = &(p.cu[BLOCK_16x16].standard_dct);

    p.cu[BLOCK_8x8].lowpass_dct = lowPassDct8_c;
    p.cu[BLOCK_16x16].lowpass_dct = lowPassDct16_c;
    p.cu[BLOCK_32x32].lowpass_dct = lowPassDct32_c;
}
}