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