1/* 2 * HEVC video decoder 3 * 4 * Copyright (C) 2012 - 2013 Guillaume Martres 5 * Copyright (C) 2013 - 2014 Pierre-Edouard Lepere 6 * 7 * 8 * This file is part of FFmpeg. 9 * 10 * FFmpeg is free software; you can redistribute it and/or 11 * modify it under the terms of the GNU Lesser General Public 12 * License as published by the Free Software Foundation; either 13 * version 2.1 of the License, or (at your option) any later version. 14 * 15 * FFmpeg is distributed in the hope that it will be useful, 16 * but WITHOUT ANY WARRANTY; without even the implied warranty of 17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 18 * Lesser General Public License for more details. 19 * 20 * You should have received a copy of the GNU Lesser General Public 21 * License along with FFmpeg; if not, write to the Free Software 22 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 23 */ 24 25#include "hevcdsp.h" 26 27static const int8_t transform[32][32] = { 28 { 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 29 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64 }, 30 { 90, 90, 88, 85, 82, 78, 73, 67, 61, 54, 46, 38, 31, 22, 13, 4, 31 -4, -13, -22, -31, -38, -46, -54, -61, -67, -73, -78, -82, -85, -88, -90, -90 }, 32 { 90, 87, 80, 70, 57, 43, 25, 9, -9, -25, -43, -57, -70, -80, -87, -90, 33 -90, -87, -80, -70, -57, -43, -25, -9, 9, 25, 43, 57, 70, 80, 87, 90 }, 34 { 90, 82, 67, 46, 22, -4, -31, -54, -73, -85, -90, -88, -78, -61, -38, -13, 35 13, 38, 61, 78, 88, 90, 85, 73, 54, 31, 4, -22, -46, -67, -82, -90 }, 36 { 89, 75, 50, 18, -18, -50, -75, -89, -89, -75, -50, -18, 18, 50, 75, 89, 37 89, 75, 50, 18, -18, -50, -75, -89, -89, -75, -50, -18, 18, 50, 75, 89 }, 38 { 88, 67, 31, -13, -54, -82, -90, -78, -46, -4, 38, 73, 90, 85, 61, 22, 39 -22, -61, -85, -90, -73, -38, 4, 46, 78, 90, 82, 54, 13, -31, -67, -88 }, 40 { 87, 57, 9, -43, -80, -90, -70, -25, 25, 70, 90, 80, 43, -9, -57, -87, 41 -87, -57, -9, 43, 80, 90, 70, 25, -25, -70, -90, -80, -43, 9, 57, 87 }, 42 { 85, 46, -13, -67, -90, -73, -22, 38, 82, 88, 54, -4, -61, -90, -78, -31, 43 31, 78, 90, 61, 4, -54, -88, -82, -38, 22, 73, 90, 67, 13, -46, -85 }, 44 { 83, 36, -36, -83, -83, -36, 36, 83, 83, 36, -36, -83, -83, -36, 36, 83, 45 83, 36, -36, -83, -83, -36, 36, 83, 83, 36, -36, -83, -83, -36, 36, 83 }, 46 { 82, 22, -54, -90, -61, 13, 78, 85, 31, -46, -90, -67, 4, 73, 88, 38, 47 -38, -88, -73, -4, 67, 90, 46, -31, -85, -78, -13, 61, 90, 54, -22, -82 }, 48 { 80, 9, -70, -87, -25, 57, 90, 43, -43, -90, -57, 25, 87, 70, -9, -80, 49 -80, -9, 70, 87, 25, -57, -90, -43, 43, 90, 57, -25, -87, -70, 9, 80 }, 50 { 78, -4, -82, -73, 13, 85, 67, -22, -88, -61, 31, 90, 54, -38, -90, -46, 51 46, 90, 38, -54, -90, -31, 61, 88, 22, -67, -85, -13, 73, 82, 4, -78 }, 52 { 75, -18, -89, -50, 50, 89, 18, -75, -75, 18, 89, 50, -50, -89, -18, 75, 53 75, -18, -89, -50, 50, 89, 18, -75, -75, 18, 89, 50, -50, -89, -18, 75 }, 54 { 73, -31, -90, -22, 78, 67, -38, -90, -13, 82, 61, -46, -88, -4, 85, 54, 55 -54, -85, 4, 88, 46, -61, -82, 13, 90, 38, -67, -78, 22, 90, 31, -73 }, 56 { 70, -43, -87, 9, 90, 25, -80, -57, 57, 80, -25, -90, -9, 87, 43, -70, 57 -70, 43, 87, -9, -90, -25, 80, 57, -57, -80, 25, 90, 9, -87, -43, 70 }, 58 { 67, -54, -78, 38, 85, -22, -90, 4, 90, 13, -88, -31, 82, 46, -73, -61, 59 61, 73, -46, -82, 31, 88, -13, -90, -4, 90, 22, -85, -38, 78, 54, -67 }, 60 { 64, -64, -64, 64, 64, -64, -64, 64, 64, -64, -64, 64, 64, -64, -64, 64, 61 64, -64, -64, 64, 64, -64, -64, 64, 64, -64, -64, 64, 64, -64, -64, 64 }, 62 { 61, -73, -46, 82, 31, -88, -13, 90, -4, -90, 22, 85, -38, -78, 54, 67, 63 -67, -54, 78, 38, -85, -22, 90, 4, -90, 13, 88, -31, -82, 46, 73, -61 }, 64 { 57, -80, -25, 90, -9, -87, 43, 70, -70, -43, 87, 9, -90, 25, 80, -57, 65 -57, 80, 25, -90, 9, 87, -43, -70, 70, 43, -87, -9, 90, -25, -80, 57 }, 66 { 54, -85, -4, 88, -46, -61, 82, 13, -90, 38, 67, -78, -22, 90, -31, -73, 67 73, 31, -90, 22, 78, -67, -38, 90, -13, -82, 61, 46, -88, 4, 85, -54 }, 68 { 50, -89, 18, 75, -75, -18, 89, -50, -50, 89, -18, -75, 75, 18, -89, 50, 69 50, -89, 18, 75, -75, -18, 89, -50, -50, 89, -18, -75, 75, 18, -89, 50 }, 70 { 46, -90, 38, 54, -90, 31, 61, -88, 22, 67, -85, 13, 73, -82, 4, 78, 71 -78, -4, 82, -73, -13, 85, -67, -22, 88, -61, -31, 90, -54, -38, 90, -46 }, 72 { 43, -90, 57, 25, -87, 70, 9, -80, 80, -9, -70, 87, -25, -57, 90, -43, 73 -43, 90, -57, -25, 87, -70, -9, 80, -80, 9, 70, -87, 25, 57, -90, 43 }, 74 { 38, -88, 73, -4, -67, 90, -46, -31, 85, -78, 13, 61, -90, 54, 22, -82, 75 82, -22, -54, 90, -61, -13, 78, -85, 31, 46, -90, 67, 4, -73, 88, -38 }, 76 { 36, -83, 83, -36, -36, 83, -83, 36, 36, -83, 83, -36, -36, 83, -83, 36, 77 36, -83, 83, -36, -36, 83, -83, 36, 36, -83, 83, -36, -36, 83, -83, 36 }, 78 { 31, -78, 90, -61, 4, 54, -88, 82, -38, -22, 73, -90, 67, -13, -46, 85, 79 -85, 46, 13, -67, 90, -73, 22, 38, -82, 88, -54, -4, 61, -90, 78, -31 }, 80 { 25, -70, 90, -80, 43, 9, -57, 87, -87, 57, -9, -43, 80, -90, 70, -25, 81 -25, 70, -90, 80, -43, -9, 57, -87, 87, -57, 9, 43, -80, 90, -70, 25 }, 82 { 22, -61, 85, -90, 73, -38, -4, 46, -78, 90, -82, 54, -13, -31, 67, -88, 83 88, -67, 31, 13, -54, 82, -90, 78, -46, 4, 38, -73, 90, -85, 61, -22 }, 84 { 18, -50, 75, -89, 89, -75, 50, -18, -18, 50, -75, 89, -89, 75, -50, 18, 85 18, -50, 75, -89, 89, -75, 50, -18, -18, 50, -75, 89, -89, 75, -50, 18 }, 86 { 13, -38, 61, -78, 88, -90, 85, -73, 54, -31, 4, 22, -46, 67, -82, 90, 87 -90, 82, -67, 46, -22, -4, 31, -54, 73, -85, 90, -88, 78, -61, 38, -13 }, 88 { 9, -25, 43, -57, 70, -80, 87, -90, 90, -87, 80, -70, 57, -43, 25, -9, 89 -9, 25, -43, 57, -70, 80, -87, 90, -90, 87, -80, 70, -57, 43, -25, 9 }, 90 { 4, -13, 22, -31, 38, -46, 54, -61, 67, -73, 78, -82, 85, -88, 90, -90, 91 90, -90, 88, -85, 82, -78, 73, -67, 61, -54, 46, -38, 31, -22, 13, -4 }, 92}; 93 94DECLARE_ALIGNED(16, const int8_t, ff_hevc_epel_filters[7][4]) = { 95 { -2, 58, 10, -2}, 96 { -4, 54, 16, -2}, 97 { -6, 46, 28, -4}, 98 { -4, 36, 36, -4}, 99 { -4, 28, 46, -6}, 100 { -2, 16, 54, -4}, 101 { -2, 10, 58, -2}, 102}; 103 104DECLARE_ALIGNED(16, const int8_t, ff_hevc_qpel_filters[3][16]) = { 105 { -1, 4,-10, 58, 17, -5, 1, 0, -1, 4,-10, 58, 17, -5, 1, 0}, 106 { -1, 4,-11, 40, 40,-11, 4, -1, -1, 4,-11, 40, 40,-11, 4, -1}, 107 { 0, 1, -5, 17, 58,-10, 4, -1, 0, 1, -5, 17, 58,-10, 4, -1} 108}; 109 110#define BIT_DEPTH 8 111#include "hevcdsp_template.c" 112#undef BIT_DEPTH 113 114#define BIT_DEPTH 9 115#include "hevcdsp_template.c" 116#undef BIT_DEPTH 117 118#define BIT_DEPTH 10 119#include "hevcdsp_template.c" 120#undef BIT_DEPTH 121 122#define BIT_DEPTH 12 123#include "hevcdsp_template.c" 124#undef BIT_DEPTH 125 126void ff_hevc_dsp_init(HEVCDSPContext *hevcdsp, int bit_depth) 127{ 128#undef FUNC 129#define FUNC(a, depth) a ## _ ## depth 130 131#undef PEL_FUNC 132#define PEL_FUNC(dst1, idx1, idx2, a, depth) \ 133 for(i = 0 ; i < 10 ; i++) \ 134{ \ 135 hevcdsp->dst1[i][idx1][idx2] = a ## _ ## depth; \ 136} 137 138#undef EPEL_FUNCS 139#define EPEL_FUNCS(depth) \ 140 PEL_FUNC(put_hevc_epel, 0, 0, put_hevc_pel_pixels, depth); \ 141 PEL_FUNC(put_hevc_epel, 0, 1, put_hevc_epel_h, depth); \ 142 PEL_FUNC(put_hevc_epel, 1, 0, put_hevc_epel_v, depth); \ 143 PEL_FUNC(put_hevc_epel, 1, 1, put_hevc_epel_hv, depth) 144 145#undef EPEL_UNI_FUNCS 146#define EPEL_UNI_FUNCS(depth) \ 147 PEL_FUNC(put_hevc_epel_uni, 0, 0, put_hevc_pel_uni_pixels, depth); \ 148 PEL_FUNC(put_hevc_epel_uni, 0, 1, put_hevc_epel_uni_h, depth); \ 149 PEL_FUNC(put_hevc_epel_uni, 1, 0, put_hevc_epel_uni_v, depth); \ 150 PEL_FUNC(put_hevc_epel_uni, 1, 1, put_hevc_epel_uni_hv, depth); \ 151 PEL_FUNC(put_hevc_epel_uni_w, 0, 0, put_hevc_pel_uni_w_pixels, depth); \ 152 PEL_FUNC(put_hevc_epel_uni_w, 0, 1, put_hevc_epel_uni_w_h, depth); \ 153 PEL_FUNC(put_hevc_epel_uni_w, 1, 0, put_hevc_epel_uni_w_v, depth); \ 154 PEL_FUNC(put_hevc_epel_uni_w, 1, 1, put_hevc_epel_uni_w_hv, depth) 155 156#undef EPEL_BI_FUNCS 157#define EPEL_BI_FUNCS(depth) \ 158 PEL_FUNC(put_hevc_epel_bi, 0, 0, put_hevc_pel_bi_pixels, depth); \ 159 PEL_FUNC(put_hevc_epel_bi, 0, 1, put_hevc_epel_bi_h, depth); \ 160 PEL_FUNC(put_hevc_epel_bi, 1, 0, put_hevc_epel_bi_v, depth); \ 161 PEL_FUNC(put_hevc_epel_bi, 1, 1, put_hevc_epel_bi_hv, depth); \ 162 PEL_FUNC(put_hevc_epel_bi_w, 0, 0, put_hevc_pel_bi_w_pixels, depth); \ 163 PEL_FUNC(put_hevc_epel_bi_w, 0, 1, put_hevc_epel_bi_w_h, depth); \ 164 PEL_FUNC(put_hevc_epel_bi_w, 1, 0, put_hevc_epel_bi_w_v, depth); \ 165 PEL_FUNC(put_hevc_epel_bi_w, 1, 1, put_hevc_epel_bi_w_hv, depth) 166 167#undef QPEL_FUNCS 168#define QPEL_FUNCS(depth) \ 169 PEL_FUNC(put_hevc_qpel, 0, 0, put_hevc_pel_pixels, depth); \ 170 PEL_FUNC(put_hevc_qpel, 0, 1, put_hevc_qpel_h, depth); \ 171 PEL_FUNC(put_hevc_qpel, 1, 0, put_hevc_qpel_v, depth); \ 172 PEL_FUNC(put_hevc_qpel, 1, 1, put_hevc_qpel_hv, depth) 173 174#undef QPEL_UNI_FUNCS 175#define QPEL_UNI_FUNCS(depth) \ 176 PEL_FUNC(put_hevc_qpel_uni, 0, 0, put_hevc_pel_uni_pixels, depth); \ 177 PEL_FUNC(put_hevc_qpel_uni, 0, 1, put_hevc_qpel_uni_h, depth); \ 178 PEL_FUNC(put_hevc_qpel_uni, 1, 0, put_hevc_qpel_uni_v, depth); \ 179 PEL_FUNC(put_hevc_qpel_uni, 1, 1, put_hevc_qpel_uni_hv, depth); \ 180 PEL_FUNC(put_hevc_qpel_uni_w, 0, 0, put_hevc_pel_uni_w_pixels, depth); \ 181 PEL_FUNC(put_hevc_qpel_uni_w, 0, 1, put_hevc_qpel_uni_w_h, depth); \ 182 PEL_FUNC(put_hevc_qpel_uni_w, 1, 0, put_hevc_qpel_uni_w_v, depth); \ 183 PEL_FUNC(put_hevc_qpel_uni_w, 1, 1, put_hevc_qpel_uni_w_hv, depth) 184 185#undef QPEL_BI_FUNCS 186#define QPEL_BI_FUNCS(depth) \ 187 PEL_FUNC(put_hevc_qpel_bi, 0, 0, put_hevc_pel_bi_pixels, depth); \ 188 PEL_FUNC(put_hevc_qpel_bi, 0, 1, put_hevc_qpel_bi_h, depth); \ 189 PEL_FUNC(put_hevc_qpel_bi, 1, 0, put_hevc_qpel_bi_v, depth); \ 190 PEL_FUNC(put_hevc_qpel_bi, 1, 1, put_hevc_qpel_bi_hv, depth); \ 191 PEL_FUNC(put_hevc_qpel_bi_w, 0, 0, put_hevc_pel_bi_w_pixels, depth); \ 192 PEL_FUNC(put_hevc_qpel_bi_w, 0, 1, put_hevc_qpel_bi_w_h, depth); \ 193 PEL_FUNC(put_hevc_qpel_bi_w, 1, 0, put_hevc_qpel_bi_w_v, depth); \ 194 PEL_FUNC(put_hevc_qpel_bi_w, 1, 1, put_hevc_qpel_bi_w_hv, depth) 195 196#define HEVC_DSP(depth) \ 197 hevcdsp->put_pcm = FUNC(put_pcm, depth); \ 198 hevcdsp->transform_add[0] = FUNC(transform_add4x4, depth); \ 199 hevcdsp->transform_add[1] = FUNC(transform_add8x8, depth); \ 200 hevcdsp->transform_add[2] = FUNC(transform_add16x16, depth); \ 201 hevcdsp->transform_add[3] = FUNC(transform_add32x32, depth); \ 202 hevcdsp->transform_skip = FUNC(transform_skip, depth); \ 203 hevcdsp->transform_rdpcm = FUNC(transform_rdpcm, depth); \ 204 hevcdsp->idct_4x4_luma = FUNC(transform_4x4_luma, depth); \ 205 hevcdsp->idct[0] = FUNC(idct_4x4, depth); \ 206 hevcdsp->idct[1] = FUNC(idct_8x8, depth); \ 207 hevcdsp->idct[2] = FUNC(idct_16x16, depth); \ 208 hevcdsp->idct[3] = FUNC(idct_32x32, depth); \ 209 \ 210 hevcdsp->idct_dc[0] = FUNC(idct_4x4_dc, depth); \ 211 hevcdsp->idct_dc[1] = FUNC(idct_8x8_dc, depth); \ 212 hevcdsp->idct_dc[2] = FUNC(idct_16x16_dc, depth); \ 213 hevcdsp->idct_dc[3] = FUNC(idct_32x32_dc, depth); \ 214 \ 215 hevcdsp->sao_band_filter = FUNC(sao_band_filter_0, depth); \ 216 hevcdsp->sao_edge_filter[0] = FUNC(sao_edge_filter_0, depth); \ 217 hevcdsp->sao_edge_filter[1] = FUNC(sao_edge_filter_1, depth); \ 218 \ 219 QPEL_FUNCS(depth); \ 220 QPEL_UNI_FUNCS(depth); \ 221 QPEL_BI_FUNCS(depth); \ 222 EPEL_FUNCS(depth); \ 223 EPEL_UNI_FUNCS(depth); \ 224 EPEL_BI_FUNCS(depth); \ 225 \ 226 hevcdsp->hevc_h_loop_filter_luma = FUNC(hevc_h_loop_filter_luma, depth); \ 227 hevcdsp->hevc_v_loop_filter_luma = FUNC(hevc_v_loop_filter_luma, depth); \ 228 hevcdsp->hevc_h_loop_filter_chroma = FUNC(hevc_h_loop_filter_chroma, depth); \ 229 hevcdsp->hevc_v_loop_filter_chroma = FUNC(hevc_v_loop_filter_chroma, depth); \ 230 hevcdsp->hevc_h_loop_filter_luma_c = FUNC(hevc_h_loop_filter_luma, depth); \ 231 hevcdsp->hevc_v_loop_filter_luma_c = FUNC(hevc_v_loop_filter_luma, depth); \ 232 hevcdsp->hevc_h_loop_filter_chroma_c = FUNC(hevc_h_loop_filter_chroma, depth); \ 233 hevcdsp->hevc_v_loop_filter_chroma_c = FUNC(hevc_v_loop_filter_chroma, depth) 234int i = 0; 235 236 switch (bit_depth) { 237 case 9: 238 HEVC_DSP(9); 239 break; 240 case 10: 241 HEVC_DSP(10); 242 break; 243 case 12: 244 HEVC_DSP(12); 245 break; 246 default: 247 HEVC_DSP(8); 248 break; 249 } 250 if (ARCH_X86) ff_hevcdsp_init_x86(hevcdsp, bit_depth); 251} 252