/src/ffmpeg/libavcodec/apv_dsp.c
Line | Count | Source |
1 | | /* |
2 | | * This file is part of FFmpeg. |
3 | | * |
4 | | * FFmpeg is free software; you can redistribute it and/or |
5 | | * modify it under the terms of the GNU Lesser General Public |
6 | | * License as published by the Free Software Foundation; either |
7 | | * version 2.1 of the License, or (at your option) any later version. |
8 | | * |
9 | | * FFmpeg is distributed in the hope that it will be useful, |
10 | | * but WITHOUT ANY WARRANTY; without even the implied warranty of |
11 | | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
12 | | * Lesser General Public License for more details. |
13 | | * |
14 | | * You should have received a copy of the GNU Lesser General Public |
15 | | * License along with FFmpeg; if not, write to the Free Software |
16 | | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA |
17 | | */ |
18 | | |
19 | | #include <stdint.h> |
20 | | |
21 | | #include "config.h" |
22 | | #include "libavutil/attributes.h" |
23 | | #include "libavutil/avassert.h" |
24 | | #include "libavutil/common.h" |
25 | | |
26 | | #include "apv.h" |
27 | | #include "apv_dsp.h" |
28 | | |
29 | | |
30 | | static const int8_t apv_trans_matrix[8][8] = { |
31 | | { 64, 64, 64, 64, 64, 64, 64, 64 }, |
32 | | { 89, 75, 50, 18, -18, -50, -75, -89 }, |
33 | | { 84, 35, -35, -84, -84, -35, 35, 84 }, |
34 | | { 75, -18, -89, -50, 50, 89, 18, -75 }, |
35 | | { 64, -64, -64, 64, 64, -64, -64, 64 }, |
36 | | { 50, -89, 18, 75, -75, -18, 89, -50 }, |
37 | | { 35, -84, 84, -35, -35, 84, -84, 35 }, |
38 | | { 18, -50, 75, -89, 89, -75, 50, -18 }, |
39 | | }; |
40 | | |
41 | | static void apv_decode_transquant_c(void *output, |
42 | | ptrdiff_t pitch, |
43 | | const int16_t *input_flat, |
44 | | const int16_t *qmatrix_flat, |
45 | | int bit_depth, |
46 | | int qp_shift) |
47 | 7.95M | { |
48 | 7.95M | const int16_t (*input)[8] = (const int16_t(*)[8])input_flat; |
49 | 7.95M | const int16_t (*qmatrix)[8] = (const int16_t(*)[8])qmatrix_flat; |
50 | | |
51 | 7.95M | int16_t scaled_coeff[8][8]; |
52 | 7.95M | int32_t recon_sample[8][8]; |
53 | | |
54 | | // Dequant. |
55 | 7.95M | { |
56 | | // Note that level_scale was already combined into qmatrix |
57 | | // before we got here. |
58 | 7.95M | int bd_shift = bit_depth + 3 - 5; |
59 | | |
60 | 71.6M | for (int y = 0; y < 8; y++) { |
61 | 572M | for (int x = 0; x < 8; x++) { |
62 | 509M | int coeff = ((int)(input[y][x] * qmatrix[y][x] * (1U << qp_shift) + |
63 | 509M | (1 << (bd_shift - 1)))) >> bd_shift; |
64 | | |
65 | 509M | scaled_coeff[y][x] = |
66 | 509M | av_clip(coeff, APV_MIN_TRANS_COEFF, |
67 | 509M | APV_MAX_TRANS_COEFF); |
68 | 509M | } |
69 | 63.6M | } |
70 | 7.95M | } |
71 | | |
72 | | // Transform. |
73 | 7.95M | { |
74 | 7.95M | int32_t tmp[8][8]; |
75 | | |
76 | | // Vertical transform of columns. |
77 | 71.6M | for (int x = 0; x < 8; x++) { |
78 | 572M | for (int i = 0; i < 8; i++) { |
79 | 509M | int sum = 0; |
80 | 4.58G | for (int j = 0; j < 8; j++) |
81 | 4.07G | sum += apv_trans_matrix[j][i] * scaled_coeff[j][x]; |
82 | 509M | tmp[i][x] = sum; |
83 | 509M | } |
84 | 63.6M | } |
85 | | |
86 | | // Renormalise. |
87 | 71.6M | for (int x = 0; x < 8; x++) { |
88 | 572M | for (int y = 0; y < 8; y++) |
89 | 509M | tmp[y][x] = (tmp[y][x] + 64) >> 7; |
90 | 63.6M | } |
91 | | |
92 | | // Horizontal transform of rows. |
93 | 71.6M | for (int y = 0; y < 8; y++) { |
94 | 572M | for (int i = 0; i < 8; i++) { |
95 | 509M | int sum = 0; |
96 | 4.58G | for (int j = 0; j < 8; j++) |
97 | 4.07G | sum += apv_trans_matrix[j][i] * tmp[y][j]; |
98 | 509M | recon_sample[y][i] = sum; |
99 | 509M | } |
100 | 63.6M | } |
101 | 7.95M | } |
102 | | |
103 | | // Output. |
104 | 7.95M | av_assert2(bit_depth > 8 && bit_depth <= 16); |
105 | 7.95M | uint16_t *ptr = output; |
106 | 7.95M | int bd_shift = 20 - bit_depth; |
107 | 7.95M | pitch /= 2; // Pitch was in bytes, 2 bytes per sample. |
108 | | |
109 | 71.6M | for (int y = 0; y < 8; y++) { |
110 | 572M | for (int x = 0; x < 8; x++) { |
111 | 509M | int sample = ((recon_sample[y][x] + |
112 | 509M | (1 << (bd_shift - 1))) >> bd_shift) + |
113 | 509M | (1 << (bit_depth - 1)); |
114 | 509M | ptr[x] = av_clip_uintp2(sample, bit_depth); |
115 | 509M | } |
116 | 63.6M | ptr += pitch; |
117 | 63.6M | } |
118 | 7.95M | } |
119 | | |
120 | | av_cold void ff_apv_dsp_init(APVDSPContext *dsp) |
121 | 2.97k | { |
122 | 2.97k | dsp->decode_transquant = apv_decode_transquant_c; |
123 | | |
124 | | #if ARCH_X86_64 && HAVE_X86ASM |
125 | | ff_apv_dsp_init_x86_64(dsp); |
126 | | #endif |
127 | 2.97k | } |