X-Git-Url: https://git.sesse.net/?a=blobdiff_plain;f=libavcodec%2Fdsputil.h;h=f48aa96017d2cf7017fd831967e3f3e278445eba;hb=4e13e50432bd1c1a89f626f8196b55a0302c8f19;hp=74831cf41be2addbdc68e99af43edfa6e3975adf;hpb=5ce5dbc5f3d0bce1f8d76fea1907c91469ebdd01;p=ffmpeg diff --git a/libavcodec/dsputil.h b/libavcodec/dsputil.h index 74831cf41be..f48aa96017d 100644 --- a/libavcodec/dsputil.h +++ b/libavcodec/dsputil.h @@ -3,20 +3,20 @@ * Copyright (c) 2000, 2001, 2002 Fabrice Bellard * Copyright (c) 2002-2004 Michael Niedermayer * - * This file is part of FFmpeg. + * This file is part of Libav. * - * FFmpeg is free software; you can redistribute it and/or + * Libav 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. * - * FFmpeg is distributed in the hope that it will be useful, + * Libav 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 FFmpeg; if not, write to the Free Software + * License along with Libav; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ @@ -38,39 +38,41 @@ /* dct code */ typedef short DCTELEM; -void fdct_ifast (DCTELEM *data); -void fdct_ifast248 (DCTELEM *data); -void ff_jpeg_fdct_islow (DCTELEM *data); -void ff_fdct248_islow (DCTELEM *data); +void ff_fdct_ifast (DCTELEM *data); +void ff_fdct_ifast248 (DCTELEM *data); +void ff_jpeg_fdct_islow_8(DCTELEM *data); +void ff_jpeg_fdct_islow_10(DCTELEM *data); +void ff_fdct248_islow_8(DCTELEM *data); +void ff_fdct248_islow_10(DCTELEM *data); -void j_rev_dct (DCTELEM *data); -void j_rev_dct4 (DCTELEM *data); -void j_rev_dct2 (DCTELEM *data); -void j_rev_dct1 (DCTELEM *data); +void ff_j_rev_dct (DCTELEM *data); void ff_wmv2_idct_c(DCTELEM *data); void ff_fdct_mmx(DCTELEM *block); -void ff_fdct_mmx2(DCTELEM *block); +void ff_fdct_mmxext(DCTELEM *block); void ff_fdct_sse2(DCTELEM *block); -void ff_h264_idct8_add_c(uint8_t *dst, DCTELEM *block, int stride); -void ff_h264_idct_add_c(uint8_t *dst, DCTELEM *block, int stride); -void ff_h264_idct8_dc_add_c(uint8_t *dst, DCTELEM *block, int stride); -void ff_h264_idct_dc_add_c(uint8_t *dst, DCTELEM *block, int stride); -void ff_h264_lowres_idct_add_c(uint8_t *dst, int stride, DCTELEM *block); -void ff_h264_lowres_idct_put_c(uint8_t *dst, int stride, DCTELEM *block); -void ff_h264_idct_add16_c(uint8_t *dst, const int *blockoffset, DCTELEM *block, int stride, const uint8_t nnzc[6*8]); -void ff_h264_idct_add16intra_c(uint8_t *dst, const int *blockoffset, DCTELEM *block, int stride, const uint8_t nnzc[6*8]); -void ff_h264_idct8_add4_c(uint8_t *dst, const int *blockoffset, DCTELEM *block, int stride, const uint8_t nnzc[6*8]); -void ff_h264_idct_add8_c(uint8_t **dest, const int *blockoffset, DCTELEM *block, int stride, const uint8_t nnzc[6*8]); - -void ff_h264_luma_dc_dequant_idct_c(DCTELEM *output, DCTELEM *input, int qmul); +#define H264_IDCT(depth) \ +void ff_h264_idct8_add_ ## depth ## _c(uint8_t *dst, DCTELEM *block, int stride);\ +void ff_h264_idct_add_ ## depth ## _c(uint8_t *dst, DCTELEM *block, int stride);\ +void ff_h264_idct8_dc_add_ ## depth ## _c(uint8_t *dst, DCTELEM *block, int stride);\ +void ff_h264_idct_dc_add_ ## depth ## _c(uint8_t *dst, DCTELEM *block, int stride);\ +void ff_h264_idct_add16_ ## depth ## _c(uint8_t *dst, const int *blockoffset, DCTELEM *block, int stride, const uint8_t nnzc[6*8]);\ +void ff_h264_idct_add16intra_ ## depth ## _c(uint8_t *dst, const int *blockoffset, DCTELEM *block, int stride, const uint8_t nnzc[6*8]);\ +void ff_h264_idct8_add4_ ## depth ## _c(uint8_t *dst, const int *blockoffset, DCTELEM *block, int stride, const uint8_t nnzc[6*8]);\ +void ff_h264_idct_add8_422_ ## depth ## _c(uint8_t **dest, const int *blockoffset, DCTELEM *block, int stride, const uint8_t nnzc[6*8]);\ +void ff_h264_idct_add8_ ## depth ## _c(uint8_t **dest, const int *blockoffset, DCTELEM *block, int stride, const uint8_t nnzc[6*8]);\ +void ff_h264_luma_dc_dequant_idct_ ## depth ## _c(DCTELEM *output, DCTELEM *input, int qmul);\ +void ff_h264_chroma422_dc_dequant_idct_ ## depth ## _c(DCTELEM *block, int qmul);\ +void ff_h264_chroma_dc_dequant_idct_ ## depth ## _c(DCTELEM *block, int qmul); + +H264_IDCT( 8) +H264_IDCT( 9) +H264_IDCT(10) + void ff_svq3_luma_dc_dequant_idct_c(DCTELEM *output, DCTELEM *input, int qp); void ff_svq3_add_idct_c(uint8_t *dst, DCTELEM *block, int stride, int qp, int dc); -void ff_vector_fmul_window_c(float *dst, const float *src0, const float *src1, - const float *win, float add_bias, int len); - /* encoding scans */ extern const uint8_t ff_alternate_horizontal_scan[64]; extern const uint8_t ff_alternate_vertical_scan[64]; @@ -84,37 +86,28 @@ extern const uint8_t ff_zigzag248_direct[64]; extern uint32_t ff_squareTbl[512]; extern uint8_t ff_cropTbl[256 + 2 * MAX_NEG_CROP]; -void ff_put_pixels8x8_c(uint8_t *dst, uint8_t *src, int stride); -void ff_avg_pixels8x8_c(uint8_t *dst, uint8_t *src, int stride); -void ff_put_pixels16x16_c(uint8_t *dst, uint8_t *src, int stride); -void ff_avg_pixels16x16_c(uint8_t *dst, uint8_t *src, int stride); +#define PUTAVG_PIXELS(depth)\ +void ff_put_pixels8x8_ ## depth ## _c(uint8_t *dst, uint8_t *src, int stride);\ +void ff_avg_pixels8x8_ ## depth ## _c(uint8_t *dst, uint8_t *src, int stride);\ +void ff_put_pixels16x16_ ## depth ## _c(uint8_t *dst, uint8_t *src, int stride);\ +void ff_avg_pixels16x16_ ## depth ## _c(uint8_t *dst, uint8_t *src, int stride); -/* VP3 DSP functions */ -void ff_vp3_idct_c(DCTELEM *block/* align 16*/); -void ff_vp3_idct_put_c(uint8_t *dest/*align 8*/, int line_size, DCTELEM *block/*align 16*/); -void ff_vp3_idct_add_c(uint8_t *dest/*align 8*/, int line_size, DCTELEM *block/*align 16*/); -void ff_vp3_idct_dc_add_c(uint8_t *dest/*align 8*/, int line_size, const DCTELEM *block/*align 16*/); +PUTAVG_PIXELS( 8) +PUTAVG_PIXELS( 9) +PUTAVG_PIXELS(10) -void ff_vp3_v_loop_filter_c(uint8_t *src, int stride, int *bounding_values); -void ff_vp3_h_loop_filter_c(uint8_t *src, int stride, int *bounding_values); +#define ff_put_pixels8x8_c ff_put_pixels8x8_8_c +#define ff_avg_pixels8x8_c ff_avg_pixels8x8_8_c +#define ff_put_pixels16x16_c ff_put_pixels16x16_8_c +#define ff_avg_pixels16x16_c ff_avg_pixels16x16_8_c -/* Bink functions */ -void ff_bink_idct_c (DCTELEM *block); -void ff_bink_idct_add_c(uint8_t *dest, int linesize, DCTELEM *block); -void ff_bink_idct_put_c(uint8_t *dest, int linesize, DCTELEM *block); - -/* EA functions */ -void ff_ea_idct_put_c(uint8_t *dest, int linesize, DCTELEM *block); +/* RV40 functions */ +void ff_put_rv40_qpel16_mc33_c(uint8_t *dst, uint8_t *src, int stride); +void ff_avg_rv40_qpel16_mc33_c(uint8_t *dst, uint8_t *src, int stride); +void ff_put_rv40_qpel8_mc33_c(uint8_t *dst, uint8_t *src, int stride); +void ff_avg_rv40_qpel8_mc33_c(uint8_t *dst, uint8_t *src, int stride); /* 1/2^n downscaling functions from imgconvert.c */ -#if LIBAVCODEC_VERSION_MAJOR < 53 -/** - * @deprecated Use av_image_copy_plane() instead. - */ -attribute_deprecated -void ff_img_copy_plane(uint8_t *dst, int dst_wrap, const uint8_t *src, int src_wrap, int width, int height); -#endif - void ff_shrink22(uint8_t *dst, int dst_wrap, const uint8_t *src, int src_wrap, int width, int height); void ff_shrink44(uint8_t *dst, int dst_wrap, const uint8_t *src, int src_wrap, int width, int height); void ff_shrink88(uint8_t *dst, int dst_wrap, const uint8_t *src, int src_wrap, int width, int height); @@ -125,7 +118,7 @@ void ff_gmc_c(uint8_t *dst, uint8_t *src, int stride, int h, int ox, int oy, /* minimum alignment rules ;) If you notice errors in the align stuff, need more alignment for some ASM code for some CPU or need to use a function with less aligned data then send a mail -to the ffmpeg-devel mailing list, ... +to the libav-devel mailing list, ... !warning These alignments might not match reality, (missing attribute((align)) stuff somewhere possible). @@ -145,7 +138,7 @@ void clear_blocks_c(DCTELEM *blocks); /* add and put pixel (decoding) */ // blocksizes for op_pixels_func are 8x4,8x8 16x8 16x16 -//h for op_pixels_func is limited to {width/2, width} but never larger than 16 and never smaller then 4 +//h for op_pixels_func is limited to {width/2, width} but never larger than 16 and never smaller than 4 typedef void (*op_pixels_func)(uint8_t *block/*align width (8 or 16)*/, const uint8_t *pixels/*align 1*/, int line_size, int h); typedef void (*tpel_mc_func)(uint8_t *block/*align width (8 or 16)*/, const uint8_t *pixels/*align 1*/, int line_size, int w, int h); typedef void (*qpel_mc_func)(uint8_t *dst/*align width (8 or 16)*/, uint8_t *src/*align 1*/, int stride); @@ -178,7 +171,7 @@ static void a(uint8_t *block, const uint8_t *pixels, int line_size, int h){\ } /* motion estimation */ -// h is limited to {width/2, width, 2*width} but never larger than 16 and never smaller then 2 +// h is limited to {width/2, width, 2*width} but never larger than 16 and never smaller than 2 // although currently h<4 is not used as functions with width <8 are neither used nor implemented typedef int (*me_cmp_func)(void /*MpegEncContext*/ *s, uint8_t *blk1/*align width (8 or 16)*/, uint8_t *blk2/*align 1*/, int line_size, int h)/* __attribute__ ((const))*/; @@ -189,32 +182,54 @@ typedef struct ScanTable{ const uint8_t *scantable; uint8_t permutated[64]; uint8_t raster_end[64]; -#if ARCH_PPC - /** Used by dct_quantize_altivec to find last-non-zero */ - DECLARE_ALIGNED(16, uint8_t, inverse)[64]; -#endif } ScanTable; void ff_init_scantable(uint8_t *, ScanTable *st, const uint8_t *src_scantable); +void ff_init_scantable_permutation(uint8_t *idct_permutation, + int idct_permutation_type); -void ff_emulated_edge_mc(uint8_t *buf, const uint8_t *src, int linesize, - int block_w, int block_h, +#define EMULATED_EDGE(depth) \ +void ff_emulated_edge_mc_ ## depth (uint8_t *buf, const uint8_t *src, int linesize,\ + int block_w, int block_h,\ int src_x, int src_y, int w, int h); +EMULATED_EDGE(8) +EMULATED_EDGE(9) +EMULATED_EDGE(10) + /** * DSPContext. */ typedef struct DSPContext { + /** + * Size of DCT coefficients. + */ + int dct_bits; + /* pixel ops : interface with DCT */ void (*get_pixels)(DCTELEM *block/*align 16*/, const uint8_t *pixels/*align 8*/, int line_size); void (*diff_pixels)(DCTELEM *block/*align 16*/, const uint8_t *s1/*align 8*/, const uint8_t *s2/*align 8*/, int stride); void (*put_pixels_clamped)(const DCTELEM *block/*align 16*/, uint8_t *pixels/*align 8*/, int line_size); void (*put_signed_pixels_clamped)(const DCTELEM *block/*align 16*/, uint8_t *pixels/*align 8*/, int line_size); - void (*put_pixels_nonclamped)(const DCTELEM *block/*align 16*/, uint8_t *pixels/*align 8*/, int line_size); void (*add_pixels_clamped)(const DCTELEM *block/*align 16*/, uint8_t *pixels/*align 8*/, int line_size); void (*add_pixels8)(uint8_t *pixels, DCTELEM *block, int line_size); void (*add_pixels4)(uint8_t *pixels, DCTELEM *block, int line_size); int (*sum_abs_dctelem)(DCTELEM *block/*align 16*/); + /** + * Motion estimation with emulated edge values. + * @param buf pointer to destination buffer (unaligned) + * @param src pointer to pixel source (unaligned) + * @param linesize width (in pixels) for src/buf + * @param block_w number of pixels (per row) to copy to buf + * @param block_h nummber of pixel rows to copy to buf + * @param src_x offset of src to start of row - this may be negative + * @param src_y offset of src to top of image - this may be negative + * @param w width of src in pixels + * @param h height of src in pixels + */ + void (*emulated_edge_mc)(uint8_t *buf, const uint8_t *src, int linesize, + int block_w, int block_h, + int src_x, int src_y, int w, int h); /** * translational global motion compensation. */ @@ -329,9 +344,6 @@ typedef struct DSPContext { */ h264_chroma_mc_func put_h264_chroma_pixels_tab[3]; h264_chroma_mc_func avg_h264_chroma_pixels_tab[3]; - /* This is really one func used in VC-1 decoding */ - h264_chroma_mc_func put_no_rnd_vc1_chroma_pixels_tab[3]; - h264_chroma_mc_func avg_no_rnd_vc1_chroma_pixels_tab[3]; qpel_mc_func put_h264_qpel_pixels_tab[4][16]; qpel_mc_func avg_h264_qpel_pixels_tab[4][16]; @@ -343,7 +355,6 @@ typedef struct DSPContext { /* huffyuv specific */ void (*add_bytes)(uint8_t *dst/*align 16*/, uint8_t *src/*align 16*/, int w); - void (*add_bytes_l2)(uint8_t *dst/*align 16*/, uint8_t *src1/*align 16*/, uint8_t *src2/*align 16*/, int w); void (*diff_bytes)(uint8_t *dst/*align 16*/, uint8_t *src1/*align 16*/, uint8_t *src2/*align 1*/,int w); /** * subtract huffyuv's variant of median prediction @@ -353,34 +364,23 @@ typedef struct DSPContext { void (*add_hfyu_median_prediction)(uint8_t *dst, const uint8_t *top, const uint8_t *diff, int w, int *left, int *left_top); int (*add_hfyu_left_prediction)(uint8_t *dst, const uint8_t *src, int w, int left); void (*add_hfyu_left_prediction_bgr32)(uint8_t *dst, const uint8_t *src, int w, int *red, int *green, int *blue, int *alpha); - /* this might write to dst[w] */ - void (*add_png_paeth_prediction)(uint8_t *dst, uint8_t *src, uint8_t *top, int w, int bpp); void (*bswap_buf)(uint32_t *dst, const uint32_t *src, int w); + void (*bswap16_buf)(uint16_t *dst, const uint16_t *src, int len); void (*h263_v_loop_filter)(uint8_t *src, int stride, int qscale); void (*h263_h_loop_filter)(uint8_t *src, int stride, int qscale); void (*h261_loop_filter)(uint8_t *src, int stride); - void (*x8_v_loop_filter)(uint8_t *src, int stride, int qscale); - void (*x8_h_loop_filter)(uint8_t *src, int stride, int qscale); - - void (*vp3_idct_dc_add)(uint8_t *dest/*align 8*/, int line_size, const DCTELEM *block/*align 16*/); - void (*vp3_v_loop_filter)(uint8_t *src, int stride, int *bounding_values); - void (*vp3_h_loop_filter)(uint8_t *src, int stride, int *bounding_values); - /* assume len is a multiple of 4, and arrays are 16-byte aligned */ void (*vorbis_inverse_coupling)(float *mag, float *ang, int blocksize); - void (*ac3_downmix)(float (*samples)[256], float (*matrix)[2], int out_ch, int in_ch, int len); - /* assume len is a multiple of 8, and arrays are 16-byte aligned */ - void (*vector_fmul)(float *dst, const float *src0, const float *src1, int len); + /* assume len is a multiple of 16, and arrays are 32-byte aligned */ void (*vector_fmul_reverse)(float *dst, const float *src0, const float *src1, int len); /* assume len is a multiple of 8, and src arrays are 16-byte aligned */ void (*vector_fmul_add)(float *dst, const float *src0, const float *src1, const float *src2, int len); /* assume len is a multiple of 4, and arrays are 16-byte aligned */ - void (*vector_fmul_window)(float *dst, const float *src0, const float *src1, const float *win, float add_bias, int len); + void (*vector_fmul_window)(float *dst, const float *src0, const float *src1, const float *win, int len); /* assume len is a multiple of 8, and arrays are 16-byte aligned */ - void (*int32_to_float_fmul_scalar)(float *dst, const int *src, float mul, int len); void (*vector_clipf)(float *dst /* align 16 */, const float *src /* align 16 */, float min, float max, int len /* align 16 */); /** * Multiply a vector of floats by a scalar float. Source and @@ -392,32 +392,6 @@ typedef struct DSPContext { */ void (*vector_fmul_scalar)(float *dst, const float *src, float mul, int len); - /** - * Multiply a vector of floats by concatenated short vectors of - * floats and by a scalar float. Source and destination vectors - * must overlap exactly or not at all. - * [0]: short vectors of length 2, 8-byte aligned - * [1]: short vectors of length 4, 16-byte aligned - * @param dst output vector, 16-byte aligned - * @param src input vector, 16-byte aligned - * @param sv array of pointers to short vectors - * @param mul scalar value - * @param len number of elements in src and dst, multiple of 4 - */ - void (*vector_fmul_sv_scalar[2])(float *dst, const float *src, - const float **sv, float mul, int len); - /** - * Multiply short vectors of floats by a scalar float, store - * concatenated result. - * [0]: short vectors of length 2, 8-byte aligned - * [1]: short vectors of length 4, 16-byte aligned - * @param dst output vector, 16-byte aligned - * @param sv array of pointers to short vectors - * @param mul scalar value - * @param len number of output elements, multiple of 4 - */ - void (*sv_fmul_scalar[2])(float *dst, const float **sv, - float mul, int len); /** * Calculate the scalar product of two vectors of floats. * @param v1 first vector, 16-byte aligned @@ -433,9 +407,22 @@ typedef struct DSPContext { */ void (*butterflies_float)(float *restrict v1, float *restrict v2, int len); - /* convert floats from [-32768.0,32767.0] without rescaling and arrays are 16byte aligned */ - void (*float_to_int16)(int16_t *dst, const float *src, long len); - void (*float_to_int16_interleave)(int16_t *dst, const float **src, long len, int channels); + /** + * Calculate the sum and difference of two vectors of floats and interleave + * results into a separate output vector of floats, with each sum + * positioned before the corresponding difference. + * + * @param dst output vector + * constraints: 16-byte aligned + * @param src0 first input vector + * constraints: 32-byte aligned + * @param src1 second input vector + * constraints: 32-byte aligned + * @param len number of elements in the input + * constraints: multiple of 8 + */ + void (*butterflies_float_interleave)(float *dst, const float *src0, + const float *src1, int len); /* (I)DCT */ void (*fdct)(DCTELEM *block/* align 16*/); @@ -465,8 +452,8 @@ typedef struct DSPContext { * with the zigzag/alternate scan
* an example to avoid confusion: * - (->decode coeffs -> zigzag reorder -> dequant -> reference idct ->...) - * - (x -> referece dct -> reference idct -> x) - * - (x -> referece dct -> simple_mmx_perm = idct_permutation -> simple_idct_mmx -> x) + * - (x -> reference dct -> reference idct -> x) + * - (x -> reference dct -> simple_mmx_perm = idct_permutation -> simple_idct_mmx -> x) * - (->decode coeffs -> zigzag reorder -> simple_mmx_perm -> dequant -> simple_idct_mmx ->...) */ uint8_t idct_permutation[64]; @@ -483,53 +470,20 @@ typedef struct DSPContext { #define BASIS_SHIFT 16 #define RECON_SHIFT 6 - void (*draw_edges)(uint8_t *buf, int wrap, int width, int height, int w); + void (*draw_edges)(uint8_t *buf, int wrap, int width, int height, int w, int h, int sides); #define EDGE_WIDTH 16 +#define EDGE_TOP 1 +#define EDGE_BOTTOM 2 void (*prefetch)(void *mem, int stride, int h); void (*shrink[4])(uint8_t *dst, int dst_wrap, const uint8_t *src, int src_wrap, int width, int height); - /* mlp/truehd functions */ - void (*mlp_filter_channel)(int32_t *state, const int32_t *coeff, - int firorder, int iirorder, - unsigned int filter_shift, int32_t mask, int blocksize, - int32_t *sample_buffer); - - /* vc1 functions */ - void (*vc1_inv_trans_8x8)(DCTELEM *b); - void (*vc1_inv_trans_8x4)(uint8_t *dest, int line_size, DCTELEM *block); - void (*vc1_inv_trans_4x8)(uint8_t *dest, int line_size, DCTELEM *block); - void (*vc1_inv_trans_4x4)(uint8_t *dest, int line_size, DCTELEM *block); - void (*vc1_inv_trans_8x8_dc)(uint8_t *dest, int line_size, DCTELEM *block); - void (*vc1_inv_trans_8x4_dc)(uint8_t *dest, int line_size, DCTELEM *block); - void (*vc1_inv_trans_4x8_dc)(uint8_t *dest, int line_size, DCTELEM *block); - void (*vc1_inv_trans_4x4_dc)(uint8_t *dest, int line_size, DCTELEM *block); - void (*vc1_v_overlap)(uint8_t* src, int stride); - void (*vc1_h_overlap)(uint8_t* src, int stride); - void (*vc1_v_loop_filter4)(uint8_t *src, int stride, int pq); - void (*vc1_h_loop_filter4)(uint8_t *src, int stride, int pq); - void (*vc1_v_loop_filter8)(uint8_t *src, int stride, int pq); - void (*vc1_h_loop_filter8)(uint8_t *src, int stride, int pq); - void (*vc1_v_loop_filter16)(uint8_t *src, int stride, int pq); - void (*vc1_h_loop_filter16)(uint8_t *src, int stride, int pq); - /* put 8x8 block with bicubic interpolation and quarterpel precision - * last argument is actually round value instead of height - */ - op_pixels_func put_vc1_mspel_pixels_tab[16]; - op_pixels_func avg_vc1_mspel_pixels_tab[16]; - - /* intrax8 functions */ - void (*x8_spatial_compensation[12])(uint8_t *src , uint8_t *dst, int linesize); - void (*x8_setup_spatial_compensation)(uint8_t *src, uint8_t *dst, int linesize, - int * range, int * sum, int edges); - /** * Calculate scalar product of two vectors. * @param len length of vectors, should be multiple of 16 - * @param shift number of bits to discard from product */ - int32_t (*scalarproduct_int16)(const int16_t *v1, const int16_t *v2/*align 16*/, int len, int shift); + int32_t (*scalarproduct_int16)(const int16_t *v1, const int16_t *v2/*align 16*/, int len); /* ape functions */ /** * Calculate scalar product of v1 and v2, @@ -538,26 +492,55 @@ typedef struct DSPContext { */ int32_t (*scalarproduct_and_madd_int16)(int16_t *v1/*align 16*/, const int16_t *v2, const int16_t *v3, int len, int mul); - /* rv30 functions */ - qpel_mc_func put_rv30_tpel_pixels_tab[4][16]; - qpel_mc_func avg_rv30_tpel_pixels_tab[4][16]; + /** + * Apply symmetric window in 16-bit fixed-point. + * @param output destination array + * constraints: 16-byte aligned + * @param input source array + * constraints: 16-byte aligned + * @param window window array + * constraints: 16-byte aligned, at least len/2 elements + * @param len full window length + * constraints: multiple of ? greater than zero + */ + void (*apply_window_int16)(int16_t *output, const int16_t *input, + const int16_t *window, unsigned int len); - /* rv40 functions */ - qpel_mc_func put_rv40_qpel_pixels_tab[4][16]; - qpel_mc_func avg_rv40_qpel_pixels_tab[4][16]; - h264_chroma_mc_func put_rv40_chroma_pixels_tab[3]; - h264_chroma_mc_func avg_rv40_chroma_pixels_tab[3]; + /** + * Clip each element in an array of int32_t to a given minimum and maximum value. + * @param dst destination array + * constraints: 16-byte aligned + * @param src source array + * constraints: 16-byte aligned + * @param min minimum value + * constraints: must be in the range [-(1 << 24), 1 << 24] + * @param max maximum value + * constraints: must be in the range [-(1 << 24), 1 << 24] + * @param len number of elements in the array + * constraints: multiple of 32 greater than zero + */ + void (*vector_clip_int32)(int32_t *dst, const int32_t *src, int32_t min, + int32_t max, unsigned int len); - /* bink functions */ op_fill_func fill_block_tab[2]; - void (*scale_block)(const uint8_t src[64]/*align 8*/, uint8_t *dst/*align 8*/, int linesize); } DSPContext; -void dsputil_static_init(void); -void dsputil_init(DSPContext* p, AVCodecContext *avctx); +void ff_dsputil_static_init(void); +void ff_dsputil_init(DSPContext* p, AVCodecContext *avctx); int ff_check_alignment(void); +/** + * Return the scalar product of two vectors. + * + * @param v1 first input vector + * @param v2 first input vector + * @param len number of elements + * + * @return sum of elementwise products + */ +float ff_scalarproduct_float_c(const float *v1, const float *v2, int len); + /** * permute block according to permuatation. * @param last last non zero element in scantable order @@ -567,6 +550,7 @@ void ff_block_permute(DCTELEM *block, uint8_t *permutation, const uint8_t *scant void ff_set_cmp(DSPContext* c, me_cmp_func *cmp, int type); #define BYTE_VEC32(c) ((c)*0x01010101UL) +#define BYTE_VEC64(c) ((c)*0x0001000100010001UL) static inline uint32_t rnd_avg32(uint32_t a, uint32_t b) { @@ -578,6 +562,16 @@ static inline uint32_t no_rnd_avg32(uint32_t a, uint32_t b) return (a & b) + (((a ^ b) & ~BYTE_VEC32(0x01)) >> 1); } +static inline uint64_t rnd_avg64(uint64_t a, uint64_t b) +{ + return (a | b) - (((a ^ b) & ~BYTE_VEC64(0x01)) >> 1); +} + +static inline uint64_t no_rnd_avg64(uint64_t a, uint64_t b) +{ + return (a & b) + (((a ^ b) & ~BYTE_VEC64(0x01)) >> 1); +} + static inline int get_penalty_factor(int lambda, int lambda2, int type){ switch(type&0xFF){ default: @@ -602,87 +596,46 @@ static inline int get_penalty_factor(int lambda, int lambda2, int type){ } } -/** - * Empty mmx state. - * this must be called between any dsp function and float/double code. - * for example sin(); dsp->idct_put(); emms_c(); cos() - */ -#define emms_c() - -void dsputil_init_alpha(DSPContext* c, AVCodecContext *avctx); -void dsputil_init_arm(DSPContext* c, AVCodecContext *avctx); -void dsputil_init_bfin(DSPContext* c, AVCodecContext *avctx); -void dsputil_init_mlib(DSPContext* c, AVCodecContext *avctx); -void dsputil_init_mmi(DSPContext* c, AVCodecContext *avctx); -void dsputil_init_mmx(DSPContext* c, AVCodecContext *avctx); -void dsputil_init_ppc(DSPContext* c, AVCodecContext *avctx); -void dsputil_init_sh4(DSPContext* c, AVCodecContext *avctx); -void dsputil_init_vis(DSPContext* c, AVCodecContext *avctx); +void ff_dsputil_init_alpha(DSPContext* c, AVCodecContext *avctx); +void ff_dsputil_init_arm(DSPContext* c, AVCodecContext *avctx); +void ff_dsputil_init_bfin(DSPContext* c, AVCodecContext *avctx); +void ff_dsputil_init_mmx(DSPContext* c, AVCodecContext *avctx); +void ff_dsputil_init_ppc(DSPContext* c, AVCodecContext *avctx); +void ff_dsputil_init_sh4(DSPContext* c, AVCodecContext *avctx); +void ff_dsputil_init_vis(DSPContext* c, AVCodecContext *avctx); void ff_dsputil_init_dwt(DSPContext *c); -void ff_rv30dsp_init(DSPContext* c, AVCodecContext *avctx); -void ff_rv40dsp_init(DSPContext* c, AVCodecContext *avctx); -void ff_vc1dsp_init(DSPContext* c, AVCodecContext *avctx); -void ff_intrax8dsp_init(DSPContext* c, AVCodecContext *avctx); -void ff_mlp_init(DSPContext* c, AVCodecContext *avctx); -void ff_mlp_init_x86(DSPContext* c, AVCodecContext *avctx); - -#if HAVE_MMX - -#undef emms_c -static inline void emms(void) -{ - __asm__ volatile ("emms;":::"memory"); -} - -#define emms_c() emms() - -#elif ARCH_ARM - -#if HAVE_NEON +#if (ARCH_ARM && HAVE_NEON) || ARCH_PPC || HAVE_MMX # define STRIDE_ALIGN 16 -#endif - -#elif ARCH_PPC - -#define STRIDE_ALIGN 16 - -#elif HAVE_MMI - -#define STRIDE_ALIGN 16 - -#endif - -#ifndef STRIDE_ALIGN +#else # define STRIDE_ALIGN 8 #endif +// Some broken preprocessors need a second expansion +// to be forced to tokenize __VA_ARGS__ +#define E(x) x + #define LOCAL_ALIGNED_A(a, t, v, s, o, ...) \ uint8_t la_##v[sizeof(t s o) + (a)]; \ t (*v) o = (void *)FFALIGN((uintptr_t)la_##v, a) #define LOCAL_ALIGNED_D(a, t, v, s, o, ...) DECLARE_ALIGNED(a, t, v) s o -#define LOCAL_ALIGNED(a, t, v, ...) LOCAL_ALIGNED_A(a, t, v, __VA_ARGS__,,) +#define LOCAL_ALIGNED(a, t, v, ...) E(LOCAL_ALIGNED_A(a, t, v, __VA_ARGS__,,)) #if HAVE_LOCAL_ALIGNED_8 -# define LOCAL_ALIGNED_8(t, v, ...) LOCAL_ALIGNED_D(8, t, v, __VA_ARGS__,,) +# define LOCAL_ALIGNED_8(t, v, ...) E(LOCAL_ALIGNED_D(8, t, v, __VA_ARGS__,,)) #else # define LOCAL_ALIGNED_8(t, v, ...) LOCAL_ALIGNED(8, t, v, __VA_ARGS__) #endif #if HAVE_LOCAL_ALIGNED_16 -# define LOCAL_ALIGNED_16(t, v, ...) LOCAL_ALIGNED_D(16, t, v, __VA_ARGS__,,) +# define LOCAL_ALIGNED_16(t, v, ...) E(LOCAL_ALIGNED_D(16, t, v, __VA_ARGS__,,)) #else # define LOCAL_ALIGNED_16(t, v, ...) LOCAL_ALIGNED(16, t, v, __VA_ARGS__) #endif -/* PSNR */ -void get_psnr(uint8_t *orig_image[3], uint8_t *coded_image[3], - int orig_linesize[3], int coded_linesize, - AVCodecContext *avctx); - #define WRAPPER8_16(name8, name16)\ static int name16(void /*MpegEncContext*/ *s, uint8_t *dst, uint8_t *src, int stride, int h){\ return name8(s, dst , src , stride, h)\ @@ -709,7 +662,7 @@ static inline void copy_block2(uint8_t *dst, const uint8_t *src, int dstStride, int i; for(i=0; i