00001 /* 00002 * Copyright (C) 2012 Michael Niedermayer (michaelni@gmx.at) 00003 * 00004 * This file is part of libswresample 00005 * 00006 * libswresample is free software; you can redistribute it and/or 00007 * modify it under the terms of the GNU Lesser General Public 00008 * License as published by the Free Software Foundation; either 00009 * version 2.1 of the License, or (at your option) any later version. 00010 * 00011 * libswresample is distributed in the hope that it will be useful, 00012 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00013 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 00014 * Lesser General Public License for more details. 00015 * 00016 * You should have received a copy of the GNU Lesser General Public 00017 * License along with libswresample; if not, write to the Free Software 00018 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 00019 */ 00020 00021 #include "libavutil/avassert.h" 00022 #include "swresample_internal.h" 00023 00024 void swri_get_dither(SwrContext *s, void *dst, int len, unsigned seed, enum AVSampleFormat out_fmt, enum AVSampleFormat in_fmt) { 00025 double scale = 0; 00026 #define TMP_EXTRA 2 00027 double *tmp = av_malloc((len + TMP_EXTRA) * sizeof(double)); 00028 int i; 00029 00030 out_fmt = av_get_packed_sample_fmt(out_fmt); 00031 in_fmt = av_get_packed_sample_fmt( in_fmt); 00032 00033 if(in_fmt == AV_SAMPLE_FMT_FLT || in_fmt == AV_SAMPLE_FMT_DBL){ 00034 if(out_fmt == AV_SAMPLE_FMT_S32) scale = 1.0/(1L<<31); 00035 if(out_fmt == AV_SAMPLE_FMT_S16) scale = 1.0/(1L<<15); 00036 if(out_fmt == AV_SAMPLE_FMT_U8 ) scale = 1.0/(1L<< 7); 00037 } 00038 if(in_fmt == AV_SAMPLE_FMT_S32 && out_fmt == AV_SAMPLE_FMT_S16) scale = 1L<<16; 00039 if(in_fmt == AV_SAMPLE_FMT_S32 && out_fmt == AV_SAMPLE_FMT_U8 ) scale = 1L<<24; 00040 if(in_fmt == AV_SAMPLE_FMT_S16 && out_fmt == AV_SAMPLE_FMT_U8 ) scale = 1L<<8; 00041 00042 scale *= s->dither_scale; 00043 00044 for(i=0; i<len + TMP_EXTRA; i++){ 00045 double v; 00046 seed = seed* 1664525 + 1013904223; 00047 00048 switch(s->dither_method){ 00049 case SWR_DITHER_RECTANGULAR: v= ((double)seed) / UINT_MAX - 0.5; break; 00050 case SWR_DITHER_TRIANGULAR : 00051 case SWR_DITHER_TRIANGULAR_HIGHPASS : 00052 v = ((double)seed) / UINT_MAX; 00053 seed = seed*1664525 + 1013904223; 00054 v-= ((double)seed) / UINT_MAX; 00055 break; 00056 default: av_assert0(0); 00057 } 00058 tmp[i] = v; 00059 } 00060 00061 for(i=0; i<len; i++){ 00062 double v; 00063 00064 switch(s->dither_method){ 00065 case SWR_DITHER_RECTANGULAR: 00066 case SWR_DITHER_TRIANGULAR : 00067 v = tmp[i]; 00068 break; 00069 case SWR_DITHER_TRIANGULAR_HIGHPASS : 00070 v = (- tmp[i] + 2*tmp[i+1] - tmp[i+2]) / sqrt(6); 00071 break; 00072 default: av_assert0(0); 00073 } 00074 00075 v*= scale; 00076 00077 switch(in_fmt){ 00078 case AV_SAMPLE_FMT_S16: ((int16_t*)dst)[i] = v; break; 00079 case AV_SAMPLE_FMT_S32: ((int32_t*)dst)[i] = v; break; 00080 case AV_SAMPLE_FMT_FLT: ((float *)dst)[i] = v; break; 00081 case AV_SAMPLE_FMT_DBL: ((double *)dst)[i] = v; break; 00082 default: av_assert0(0); 00083 } 00084 } 00085 00086 av_free(tmp); 00087 }