Imported Upstream version 1.4
[deb_x265.git] / source / common / scalinglist.cpp
CommitLineData
72b9787e
JB
1/*****************************************************************************
2 * Copyright (C) 2014 x265 project
3 *
4 * Authors: Steve Borho <steve@borho.org>
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111, USA.
19 *
20 * This program is also available under a commercial proprietary license.
21 * For more information, contact us at license @ x265.com.
22 *****************************************************************************/
23
24#include "common.h"
25#include "primitives.h"
26#include "scalinglist.h"
27
28namespace {
29// file-anonymous namespace
30
31/* Strings for scaling list file parsing */
32const char MatrixType[4][6][20] =
33{
34 {
35 "INTRA4X4_LUMA",
36 "INTRA4X4_CHROMAU",
37 "INTRA4X4_CHROMAV",
38 "INTER4X4_LUMA",
39 "INTER4X4_CHROMAU",
40 "INTER4X4_CHROMAV"
41 },
42 {
43 "INTRA8X8_LUMA",
44 "INTRA8X8_CHROMAU",
45 "INTRA8X8_CHROMAV",
46 "INTER8X8_LUMA",
47 "INTER8X8_CHROMAU",
48 "INTER8X8_CHROMAV"
49 },
50 {
51 "INTRA16X16_LUMA",
52 "INTRA16X16_CHROMAU",
53 "INTRA16X16_CHROMAV",
54 "INTER16X16_LUMA",
55 "INTER16X16_CHROMAU",
56 "INTER16X16_CHROMAV"
57 },
58 {
59 "INTRA32X32_LUMA",
60 "INTER32X32_LUMA",
61 },
62};
63const char MatrixType_DC[4][12][22] =
64{
65 {
66 },
67 {
68 },
69 {
70 "INTRA16X16_LUMA_DC",
71 "INTRA16X16_CHROMAU_DC",
72 "INTRA16X16_CHROMAV_DC",
73 "INTER16X16_LUMA_DC",
74 "INTER16X16_CHROMAU_DC",
75 "INTER16X16_CHROMAV_DC"
76 },
77 {
78 "INTRA32X32_LUMA_DC",
79 "INTER32X32_LUMA_DC",
80 },
81};
82
83int quantTSDefault4x4[16] =
84{
85 16, 16, 16, 16,
86 16, 16, 16, 16,
87 16, 16, 16, 16,
88 16, 16, 16, 16
89};
90
91int quantIntraDefault8x8[64] =
92{
93 16, 16, 16, 16, 17, 18, 21, 24,
94 16, 16, 16, 16, 17, 19, 22, 25,
95 16, 16, 17, 18, 20, 22, 25, 29,
96 16, 16, 18, 21, 24, 27, 31, 36,
97 17, 17, 20, 24, 30, 35, 41, 47,
98 18, 19, 22, 27, 35, 44, 54, 65,
99 21, 22, 25, 31, 41, 54, 70, 88,
100 24, 25, 29, 36, 47, 65, 88, 115
101};
102
103int quantInterDefault8x8[64] =
104{
105 16, 16, 16, 16, 17, 18, 20, 24,
106 16, 16, 16, 17, 18, 20, 24, 25,
107 16, 16, 17, 18, 20, 24, 25, 28,
108 16, 17, 18, 20, 24, 25, 28, 33,
109 17, 18, 20, 24, 25, 28, 33, 41,
110 18, 20, 24, 25, 28, 33, 41, 54,
111 20, 24, 25, 28, 33, 41, 54, 71,
112 24, 25, 28, 33, 41, 54, 71, 91
113};
114
115}
116
117namespace x265 {
118// private namespace
119
120const int ScalingList::s_numCoefPerSize[NUM_SIZES] = { 16, 64, 256, 1024 };
121const int32_t ScalingList::s_quantScales[NUM_REM] = { 26214, 23302, 20560, 18396, 16384, 14564 };
122const int32_t ScalingList::s_invQuantScales[NUM_REM] = { 40, 45, 51, 57, 64, 72 };
123
124ScalingList::ScalingList()
125{
126 memset(m_quantCoef, 0, sizeof(m_quantCoef));
127 memset(m_dequantCoef, 0, sizeof(m_dequantCoef));
128 memset(m_scalingListCoef, 0, sizeof(m_scalingListCoef));
129}
130
131bool ScalingList::init()
132{
133 bool ok = true;
134 for (int sizeId = 0; sizeId < NUM_SIZES; sizeId++)
135 {
136 for (int listId = 0; listId < NUM_LISTS; listId++)
137 {
138 m_scalingListCoef[sizeId][listId] = X265_MALLOC(int32_t, X265_MIN(MAX_MATRIX_COEF_NUM, s_numCoefPerSize[sizeId]));
139 ok &= !!m_scalingListCoef[sizeId][listId];
140 for (int rem = 0; rem < NUM_REM; rem++)
141 {
142 m_quantCoef[sizeId][listId][rem] = X265_MALLOC(int32_t, s_numCoefPerSize[sizeId]);
143 m_dequantCoef[sizeId][listId][rem] = X265_MALLOC(int32_t, s_numCoefPerSize[sizeId]);
144 ok &= m_quantCoef[sizeId][listId][rem] && m_dequantCoef[sizeId][listId][rem];
145 }
146 }
147 }
148 return ok;
149}
150
151ScalingList::~ScalingList()
152{
153 for (int sizeId = 0; sizeId < NUM_SIZES; sizeId++)
154 {
155 for (int listId = 0; listId < NUM_LISTS; listId++)
156 {
157 X265_FREE(m_scalingListCoef[sizeId][listId]);
158 for (int rem = 0; rem < NUM_REM; rem++)
159 {
160 X265_FREE(m_quantCoef[sizeId][listId][rem]);
161 X265_FREE(m_dequantCoef[sizeId][listId][rem]);
162 }
163 }
164 }
165}
166
167/* returns predicted list index if a match is found, else -1 */
168int ScalingList::checkPredMode(int size, int list) const
169{
170 for (int predList = list; predList >= 0; predList--)
171 {
172 // check DC value
173 if (size < BLOCK_16x16 && m_scalingListDC[size][list] != m_scalingListDC[size][predList])
174 continue;
175
176 // check value of matrix
177 if (!memcmp(m_scalingListCoef[size][list],
178 list == predList ? getScalingListDefaultAddress(size, predList) : m_scalingListCoef[size][predList],
179 sizeof(int32_t) * X265_MIN(MAX_MATRIX_COEF_NUM, s_numCoefPerSize[size])))
180 return predList;
181 }
182
183 return -1;
184}
185
186/* check if use default quantization matrix
187 * returns true if default quantization matrix is used in all sizes */
188bool ScalingList::checkDefaultScalingList() const
189{
190 int defaultCounter = 0;
191
192 for (int s = 0; s < NUM_SIZES; s++)
193 for (int l = 0; l < NUM_LISTS; l++)
194 if (!memcmp(m_scalingListCoef[s][l], getScalingListDefaultAddress(s, l),
195 sizeof(int32_t) * X265_MIN(MAX_MATRIX_COEF_NUM, s_numCoefPerSize[s])) &&
196 ((s < BLOCK_16x16) || (m_scalingListDC[s][l] == 16)))
197 defaultCounter++;
198
199 return defaultCounter != (NUM_LISTS * NUM_SIZES - 4); // -4 for 32x32
200}
201
202/* get address of default quantization matrix */
203const int32_t* ScalingList::getScalingListDefaultAddress(int sizeId, int listId) const
204{
205 switch (sizeId)
206 {
207 case BLOCK_4x4:
208 return quantTSDefault4x4;
209 case BLOCK_8x8:
210 return (listId < 3) ? quantIntraDefault8x8 : quantInterDefault8x8;
211 case BLOCK_16x16:
212 return (listId < 3) ? quantIntraDefault8x8 : quantInterDefault8x8;
213 case BLOCK_32x32:
214 return (listId < 1) ? quantIntraDefault8x8 : quantInterDefault8x8;
215 default:
216 break;
217 }
218
219 X265_CHECK(0, "invalid scaling list size\n");
220 return NULL;
221}
222
223void ScalingList::processDefaultMarix(int sizeId, int listId)
224{
225 ::memcpy(m_scalingListCoef[sizeId][listId], getScalingListDefaultAddress(sizeId, listId), sizeof(int) * X265_MIN(MAX_MATRIX_COEF_NUM, s_numCoefPerSize[sizeId]));
226 m_scalingListDC[sizeId][listId] = SCALING_LIST_DC;
227}
228
229void ScalingList::setDefaultScalingList()
230{
231 for (int sizeId = 0; sizeId < NUM_SIZES; sizeId++)
232 for (int listId = 0; listId < NUM_LISTS; listId++)
233 processDefaultMarix(sizeId, listId);
234 m_bEnabled = true;
235 m_bDataPresent = false;
236}
237
238bool ScalingList::parseScalingList(const char* filename)
239{
240 FILE *fp = fopen(filename, "r");
241 if (!fp)
242 {
243 x265_log(NULL, X265_LOG_ERROR, "can't open scaling list file %s\n", filename);
244 return true;
245 }
246
247 char line[1024];
248 int32_t *src = NULL;
249
250 for (int sizeIdc = 0; sizeIdc < NUM_SIZES; sizeIdc++)
251 {
252 int size = X265_MIN(MAX_MATRIX_COEF_NUM, s_numCoefPerSize[sizeIdc]);
253 for (int listIdc = 0; listIdc < NUM_LISTS; listIdc++)
254 {
255 src = m_scalingListCoef[sizeIdc][listIdc];
256
257 fseek(fp, 0, 0);
258 do
259 {
260 char *ret = fgets(line, 1024, fp);
261 if (!ret || (!strstr(line, MatrixType[sizeIdc][listIdc]) && feof(fp)))
262 {
263 x265_log(NULL, X265_LOG_ERROR, "can't read matrix from %s\n", filename);
264 return true;
265 }
266 }
267 while (!strstr(line, MatrixType[sizeIdc][listIdc]));
268
269 for (int i = 0; i < size; i++)
270 {
271 int data;
272 if (fscanf(fp, "%d,", &data) != 1)
273 {
274 x265_log(NULL, X265_LOG_ERROR, "can't read matrix from %s\n", filename);
275 return true;
276 }
277 src[i] = data;
278 }
279
280 // set DC value for default matrix check
281 m_scalingListDC[sizeIdc][listIdc] = src[0];
282
283 if (sizeIdc > BLOCK_8x8)
284 {
285 fseek(fp, 0, 0);
286 do
287 {
288 char *ret = fgets(line, 1024, fp);
289 if (!ret || (!strstr(line, MatrixType_DC[sizeIdc][listIdc]) && feof(fp)))
290 {
291 x265_log(NULL, X265_LOG_ERROR, "can't read DC from %s\n", filename);
292 return true;
293 }
294 }
295 while (!strstr(line, MatrixType_DC[sizeIdc][listIdc]));
296
297 int data;
298 if (fscanf(fp, "%d,", &data) != 1)
299 {
300 x265_log(NULL, X265_LOG_ERROR, "can't read matrix from %s\n", filename);
301 return true;
302 }
303
304 // overwrite DC value when size of matrix is larger than 16x16
305 m_scalingListDC[sizeIdc][listIdc] = data;
306 }
307 }
308 }
309
310 fclose(fp);
311
312 m_bEnabled = true;
313 m_bDataPresent = !checkDefaultScalingList();
314
315 return false;
316}
317
318/** set quantized matrix coefficient for encode */
319void ScalingList::setupQuantMatrices()
320{
321 for (int size = 0; size < NUM_SIZES; size++)
322 {
323 int width = 1 << (size + 2);
324 int ratio = width / X265_MIN(MAX_MATRIX_SIZE_NUM, width);
325 int stride = X265_MIN(MAX_MATRIX_SIZE_NUM, width);
326 int count = s_numCoefPerSize[size];
327
328 for (int list = 0; list < NUM_LISTS; list++)
329 {
330 int32_t *coeff = m_scalingListCoef[size][list];
331 int32_t dc = m_scalingListDC[size][list];
332
333 for (int rem = 0; rem < NUM_REM; rem++)
334 {
335 int32_t *quantCoeff = m_quantCoef[size][list][rem];
336 int32_t *dequantCoeff = m_dequantCoef[size][list][rem];
337
338 if (m_bEnabled)
339 {
340 processScalingListEnc(coeff, quantCoeff, s_quantScales[rem] << 4, width, width, ratio, stride, dc);
341 processScalingListDec(coeff, dequantCoeff, s_invQuantScales[rem], width, width, ratio, stride, dc);
342 }
343 else
344 {
345 /* flat quant and dequant coefficients */
346 for (int i = 0; i < count; i++)
347 {
348 quantCoeff[i] = s_quantScales[rem];
349 dequantCoeff[i] = s_invQuantScales[rem];
350 }
351 }
352 }
353 }
354 }
355}
356
357void ScalingList::processScalingListEnc(int32_t *coeff, int32_t *quantcoeff, int32_t quantScales, int height, int width,
358 int ratio, int stride, int32_t dc)
359{
360 for (int j = 0; j < height; j++)
361 for (int i = 0; i < width; i++)
362 quantcoeff[j * width + i] = quantScales / coeff[stride * (j / ratio) + i / ratio];
363
364 if (ratio > 1)
365 quantcoeff[0] = quantScales / dc;
366}
367
368void ScalingList::processScalingListDec(int32_t *coeff, int32_t *dequantcoeff, int32_t invQuantScales, int height, int width,
369 int ratio, int stride, int32_t dc)
370{
371 for (int j = 0; j < height; j++)
372 for (int i = 0; i < width; i++)
373 dequantcoeff[j * width + i] = invQuantScales * coeff[stride * (j / ratio) + i / ratio];
374
375 if (ratio > 1)
376 dequantcoeff[0] = invQuantScales * dc;
377}
378
379}