Libav
|
00001 /* 00002 * Sun mediaLib optimized DSP utils 00003 * Copyright (c) 2001 Fabrice Bellard 00004 * 00005 * This file is part of FFmpeg. 00006 * 00007 * FFmpeg is free software; you can redistribute it and/or 00008 * modify it under the terms of the GNU Lesser General Public 00009 * License as published by the Free Software Foundation; either 00010 * version 2.1 of the License, or (at your option) any later version. 00011 * 00012 * FFmpeg is distributed in the hope that it will be useful, 00013 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00014 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 00015 * Lesser General Public License for more details. 00016 * 00017 * You should have received a copy of the GNU Lesser General Public 00018 * License along with FFmpeg; if not, write to the Free Software 00019 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 00020 */ 00021 00022 #include "libavcodec/dsputil.h" 00023 #include "libavcodec/mpegvideo.h" 00024 00025 #include <mlib_types.h> 00026 #include <mlib_status.h> 00027 #include <mlib_sys.h> 00028 #include <mlib_algebra.h> 00029 #include <mlib_video.h> 00030 00031 /* misc */ 00032 00033 static void get_pixels_mlib(DCTELEM *restrict block, const uint8_t *pixels, int line_size) 00034 { 00035 int i; 00036 00037 for (i=0;i<8;i++) { 00038 mlib_VectorConvert_S16_U8_Mod((mlib_s16 *)block, (mlib_u8 *)pixels, 8); 00039 00040 pixels += line_size; 00041 block += 8; 00042 } 00043 } 00044 00045 static void diff_pixels_mlib(DCTELEM *restrict block, const uint8_t *s1, const uint8_t *s2, int line_size) 00046 { 00047 int i; 00048 00049 for (i=0;i<8;i++) { 00050 mlib_VectorSub_S16_U8_Mod((mlib_s16 *)block, (mlib_u8 *)s1, (mlib_u8 *)s2, 8); 00051 00052 s1 += line_size; 00053 s2 += line_size; 00054 block += 8; 00055 } 00056 } 00057 00058 static void add_pixels_clamped_mlib(const DCTELEM *block, uint8_t *pixels, int line_size) 00059 { 00060 mlib_VideoAddBlock_U8_S16(pixels, (mlib_s16 *)block, line_size); 00061 } 00062 00063 /* put block, width 16 pixel, height 8/16 */ 00064 00065 static void put_pixels16_mlib (uint8_t * dest, const uint8_t * ref, 00066 int stride, int height) 00067 { 00068 switch (height) { 00069 case 8: 00070 mlib_VideoCopyRef_U8_U8_16x8(dest, (uint8_t *)ref, stride); 00071 break; 00072 00073 case 16: 00074 mlib_VideoCopyRef_U8_U8_16x16(dest, (uint8_t *)ref, stride); 00075 break; 00076 00077 default: 00078 assert(0); 00079 } 00080 } 00081 00082 static void put_pixels16_x2_mlib (uint8_t * dest, const uint8_t * ref, 00083 int stride, int height) 00084 { 00085 switch (height) { 00086 case 8: 00087 mlib_VideoInterpX_U8_U8_16x8(dest, (uint8_t *)ref, stride, stride); 00088 break; 00089 00090 case 16: 00091 mlib_VideoInterpX_U8_U8_16x16(dest, (uint8_t *)ref, stride, stride); 00092 break; 00093 00094 default: 00095 assert(0); 00096 } 00097 } 00098 00099 static void put_pixels16_y2_mlib (uint8_t * dest, const uint8_t * ref, 00100 int stride, int height) 00101 { 00102 switch (height) { 00103 case 8: 00104 mlib_VideoInterpY_U8_U8_16x8(dest, (uint8_t *)ref, stride, stride); 00105 break; 00106 00107 case 16: 00108 mlib_VideoInterpY_U8_U8_16x16(dest, (uint8_t *)ref, stride, stride); 00109 break; 00110 00111 default: 00112 assert(0); 00113 } 00114 } 00115 00116 static void put_pixels16_xy2_mlib(uint8_t * dest, const uint8_t * ref, 00117 int stride, int height) 00118 { 00119 switch (height) { 00120 case 8: 00121 mlib_VideoInterpXY_U8_U8_16x8(dest, (uint8_t *)ref, stride, stride); 00122 break; 00123 00124 case 16: 00125 mlib_VideoInterpXY_U8_U8_16x16(dest, (uint8_t *)ref, stride, stride); 00126 break; 00127 00128 default: 00129 assert(0); 00130 } 00131 } 00132 00133 /* put block, width 8 pixel, height 4/8/16 */ 00134 00135 static void put_pixels8_mlib (uint8_t * dest, const uint8_t * ref, 00136 int stride, int height) 00137 { 00138 switch (height) { 00139 case 4: 00140 mlib_VideoCopyRef_U8_U8_8x4(dest, (uint8_t *)ref, stride); 00141 break; 00142 00143 case 8: 00144 mlib_VideoCopyRef_U8_U8_8x8(dest, (uint8_t *)ref, stride); 00145 break; 00146 00147 case 16: 00148 mlib_VideoCopyRef_U8_U8_8x16(dest, (uint8_t *)ref, stride); 00149 break; 00150 00151 default: 00152 assert(0); 00153 } 00154 } 00155 00156 static void put_pixels8_x2_mlib (uint8_t * dest, const uint8_t * ref, 00157 int stride, int height) 00158 { 00159 switch (height) { 00160 case 4: 00161 mlib_VideoInterpX_U8_U8_8x4(dest, (uint8_t *)ref, stride, stride); 00162 break; 00163 00164 case 8: 00165 mlib_VideoInterpX_U8_U8_8x8(dest, (uint8_t *)ref, stride, stride); 00166 break; 00167 00168 case 16: 00169 mlib_VideoInterpX_U8_U8_8x16(dest, (uint8_t *)ref, stride, stride); 00170 break; 00171 00172 default: 00173 assert(0); 00174 } 00175 } 00176 00177 static void put_pixels8_y2_mlib (uint8_t * dest, const uint8_t * ref, 00178 int stride, int height) 00179 { 00180 switch (height) { 00181 case 4: 00182 mlib_VideoInterpY_U8_U8_8x4(dest, (uint8_t *)ref, stride, stride); 00183 break; 00184 00185 case 8: 00186 mlib_VideoInterpY_U8_U8_8x8(dest, (uint8_t *)ref, stride, stride); 00187 break; 00188 00189 case 16: 00190 mlib_VideoInterpY_U8_U8_8x16(dest, (uint8_t *)ref, stride, stride); 00191 break; 00192 00193 default: 00194 assert(0); 00195 } 00196 } 00197 00198 static void put_pixels8_xy2_mlib(uint8_t * dest, const uint8_t * ref, 00199 int stride, int height) 00200 { 00201 switch (height) { 00202 case 4: 00203 mlib_VideoInterpXY_U8_U8_8x4(dest, (uint8_t *)ref, stride, stride); 00204 break; 00205 00206 case 8: 00207 mlib_VideoInterpXY_U8_U8_8x8(dest, (uint8_t *)ref, stride, stride); 00208 break; 00209 00210 case 16: 00211 mlib_VideoInterpXY_U8_U8_8x16(dest, (uint8_t *)ref, stride, stride); 00212 break; 00213 00214 default: 00215 assert(0); 00216 } 00217 } 00218 00219 /* average block, width 16 pixel, height 8/16 */ 00220 00221 static void avg_pixels16_mlib (uint8_t * dest, const uint8_t * ref, 00222 int stride, int height) 00223 { 00224 switch (height) { 00225 case 8: 00226 mlib_VideoCopyRefAve_U8_U8_16x8(dest, (uint8_t *)ref, stride); 00227 break; 00228 00229 case 16: 00230 mlib_VideoCopyRefAve_U8_U8_16x16(dest, (uint8_t *)ref, stride); 00231 break; 00232 00233 default: 00234 assert(0); 00235 } 00236 } 00237 00238 static void avg_pixels16_x2_mlib (uint8_t * dest, const uint8_t * ref, 00239 int stride, int height) 00240 { 00241 switch (height) { 00242 case 8: 00243 mlib_VideoInterpAveX_U8_U8_16x8(dest, (uint8_t *)ref, stride, stride); 00244 break; 00245 00246 case 16: 00247 mlib_VideoInterpAveX_U8_U8_16x16(dest, (uint8_t *)ref, stride, stride); 00248 break; 00249 00250 default: 00251 assert(0); 00252 } 00253 } 00254 00255 static void avg_pixels16_y2_mlib (uint8_t * dest, const uint8_t * ref, 00256 int stride, int height) 00257 { 00258 switch (height) { 00259 case 8: 00260 mlib_VideoInterpAveY_U8_U8_16x8(dest, (uint8_t *)ref, stride, stride); 00261 break; 00262 00263 case 16: 00264 mlib_VideoInterpAveY_U8_U8_16x16(dest, (uint8_t *)ref, stride, stride); 00265 break; 00266 00267 default: 00268 assert(0); 00269 } 00270 } 00271 00272 static void avg_pixels16_xy2_mlib(uint8_t * dest, const uint8_t * ref, 00273 int stride, int height) 00274 { 00275 switch (height) { 00276 case 8: 00277 mlib_VideoInterpAveXY_U8_U8_16x8(dest, (uint8_t *)ref, stride, stride); 00278 break; 00279 00280 case 16: 00281 mlib_VideoInterpAveXY_U8_U8_16x16(dest, (uint8_t *)ref, stride, stride); 00282 break; 00283 00284 default: 00285 assert(0); 00286 } 00287 } 00288 00289 /* average block, width 8 pixel, height 4/8/16 */ 00290 00291 static void avg_pixels8_mlib (uint8_t * dest, const uint8_t * ref, 00292 int stride, int height) 00293 { 00294 switch (height) { 00295 case 4: 00296 mlib_VideoCopyRefAve_U8_U8_8x4(dest, (uint8_t *)ref, stride); 00297 break; 00298 00299 case 8: 00300 mlib_VideoCopyRefAve_U8_U8_8x8(dest, (uint8_t *)ref, stride); 00301 break; 00302 00303 case 16: 00304 mlib_VideoCopyRefAve_U8_U8_8x16(dest, (uint8_t *)ref, stride); 00305 break; 00306 00307 default: 00308 assert(0); 00309 } 00310 } 00311 00312 static void avg_pixels8_x2_mlib (uint8_t * dest, const uint8_t * ref, 00313 int stride, int height) 00314 { 00315 switch (height) { 00316 case 4: 00317 mlib_VideoInterpAveX_U8_U8_8x4(dest, (uint8_t *)ref, stride, stride); 00318 break; 00319 00320 case 8: 00321 mlib_VideoInterpAveX_U8_U8_8x8(dest, (uint8_t *)ref, stride, stride); 00322 break; 00323 00324 case 16: 00325 mlib_VideoInterpAveX_U8_U8_8x16(dest, (uint8_t *)ref, stride, stride); 00326 break; 00327 00328 default: 00329 assert(0); 00330 } 00331 } 00332 00333 static void avg_pixels8_y2_mlib (uint8_t * dest, const uint8_t * ref, 00334 int stride, int height) 00335 { 00336 switch (height) { 00337 case 4: 00338 mlib_VideoInterpAveY_U8_U8_8x4(dest, (uint8_t *)ref, stride, stride); 00339 break; 00340 00341 case 8: 00342 mlib_VideoInterpAveY_U8_U8_8x8(dest, (uint8_t *)ref, stride, stride); 00343 break; 00344 00345 case 16: 00346 mlib_VideoInterpAveY_U8_U8_8x16(dest, (uint8_t *)ref, stride, stride); 00347 break; 00348 00349 default: 00350 assert(0); 00351 } 00352 } 00353 00354 static void avg_pixels8_xy2_mlib(uint8_t * dest, const uint8_t * ref, 00355 int stride, int height) 00356 { 00357 switch (height) { 00358 case 4: 00359 mlib_VideoInterpAveXY_U8_U8_8x4(dest, (uint8_t *)ref, stride, stride); 00360 break; 00361 00362 case 8: 00363 mlib_VideoInterpAveXY_U8_U8_8x8(dest, (uint8_t *)ref, stride, stride); 00364 break; 00365 00366 case 16: 00367 mlib_VideoInterpAveXY_U8_U8_8x16(dest, (uint8_t *)ref, stride, stride); 00368 break; 00369 00370 default: 00371 assert(0); 00372 } 00373 } 00374 00375 /* swap byte order of a buffer */ 00376 00377 static void bswap_buf_mlib(uint32_t *dst, const uint32_t *src, int w) 00378 { 00379 mlib_VectorReverseByteOrder_U32_U32(dst, src, w); 00380 } 00381 00382 /* transformations */ 00383 00384 static void ff_idct_put_mlib(uint8_t *dest, int line_size, DCTELEM *data) 00385 { 00386 int i; 00387 uint8_t *cm = ff_cropTbl + MAX_NEG_CROP; 00388 00389 mlib_VideoIDCT8x8_S16_S16 (data, data); 00390 00391 for(i=0;i<8;i++) { 00392 dest[0] = cm[data[0]]; 00393 dest[1] = cm[data[1]]; 00394 dest[2] = cm[data[2]]; 00395 dest[3] = cm[data[3]]; 00396 dest[4] = cm[data[4]]; 00397 dest[5] = cm[data[5]]; 00398 dest[6] = cm[data[6]]; 00399 dest[7] = cm[data[7]]; 00400 00401 dest += line_size; 00402 data += 8; 00403 } 00404 } 00405 00406 static void ff_idct_add_mlib(uint8_t *dest, int line_size, DCTELEM *data) 00407 { 00408 mlib_VideoIDCT8x8_S16_S16 (data, data); 00409 mlib_VideoAddBlock_U8_S16(dest, (mlib_s16 *)data, line_size); 00410 } 00411 00412 static void ff_idct_mlib(DCTELEM *data) 00413 { 00414 mlib_VideoIDCT8x8_S16_S16 (data, data); 00415 } 00416 00417 static void ff_fdct_mlib(DCTELEM *data) 00418 { 00419 mlib_VideoDCT8x8_S16_S16 (data, data); 00420 } 00421 00422 void dsputil_init_mlib(DSPContext* c, AVCodecContext *avctx) 00423 { 00424 c->get_pixels = get_pixels_mlib; 00425 c->diff_pixels = diff_pixels_mlib; 00426 c->add_pixels_clamped = add_pixels_clamped_mlib; 00427 00428 c->put_pixels_tab[0][0] = put_pixels16_mlib; 00429 c->put_pixels_tab[0][1] = put_pixels16_x2_mlib; 00430 c->put_pixels_tab[0][2] = put_pixels16_y2_mlib; 00431 c->put_pixels_tab[0][3] = put_pixels16_xy2_mlib; 00432 c->put_pixels_tab[1][0] = put_pixels8_mlib; 00433 c->put_pixels_tab[1][1] = put_pixels8_x2_mlib; 00434 c->put_pixels_tab[1][2] = put_pixels8_y2_mlib; 00435 c->put_pixels_tab[1][3] = put_pixels8_xy2_mlib; 00436 00437 c->avg_pixels_tab[0][0] = avg_pixels16_mlib; 00438 c->avg_pixels_tab[0][1] = avg_pixels16_x2_mlib; 00439 c->avg_pixels_tab[0][2] = avg_pixels16_y2_mlib; 00440 c->avg_pixels_tab[0][3] = avg_pixels16_xy2_mlib; 00441 c->avg_pixels_tab[1][0] = avg_pixels8_mlib; 00442 c->avg_pixels_tab[1][1] = avg_pixels8_x2_mlib; 00443 c->avg_pixels_tab[1][2] = avg_pixels8_y2_mlib; 00444 c->avg_pixels_tab[1][3] = avg_pixels8_xy2_mlib; 00445 00446 c->put_no_rnd_pixels_tab[0][0] = put_pixels16_mlib; 00447 c->put_no_rnd_pixels_tab[1][0] = put_pixels8_mlib; 00448 00449 c->bswap_buf = bswap_buf_mlib; 00450 } 00451 00452 void MPV_common_init_mlib(MpegEncContext *s) 00453 { 00454 if(s->avctx->dct_algo==FF_DCT_AUTO || s->avctx->dct_algo==FF_DCT_MLIB){ 00455 s->dsp.fdct = ff_fdct_mlib; 00456 } 00457 00458 if(s->avctx->idct_algo==FF_IDCT_MLIB){ 00459 s->dsp.idct_put= ff_idct_put_mlib; 00460 s->dsp.idct_add= ff_idct_add_mlib; 00461 s->dsp.idct = ff_idct_mlib; 00462 s->dsp.idct_permutation_type= FF_NO_IDCT_PERM; 00463 } 00464 }