00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00028 #if defined(TEMPLATE_RESAMPLE_DBL)
00029 # define RENAME(N) N ## _double
00030 # define FILTER_SHIFT 0
00031 # define DELEM double
00032 # define FELEM double
00033 # define FELEM2 double
00034 # define FELEML double
00035 # define OUT(d, v) d = v
00036
00037 #elif defined(TEMPLATE_RESAMPLE_FLT)
00038 # define RENAME(N) N ## _float
00039 # define FILTER_SHIFT 0
00040 # define DELEM float
00041 # define FELEM float
00042 # define FELEM2 float
00043 # define FELEML float
00044 # define OUT(d, v) d = v
00045
00046 #elif defined(TEMPLATE_RESAMPLE_S32)
00047 # define RENAME(N) N ## _int32
00048 # define FILTER_SHIFT 30
00049 # define DELEM int32_t
00050 # define FELEM int32_t
00051 # define FELEM2 int64_t
00052 # define FELEML int64_t
00053 # define FELEM_MAX INT32_MAX
00054 # define FELEM_MIN INT32_MIN
00055 # define OUT(d, v) v = (v + (1<<(FILTER_SHIFT-1)))>>FILTER_SHIFT;\
00056 d = (uint64_t)(v + 0x80000000) > 0xFFFFFFFF ? (v>>63) ^ 0x7FFFFFFF : v
00057
00058 #elif defined(TEMPLATE_RESAMPLE_S16) \
00059 || defined(TEMPLATE_RESAMPLE_S16_MMX2) \
00060 || defined(TEMPLATE_RESAMPLE_S16_SSSE3)
00061
00062 # define FILTER_SHIFT 15
00063 # define DELEM int16_t
00064 # define FELEM int16_t
00065 # define FELEM2 int32_t
00066 # define FELEML int64_t
00067 # define FELEM_MAX INT16_MAX
00068 # define FELEM_MIN INT16_MIN
00069 # define OUT(d, v) v = (v + (1<<(FILTER_SHIFT-1)))>>FILTER_SHIFT;\
00070 d = (unsigned)(v + 32768) > 65535 ? (v>>31) ^ 32767 : v
00071
00072 # if defined(TEMPLATE_RESAMPLE_S16)
00073 # define RENAME(N) N ## _int16
00074 # elif defined(TEMPLATE_RESAMPLE_S16_MMX2)
00075 # define COMMON_CORE COMMON_CORE_INT16_MMX2
00076 # define RENAME(N) N ## _int16_mmx2
00077 # elif defined(TEMPLATE_RESAMPLE_S16_SSSE3)
00078 # define COMMON_CORE COMMON_CORE_INT16_SSSE3
00079 # define RENAME(N) N ## _int16_ssse3
00080 # endif
00081
00082 #endif
00083
00084 int RENAME(swri_resample)(ResampleContext *c, DELEM *dst, const DELEM *src, int *consumed, int src_size, int dst_size, int update_ctx){
00085 int dst_index, i;
00086 int index= c->index;
00087 int frac= c->frac;
00088 int dst_incr_frac= c->dst_incr % c->src_incr;
00089 int dst_incr= c->dst_incr / c->src_incr;
00090 int compensation_distance= c->compensation_distance;
00091
00092 av_assert1(c->filter_shift == FILTER_SHIFT);
00093 av_assert1(c->felem_size == sizeof(FELEM));
00094
00095 if(compensation_distance == 0 && c->filter_length == 1 && c->phase_shift==0){
00096 int64_t index2= ((int64_t)index)<<32;
00097 int64_t incr= (1LL<<32) * c->dst_incr / c->src_incr;
00098 dst_size= FFMIN(dst_size, (src_size-1-index) * (int64_t)c->src_incr / c->dst_incr);
00099
00100 for(dst_index=0; dst_index < dst_size; dst_index++){
00101 dst[dst_index] = src[index2>>32];
00102 index2 += incr;
00103 }
00104 index += dst_index * dst_incr;
00105 index += (frac + dst_index * (int64_t)dst_incr_frac) / c->src_incr;
00106 frac = (frac + dst_index * (int64_t)dst_incr_frac) % c->src_incr;
00107 av_assert2(index >= 0);
00108 *consumed= index >> c->phase_shift;
00109 index &= c->phase_mask;
00110 }else if(compensation_distance == 0 && !c->linear && index >= 0){
00111 int sample_index = 0;
00112 for(dst_index=0; dst_index < dst_size; dst_index++){
00113 FELEM *filter;
00114 sample_index += index >> c->phase_shift;
00115 index &= c->phase_mask;
00116 filter= ((FELEM*)c->filter_bank) + c->filter_alloc*index;
00117
00118 if(sample_index + c->filter_length > src_size){
00119 break;
00120 }else{
00121 #ifdef COMMON_CORE
00122 COMMON_CORE
00123 #else
00124 FELEM2 val=0;
00125 for(i=0; i<c->filter_length; i++){
00126 val += src[sample_index + i] * (FELEM2)filter[i];
00127 }
00128 OUT(dst[dst_index], val);
00129 #endif
00130 }
00131
00132 frac += dst_incr_frac;
00133 index += dst_incr;
00134 if(frac >= c->src_incr){
00135 frac -= c->src_incr;
00136 index++;
00137 }
00138 }
00139 *consumed = sample_index;
00140 }else{
00141 int sample_index = 0;
00142 for(dst_index=0; dst_index < dst_size; dst_index++){
00143 FELEM *filter;
00144 FELEM2 val=0;
00145
00146 sample_index += index >> c->phase_shift;
00147 index &= c->phase_mask;
00148 filter = ((FELEM*)c->filter_bank) + c->filter_alloc*index;
00149
00150 if(sample_index + c->filter_length > src_size || -sample_index >= src_size){
00151 break;
00152 }else if(sample_index < 0){
00153 for(i=0; i<c->filter_length; i++)
00154 val += src[FFABS(sample_index + i)] * filter[i];
00155 }else if(c->linear){
00156 FELEM2 v2=0;
00157 for(i=0; i<c->filter_length; i++){
00158 val += src[sample_index + i] * (FELEM2)filter[i];
00159 v2 += src[sample_index + i] * (FELEM2)filter[i + c->filter_alloc];
00160 }
00161 val+=(v2-val)*(FELEML)frac / c->src_incr;
00162 }else{
00163 for(i=0; i<c->filter_length; i++){
00164 val += src[sample_index + i] * (FELEM2)filter[i];
00165 }
00166 }
00167
00168 OUT(dst[dst_index], val);
00169
00170 frac += dst_incr_frac;
00171 index += dst_incr;
00172 if(frac >= c->src_incr){
00173 frac -= c->src_incr;
00174 index++;
00175 }
00176
00177 if(dst_index + 1 == compensation_distance){
00178 compensation_distance= 0;
00179 dst_incr_frac= c->ideal_dst_incr % c->src_incr;
00180 dst_incr= c->ideal_dst_incr / c->src_incr;
00181 }
00182 }
00183 *consumed= FFMAX(sample_index, 0);
00184 index += FFMIN(sample_index, 0) << c->phase_shift;
00185
00186 if(compensation_distance){
00187 compensation_distance -= dst_index;
00188 av_assert1(compensation_distance > 0);
00189 }
00190 }
00191
00192 if(update_ctx){
00193 c->frac= frac;
00194 c->index= index;
00195 c->dst_incr= dst_incr_frac + c->src_incr*dst_incr;
00196 c->compensation_distance= compensation_distance;
00197 }
00198
00199 return dst_index;
00200 }
00201
00202 #undef COMMON_CORE
00203 #undef RENAME
00204 #undef FILTER_SHIFT
00205 #undef DELEM
00206 #undef FELEM
00207 #undef FELEM2
00208 #undef FELEML
00209 #undef FELEM_MAX
00210 #undef FELEM_MIN
00211 #undef OUT