00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023 #include "libavcodec/avcodec.h"
00024 #include "libavcodec/dsputil.h"
00025 #include "dsputil_sh4.h"
00026 #include "sh4.h"
00027
00028 static void memzero_align8(void *dst,size_t size)
00029 {
00030 int fpscr;
00031 fp_single_enter(fpscr);
00032 dst = (char *)dst + size;
00033 size /= 32;
00034 __asm__ volatile (
00035 " fldi0 fr0\n"
00036 " fldi0 fr1\n"
00037 " fschg\n"
00038 "1: \n" \
00039 " dt %1\n"
00040 " fmov dr0,@-%0\n"
00041 " fmov dr0,@-%0\n"
00042 " fmov dr0,@-%0\n"
00043 " bf.s 1b\n"
00044 " fmov dr0,@-%0\n"
00045 " fschg"
00046 : "+r"(dst),"+r"(size) :: "memory" );
00047 fp_single_leave(fpscr);
00048 }
00049
00050 static void clear_blocks_sh4(DCTELEM *blocks)
00051 {
00052 memzero_align8(blocks,sizeof(DCTELEM)*6*64);
00053 }
00054
00055 static void idct_put(uint8_t *dest, int line_size, DCTELEM *block)
00056 {
00057 int i;
00058 uint8_t *cm = ff_cropTbl + MAX_NEG_CROP;
00059 ff_idct_sh4(block);
00060 for(i=0;i<8;i++) {
00061 dest[0] = cm[block[0]];
00062 dest[1] = cm[block[1]];
00063 dest[2] = cm[block[2]];
00064 dest[3] = cm[block[3]];
00065 dest[4] = cm[block[4]];
00066 dest[5] = cm[block[5]];
00067 dest[6] = cm[block[6]];
00068 dest[7] = cm[block[7]];
00069 dest+=line_size;
00070 block+=8;
00071 }
00072 }
00073 static void idct_add(uint8_t *dest, int line_size, DCTELEM *block)
00074 {
00075 int i;
00076 uint8_t *cm = ff_cropTbl + MAX_NEG_CROP;
00077 ff_idct_sh4(block);
00078 for(i=0;i<8;i++) {
00079 dest[0] = cm[dest[0]+block[0]];
00080 dest[1] = cm[dest[1]+block[1]];
00081 dest[2] = cm[dest[2]+block[2]];
00082 dest[3] = cm[dest[3]+block[3]];
00083 dest[4] = cm[dest[4]+block[4]];
00084 dest[5] = cm[dest[5]+block[5]];
00085 dest[6] = cm[dest[6]+block[6]];
00086 dest[7] = cm[dest[7]+block[7]];
00087 dest+=line_size;
00088 block+=8;
00089 }
00090 }
00091
00092 void ff_dsputil_init_sh4(DSPContext* c, AVCodecContext *avctx)
00093 {
00094 const int idct_algo= avctx->idct_algo;
00095 const int high_bit_depth = avctx->bits_per_raw_sample > 8;
00096 ff_dsputil_init_align(c,avctx);
00097
00098 if (!high_bit_depth)
00099 c->clear_blocks = clear_blocks_sh4;
00100 if (avctx->bits_per_raw_sample <= 8 &&
00101 (idct_algo==FF_IDCT_AUTO || idct_algo==FF_IDCT_SH4)) {
00102 c->idct_put = idct_put;
00103 c->idct_add = idct_add;
00104 c->idct = ff_idct_sh4;
00105 c->idct_permutation_type= FF_NO_IDCT_PERM;
00106 }
00107 }