/src/x265/source/encoder/bitcost.cpp
Line | Count | Source (jump to first uncovered line) |
1 | | /***************************************************************************** |
2 | | * Copyright (C) 2013-2020 MulticoreWare, Inc |
3 | | * |
4 | | * Authors: Steve Borho <steve@borho.org> |
5 | | * Min Chen <chenm003@163.com> |
6 | | * |
7 | | * This program is free software; you can redistribute it and/or modify |
8 | | * it under the terms of the GNU General Public License as published by |
9 | | * the Free Software Foundation; either version 2 of the License, or |
10 | | * (at your option) any later version. |
11 | | * |
12 | | * This program is distributed in the hope that it will be useful, |
13 | | * but WITHOUT ANY WARRANTY; without even the implied warranty of |
14 | | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
15 | | * GNU General Public License for more details. |
16 | | * |
17 | | * You should have received a copy of the GNU General Public License |
18 | | * along with this program; if not, write to the Free Software |
19 | | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111, USA. |
20 | | * |
21 | | * This program is also available under a commercial proprietary license. |
22 | | * For more information, contact us at license @ x265.com. |
23 | | *****************************************************************************/ |
24 | | |
25 | | #include "common.h" |
26 | | #include "primitives.h" |
27 | | #include "bitcost.h" |
28 | | |
29 | | using namespace X265_NS; |
30 | | |
31 | | void BitCost::setQP(unsigned int qp) |
32 | 51.2k | { |
33 | 51.2k | if (!s_costs[qp]) |
34 | 33 | { |
35 | 33 | ScopedLock s(s_costCalcLock); |
36 | | |
37 | | // Now that we have acquired the lock, check again if another thread calculated |
38 | | // this row while we were blocked |
39 | 33 | if (!s_costs[qp]) |
40 | 33 | { |
41 | 33 | x265_emms(); // just to be safe |
42 | | |
43 | 33 | CalculateLogs(); |
44 | 33 | s_costs[qp] = X265_MALLOC(uint16_t, 4 * BC_MAX_MV + 1) + 2 * BC_MAX_MV; |
45 | 33 | if (!s_costs[qp]) |
46 | 0 | { |
47 | 0 | x265_log(NULL, X265_LOG_ERROR, "BitCost s_costs buffer allocation failure\n"); |
48 | 0 | return; |
49 | 0 | } |
50 | 33 | double lambda = x265_lambda_tab[qp]; |
51 | | |
52 | | // estimate same cost for negative and positive MVD |
53 | 2.16M | for (int i = 0; i <= 2 * BC_MAX_MV; i++) |
54 | 2.16M | s_costs[qp][i] = s_costs[qp][-i] = (uint16_t)X265_MIN(s_bitsizes[i] * lambda + 0.5f, (1 << 15) - 1); |
55 | 33 | } |
56 | 33 | } |
57 | 256k | for (int j = 0; j < 4; j++) |
58 | 204k | { |
59 | 204k | if (!s_fpelMvCosts[qp][j]) |
60 | 132 | { |
61 | 132 | ScopedLock s(s_costCalcLock); |
62 | 132 | if (!s_fpelMvCosts[qp][j]) |
63 | 132 | { |
64 | 132 | s_fpelMvCosts[qp][j] = X265_MALLOC(uint16_t, BC_MAX_MV + 1) + (BC_MAX_MV >> 1); |
65 | 132 | if (!s_fpelMvCosts[qp][j]) |
66 | 0 | { |
67 | 0 | x265_log(NULL, X265_LOG_ERROR, "BitCost s_fpelMvCosts buffer allocation failure\n"); |
68 | 0 | return; |
69 | 0 | } |
70 | 4.32M | for (int i = -(BC_MAX_MV >> 1); i < (BC_MAX_MV >> 1); i++) |
71 | 4.32M | { |
72 | 4.32M | s_fpelMvCosts[qp][j][i] = s_costs[qp][i * 4 + j]; |
73 | 4.32M | } |
74 | 132 | } |
75 | 132 | } |
76 | 204k | } |
77 | 51.2k | m_cost = s_costs[qp]; |
78 | 256k | for (int j = 0; j < 4; j++) |
79 | 204k | { |
80 | 204k | m_fpelMvCosts[j] = s_fpelMvCosts[qp][j]; |
81 | 204k | } |
82 | 51.2k | } |
83 | | /*** |
84 | | * Class static data and methods |
85 | | */ |
86 | | |
87 | | uint16_t *BitCost::s_costs[BC_MAX_QP]; |
88 | | |
89 | | uint16_t* BitCost::s_fpelMvCosts[BC_MAX_QP][4]; |
90 | | |
91 | | float *BitCost::s_bitsizes; |
92 | | |
93 | | Lock BitCost::s_costCalcLock; |
94 | | |
95 | | void BitCost::CalculateLogs() |
96 | 33 | { |
97 | 33 | if (!s_bitsizes) |
98 | 1 | { |
99 | 1 | s_bitsizes = X265_MALLOC(float, 4 * BC_MAX_MV + 1) + 2 * BC_MAX_MV; |
100 | 1 | if (!s_bitsizes) |
101 | 0 | { |
102 | 0 | x265_log(NULL, X265_LOG_ERROR, "BitCost s_bitsizes buffer allocation failure\n"); |
103 | 0 | return; |
104 | 0 | } |
105 | 1 | s_bitsizes[0] = 0.718f; |
106 | 1 | float log2_2 = 2.0f / log(2.0f); // 2 x 1/log(2) |
107 | 65.5k | for (int i = 1; i <= 2 * BC_MAX_MV; i++) |
108 | 65.5k | s_bitsizes[i] = s_bitsizes[-i] = log((float)(i + 1)) * log2_2 + 1.718f; |
109 | 1 | } |
110 | 33 | } |
111 | | |
112 | | void BitCost::destroy() |
113 | 0 | { |
114 | 0 | for (int i = 0; i < BC_MAX_QP; i++) |
115 | 0 | { |
116 | 0 | if (s_costs[i]) |
117 | 0 | { |
118 | 0 | X265_FREE(s_costs[i] - 2 * BC_MAX_MV); |
119 | |
|
120 | 0 | s_costs[i] = NULL; |
121 | 0 | } |
122 | 0 | } |
123 | 0 | for (int i = 0; i < BC_MAX_QP; i++) |
124 | 0 | { |
125 | 0 | for (int j = 0; j < 4; j++) |
126 | 0 | { |
127 | 0 | if (s_fpelMvCosts[i][j]) |
128 | 0 | { |
129 | 0 | X265_FREE(s_fpelMvCosts[i][j] - (BC_MAX_MV >> 1)); |
130 | 0 | s_fpelMvCosts[i][j] = NULL; |
131 | 0 | } |
132 | 0 | } |
133 | 0 | } |
134 | |
|
135 | 0 | if (s_bitsizes) |
136 | 0 | { |
137 | 0 | X265_FREE(s_bitsizes - 2 * BC_MAX_MV); |
138 | 0 | s_bitsizes = NULL; |
139 | 0 | } |
140 | 0 | } |