diff options
Diffstat (limited to 'libavcodec/hevcdsp.c')
-rw-r--r-- | libavcodec/hevcdsp.c | 214 |
1 files changed, 114 insertions, 100 deletions
diff --git a/libavcodec/hevcdsp.c b/libavcodec/hevcdsp.c index 558e938..957e40d 100644 --- a/libavcodec/hevcdsp.c +++ b/libavcodec/hevcdsp.c @@ -2,21 +2,23 @@ * HEVC video decoder * * Copyright (C) 2012 - 2013 Guillaume Martres + * Copyright (C) 2013 - 2014 Pierre-Edouard Lepere * - * This file is part of Libav. * - * Libav is free software; you can redistribute it and/or + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * - * Libav is distributed in the hope that it will be useful, + * FFmpeg 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 * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public - * License along with Libav; if not, write to the Free Software + * License along with FFmpeg; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ @@ -89,36 +91,20 @@ static const int8_t transform[32][32] = { 90, -90, 88, -85, 82, -78, 73, -67, 61, -54, 46, -38, 31, -22, 13, -4 }, }; -DECLARE_ALIGNED(16, const int16_t, ff_hevc_epel_coeffs)[7][16] = { - { -2, 58, 10, -2, -2, 58, 10, -2, -2, 58, 10, -2, -2, 58, 10, -2 }, - { -4, 54, 16, -2, -4, 54, 16, -2, -4, 54, 16, -2, -4, 54, 16, -2 }, - { -6, 46, 28, -4, -6, 46, 28, -4, -6, 46, 28, -4, -6, 46, 28, -4 }, - { -4, 36, 36, -4, -4, 36, 36, -4, -4, 36, 36, -4, -4, 36, 36, -4 }, - { -4, 28, 46, -6, -4, 28, 46, -6, -4, 28, 46, -6, -4, 28, 46, -6 }, - { -2, 16, 54, -4, -2, 16, 54, -4, -2, 16, 54, -4, -2, 16, 54, -4 }, - { -2, 10, 58, -2, -2, 10, 58, -2, -2, 10, 58, -2, -2, 10, 58, -2 }, -}; - -DECLARE_ALIGNED(16, const int8_t, ff_hevc_epel_coeffs8)[7][16] = { - { -2, 58, 10, -2, -2, 58, 10, -2, -2, 58, 10, -2, -2, 58, 10, -2 }, - { -4, 54, 16, -2, -4, 54, 16, -2, -4, 54, 16, -2, -4, 54, 16, -2 }, - { -6, 46, 28, -4, -6, 46, 28, -4, -6, 46, 28, -4, -6, 46, 28, -4 }, - { -4, 36, 36, -4, -4, 36, 36, -4, -4, 36, 36, -4, -4, 36, 36, -4 }, - { -4, 28, 46, -6, -4, 28, 46, -6, -4, 28, 46, -6, -4, 28, 46, -6 }, - { -2, 16, 54, -4, -2, 16, 54, -4, -2, 16, 54, -4, -2, 16, 54, -4 }, - { -2, 10, 58, -2, -2, 10, 58, -2, -2, 10, 58, -2, -2, 10, 58, -2 }, -}; - -DECLARE_ALIGNED(16, const int16_t, ff_hevc_qpel_coeffs)[3][8] = { - { -1, 4, -10, 58, 17, -5, 1, 0 }, - { -1, 4, -11, 40, 40, -11, 4, -1 }, - { 0, 1, -5, 17, 58, -10, 4, -1 }, +DECLARE_ALIGNED(16, const int8_t, ff_hevc_epel_filters)[7][4] = { + { -2, 58, 10, -2}, + { -4, 54, 16, -2}, + { -6, 46, 28, -4}, + { -4, 36, 36, -4}, + { -4, 28, 46, -6}, + { -2, 16, 54, -4}, + { -2, 10, 58, -2}, }; -DECLARE_ALIGNED(16, const int8_t, ff_hevc_qpel_coeffs8)[3][16] = { - { -1, 4, -10, 58, 17, -5, 1, 0, -1, 4, -10, 58, 17, -5, 1, 0 }, - { -1, 4, -11, 40, 40, -11, 4, -1, -1, 4, -11, 40, 40, -11, 4, -1 }, - { 0, 1, -5, 17, 58, -10, 4, -1, 0, 1, -5, 17, 58, -10, 4, -1 }, +DECLARE_ALIGNED(16, const int8_t, ff_hevc_qpel_filters)[3][16] = { + { -1, 4,-10, 58, 17, -5, 1, 0, -1, 4,-10, 58, 17, -5, 1, 0}, + { -1, 4,-11, 40, 40,-11, 4, -1, -1, 4,-11, 40, 40,-11, 4, -1}, + { 0, 1, -5, 17, 58,-10, 4, -1, 0, 1, -5, 17, 58,-10, 4, -1} }; #define BIT_DEPTH 8 @@ -133,34 +119,79 @@ DECLARE_ALIGNED(16, const int8_t, ff_hevc_qpel_coeffs8)[3][16] = { #include "hevcdsp_template.c" #undef BIT_DEPTH +#define BIT_DEPTH 12 +#include "hevcdsp_template.c" +#undef BIT_DEPTH + void ff_hevc_dsp_init(HEVCDSPContext *hevcdsp, int bit_depth) { #undef FUNC #define FUNC(a, depth) a ## _ ## depth -#define QPEL_FUNC(i, width, depth) \ - hevcdsp->put_hevc_qpel[0][0][i] = FUNC(put_hevc_qpel_pixels_ ## width, depth); \ - hevcdsp->put_hevc_qpel[0][1][i] = FUNC(put_hevc_qpel_h_ ## width, depth); \ - hevcdsp->put_hevc_qpel[1][0][i] = FUNC(put_hevc_qpel_v_ ## width, depth); \ - hevcdsp->put_hevc_qpel[1][1][i] = FUNC(put_hevc_qpel_hv_ ## width, depth); \ - -#define EPEL_FUNC(i, width, depth) \ - hevcdsp->put_hevc_epel[0][0][i] = FUNC(put_hevc_epel_pixels_ ## width, depth); \ - hevcdsp->put_hevc_epel[0][1][i] = FUNC(put_hevc_epel_h_ ## width, depth); \ - hevcdsp->put_hevc_epel[1][0][i] = FUNC(put_hevc_epel_v_ ## width, depth); \ - hevcdsp->put_hevc_epel[1][1][i] = FUNC(put_hevc_epel_hv_ ## width, depth); \ - -#define PRED_FUNC(i, width, depth) \ - hevcdsp->put_unweighted_pred[i] = FUNC(put_unweighted_pred_ ## width, depth); \ - hevcdsp->put_unweighted_pred_avg[i] = FUNC(put_unweighted_pred_avg_ ## width, depth); \ - hevcdsp->weighted_pred[i] = FUNC(put_weighted_pred_ ## width, depth); \ - hevcdsp->weighted_pred_avg[i] = FUNC(put_weighted_pred_avg_ ## width, depth); \ - -#define PRED_FUNC_CHROMA(i, width, depth) \ - hevcdsp->put_unweighted_pred_chroma[i] = FUNC(put_unweighted_pred_ ## width, depth); \ - hevcdsp->put_unweighted_pred_avg_chroma[i] = FUNC(put_unweighted_pred_avg_ ## width, depth); \ - hevcdsp->weighted_pred_chroma[i] = FUNC(put_weighted_pred_ ## width, depth); \ - hevcdsp->weighted_pred_avg_chroma[i] = FUNC(put_weighted_pred_avg_ ## width, depth); \ +#undef PEL_FUNC +#define PEL_FUNC(dst1, idx1, idx2, a, depth) \ + for(i = 0 ; i < 10 ; i++) \ +{ \ + hevcdsp->dst1[i][idx1][idx2] = a ## _ ## depth; \ +} + +#undef EPEL_FUNCS +#define EPEL_FUNCS(depth) \ + PEL_FUNC(put_hevc_epel, 0, 0, put_hevc_pel_pixels, depth); \ + PEL_FUNC(put_hevc_epel, 0, 1, put_hevc_epel_h, depth); \ + PEL_FUNC(put_hevc_epel, 1, 0, put_hevc_epel_v, depth); \ + PEL_FUNC(put_hevc_epel, 1, 1, put_hevc_epel_hv, depth) + +#undef EPEL_UNI_FUNCS +#define EPEL_UNI_FUNCS(depth) \ + PEL_FUNC(put_hevc_epel_uni, 0, 0, put_hevc_pel_uni_pixels, depth); \ + PEL_FUNC(put_hevc_epel_uni, 0, 1, put_hevc_epel_uni_h, depth); \ + PEL_FUNC(put_hevc_epel_uni, 1, 0, put_hevc_epel_uni_v, depth); \ + PEL_FUNC(put_hevc_epel_uni, 1, 1, put_hevc_epel_uni_hv, depth); \ + PEL_FUNC(put_hevc_epel_uni_w, 0, 0, put_hevc_pel_uni_w_pixels, depth); \ + PEL_FUNC(put_hevc_epel_uni_w, 0, 1, put_hevc_epel_uni_w_h, depth); \ + PEL_FUNC(put_hevc_epel_uni_w, 1, 0, put_hevc_epel_uni_w_v, depth); \ + PEL_FUNC(put_hevc_epel_uni_w, 1, 1, put_hevc_epel_uni_w_hv, depth) + +#undef EPEL_BI_FUNCS +#define EPEL_BI_FUNCS(depth) \ + PEL_FUNC(put_hevc_epel_bi, 0, 0, put_hevc_pel_bi_pixels, depth); \ + PEL_FUNC(put_hevc_epel_bi, 0, 1, put_hevc_epel_bi_h, depth); \ + PEL_FUNC(put_hevc_epel_bi, 1, 0, put_hevc_epel_bi_v, depth); \ + PEL_FUNC(put_hevc_epel_bi, 1, 1, put_hevc_epel_bi_hv, depth); \ + PEL_FUNC(put_hevc_epel_bi_w, 0, 0, put_hevc_pel_bi_w_pixels, depth); \ + PEL_FUNC(put_hevc_epel_bi_w, 0, 1, put_hevc_epel_bi_w_h, depth); \ + PEL_FUNC(put_hevc_epel_bi_w, 1, 0, put_hevc_epel_bi_w_v, depth); \ + PEL_FUNC(put_hevc_epel_bi_w, 1, 1, put_hevc_epel_bi_w_hv, depth) + +#undef QPEL_FUNCS +#define QPEL_FUNCS(depth) \ + PEL_FUNC(put_hevc_qpel, 0, 0, put_hevc_pel_pixels, depth); \ + PEL_FUNC(put_hevc_qpel, 0, 1, put_hevc_qpel_h, depth); \ + PEL_FUNC(put_hevc_qpel, 1, 0, put_hevc_qpel_v, depth); \ + PEL_FUNC(put_hevc_qpel, 1, 1, put_hevc_qpel_hv, depth) + +#undef QPEL_UNI_FUNCS +#define QPEL_UNI_FUNCS(depth) \ + PEL_FUNC(put_hevc_qpel_uni, 0, 0, put_hevc_pel_uni_pixels, depth); \ + PEL_FUNC(put_hevc_qpel_uni, 0, 1, put_hevc_qpel_uni_h, depth); \ + PEL_FUNC(put_hevc_qpel_uni, 1, 0, put_hevc_qpel_uni_v, depth); \ + PEL_FUNC(put_hevc_qpel_uni, 1, 1, put_hevc_qpel_uni_hv, depth); \ + PEL_FUNC(put_hevc_qpel_uni_w, 0, 0, put_hevc_pel_uni_w_pixels, depth); \ + PEL_FUNC(put_hevc_qpel_uni_w, 0, 1, put_hevc_qpel_uni_w_h, depth); \ + PEL_FUNC(put_hevc_qpel_uni_w, 1, 0, put_hevc_qpel_uni_w_v, depth); \ + PEL_FUNC(put_hevc_qpel_uni_w, 1, 1, put_hevc_qpel_uni_w_hv, depth) + +#undef QPEL_BI_FUNCS +#define QPEL_BI_FUNCS(depth) \ + PEL_FUNC(put_hevc_qpel_bi, 0, 0, put_hevc_pel_bi_pixels, depth); \ + PEL_FUNC(put_hevc_qpel_bi, 0, 1, put_hevc_qpel_bi_h, depth); \ + PEL_FUNC(put_hevc_qpel_bi, 1, 0, put_hevc_qpel_bi_v, depth); \ + PEL_FUNC(put_hevc_qpel_bi, 1, 1, put_hevc_qpel_bi_hv, depth); \ + PEL_FUNC(put_hevc_qpel_bi_w, 0, 0, put_hevc_pel_bi_w_pixels, depth); \ + PEL_FUNC(put_hevc_qpel_bi_w, 0, 1, put_hevc_qpel_bi_w_h, depth); \ + PEL_FUNC(put_hevc_qpel_bi_w, 1, 0, put_hevc_qpel_bi_w_v, depth); \ + PEL_FUNC(put_hevc_qpel_bi_w, 1, 1, put_hevc_qpel_bi_w_hv, depth) #define HEVC_DSP(depth) \ hevcdsp->put_pcm = FUNC(put_pcm, depth); \ @@ -169,6 +200,7 @@ void ff_hevc_dsp_init(HEVCDSPContext *hevcdsp, int bit_depth) hevcdsp->add_residual[2] = FUNC(add_residual16x16, depth); \ hevcdsp->add_residual[3] = FUNC(add_residual32x32, depth); \ hevcdsp->dequant = FUNC(dequant, depth); \ + hevcdsp->transform_rdpcm = FUNC(transform_rdpcm, depth); \ hevcdsp->transform_4x4_luma = FUNC(transform_4x4_luma, depth); \ hevcdsp->idct[0] = FUNC(idct_4x4, depth); \ hevcdsp->idct[1] = FUNC(idct_8x8, depth); \ @@ -179,51 +211,27 @@ void ff_hevc_dsp_init(HEVCDSPContext *hevcdsp, int bit_depth) hevcdsp->idct_dc[1] = FUNC(idct_8x8_dc, depth); \ hevcdsp->idct_dc[2] = FUNC(idct_16x16_dc, depth); \ hevcdsp->idct_dc[3] = FUNC(idct_32x32_dc, depth); \ - hevcdsp->sao_band_filter[0] = FUNC(sao_band_filter_0, depth); \ - hevcdsp->sao_band_filter[1] = FUNC(sao_band_filter_1, depth); \ - hevcdsp->sao_band_filter[2] = FUNC(sao_band_filter_2, depth); \ - hevcdsp->sao_band_filter[3] = FUNC(sao_band_filter_3, depth); \ - \ - hevcdsp->sao_edge_filter[0] = FUNC(sao_edge_filter_0, depth); \ - hevcdsp->sao_edge_filter[1] = FUNC(sao_edge_filter_1, depth); \ - hevcdsp->sao_edge_filter[2] = FUNC(sao_edge_filter_2, depth); \ - hevcdsp->sao_edge_filter[3] = FUNC(sao_edge_filter_3, depth); \ - \ - QPEL_FUNC(0, 4, depth); \ - QPEL_FUNC(1, 8, depth); \ - QPEL_FUNC(2, 12, depth); \ - QPEL_FUNC(3, 16, depth); \ - QPEL_FUNC(4, 24, depth); \ - QPEL_FUNC(5, 32, depth); \ - QPEL_FUNC(6, 48, depth); \ - QPEL_FUNC(7, 64, depth); \ - \ - EPEL_FUNC(0, 2, depth); \ - EPEL_FUNC(1, 4, depth); \ - EPEL_FUNC(2, 6, depth); \ - EPEL_FUNC(3, 8, depth); \ - EPEL_FUNC(4, 12, depth); \ - EPEL_FUNC(5, 16, depth); \ - EPEL_FUNC(6, 24, depth); \ - EPEL_FUNC(7, 32, depth); \ - \ - PRED_FUNC(0, 4, depth); \ - PRED_FUNC(1, 8, depth); \ - PRED_FUNC(2, 12, depth); \ - PRED_FUNC(3, 16, depth); \ - PRED_FUNC(4, 24, depth); \ - PRED_FUNC(5, 32, depth); \ - PRED_FUNC(6, 48, depth); \ - PRED_FUNC(7, 64, depth); \ - PRED_FUNC_CHROMA(0, 2, depth); \ - PRED_FUNC_CHROMA(1, 4, depth); \ - PRED_FUNC_CHROMA(2, 6, depth); \ - PRED_FUNC_CHROMA(3, 8, depth); \ - PRED_FUNC_CHROMA(4, 12, depth); \ - PRED_FUNC_CHROMA(5, 16, depth); \ - PRED_FUNC_CHROMA(6, 24, depth); \ - PRED_FUNC_CHROMA(7, 32, depth); \ \ + hevcdsp->sao_band_filter[0] = \ + hevcdsp->sao_band_filter[1] = \ + hevcdsp->sao_band_filter[2] = \ + hevcdsp->sao_band_filter[3] = \ + hevcdsp->sao_band_filter[4] = FUNC(sao_band_filter, depth); \ + hevcdsp->sao_edge_filter[0] = \ + hevcdsp->sao_edge_filter[1] = \ + hevcdsp->sao_edge_filter[2] = \ + hevcdsp->sao_edge_filter[3] = \ + hevcdsp->sao_edge_filter[4] = FUNC(sao_edge_filter, depth); \ + hevcdsp->sao_edge_restore[0] = FUNC(sao_edge_restore_0, depth); \ + hevcdsp->sao_edge_restore[1] = FUNC(sao_edge_restore_1, depth); \ + \ + QPEL_FUNCS(depth); \ + QPEL_UNI_FUNCS(depth); \ + QPEL_BI_FUNCS(depth); \ + EPEL_FUNCS(depth); \ + EPEL_UNI_FUNCS(depth); \ + EPEL_BI_FUNCS(depth); \ + \ hevcdsp->hevc_h_loop_filter_luma = FUNC(hevc_h_loop_filter_luma, depth); \ hevcdsp->hevc_v_loop_filter_luma = FUNC(hevc_v_loop_filter_luma, depth); \ hevcdsp->hevc_h_loop_filter_chroma = FUNC(hevc_h_loop_filter_chroma, depth); \ @@ -231,7 +239,8 @@ void ff_hevc_dsp_init(HEVCDSPContext *hevcdsp, int bit_depth) hevcdsp->hevc_h_loop_filter_luma_c = FUNC(hevc_h_loop_filter_luma, depth); \ hevcdsp->hevc_v_loop_filter_luma_c = FUNC(hevc_v_loop_filter_luma, depth); \ hevcdsp->hevc_h_loop_filter_chroma_c = FUNC(hevc_h_loop_filter_chroma, depth); \ - hevcdsp->hevc_v_loop_filter_chroma_c = FUNC(hevc_v_loop_filter_chroma, depth); + hevcdsp->hevc_v_loop_filter_chroma_c = FUNC(hevc_v_loop_filter_chroma, depth) +int i = 0; switch (bit_depth) { case 9: @@ -240,6 +249,9 @@ void ff_hevc_dsp_init(HEVCDSPContext *hevcdsp, int bit_depth) case 10: HEVC_DSP(10); break; + case 12: + HEVC_DSP(12); + break; default: HEVC_DSP(8); break; @@ -251,4 +263,6 @@ void ff_hevc_dsp_init(HEVCDSPContext *hevcdsp, int bit_depth) ff_hevc_dsp_init_ppc(hevcdsp, bit_depth); if (ARCH_X86) ff_hevc_dsp_init_x86(hevcdsp, bit_depth); + if (ARCH_MIPS) + ff_hevc_dsp_init_mips(hevcdsp, bit_depth); } |