00001 
00002 
00003 
00004 
00005 
00006 
00007 
00008 
00009 
00010 
00011 
00012 
00013 
00014 
00015 
00016 
00017 
00018 
00019 
00020 
00021 #include "libavutil/opt.h"
00022 #include "swresample_internal.h"
00023 #include "audioconvert.h"
00024 #include "libavutil/avassert.h"
00025 #include "libavutil/audioconvert.h"
00026 
00027 #include <float.h>
00028 
00029 #define  C30DB  M_SQRT2
00030 #define  C15DB  1.189207115
00031 #define C__0DB  1.0
00032 #define C_15DB  0.840896415
00033 #define C_30DB  M_SQRT1_2
00034 #define C_45DB  0.594603558
00035 #define C_60DB  0.5
00036 
00037 #define ALIGN 32
00038 
00039 
00040 #define OFFSET(x) offsetof(SwrContext,x)
00041 #define PARAM AV_OPT_FLAG_AUDIO_PARAM
00042 
00043 static const AVOption options[]={
00044 {"ich"                  ,  "Input Channel Count"        , OFFSET( in.ch_count   ), AV_OPT_TYPE_INT  , {.i64=2                     }, 0      , SWR_CH_MAX, PARAM},
00045 {"in_channel_count"     ,  "Input Channel Count"        , OFFSET( in.ch_count   ), AV_OPT_TYPE_INT  , {.i64=2                     }, 0      , SWR_CH_MAX, PARAM},
00046 {"och"                  , "Output Channel Count"        , OFFSET(out.ch_count   ), AV_OPT_TYPE_INT  , {.i64=2                     }, 0      , SWR_CH_MAX, PARAM},
00047 {"out_channel_count"    , "Output Channel Count"        , OFFSET(out.ch_count   ), AV_OPT_TYPE_INT  , {.i64=2                     }, 0      , SWR_CH_MAX, PARAM},
00048 {"uch"                  ,   "Used Channel Count"        , OFFSET(used_ch_count  ), AV_OPT_TYPE_INT  , {.i64=0                     }, 0      , SWR_CH_MAX, PARAM},
00049 {"used_channel_count"   ,   "Used Channel Count"        , OFFSET(used_ch_count  ), AV_OPT_TYPE_INT  , {.i64=0                     }, 0      , SWR_CH_MAX, PARAM},
00050 {"isr"                  ,  "Input Sample Rate"          , OFFSET( in_sample_rate), AV_OPT_TYPE_INT  , {.i64=0                     }, 0      , INT_MAX   , PARAM},
00051 {"in_sample_rate"       ,  "Input Sample Rate"          , OFFSET( in_sample_rate), AV_OPT_TYPE_INT  , {.i64=0                     }, 0      , INT_MAX   , PARAM},
00052 {"osr"                  , "Output Sample Rate"          , OFFSET(out_sample_rate), AV_OPT_TYPE_INT  , {.i64=0                     }, 0      , INT_MAX   , PARAM},
00053 {"out_sample_rate"      , "Output Sample Rate"          , OFFSET(out_sample_rate), AV_OPT_TYPE_INT  , {.i64=0                     }, 0      , INT_MAX   , PARAM},
00054 {"isf"                  ,    "Input Sample Format"      , OFFSET( in_sample_fmt ), AV_OPT_TYPE_INT  , {.i64=AV_SAMPLE_FMT_NONE    }, -1     , AV_SAMPLE_FMT_NB-1+256, PARAM},
00055 {"in_sample_fmt"        ,    "Input Sample Format"      , OFFSET( in_sample_fmt ), AV_OPT_TYPE_INT  , {.i64=AV_SAMPLE_FMT_NONE    }, -1     , AV_SAMPLE_FMT_NB-1+256, PARAM},
00056 {"osf"                  ,   "Output Sample Format"      , OFFSET(out_sample_fmt ), AV_OPT_TYPE_INT  , {.i64=AV_SAMPLE_FMT_NONE    }, -1     , AV_SAMPLE_FMT_NB-1+256, PARAM},
00057 {"out_sample_fmt"       ,   "Output Sample Format"      , OFFSET(out_sample_fmt ), AV_OPT_TYPE_INT  , {.i64=AV_SAMPLE_FMT_NONE    }, -1     , AV_SAMPLE_FMT_NB-1+256, PARAM},
00058 {"tsf"                  , "Internal Sample Format"      , OFFSET(int_sample_fmt ), AV_OPT_TYPE_INT  , {.i64=AV_SAMPLE_FMT_NONE    }, -1     , AV_SAMPLE_FMT_FLTP, PARAM},
00059 {"internal_sample_fmt"  , "Internal Sample Format"      , OFFSET(int_sample_fmt ), AV_OPT_TYPE_INT  , {.i64=AV_SAMPLE_FMT_NONE    }, -1     , AV_SAMPLE_FMT_FLTP, PARAM},
00060 {"icl"                  ,   "Input Channel Layout"      , OFFSET( in_ch_layout  ), AV_OPT_TYPE_INT64, {.i64=0                     }, 0      , INT64_MAX , PARAM, "channel_layout"},
00061 {"in_channel_layout"    ,   "Input Channel Layout"      , OFFSET( in_ch_layout  ), AV_OPT_TYPE_INT64, {.i64=0                     }, 0      , INT64_MAX , PARAM, "channel_layout"},
00062 {"ocl"                  ,  "Output Channel Layout"      , OFFSET(out_ch_layout  ), AV_OPT_TYPE_INT64, {.i64=0                     }, 0      , INT64_MAX , PARAM, "channel_layout"},
00063 {"out_channel_layout"   ,  "Output Channel Layout"      , OFFSET(out_ch_layout  ), AV_OPT_TYPE_INT64, {.i64=0                     }, 0      , INT64_MAX , PARAM, "channel_layout"},
00064 {"clev"                 ,    "Center Mix Level"         , OFFSET(clev           ), AV_OPT_TYPE_FLOAT, {.dbl=C_30DB                }, -32    , 32        , PARAM},
00065 {"center_mix_level"     ,    "Center Mix Level"         , OFFSET(clev           ), AV_OPT_TYPE_FLOAT, {.dbl=C_30DB                }, -32    , 32        , PARAM},
00066 {"slev"                 , "Sourround Mix Level"         , OFFSET(slev           ), AV_OPT_TYPE_FLOAT, {.dbl=C_30DB                }, -32    , 32        , PARAM},
00067 {"surround_mix_level"   , "Sourround Mix Level"         , OFFSET(slev           ), AV_OPT_TYPE_FLOAT, {.dbl=C_30DB                }, -32    , 32        , PARAM},
00068 {"lfe_mix_level"        , "LFE Mix Level"               , OFFSET(lfe_mix_level  ), AV_OPT_TYPE_FLOAT, {.dbl=0                     }, -32    , 32        , PARAM},
00069 {"rmvol"                , "Rematrix Volume"             , OFFSET(rematrix_volume), AV_OPT_TYPE_FLOAT, {.dbl=1.0                   }, -1000  , 1000      , PARAM},
00070 {"rematrix_volume"      , "Rematrix Volume"             , OFFSET(rematrix_volume), AV_OPT_TYPE_FLOAT, {.dbl=1.0                   }, -1000  , 1000      , PARAM},
00071 {"flags"                , NULL                          , OFFSET(flags          ), AV_OPT_TYPE_FLAGS, {.i64=0                     }, 0      , UINT_MAX  , PARAM, "flags"},
00072 {"swr_flags"            , NULL                          , OFFSET(flags          ), AV_OPT_TYPE_FLAGS, {.i64=0                     }, 0      , UINT_MAX  , PARAM, "flags"},
00073 {"res"                  , "Force Resampling"            , 0                      , AV_OPT_TYPE_CONST, {.i64=SWR_FLAG_RESAMPLE     }, INT_MIN, INT_MAX   , PARAM, "flags"},
00074 {"dither_scale"         , "Dither Scale"                , OFFSET(dither_scale   ), AV_OPT_TYPE_FLOAT, {.dbl=1                     }, 0      , INT_MAX   , PARAM},
00075 {"dither_method"        , "Dither Method"               , OFFSET(dither_method  ), AV_OPT_TYPE_INT  , {.i64=0                     }, 0      , SWR_DITHER_NB-1, PARAM, "dither_method"},
00076 {"rectangular"          , "Rectangular Dither"          , 0                      , AV_OPT_TYPE_CONST, {.i64=SWR_DITHER_RECTANGULAR}, INT_MIN, INT_MAX   , PARAM, "dither_method"},
00077 {"triangular"           ,  "Triangular Dither"          , 0                      , AV_OPT_TYPE_CONST, {.i64=SWR_DITHER_TRIANGULAR }, INT_MIN, INT_MAX   , PARAM, "dither_method"},
00078 {"triangular_hp"        , "Triangular Dither With High Pass" , 0                 , AV_OPT_TYPE_CONST, {.i64=SWR_DITHER_TRIANGULAR_HIGHPASS }, INT_MIN, INT_MAX, PARAM, "dither_method"},
00079 {"filter_size"          , "Resampling Filter Size"      , OFFSET(filter_size)    , AV_OPT_TYPE_INT  , {.i64=16                    }, 0      , INT_MAX   , PARAM },
00080 {"phase_shift"          , "Resampling Phase Shift"      , OFFSET(phase_shift)    , AV_OPT_TYPE_INT  , {.i64=10                    }, 0      , 30        , PARAM },
00081 {"linear_interp"        , "Use Linear Interpolation"    , OFFSET(linear_interp)  , AV_OPT_TYPE_INT  , {.i64=0                     }, 0      , 1         , PARAM },
00082 {"cutoff"               , "Cutoff Frequency Ratio"      , OFFSET(cutoff)         , AV_OPT_TYPE_DOUBLE,{.dbl=0.8                   }, 0      , 1         , PARAM },
00083 {"min_comp"             , "Minimum difference between timestamps and audio data (in seconds) below which no timestamp compensation of either kind is applied"
00084                                                         , OFFSET(min_compensation),AV_OPT_TYPE_FLOAT ,{.dbl=FLT_MAX               }, 0      , FLT_MAX   , PARAM },
00085 {"min_hard_comp"        , "Minimum difference between timestamps and audio data (in seconds) to trigger padding/trimming the data."
00086                                                    , OFFSET(min_hard_compensation),AV_OPT_TYPE_FLOAT ,{.dbl=0.1                   }, 0      , INT_MAX   , PARAM },
00087 {"comp_duration"        , "Duration (in seconds) over which data is stretched/squeezed to make it match the timestamps."
00088                                               , OFFSET(soft_compensation_duration),AV_OPT_TYPE_FLOAT ,{.dbl=1                     }, 0      , INT_MAX   , PARAM },
00089 {"max_soft_comp"        , "Maximum factor by which data is stretched/squeezed to make it match the timestamps."
00090                                                    , OFFSET(max_soft_compensation),AV_OPT_TYPE_FLOAT ,{.dbl=0                     }, INT_MIN, INT_MAX   , PARAM },
00091 { "matrix_encoding"     , "Matrixed Stereo Encoding"    , OFFSET(matrix_encoding), AV_OPT_TYPE_INT   ,{.i64 = AV_MATRIX_ENCODING_NONE}, AV_MATRIX_ENCODING_NONE,     AV_MATRIX_ENCODING_NB-1, PARAM, "matrix_encoding" },
00092     { "none",  "None",               0, AV_OPT_TYPE_CONST, { .i64 = AV_MATRIX_ENCODING_NONE  }, INT_MIN, INT_MAX, PARAM, "matrix_encoding" },
00093     { "dolby", "Dolby",              0, AV_OPT_TYPE_CONST, { .i64 = AV_MATRIX_ENCODING_DOLBY }, INT_MIN, INT_MAX, PARAM, "matrix_encoding" },
00094     { "dplii", "Dolby Pro Logic II", 0, AV_OPT_TYPE_CONST, { .i64 = AV_MATRIX_ENCODING_DPLII }, INT_MIN, INT_MAX, PARAM, "matrix_encoding" },
00095 { "filter_type"         , "Filter Type"                 , OFFSET(filter_type)    , AV_OPT_TYPE_INT  , { .i64 = SWR_FILTER_TYPE_KAISER }, SWR_FILTER_TYPE_CUBIC, SWR_FILTER_TYPE_KAISER, PARAM, "filter_type" },
00096     { "cubic"           , "Cubic"                       , 0                      , AV_OPT_TYPE_CONST, { .i64 = SWR_FILTER_TYPE_CUBIC            }, INT_MIN, INT_MAX, PARAM, "filter_type" },
00097     { "blackman_nuttall", "Blackman Nuttall Windowed Sinc", 0                    , AV_OPT_TYPE_CONST, { .i64 = SWR_FILTER_TYPE_BLACKMAN_NUTTALL }, INT_MIN, INT_MAX, PARAM, "filter_type" },
00098     { "kaiser"          , "Kaiser Windowed Sinc"        , 0                      , AV_OPT_TYPE_CONST, { .i64 = SWR_FILTER_TYPE_KAISER           }, INT_MIN, INT_MAX, PARAM, "filter_type" },
00099 { "kaiser_beta"         , "Kaiser Window Beta"          ,OFFSET(kaiser_beta)     , AV_OPT_TYPE_INT  , {.i64=9                     }, 2      , 16        , PARAM },
00100 
00101 {0}
00102 };
00103 
00104 static const char* context_to_name(void* ptr) {
00105     return "SWR";
00106 }
00107 
00108 static const AVClass av_class = {
00109     .class_name                = "SWResampler",
00110     .item_name                 = context_to_name,
00111     .option                    = options,
00112     .version                   = LIBAVUTIL_VERSION_INT,
00113     .log_level_offset_offset   = OFFSET(log_level_offset),
00114     .parent_log_context_offset = OFFSET(log_ctx),
00115     .category                  = AV_CLASS_CATEGORY_SWRESAMPLER,
00116 };
00117 
00118 unsigned swresample_version(void)
00119 {
00120     av_assert0(LIBSWRESAMPLE_VERSION_MICRO >= 100);
00121     return LIBSWRESAMPLE_VERSION_INT;
00122 }
00123 
00124 const char *swresample_configuration(void)
00125 {
00126     return FFMPEG_CONFIGURATION;
00127 }
00128 
00129 const char *swresample_license(void)
00130 {
00131 #define LICENSE_PREFIX "libswresample license: "
00132     return LICENSE_PREFIX FFMPEG_LICENSE + sizeof(LICENSE_PREFIX) - 1;
00133 }
00134 
00135 int swr_set_channel_mapping(struct SwrContext *s, const int *channel_map){
00136     if(!s || s->in_convert) 
00137         return AVERROR(EINVAL);
00138     s->channel_map = channel_map;
00139     return 0;
00140 }
00141 
00142 const AVClass *swr_get_class(void)
00143 {
00144     return &av_class;
00145 }
00146 
00147 av_cold struct SwrContext *swr_alloc(void){
00148     SwrContext *s= av_mallocz(sizeof(SwrContext));
00149     if(s){
00150         s->av_class= &av_class;
00151         av_opt_set_defaults(s);
00152     }
00153     return s;
00154 }
00155 
00156 struct SwrContext *swr_alloc_set_opts(struct SwrContext *s,
00157                                       int64_t out_ch_layout, enum AVSampleFormat out_sample_fmt, int out_sample_rate,
00158                                       int64_t  in_ch_layout, enum AVSampleFormat  in_sample_fmt, int  in_sample_rate,
00159                                       int log_offset, void *log_ctx){
00160     if(!s) s= swr_alloc();
00161     if(!s) return NULL;
00162 
00163     s->log_level_offset= log_offset;
00164     s->log_ctx= log_ctx;
00165 
00166     av_opt_set_int(s, "ocl", out_ch_layout,   0);
00167     av_opt_set_int(s, "osf", out_sample_fmt,  0);
00168     av_opt_set_int(s, "osr", out_sample_rate, 0);
00169     av_opt_set_int(s, "icl", in_ch_layout,    0);
00170     av_opt_set_int(s, "isf", in_sample_fmt,   0);
00171     av_opt_set_int(s, "isr", in_sample_rate,  0);
00172     av_opt_set_int(s, "tsf", AV_SAMPLE_FMT_NONE,   0);
00173     av_opt_set_int(s, "ich", av_get_channel_layout_nb_channels(s-> in_ch_layout), 0);
00174     av_opt_set_int(s, "och", av_get_channel_layout_nb_channels(s->out_ch_layout), 0);
00175     av_opt_set_int(s, "uch", 0, 0);
00176     return s;
00177 }
00178 
00179 static void set_audiodata_fmt(AudioData *a, enum AVSampleFormat fmt){
00180     a->fmt   = fmt;
00181     a->bps   = av_get_bytes_per_sample(fmt);
00182     a->planar= av_sample_fmt_is_planar(fmt);
00183 }
00184 
00185 static void free_temp(AudioData *a){
00186     av_free(a->data);
00187     memset(a, 0, sizeof(*a));
00188 }
00189 
00190 av_cold void swr_free(SwrContext **ss){
00191     SwrContext *s= *ss;
00192     if(s){
00193         free_temp(&s->postin);
00194         free_temp(&s->midbuf);
00195         free_temp(&s->preout);
00196         free_temp(&s->in_buffer);
00197         free_temp(&s->dither);
00198         swri_audio_convert_free(&s-> in_convert);
00199         swri_audio_convert_free(&s->out_convert);
00200         swri_audio_convert_free(&s->full_convert);
00201         swri_resample_free(&s->resample);
00202         swri_rematrix_free(s);
00203     }
00204 
00205     av_freep(ss);
00206 }
00207 
00208 av_cold int swr_init(struct SwrContext *s){
00209     s->in_buffer_index= 0;
00210     s->in_buffer_count= 0;
00211     s->resample_in_constraint= 0;
00212     free_temp(&s->postin);
00213     free_temp(&s->midbuf);
00214     free_temp(&s->preout);
00215     free_temp(&s->in_buffer);
00216     free_temp(&s->dither);
00217     memset(s->in.ch, 0, sizeof(s->in.ch));
00218     memset(s->out.ch, 0, sizeof(s->out.ch));
00219     swri_audio_convert_free(&s-> in_convert);
00220     swri_audio_convert_free(&s->out_convert);
00221     swri_audio_convert_free(&s->full_convert);
00222     swri_rematrix_free(s);
00223 
00224     s->flushed = 0;
00225 
00226     if(s-> in_sample_fmt >= AV_SAMPLE_FMT_NB){
00227         av_log(s, AV_LOG_ERROR, "Requested input sample format %d is invalid\n", s->in_sample_fmt);
00228         return AVERROR(EINVAL);
00229     }
00230     if(s->out_sample_fmt >= AV_SAMPLE_FMT_NB){
00231         av_log(s, AV_LOG_ERROR, "Requested output sample format %d is invalid\n", s->out_sample_fmt);
00232         return AVERROR(EINVAL);
00233     }
00234 
00235     if(s->int_sample_fmt == AV_SAMPLE_FMT_NONE){
00236         if(av_get_planar_sample_fmt(s->in_sample_fmt) <= AV_SAMPLE_FMT_S16P){
00237             s->int_sample_fmt= AV_SAMPLE_FMT_S16P;
00238         }else if(av_get_planar_sample_fmt(s->in_sample_fmt) <= AV_SAMPLE_FMT_FLTP){
00239             s->int_sample_fmt= AV_SAMPLE_FMT_FLTP;
00240         }else{
00241             av_log(s, AV_LOG_DEBUG, "Using double precision mode\n");
00242             s->int_sample_fmt= AV_SAMPLE_FMT_DBLP;
00243         }
00244     }
00245 
00246     if(   s->int_sample_fmt != AV_SAMPLE_FMT_S16P
00247         &&s->int_sample_fmt != AV_SAMPLE_FMT_S32P
00248         &&s->int_sample_fmt != AV_SAMPLE_FMT_FLTP
00249         &&s->int_sample_fmt != AV_SAMPLE_FMT_DBLP){
00250         av_log(s, AV_LOG_ERROR, "Requested sample format %s is not supported internally, S16/S32/FLT/DBL is supported\n", av_get_sample_fmt_name(s->int_sample_fmt));
00251         return AVERROR(EINVAL);
00252     }
00253 
00254     set_audiodata_fmt(&s-> in, s-> in_sample_fmt);
00255     set_audiodata_fmt(&s->out, s->out_sample_fmt);
00256 
00257     if (s->out_sample_rate!=s->in_sample_rate || (s->flags & SWR_FLAG_RESAMPLE)){
00258         s->resample = swri_resample_init(s->resample, s->out_sample_rate, s->in_sample_rate, s->filter_size, s->phase_shift, s->linear_interp, s->cutoff, s->int_sample_fmt, s->filter_type, s->kaiser_beta);
00259     }else
00260         swri_resample_free(&s->resample);
00261     if(    s->int_sample_fmt != AV_SAMPLE_FMT_S16P
00262         && s->int_sample_fmt != AV_SAMPLE_FMT_S32P
00263         && s->int_sample_fmt != AV_SAMPLE_FMT_FLTP
00264         && s->int_sample_fmt != AV_SAMPLE_FMT_DBLP
00265         && s->resample){
00266         av_log(s, AV_LOG_ERROR, "Resampling only supported with internal s16/s32/flt/dbl\n");
00267         return -1;
00268     }
00269 
00270     if(!s->used_ch_count)
00271         s->used_ch_count= s->in.ch_count;
00272 
00273     if(s->used_ch_count && s-> in_ch_layout && s->used_ch_count != av_get_channel_layout_nb_channels(s-> in_ch_layout)){
00274         av_log(s, AV_LOG_WARNING, "Input channel layout has a different number of channels than the number of used channels, ignoring layout\n");
00275         s-> in_ch_layout= 0;
00276     }
00277 
00278     if(!s-> in_ch_layout)
00279         s-> in_ch_layout= av_get_default_channel_layout(s->used_ch_count);
00280     if(!s->out_ch_layout)
00281         s->out_ch_layout= av_get_default_channel_layout(s->out.ch_count);
00282 
00283     s->rematrix= s->out_ch_layout  !=s->in_ch_layout || s->rematrix_volume!=1.0 ||
00284                  s->rematrix_custom;
00285 
00286 #define RSC 1 //FIXME finetune
00287     if(!s-> in.ch_count)
00288         s-> in.ch_count= av_get_channel_layout_nb_channels(s-> in_ch_layout);
00289     if(!s->used_ch_count)
00290         s->used_ch_count= s->in.ch_count;
00291     if(!s->out.ch_count)
00292         s->out.ch_count= av_get_channel_layout_nb_channels(s->out_ch_layout);
00293 
00294     if(!s-> in.ch_count){
00295         av_assert0(!s->in_ch_layout);
00296         av_log(s, AV_LOG_ERROR, "Input channel count and layout are unset\n");
00297         return -1;
00298     }
00299 
00300     if ((!s->out_ch_layout || !s->in_ch_layout) && s->used_ch_count != s->out.ch_count && !s->rematrix_custom) {
00301         av_log(s, AV_LOG_ERROR, "Rematrix is needed but there is not enough information to do it\n");
00302         return -1;
00303     }
00304 
00305 av_assert0(s->used_ch_count);
00306 av_assert0(s->out.ch_count);
00307     s->resample_first= RSC*s->out.ch_count/s->in.ch_count - RSC < s->out_sample_rate/(float)s-> in_sample_rate - 1.0;
00308 
00309     s->in_buffer= s->in;
00310 
00311     if(!s->resample && !s->rematrix && !s->channel_map && !s->dither_method){
00312         s->full_convert = swri_audio_convert_alloc(s->out_sample_fmt,
00313                                                    s-> in_sample_fmt, s-> in.ch_count, NULL, 0);
00314         return 0;
00315     }
00316 
00317     s->in_convert = swri_audio_convert_alloc(s->int_sample_fmt,
00318                                              s-> in_sample_fmt, s->used_ch_count, s->channel_map, 0);
00319     s->out_convert= swri_audio_convert_alloc(s->out_sample_fmt,
00320                                              s->int_sample_fmt, s->out.ch_count, NULL, 0);
00321 
00322 
00323     s->postin= s->in;
00324     s->preout= s->out;
00325     s->midbuf= s->in;
00326 
00327     if(s->channel_map){
00328         s->postin.ch_count=
00329         s->midbuf.ch_count= s->used_ch_count;
00330         if(s->resample)
00331             s->in_buffer.ch_count= s->used_ch_count;
00332     }
00333     if(!s->resample_first){
00334         s->midbuf.ch_count= s->out.ch_count;
00335         if(s->resample)
00336             s->in_buffer.ch_count = s->out.ch_count;
00337     }
00338 
00339     set_audiodata_fmt(&s->postin, s->int_sample_fmt);
00340     set_audiodata_fmt(&s->midbuf, s->int_sample_fmt);
00341     set_audiodata_fmt(&s->preout, s->int_sample_fmt);
00342 
00343     if(s->resample){
00344         set_audiodata_fmt(&s->in_buffer, s->int_sample_fmt);
00345     }
00346 
00347     s->dither = s->preout;
00348 
00349     if(s->rematrix || s->dither_method)
00350         return swri_rematrix_init(s);
00351 
00352     return 0;
00353 }
00354 
00355 static int realloc_audio(AudioData *a, int count){
00356     int i, countb;
00357     AudioData old;
00358 
00359     if(count < 0 || count > INT_MAX/2/a->bps/a->ch_count)
00360         return AVERROR(EINVAL);
00361 
00362     if(a->count >= count)
00363         return 0;
00364 
00365     count*=2;
00366 
00367     countb= FFALIGN(count*a->bps, ALIGN);
00368     old= *a;
00369 
00370     av_assert0(a->bps);
00371     av_assert0(a->ch_count);
00372 
00373     a->data= av_mallocz(countb*a->ch_count);
00374     if(!a->data)
00375         return AVERROR(ENOMEM);
00376     for(i=0; i<a->ch_count; i++){
00377         a->ch[i]= a->data + i*(a->planar ? countb : a->bps);
00378         if(a->planar) memcpy(a->ch[i], old.ch[i], a->count*a->bps);
00379     }
00380     if(!a->planar) memcpy(a->ch[0], old.ch[0], a->count*a->ch_count*a->bps);
00381     av_free(old.data);
00382     a->count= count;
00383 
00384     return 1;
00385 }
00386 
00387 static void copy(AudioData *out, AudioData *in,
00388                  int count){
00389     av_assert0(out->planar == in->planar);
00390     av_assert0(out->bps == in->bps);
00391     av_assert0(out->ch_count == in->ch_count);
00392     if(out->planar){
00393         int ch;
00394         for(ch=0; ch<out->ch_count; ch++)
00395             memcpy(out->ch[ch], in->ch[ch], count*out->bps);
00396     }else
00397         memcpy(out->ch[0], in->ch[0], count*out->ch_count*out->bps);
00398 }
00399 
00400 static void fill_audiodata(AudioData *out, uint8_t *in_arg [SWR_CH_MAX]){
00401     int i;
00402     if(!in_arg){
00403         memset(out->ch, 0, sizeof(out->ch));
00404     }else if(out->planar){
00405         for(i=0; i<out->ch_count; i++)
00406             out->ch[i]= in_arg[i];
00407     }else{
00408         for(i=0; i<out->ch_count; i++)
00409             out->ch[i]= in_arg[0] + i*out->bps;
00410     }
00411 }
00412 
00413 static void reversefill_audiodata(AudioData *out, uint8_t *in_arg [SWR_CH_MAX]){
00414     int i;
00415     if(out->planar){
00416         for(i=0; i<out->ch_count; i++)
00417             in_arg[i]= out->ch[i];
00418     }else{
00419         in_arg[0]= out->ch[0];
00420     }
00421 }
00422 
00427 static void buf_set(AudioData *out, AudioData *in, int count){
00428     int ch;
00429     if(in->planar){
00430         for(ch=0; ch<out->ch_count; ch++)
00431             out->ch[ch]= in->ch[ch] + count*out->bps;
00432     }else{
00433         for(ch=out->ch_count-1; ch>=0; ch--)
00434             out->ch[ch]= in->ch[0] + (ch + count*out->ch_count) * out->bps;
00435     }
00436 }
00437 
00442 static int resample(SwrContext *s, AudioData *out_param, int out_count,
00443                              const AudioData * in_param, int in_count){
00444     AudioData in, out, tmp;
00445     int ret_sum=0;
00446     int border=0;
00447 
00448     av_assert1(s->in_buffer.ch_count == in_param->ch_count);
00449     av_assert1(s->in_buffer.planar   == in_param->planar);
00450     av_assert1(s->in_buffer.fmt      == in_param->fmt);
00451 
00452     tmp=out=*out_param;
00453     in =  *in_param;
00454 
00455     do{
00456         int ret, size, consumed;
00457         if(!s->resample_in_constraint && s->in_buffer_count){
00458             buf_set(&tmp, &s->in_buffer, s->in_buffer_index);
00459             ret= swri_multiple_resample(s->resample, &out, out_count, &tmp, s->in_buffer_count, &consumed);
00460             out_count -= ret;
00461             ret_sum += ret;
00462             buf_set(&out, &out, ret);
00463             s->in_buffer_count -= consumed;
00464             s->in_buffer_index += consumed;
00465 
00466             if(!in_count)
00467                 break;
00468             if(s->in_buffer_count <= border){
00469                 buf_set(&in, &in, -s->in_buffer_count);
00470                 in_count += s->in_buffer_count;
00471                 s->in_buffer_count=0;
00472                 s->in_buffer_index=0;
00473                 border = 0;
00474             }
00475         }
00476 
00477         if(in_count && !s->in_buffer_count){
00478             s->in_buffer_index=0;
00479             ret= swri_multiple_resample(s->resample, &out, out_count, &in, in_count, &consumed);
00480             out_count -= ret;
00481             ret_sum += ret;
00482             buf_set(&out, &out, ret);
00483             in_count -= consumed;
00484             buf_set(&in, &in, consumed);
00485         }
00486 
00487         
00488         size= s->in_buffer_index + s->in_buffer_count + in_count;
00489         if(   size > s->in_buffer.count
00490            && s->in_buffer_count + in_count <= s->in_buffer_index){
00491             buf_set(&tmp, &s->in_buffer, s->in_buffer_index);
00492             copy(&s->in_buffer, &tmp, s->in_buffer_count);
00493             s->in_buffer_index=0;
00494         }else
00495             if((ret=realloc_audio(&s->in_buffer, size)) < 0)
00496                 return ret;
00497 
00498         if(in_count){
00499             int count= in_count;
00500             if(s->in_buffer_count && s->in_buffer_count+2 < count && out_count) count= s->in_buffer_count+2;
00501 
00502             buf_set(&tmp, &s->in_buffer, s->in_buffer_index + s->in_buffer_count);
00503             copy(&tmp, &in, count);
00504             s->in_buffer_count += count;
00505             in_count -= count;
00506             border += count;
00507             buf_set(&in, &in, count);
00508             s->resample_in_constraint= 0;
00509             if(s->in_buffer_count != count || in_count)
00510                 continue;
00511         }
00512         break;
00513     }while(1);
00514 
00515     s->resample_in_constraint= !!out_count;
00516 
00517     return ret_sum;
00518 }
00519 
00520 static int swr_convert_internal(struct SwrContext *s, AudioData *out, int out_count,
00521                                                       AudioData *in , int  in_count){
00522     AudioData *postin, *midbuf, *preout;
00523     int ret;
00524     AudioData preout_tmp, midbuf_tmp;
00525 
00526     if(s->full_convert){
00527         av_assert0(!s->resample);
00528         swri_audio_convert(s->full_convert, out, in, in_count);
00529         return out_count;
00530     }
00531 
00532 
00533 
00534 
00535     if((ret=realloc_audio(&s->postin, in_count))<0)
00536         return ret;
00537     if(s->resample_first){
00538         av_assert0(s->midbuf.ch_count == s->used_ch_count);
00539         if((ret=realloc_audio(&s->midbuf, out_count))<0)
00540             return ret;
00541     }else{
00542         av_assert0(s->midbuf.ch_count ==  s->out.ch_count);
00543         if((ret=realloc_audio(&s->midbuf,  in_count))<0)
00544             return ret;
00545     }
00546     if((ret=realloc_audio(&s->preout, out_count))<0)
00547         return ret;
00548 
00549     postin= &s->postin;
00550 
00551     midbuf_tmp= s->midbuf;
00552     midbuf= &midbuf_tmp;
00553     preout_tmp= s->preout;
00554     preout= &preout_tmp;
00555 
00556     if(s->int_sample_fmt == s-> in_sample_fmt && s->in.planar && !s->channel_map)
00557         postin= in;
00558 
00559     if(s->resample_first ? !s->resample : !s->rematrix)
00560         midbuf= postin;
00561 
00562     if(s->resample_first ? !s->rematrix : !s->resample)
00563         preout= midbuf;
00564 
00565     if(s->int_sample_fmt == s->out_sample_fmt && s->out.planar){
00566         if(preout==in){
00567             out_count= FFMIN(out_count, in_count); 
00568             av_assert0(s->in.planar); 
00569             copy(out, in, out_count);
00570             return out_count;
00571         }
00572         else if(preout==postin) preout= midbuf= postin= out;
00573         else if(preout==midbuf) preout= midbuf= out;
00574         else                    preout= out;
00575     }
00576 
00577     if(in != postin){
00578         swri_audio_convert(s->in_convert, postin, in, in_count);
00579     }
00580 
00581     if(s->resample_first){
00582         if(postin != midbuf)
00583             out_count= resample(s, midbuf, out_count, postin, in_count);
00584         if(midbuf != preout)
00585             swri_rematrix(s, preout, midbuf, out_count, preout==out);
00586     }else{
00587         if(postin != midbuf)
00588             swri_rematrix(s, midbuf, postin, in_count, midbuf==out);
00589         if(midbuf != preout)
00590             out_count= resample(s, preout, out_count, midbuf, in_count);
00591     }
00592 
00593     if(preout != out && out_count){
00594         if(s->dither_method){
00595             int ch;
00596             int dither_count= FFMAX(out_count, 1<<16);
00597             av_assert0(preout != in);
00598 
00599             if((ret=realloc_audio(&s->dither, dither_count))<0)
00600                 return ret;
00601             if(ret)
00602                 for(ch=0; ch<s->dither.ch_count; ch++)
00603                     swri_get_dither(s, s->dither.ch[ch], s->dither.count, 12345678913579<<ch, s->out_sample_fmt, s->int_sample_fmt);
00604             av_assert0(s->dither.ch_count == preout->ch_count);
00605 
00606             if(s->dither_pos + out_count > s->dither.count)
00607                 s->dither_pos = 0;
00608 
00609             for(ch=0; ch<preout->ch_count; ch++)
00610                 s->mix_2_1_f(preout->ch[ch], preout->ch[ch], s->dither.ch[ch] + s->dither.bps * s->dither_pos, s->native_one, 0, 0, out_count);
00611 
00612             s->dither_pos += out_count;
00613         }
00614 
00615         swri_audio_convert(s->out_convert, out, preout, out_count);
00616     }
00617     return out_count;
00618 }
00619 
00620 int swr_convert(struct SwrContext *s, uint8_t *out_arg[SWR_CH_MAX], int out_count,
00621                                 const uint8_t *in_arg [SWR_CH_MAX], int  in_count){
00622     AudioData * in= &s->in;
00623     AudioData *out= &s->out;
00624 
00625     if(s->drop_output > 0){
00626         int ret;
00627         AudioData tmp = s->out;
00628         uint8_t *tmp_arg[SWR_CH_MAX];
00629         tmp.count = 0;
00630         tmp.data  = NULL;
00631         if((ret=realloc_audio(&tmp, s->drop_output))<0)
00632             return ret;
00633 
00634         reversefill_audiodata(&tmp, tmp_arg);
00635         s->drop_output *= -1; 
00636         ret = swr_convert(s, tmp_arg, -s->drop_output, in_arg, in_count); 
00637         s->drop_output *= -1;
00638         if(ret>0)
00639             s->drop_output -= ret;
00640 
00641         av_freep(&tmp.data);
00642         if(s->drop_output || !out_arg)
00643             return 0;
00644         in_count = 0;
00645     }
00646 
00647     if(!in_arg){
00648         if(s->in_buffer_count){
00649             if (s->resample && !s->flushed) {
00650                 AudioData *a= &s->in_buffer;
00651                 int i, j, ret;
00652                 if((ret=realloc_audio(a, s->in_buffer_index + 2*s->in_buffer_count)) < 0)
00653                     return ret;
00654                 av_assert0(a->planar);
00655                 for(i=0; i<a->ch_count; i++){
00656                     for(j=0; j<s->in_buffer_count; j++){
00657                         memcpy(a->ch[i] + (s->in_buffer_index+s->in_buffer_count+j  )*a->bps,
00658                             a->ch[i] + (s->in_buffer_index+s->in_buffer_count-j-1)*a->bps, a->bps);
00659                     }
00660                 }
00661                 s->in_buffer_count += (s->in_buffer_count+1)/2;
00662                 s->resample_in_constraint = 0;
00663                 s->flushed = 1;
00664             }
00665         }else{
00666             return 0;
00667         }
00668     }else
00669         fill_audiodata(in ,  (void*)in_arg);
00670 
00671     fill_audiodata(out, out_arg);
00672 
00673     if(s->resample){
00674         int ret = swr_convert_internal(s, out, out_count, in, in_count);
00675         if(ret>0 && !s->drop_output)
00676             s->outpts += ret * (int64_t)s->in_sample_rate;
00677         return ret;
00678     }else{
00679         AudioData tmp= *in;
00680         int ret2=0;
00681         int ret, size;
00682         size = FFMIN(out_count, s->in_buffer_count);
00683         if(size){
00684             buf_set(&tmp, &s->in_buffer, s->in_buffer_index);
00685             ret= swr_convert_internal(s, out, size, &tmp, size);
00686             if(ret<0)
00687                 return ret;
00688             ret2= ret;
00689             s->in_buffer_count -= ret;
00690             s->in_buffer_index += ret;
00691             buf_set(out, out, ret);
00692             out_count -= ret;
00693             if(!s->in_buffer_count)
00694                 s->in_buffer_index = 0;
00695         }
00696 
00697         if(in_count){
00698             size= s->in_buffer_index + s->in_buffer_count + in_count - out_count;
00699 
00700             if(in_count > out_count) { 
00701                 if(   size > s->in_buffer.count
00702                 && s->in_buffer_count + in_count - out_count <= s->in_buffer_index){
00703                     buf_set(&tmp, &s->in_buffer, s->in_buffer_index);
00704                     copy(&s->in_buffer, &tmp, s->in_buffer_count);
00705                     s->in_buffer_index=0;
00706                 }else
00707                     if((ret=realloc_audio(&s->in_buffer, size)) < 0)
00708                         return ret;
00709             }
00710 
00711             if(out_count){
00712                 size = FFMIN(in_count, out_count);
00713                 ret= swr_convert_internal(s, out, size, in, size);
00714                 if(ret<0)
00715                     return ret;
00716                 buf_set(in, in, ret);
00717                 in_count -= ret;
00718                 ret2 += ret;
00719             }
00720             if(in_count){
00721                 buf_set(&tmp, &s->in_buffer, s->in_buffer_index + s->in_buffer_count);
00722                 copy(&tmp, in, in_count);
00723                 s->in_buffer_count += in_count;
00724             }
00725         }
00726         if(ret2>0 && !s->drop_output)
00727             s->outpts += ret2 * (int64_t)s->in_sample_rate;
00728         return ret2;
00729     }
00730 }
00731 
00732 int swr_drop_output(struct SwrContext *s, int count){
00733     s->drop_output += count;
00734 
00735     if(s->drop_output <= 0)
00736         return 0;
00737 
00738     av_log(s, AV_LOG_VERBOSE, "discarding %d audio samples\n", count);
00739     return swr_convert(s, NULL, s->drop_output, NULL, 0);
00740 }
00741 
00742 int swr_inject_silence(struct SwrContext *s, int count){
00743     int ret, i;
00744     AudioData silence = s->in;
00745     uint8_t *tmp_arg[SWR_CH_MAX];
00746 
00747     if(count <= 0)
00748         return 0;
00749 
00750     silence.count = 0;
00751     silence.data  = NULL;
00752     if((ret=realloc_audio(&silence, count))<0)
00753         return ret;
00754 
00755     if(silence.planar) for(i=0; i<silence.ch_count; i++) {
00756         memset(silence.ch[i], silence.bps==1 ? 0x80 : 0, count*silence.bps);
00757     } else
00758         memset(silence.ch[0], silence.bps==1 ? 0x80 : 0, count*silence.bps*silence.ch_count);
00759 
00760     reversefill_audiodata(&silence, tmp_arg);
00761     av_log(s, AV_LOG_VERBOSE, "adding %d audio samples of silence\n", count);
00762     ret = swr_convert(s, NULL, 0, (const uint8_t**)tmp_arg, count);
00763     av_freep(&silence.data);
00764     return ret;
00765 }
00766 
00767 int64_t swr_next_pts(struct SwrContext *s, int64_t pts){
00768     if(pts == INT64_MIN)
00769         return s->outpts;
00770     if(s->min_compensation >= FLT_MAX) {
00771         return (s->outpts = pts - swr_get_delay(s, s->in_sample_rate * (int64_t)s->out_sample_rate));
00772     } else {
00773         int64_t delta = pts - swr_get_delay(s, s->in_sample_rate * (int64_t)s->out_sample_rate) - s->outpts;
00774         double fdelta = delta /(double)(s->in_sample_rate * (int64_t)s->out_sample_rate);
00775 
00776         if(fabs(fdelta) > s->min_compensation) {
00777             if(!s->outpts || fabs(fdelta) > s->min_hard_compensation){
00778                 int ret;
00779                 if(delta > 0) ret = swr_inject_silence(s,  delta / s->out_sample_rate);
00780                 else          ret = swr_drop_output   (s, -delta / s-> in_sample_rate);
00781                 if(ret<0){
00782                     av_log(s, AV_LOG_ERROR, "Failed to compensate for timestamp delta of %f\n", fdelta);
00783                 }
00784             } else if(s->soft_compensation_duration && s->max_soft_compensation) {
00785                 int duration = s->out_sample_rate * s->soft_compensation_duration;
00786                 double max_soft_compensation = s->max_soft_compensation / (s->max_soft_compensation < 0 ? -s->in_sample_rate : 1);
00787                 int comp = av_clipf(fdelta, -max_soft_compensation, max_soft_compensation) * duration ;
00788                 av_log(s, AV_LOG_VERBOSE, "compensating audio timestamp drift:%f compensation:%d in:%d\n", fdelta, comp, duration);
00789                 swr_set_compensation(s, comp, duration);
00790             }
00791         }
00792 
00793         return s->outpts;
00794     }
00795 }