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