Libav
|
00001 /* 00002 * DSP utils 00003 * Copyright (c) 2000, 2001, 2002 Fabrice Bellard 00004 * Copyright (c) 2002-2004 Michael Niedermayer <michaelni@gmx.at> 00005 * 00006 * This file is part of FFmpeg. 00007 * 00008 * FFmpeg is free software; you can redistribute it and/or 00009 * modify it under the terms of the GNU Lesser General Public 00010 * License as published by the Free Software Foundation; either 00011 * version 2.1 of the License, or (at your option) any later version. 00012 * 00013 * FFmpeg is distributed in the hope that it will be useful, 00014 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00015 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 00016 * Lesser General Public License for more details. 00017 * 00018 * You should have received a copy of the GNU Lesser General Public 00019 * License along with FFmpeg; if not, write to the Free Software 00020 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 00021 */ 00022 00030 #ifndef AVCODEC_DSPUTIL_H 00031 #define AVCODEC_DSPUTIL_H 00032 00033 #include "libavutil/intreadwrite.h" 00034 #include "avcodec.h" 00035 00036 00037 //#define DEBUG 00038 /* dct code */ 00039 typedef short DCTELEM; 00040 00041 void fdct_ifast (DCTELEM *data); 00042 void fdct_ifast248 (DCTELEM *data); 00043 void ff_jpeg_fdct_islow (DCTELEM *data); 00044 void ff_fdct248_islow (DCTELEM *data); 00045 00046 void j_rev_dct (DCTELEM *data); 00047 void j_rev_dct4 (DCTELEM *data); 00048 void j_rev_dct2 (DCTELEM *data); 00049 void j_rev_dct1 (DCTELEM *data); 00050 void ff_wmv2_idct_c(DCTELEM *data); 00051 00052 void ff_fdct_mmx(DCTELEM *block); 00053 void ff_fdct_mmx2(DCTELEM *block); 00054 void ff_fdct_sse2(DCTELEM *block); 00055 00056 void ff_h264_idct8_add_c(uint8_t *dst, DCTELEM *block, int stride); 00057 void ff_h264_idct_add_c(uint8_t *dst, DCTELEM *block, int stride); 00058 void ff_h264_idct8_dc_add_c(uint8_t *dst, DCTELEM *block, int stride); 00059 void ff_h264_idct_dc_add_c(uint8_t *dst, DCTELEM *block, int stride); 00060 void ff_h264_lowres_idct_add_c(uint8_t *dst, int stride, DCTELEM *block); 00061 void ff_h264_lowres_idct_put_c(uint8_t *dst, int stride, DCTELEM *block); 00062 void ff_h264_idct_add16_c(uint8_t *dst, const int *blockoffset, DCTELEM *block, int stride, const uint8_t nnzc[6*8]); 00063 void ff_h264_idct_add16intra_c(uint8_t *dst, const int *blockoffset, DCTELEM *block, int stride, const uint8_t nnzc[6*8]); 00064 void ff_h264_idct8_add4_c(uint8_t *dst, const int *blockoffset, DCTELEM *block, int stride, const uint8_t nnzc[6*8]); 00065 void ff_h264_idct_add8_c(uint8_t **dest, const int *blockoffset, DCTELEM *block, int stride, const uint8_t nnzc[6*8]); 00066 00067 void ff_vector_fmul_window_c(float *dst, const float *src0, const float *src1, 00068 const float *win, float add_bias, int len); 00069 void ff_float_to_int16_c(int16_t *dst, const float *src, long len); 00070 void ff_float_to_int16_interleave_c(int16_t *dst, const float **src, long len, int channels); 00071 00072 /* encoding scans */ 00073 extern const uint8_t ff_alternate_horizontal_scan[64]; 00074 extern const uint8_t ff_alternate_vertical_scan[64]; 00075 extern const uint8_t ff_zigzag_direct[64]; 00076 extern const uint8_t ff_zigzag248_direct[64]; 00077 00078 /* pixel operations */ 00079 #define MAX_NEG_CROP 1024 00080 00081 /* temporary */ 00082 extern uint32_t ff_squareTbl[512]; 00083 extern uint8_t ff_cropTbl[256 + 2 * MAX_NEG_CROP]; 00084 00085 /* VP3 DSP functions */ 00086 void ff_vp3_idct_c(DCTELEM *block/* align 16*/); 00087 void ff_vp3_idct_put_c(uint8_t *dest/*align 8*/, int line_size, DCTELEM *block/*align 16*/); 00088 void ff_vp3_idct_add_c(uint8_t *dest/*align 8*/, int line_size, DCTELEM *block/*align 16*/); 00089 void ff_vp3_idct_dc_add_c(uint8_t *dest/*align 8*/, int line_size, const DCTELEM *block/*align 16*/); 00090 00091 void ff_vp3_v_loop_filter_c(uint8_t *src, int stride, int *bounding_values); 00092 void ff_vp3_h_loop_filter_c(uint8_t *src, int stride, int *bounding_values); 00093 00094 /* VP6 DSP functions */ 00095 void ff_vp6_filter_diag4_c(uint8_t *dst, uint8_t *src, int stride, 00096 const int16_t *h_weights, const int16_t *v_weights); 00097 00098 /* Bink functions */ 00099 void ff_bink_idct_c (DCTELEM *block); 00100 void ff_bink_idct_add_c(uint8_t *dest, int linesize, DCTELEM *block); 00101 void ff_bink_idct_put_c(uint8_t *dest, int linesize, DCTELEM *block); 00102 00103 /* CAVS functions */ 00104 void ff_put_cavs_qpel8_mc00_c(uint8_t *dst, uint8_t *src, int stride); 00105 void ff_avg_cavs_qpel8_mc00_c(uint8_t *dst, uint8_t *src, int stride); 00106 void ff_put_cavs_qpel16_mc00_c(uint8_t *dst, uint8_t *src, int stride); 00107 void ff_avg_cavs_qpel16_mc00_c(uint8_t *dst, uint8_t *src, int stride); 00108 00109 /* VC1 functions */ 00110 void ff_put_vc1_mspel_mc00_c(uint8_t *dst, const uint8_t *src, int stride, int rnd); 00111 void ff_avg_vc1_mspel_mc00_c(uint8_t *dst, const uint8_t *src, int stride, int rnd); 00112 00113 /* EA functions */ 00114 void ff_ea_idct_put_c(uint8_t *dest, int linesize, DCTELEM *block); 00115 00116 /* 1/2^n downscaling functions from imgconvert.c */ 00117 void ff_img_copy_plane(uint8_t *dst, int dst_wrap, const uint8_t *src, int src_wrap, int width, int height); 00118 void ff_shrink22(uint8_t *dst, int dst_wrap, const uint8_t *src, int src_wrap, int width, int height); 00119 void ff_shrink44(uint8_t *dst, int dst_wrap, const uint8_t *src, int src_wrap, int width, int height); 00120 void ff_shrink88(uint8_t *dst, int dst_wrap, const uint8_t *src, int src_wrap, int width, int height); 00121 00122 void ff_gmc_c(uint8_t *dst, uint8_t *src, int stride, int h, int ox, int oy, 00123 int dxx, int dxy, int dyx, int dyy, int shift, int r, int width, int height); 00124 00125 /* minimum alignment rules ;) 00126 If you notice errors in the align stuff, need more alignment for some ASM code 00127 for some CPU or need to use a function with less aligned data then send a mail 00128 to the ffmpeg-devel mailing list, ... 00129 00130 !warning These alignments might not match reality, (missing attribute((align)) 00131 stuff somewhere possible). 00132 I (Michael) did not check them, these are just the alignments which I think 00133 could be reached easily ... 00134 00135 !future video codecs might need functions with less strict alignment 00136 */ 00137 00138 /* 00139 void get_pixels_c(DCTELEM *block, const uint8_t *pixels, int line_size); 00140 void diff_pixels_c(DCTELEM *block, const uint8_t *s1, const uint8_t *s2, int stride); 00141 void put_pixels_clamped_c(const DCTELEM *block, uint8_t *pixels, int line_size); 00142 void add_pixels_clamped_c(const DCTELEM *block, uint8_t *pixels, int line_size); 00143 void clear_blocks_c(DCTELEM *blocks); 00144 */ 00145 00146 /* add and put pixel (decoding) */ 00147 // blocksizes for op_pixels_func are 8x4,8x8 16x8 16x16 00148 //h for op_pixels_func is limited to {width/2, width} but never larger than 16 and never smaller then 4 00149 typedef void (*op_pixels_func)(uint8_t *block/*align width (8 or 16)*/, const uint8_t *pixels/*align 1*/, int line_size, int h); 00150 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); 00151 typedef void (*qpel_mc_func)(uint8_t *dst/*align width (8 or 16)*/, uint8_t *src/*align 1*/, int stride); 00152 typedef void (*h264_chroma_mc_func)(uint8_t *dst/*align 8*/, uint8_t *src/*align 1*/, int srcStride, int h, int x, int y); 00153 00154 typedef void (*op_fill_func)(uint8_t *block/*align width (8 or 16)*/, uint8_t value, int line_size, int h); 00155 00156 #define DEF_OLD_QPEL(name)\ 00157 void ff_put_ ## name (uint8_t *dst/*align width (8 or 16)*/, uint8_t *src/*align 1*/, int stride);\ 00158 void ff_put_no_rnd_ ## name (uint8_t *dst/*align width (8 or 16)*/, uint8_t *src/*align 1*/, int stride);\ 00159 void ff_avg_ ## name (uint8_t *dst/*align width (8 or 16)*/, uint8_t *src/*align 1*/, int stride); 00160 00161 DEF_OLD_QPEL(qpel16_mc11_old_c) 00162 DEF_OLD_QPEL(qpel16_mc31_old_c) 00163 DEF_OLD_QPEL(qpel16_mc12_old_c) 00164 DEF_OLD_QPEL(qpel16_mc32_old_c) 00165 DEF_OLD_QPEL(qpel16_mc13_old_c) 00166 DEF_OLD_QPEL(qpel16_mc33_old_c) 00167 DEF_OLD_QPEL(qpel8_mc11_old_c) 00168 DEF_OLD_QPEL(qpel8_mc31_old_c) 00169 DEF_OLD_QPEL(qpel8_mc12_old_c) 00170 DEF_OLD_QPEL(qpel8_mc32_old_c) 00171 DEF_OLD_QPEL(qpel8_mc13_old_c) 00172 DEF_OLD_QPEL(qpel8_mc33_old_c) 00173 00174 #define CALL_2X_PIXELS(a, b, n)\ 00175 static void a(uint8_t *block, const uint8_t *pixels, int line_size, int h){\ 00176 b(block , pixels , line_size, h);\ 00177 b(block+n, pixels+n, line_size, h);\ 00178 } 00179 00180 /* motion estimation */ 00181 // h is limited to {width/2, width, 2*width} but never larger than 16 and never smaller then 2 00182 // although currently h<4 is not used as functions with width <8 are neither used nor implemented 00183 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))*/; 00184 00188 typedef struct ScanTable{ 00189 const uint8_t *scantable; 00190 uint8_t permutated[64]; 00191 uint8_t raster_end[64]; 00192 #if ARCH_PPC 00193 00194 DECLARE_ALIGNED(16, uint8_t, inverse)[64]; 00195 #endif 00196 } ScanTable; 00197 00198 void ff_init_scantable(uint8_t *, ScanTable *st, const uint8_t *src_scantable); 00199 00200 void ff_emulated_edge_mc(uint8_t *buf, uint8_t *src, int linesize, 00201 int block_w, int block_h, 00202 int src_x, int src_y, int w, int h); 00203 00207 typedef struct DSPContext { 00208 /* pixel ops : interface with DCT */ 00209 void (*get_pixels)(DCTELEM *block/*align 16*/, const uint8_t *pixels/*align 8*/, int line_size); 00210 void (*diff_pixels)(DCTELEM *block/*align 16*/, const uint8_t *s1/*align 8*/, const uint8_t *s2/*align 8*/, int stride); 00211 void (*put_pixels_clamped)(const DCTELEM *block/*align 16*/, uint8_t *pixels/*align 8*/, int line_size); 00212 void (*put_signed_pixels_clamped)(const DCTELEM *block/*align 16*/, uint8_t *pixels/*align 8*/, int line_size); 00213 void (*put_pixels_nonclamped)(const DCTELEM *block/*align 16*/, uint8_t *pixels/*align 8*/, int line_size); 00214 void (*add_pixels_clamped)(const DCTELEM *block/*align 16*/, uint8_t *pixels/*align 8*/, int line_size); 00215 void (*add_pixels8)(uint8_t *pixels, DCTELEM *block, int line_size); 00216 void (*add_pixels4)(uint8_t *pixels, DCTELEM *block, int line_size); 00217 int (*sum_abs_dctelem)(DCTELEM *block/*align 16*/); 00221 void (*gmc1)(uint8_t *dst/*align 8*/, uint8_t *src/*align 1*/, int srcStride, int h, int x16, int y16, int rounder); 00225 void (*gmc )(uint8_t *dst/*align 8*/, uint8_t *src/*align 1*/, int stride, int h, int ox, int oy, 00226 int dxx, int dxy, int dyx, int dyy, int shift, int r, int width, int height); 00227 void (*clear_block)(DCTELEM *block/*align 16*/); 00228 void (*clear_blocks)(DCTELEM *blocks/*align 16*/); 00229 int (*pix_sum)(uint8_t * pix, int line_size); 00230 int (*pix_norm1)(uint8_t * pix, int line_size); 00231 // 16x16 8x8 4x4 2x2 16x8 8x4 4x2 8x16 4x8 2x4 00232 00233 me_cmp_func sad[6]; /* identical to pix_absAxA except additional void * */ 00234 me_cmp_func sse[6]; 00235 me_cmp_func hadamard8_diff[6]; 00236 me_cmp_func dct_sad[6]; 00237 me_cmp_func quant_psnr[6]; 00238 me_cmp_func bit[6]; 00239 me_cmp_func rd[6]; 00240 me_cmp_func vsad[6]; 00241 me_cmp_func vsse[6]; 00242 me_cmp_func nsse[6]; 00243 me_cmp_func w53[6]; 00244 me_cmp_func w97[6]; 00245 me_cmp_func dct_max[6]; 00246 me_cmp_func dct264_sad[6]; 00247 00248 me_cmp_func me_pre_cmp[6]; 00249 me_cmp_func me_cmp[6]; 00250 me_cmp_func me_sub_cmp[6]; 00251 me_cmp_func mb_cmp[6]; 00252 me_cmp_func ildct_cmp[6]; //only width 16 used 00253 me_cmp_func frame_skip_cmp[6]; //only width 8 used 00254 00255 int (*ssd_int8_vs_int16)(const int8_t *pix1, const int16_t *pix2, 00256 int size); 00257 00268 op_pixels_func put_pixels_tab[4][4]; 00269 00280 op_pixels_func avg_pixels_tab[4][4]; 00281 00292 op_pixels_func put_no_rnd_pixels_tab[4][4]; 00293 00304 op_pixels_func avg_no_rnd_pixels_tab[4][4]; 00305 00306 void (*put_no_rnd_pixels_l2[2])(uint8_t *block/*align width (8 or 16)*/, const uint8_t *a/*align 1*/, const uint8_t *b/*align 1*/, int line_size, int h); 00307 00318 tpel_mc_func put_tpel_pixels_tab[11]; //FIXME individual func ptr per width? 00319 tpel_mc_func avg_tpel_pixels_tab[11]; //FIXME individual func ptr per width? 00320 00321 qpel_mc_func put_qpel_pixels_tab[2][16]; 00322 qpel_mc_func avg_qpel_pixels_tab[2][16]; 00323 qpel_mc_func put_no_rnd_qpel_pixels_tab[2][16]; 00324 qpel_mc_func avg_no_rnd_qpel_pixels_tab[2][16]; 00325 qpel_mc_func put_mspel_pixels_tab[8]; 00326 00330 h264_chroma_mc_func put_h264_chroma_pixels_tab[3]; 00331 h264_chroma_mc_func avg_h264_chroma_pixels_tab[3]; 00332 /* This is really one func used in VC-1 decoding */ 00333 h264_chroma_mc_func put_no_rnd_vc1_chroma_pixels_tab[3]; 00334 h264_chroma_mc_func avg_no_rnd_vc1_chroma_pixels_tab[3]; 00335 00336 qpel_mc_func put_h264_qpel_pixels_tab[4][16]; 00337 qpel_mc_func avg_h264_qpel_pixels_tab[4][16]; 00338 00339 qpel_mc_func put_2tap_qpel_pixels_tab[4][16]; 00340 qpel_mc_func avg_2tap_qpel_pixels_tab[4][16]; 00341 00342 /* AVS specific */ 00343 qpel_mc_func put_cavs_qpel_pixels_tab[2][16]; 00344 qpel_mc_func avg_cavs_qpel_pixels_tab[2][16]; 00345 void (*cavs_filter_lv)(uint8_t *pix, int stride, int alpha, int beta, int tc, int bs1, int bs2); 00346 void (*cavs_filter_lh)(uint8_t *pix, int stride, int alpha, int beta, int tc, int bs1, int bs2); 00347 void (*cavs_filter_cv)(uint8_t *pix, int stride, int alpha, int beta, int tc, int bs1, int bs2); 00348 void (*cavs_filter_ch)(uint8_t *pix, int stride, int alpha, int beta, int tc, int bs1, int bs2); 00349 void (*cavs_idct8_add)(uint8_t *dst, DCTELEM *block, int stride); 00350 00351 me_cmp_func pix_abs[2][4]; 00352 00353 /* huffyuv specific */ 00354 void (*add_bytes)(uint8_t *dst/*align 16*/, uint8_t *src/*align 16*/, int w); 00355 void (*add_bytes_l2)(uint8_t *dst/*align 16*/, uint8_t *src1/*align 16*/, uint8_t *src2/*align 16*/, int w); 00356 void (*diff_bytes)(uint8_t *dst/*align 16*/, uint8_t *src1/*align 16*/, uint8_t *src2/*align 1*/,int w); 00361 void (*sub_hfyu_median_prediction)(uint8_t *dst, const uint8_t *src1, const uint8_t *src2, int w, int *left, int *left_top); 00362 void (*add_hfyu_median_prediction)(uint8_t *dst, const uint8_t *top, const uint8_t *diff, int w, int *left, int *left_top); 00363 int (*add_hfyu_left_prediction)(uint8_t *dst, const uint8_t *src, int w, int left); 00364 void (*add_hfyu_left_prediction_bgr32)(uint8_t *dst, const uint8_t *src, int w, int *red, int *green, int *blue, int *alpha); 00365 /* this might write to dst[w] */ 00366 void (*add_png_paeth_prediction)(uint8_t *dst, uint8_t *src, uint8_t *top, int w, int bpp); 00367 void (*bswap_buf)(uint32_t *dst, const uint32_t *src, int w); 00368 00369 void (*h263_v_loop_filter)(uint8_t *src, int stride, int qscale); 00370 void (*h263_h_loop_filter)(uint8_t *src, int stride, int qscale); 00371 00372 void (*h261_loop_filter)(uint8_t *src, int stride); 00373 00374 void (*x8_v_loop_filter)(uint8_t *src, int stride, int qscale); 00375 void (*x8_h_loop_filter)(uint8_t *src, int stride, int qscale); 00376 00377 void (*vp3_idct_dc_add)(uint8_t *dest/*align 8*/, int line_size, const DCTELEM *block/*align 16*/); 00378 void (*vp3_v_loop_filter)(uint8_t *src, int stride, int *bounding_values); 00379 void (*vp3_h_loop_filter)(uint8_t *src, int stride, int *bounding_values); 00380 00381 void (*vp6_filter_diag4)(uint8_t *dst, uint8_t *src, int stride, 00382 const int16_t *h_weights,const int16_t *v_weights); 00383 00384 /* assume len is a multiple of 4, and arrays are 16-byte aligned */ 00385 void (*vorbis_inverse_coupling)(float *mag, float *ang, int blocksize); 00386 void (*ac3_downmix)(float (*samples)[256], float (*matrix)[2], int out_ch, int in_ch, int len); 00387 /* no alignment needed */ 00388 void (*lpc_compute_autocorr)(const int32_t *data, int len, int lag, double *autoc); 00389 /* assume len is a multiple of 8, and arrays are 16-byte aligned */ 00390 void (*vector_fmul)(float *dst, const float *src, int len); 00391 void (*vector_fmul_reverse)(float *dst, const float *src0, const float *src1, int len); 00392 /* assume len is a multiple of 8, and src arrays are 16-byte aligned */ 00393 void (*vector_fmul_add)(float *dst, const float *src0, const float *src1, const float *src2, int len); 00394 /* assume len is a multiple of 4, and arrays are 16-byte aligned */ 00395 void (*vector_fmul_window)(float *dst, const float *src0, const float *src1, const float *win, float add_bias, int len); 00396 /* assume len is a multiple of 8, and arrays are 16-byte aligned */ 00397 void (*int32_to_float_fmul_scalar)(float *dst, const int *src, float mul, int len); 00398 void (*vector_clipf)(float *dst /* align 16 */, const float *src /* align 16 */, float min, float max, int len /* align 16 */); 00407 void (*vector_fmul_scalar)(float *dst, const float *src, float mul, 00408 int len); 00421 void (*vector_fmul_sv_scalar[2])(float *dst, const float *src, 00422 const float **sv, float mul, int len); 00433 void (*sv_fmul_scalar[2])(float *dst, const float **sv, 00434 float mul, int len); 00441 float (*scalarproduct_float)(const float *v1, const float *v2, int len); 00448 void (*butterflies_float)(float *restrict v1, float *restrict v2, int len); 00449 00450 /* C version: convert floats from the range [384.0,386.0] to ints in [-32768,32767] 00451 * simd versions: convert floats from [-32768.0,32767.0] without rescaling and arrays are 16byte aligned */ 00452 void (*float_to_int16)(int16_t *dst, const float *src, long len); 00453 void (*float_to_int16_interleave)(int16_t *dst, const float **src, long len, int channels); 00454 00455 /* (I)DCT */ 00456 void (*fdct)(DCTELEM *block/* align 16*/); 00457 void (*fdct248)(DCTELEM *block/* align 16*/); 00458 00459 /* IDCT really*/ 00460 void (*idct)(DCTELEM *block/* align 16*/); 00461 00467 void (*idct_put)(uint8_t *dest/*align 8*/, int line_size, DCTELEM *block/*align 16*/); 00468 00473 void (*idct_add)(uint8_t *dest/*align 8*/, int line_size, DCTELEM *block/*align 16*/); 00474 00487 uint8_t idct_permutation[64]; 00488 int idct_permutation_type; 00489 #define FF_NO_IDCT_PERM 1 00490 #define FF_LIBMPEG2_IDCT_PERM 2 00491 #define FF_SIMPLE_IDCT_PERM 3 00492 #define FF_TRANSPOSE_IDCT_PERM 4 00493 #define FF_PARTTRANS_IDCT_PERM 5 00494 #define FF_SSE2_IDCT_PERM 6 00495 00496 int (*try_8x8basis)(int16_t rem[64], int16_t weight[64], int16_t basis[64], int scale); 00497 void (*add_8x8basis)(int16_t rem[64], int16_t basis[64], int scale); 00498 #define BASIS_SHIFT 16 00499 #define RECON_SHIFT 6 00500 00501 void (*draw_edges)(uint8_t *buf, int wrap, int width, int height, int w); 00502 #define EDGE_WIDTH 16 00503 00504 void (*prefetch)(void *mem, int stride, int h); 00505 00506 void (*shrink[4])(uint8_t *dst, int dst_wrap, const uint8_t *src, int src_wrap, int width, int height); 00507 00508 /* mlp/truehd functions */ 00509 void (*mlp_filter_channel)(int32_t *state, const int32_t *coeff, 00510 int firorder, int iirorder, 00511 unsigned int filter_shift, int32_t mask, int blocksize, 00512 int32_t *sample_buffer); 00513 00514 /* vc1 functions */ 00515 void (*vc1_inv_trans_8x8)(DCTELEM *b); 00516 void (*vc1_inv_trans_8x4)(uint8_t *dest, int line_size, DCTELEM *block); 00517 void (*vc1_inv_trans_4x8)(uint8_t *dest, int line_size, DCTELEM *block); 00518 void (*vc1_inv_trans_4x4)(uint8_t *dest, int line_size, DCTELEM *block); 00519 void (*vc1_inv_trans_8x8_dc)(uint8_t *dest, int line_size, DCTELEM *block); 00520 void (*vc1_inv_trans_8x4_dc)(uint8_t *dest, int line_size, DCTELEM *block); 00521 void (*vc1_inv_trans_4x8_dc)(uint8_t *dest, int line_size, DCTELEM *block); 00522 void (*vc1_inv_trans_4x4_dc)(uint8_t *dest, int line_size, DCTELEM *block); 00523 void (*vc1_v_overlap)(uint8_t* src, int stride); 00524 void (*vc1_h_overlap)(uint8_t* src, int stride); 00525 void (*vc1_v_loop_filter4)(uint8_t *src, int stride, int pq); 00526 void (*vc1_h_loop_filter4)(uint8_t *src, int stride, int pq); 00527 void (*vc1_v_loop_filter8)(uint8_t *src, int stride, int pq); 00528 void (*vc1_h_loop_filter8)(uint8_t *src, int stride, int pq); 00529 void (*vc1_v_loop_filter16)(uint8_t *src, int stride, int pq); 00530 void (*vc1_h_loop_filter16)(uint8_t *src, int stride, int pq); 00531 /* put 8x8 block with bicubic interpolation and quarterpel precision 00532 * last argument is actually round value instead of height 00533 */ 00534 op_pixels_func put_vc1_mspel_pixels_tab[16]; 00535 op_pixels_func avg_vc1_mspel_pixels_tab[16]; 00536 00537 /* intrax8 functions */ 00538 void (*x8_spatial_compensation[12])(uint8_t *src , uint8_t *dst, int linesize); 00539 void (*x8_setup_spatial_compensation)(uint8_t *src, uint8_t *dst, int linesize, 00540 int * range, int * sum, int edges); 00541 00547 int32_t (*scalarproduct_int16)(int16_t *v1, int16_t *v2/*align 16*/, int len, int shift); 00548 /* ape functions */ 00554 int32_t (*scalarproduct_and_madd_int16)(int16_t *v1/*align 16*/, int16_t *v2, int16_t *v3, int len, int mul); 00555 00556 /* rv30 functions */ 00557 qpel_mc_func put_rv30_tpel_pixels_tab[4][16]; 00558 qpel_mc_func avg_rv30_tpel_pixels_tab[4][16]; 00559 00560 /* rv40 functions */ 00561 qpel_mc_func put_rv40_qpel_pixels_tab[4][16]; 00562 qpel_mc_func avg_rv40_qpel_pixels_tab[4][16]; 00563 h264_chroma_mc_func put_rv40_chroma_pixels_tab[3]; 00564 h264_chroma_mc_func avg_rv40_chroma_pixels_tab[3]; 00565 00566 /* bink functions */ 00567 op_fill_func fill_block_tab[2]; 00568 void (*scale_block)(const uint8_t src[64]/*align 8*/, uint8_t *dst/*align 8*/, int linesize); 00569 } DSPContext; 00570 00571 void dsputil_static_init(void); 00572 void dsputil_init(DSPContext* p, AVCodecContext *avctx); 00573 00574 int ff_check_alignment(void); 00575 00580 void ff_block_permute(DCTELEM *block, uint8_t *permutation, const uint8_t *scantable, int last); 00581 00582 void ff_set_cmp(DSPContext* c, me_cmp_func *cmp, int type); 00583 00584 #define BYTE_VEC32(c) ((c)*0x01010101UL) 00585 00586 static inline uint32_t rnd_avg32(uint32_t a, uint32_t b) 00587 { 00588 return (a | b) - (((a ^ b) & ~BYTE_VEC32(0x01)) >> 1); 00589 } 00590 00591 static inline uint32_t no_rnd_avg32(uint32_t a, uint32_t b) 00592 { 00593 return (a & b) + (((a ^ b) & ~BYTE_VEC32(0x01)) >> 1); 00594 } 00595 00596 static inline int get_penalty_factor(int lambda, int lambda2, int type){ 00597 switch(type&0xFF){ 00598 default: 00599 case FF_CMP_SAD: 00600 return lambda>>FF_LAMBDA_SHIFT; 00601 case FF_CMP_DCT: 00602 return (3*lambda)>>(FF_LAMBDA_SHIFT+1); 00603 case FF_CMP_W53: 00604 return (4*lambda)>>(FF_LAMBDA_SHIFT); 00605 case FF_CMP_W97: 00606 return (2*lambda)>>(FF_LAMBDA_SHIFT); 00607 case FF_CMP_SATD: 00608 case FF_CMP_DCT264: 00609 return (2*lambda)>>FF_LAMBDA_SHIFT; 00610 case FF_CMP_RD: 00611 case FF_CMP_PSNR: 00612 case FF_CMP_SSE: 00613 case FF_CMP_NSSE: 00614 return lambda2>>FF_LAMBDA_SHIFT; 00615 case FF_CMP_BIT: 00616 return 1; 00617 } 00618 } 00619 00625 #define emms_c() 00626 00627 /* should be defined by architectures supporting 00628 one or more MultiMedia extension */ 00629 int mm_support(void); 00630 extern int mm_flags; 00631 00632 void dsputil_init_alpha(DSPContext* c, AVCodecContext *avctx); 00633 void dsputil_init_arm(DSPContext* c, AVCodecContext *avctx); 00634 void dsputil_init_bfin(DSPContext* c, AVCodecContext *avctx); 00635 void dsputil_init_mlib(DSPContext* c, AVCodecContext *avctx); 00636 void dsputil_init_mmi(DSPContext* c, AVCodecContext *avctx); 00637 void dsputil_init_mmx(DSPContext* c, AVCodecContext *avctx); 00638 void dsputil_init_ppc(DSPContext* c, AVCodecContext *avctx); 00639 void dsputil_init_sh4(DSPContext* c, AVCodecContext *avctx); 00640 void dsputil_init_vis(DSPContext* c, AVCodecContext *avctx); 00641 00642 void ff_dsputil_init_dwt(DSPContext *c); 00643 void ff_cavsdsp_init(DSPContext* c, AVCodecContext *avctx); 00644 void ff_rv30dsp_init(DSPContext* c, AVCodecContext *avctx); 00645 void ff_rv40dsp_init(DSPContext* c, AVCodecContext *avctx); 00646 void ff_vc1dsp_init(DSPContext* c, AVCodecContext *avctx); 00647 void ff_intrax8dsp_init(DSPContext* c, AVCodecContext *avctx); 00648 void ff_mlp_init(DSPContext* c, AVCodecContext *avctx); 00649 void ff_mlp_init_x86(DSPContext* c, AVCodecContext *avctx); 00650 00651 #if HAVE_MMX 00652 00653 #undef emms_c 00654 00655 static inline void emms(void) 00656 { 00657 __asm__ volatile ("emms;":::"memory"); 00658 } 00659 00660 00661 #define emms_c() \ 00662 {\ 00663 if (mm_flags & FF_MM_MMX)\ 00664 emms();\ 00665 } 00666 00667 #elif ARCH_ARM 00668 00669 #if HAVE_NEON 00670 # define STRIDE_ALIGN 16 00671 #endif 00672 00673 #elif ARCH_PPC 00674 00675 #define STRIDE_ALIGN 16 00676 00677 #elif HAVE_MMI 00678 00679 #define STRIDE_ALIGN 16 00680 00681 #else 00682 00683 #define mm_flags 0 00684 #define mm_support() 0 00685 00686 #endif 00687 00688 #ifndef STRIDE_ALIGN 00689 # define STRIDE_ALIGN 8 00690 #endif 00691 00692 #define LOCAL_ALIGNED(a, t, v, s, ...) \ 00693 uint8_t la_##v[sizeof(t s __VA_ARGS__) + (a)]; \ 00694 t (*v) __VA_ARGS__ = (void *)FFALIGN((uintptr_t)la_##v, a) 00695 00696 #if HAVE_LOCAL_ALIGNED_8 00697 # define LOCAL_ALIGNED_8(t, v, s, ...) DECLARE_ALIGNED(8, t, v) s __VA_ARGS__ 00698 #else 00699 # define LOCAL_ALIGNED_8(t, v, s, ...) LOCAL_ALIGNED(8, t, v, s, __VA_ARGS__) 00700 #endif 00701 00702 #if HAVE_LOCAL_ALIGNED_16 00703 # define LOCAL_ALIGNED_16(t, v, s, ...) DECLARE_ALIGNED(16, t, v) s __VA_ARGS__ 00704 #else 00705 # define LOCAL_ALIGNED_16(t, v, s, ...) LOCAL_ALIGNED(16, t, v, s, __VA_ARGS__) 00706 #endif 00707 00708 /* PSNR */ 00709 void get_psnr(uint8_t *orig_image[3], uint8_t *coded_image[3], 00710 int orig_linesize[3], int coded_linesize, 00711 AVCodecContext *avctx); 00712 00713 #define WRAPPER8_16(name8, name16)\ 00714 static int name16(void /*MpegEncContext*/ *s, uint8_t *dst, uint8_t *src, int stride, int h){\ 00715 return name8(s, dst , src , stride, h)\ 00716 +name8(s, dst+8 , src+8 , stride, h);\ 00717 } 00718 00719 #define WRAPPER8_16_SQ(name8, name16)\ 00720 static int name16(void /*MpegEncContext*/ *s, uint8_t *dst, uint8_t *src, int stride, int h){\ 00721 int score=0;\ 00722 score +=name8(s, dst , src , stride, 8);\ 00723 score +=name8(s, dst+8 , src+8 , stride, 8);\ 00724 if(h==16){\ 00725 dst += 8*stride;\ 00726 src += 8*stride;\ 00727 score +=name8(s, dst , src , stride, 8);\ 00728 score +=name8(s, dst+8 , src+8 , stride, 8);\ 00729 }\ 00730 return score;\ 00731 } 00732 00733 00734 static inline void copy_block2(uint8_t *dst, const uint8_t *src, int dstStride, int srcStride, int h) 00735 { 00736 int i; 00737 for(i=0; i<h; i++) 00738 { 00739 AV_WN16(dst , AV_RN16(src )); 00740 dst+=dstStride; 00741 src+=srcStride; 00742 } 00743 } 00744 00745 static inline void copy_block4(uint8_t *dst, const uint8_t *src, int dstStride, int srcStride, int h) 00746 { 00747 int i; 00748 for(i=0; i<h; i++) 00749 { 00750 AV_WN32(dst , AV_RN32(src )); 00751 dst+=dstStride; 00752 src+=srcStride; 00753 } 00754 } 00755 00756 static inline void copy_block8(uint8_t *dst, const uint8_t *src, int dstStride, int srcStride, int h) 00757 { 00758 int i; 00759 for(i=0; i<h; i++) 00760 { 00761 AV_WN32(dst , AV_RN32(src )); 00762 AV_WN32(dst+4 , AV_RN32(src+4 )); 00763 dst+=dstStride; 00764 src+=srcStride; 00765 } 00766 } 00767 00768 static inline void copy_block9(uint8_t *dst, const uint8_t *src, int dstStride, int srcStride, int h) 00769 { 00770 int i; 00771 for(i=0; i<h; i++) 00772 { 00773 AV_WN32(dst , AV_RN32(src )); 00774 AV_WN32(dst+4 , AV_RN32(src+4 )); 00775 dst[8]= src[8]; 00776 dst+=dstStride; 00777 src+=srcStride; 00778 } 00779 } 00780 00781 static inline void copy_block16(uint8_t *dst, const uint8_t *src, int dstStride, int srcStride, int h) 00782 { 00783 int i; 00784 for(i=0; i<h; i++) 00785 { 00786 AV_WN32(dst , AV_RN32(src )); 00787 AV_WN32(dst+4 , AV_RN32(src+4 )); 00788 AV_WN32(dst+8 , AV_RN32(src+8 )); 00789 AV_WN32(dst+12, AV_RN32(src+12)); 00790 dst+=dstStride; 00791 src+=srcStride; 00792 } 00793 } 00794 00795 static inline void copy_block17(uint8_t *dst, const uint8_t *src, int dstStride, int srcStride, int h) 00796 { 00797 int i; 00798 for(i=0; i<h; i++) 00799 { 00800 AV_WN32(dst , AV_RN32(src )); 00801 AV_WN32(dst+4 , AV_RN32(src+4 )); 00802 AV_WN32(dst+8 , AV_RN32(src+8 )); 00803 AV_WN32(dst+12, AV_RN32(src+12)); 00804 dst[16]= src[16]; 00805 dst+=dstStride; 00806 src+=srcStride; 00807 } 00808 } 00809 00810 #endif /* AVCODEC_DSPUTIL_H */