+
+int swr_convert(struct SwrContext *s, uint8_t *out_arg[SWR_CH_MAX], int out_count,
+ const uint8_t *in_arg [SWR_CH_MAX], int in_count){
+ AudioData *postin, *midbuf, *preout;
+ int ret/*, in_max*/;
+ AudioData * in= &s->in;
+ AudioData *out= &s->out;
+ AudioData preout_tmp, midbuf_tmp;
+
+ if(!s->resample){
+ if(in_count > out_count)
+ return -1;
+ out_count = in_count;
+ }
+
+ if(!in_arg){
+ if(s->in_buffer_count){
+ AudioData *a= &s->in_buffer;
+ int i, j, ret;
+ if((ret=realloc_audio(a, s->in_buffer_index + 2*s->in_buffer_count)) < 0)
+ return ret;
+ av_assert0(a->planar);
+ for(i=0; i<a->ch_count; i++){
+ for(j=0; j<s->in_buffer_count; j++){
+ memcpy(a->ch[i] + (s->in_buffer_index+s->in_buffer_count+j )*a->bps,
+ a->ch[i] + (s->in_buffer_index+s->in_buffer_count-j-1)*a->bps, a->bps);
+ }
+ }
+ s->in_buffer_count += (s->in_buffer_count+1)/2;
+ s->resample_in_constraint = 0;
+ }else{
+ return 0;
+ }
+ }else
+ fill_audiodata(in , (void*)in_arg);
+ fill_audiodata(out, out_arg);
+
+ if(s->full_convert){
+ av_assert0(!s->resample);
+ swri_audio_convert(s->full_convert, out, in, in_count);
+ return out_count;
+ }
+
+// in_max= out_count*(int64_t)s->in_sample_rate / s->out_sample_rate + resample_filter_taps;
+// in_count= FFMIN(in_count, in_in + 2 - s->hist_buffer_count);
+
+ if((ret=realloc_audio(&s->postin, in_count))<0)
+ return ret;
+ if(s->resample_first){
+ av_assert0(s->midbuf.ch_count == s->used_ch_count);
+ if((ret=realloc_audio(&s->midbuf, out_count))<0)
+ return ret;
+ }else{
+ av_assert0(s->midbuf.ch_count == s->out.ch_count);
+ if((ret=realloc_audio(&s->midbuf, in_count))<0)
+ return ret;
+ }
+ if((ret=realloc_audio(&s->preout, out_count))<0)
+ return ret;
+
+ postin= &s->postin;
+
+ midbuf_tmp= s->midbuf;
+ midbuf= &midbuf_tmp;
+ preout_tmp= s->preout;
+ preout= &preout_tmp;
+
+ if(s->int_sample_fmt == s-> in_sample_fmt && s->in.planar)
+ postin= in;
+
+ if(s->resample_first ? !s->resample : !s->rematrix)
+ midbuf= postin;
+
+ if(s->resample_first ? !s->rematrix : !s->resample)
+ preout= midbuf;
+
+ if(s->int_sample_fmt == s->out_sample_fmt && s->out.planar){
+ if(preout==in){
+ out_count= FFMIN(out_count, in_count); //TODO check at teh end if this is needed or redundant
+ av_assert0(s->in.planar); //we only support planar internally so it has to be, we support copying non planar though
+ copy(out, in, out_count);
+ return out_count;
+ }
+ else if(preout==postin) preout= midbuf= postin= out;
+ else if(preout==midbuf) preout= midbuf= out;
+ else preout= out;
+ }
+
+ if(in != postin){
+ swri_audio_convert(s->in_convert, postin, in, in_count);
+ }
+
+ if(s->resample_first){
+ if(postin != midbuf)
+ out_count= resample(s, midbuf, out_count, postin, in_count);
+ if(midbuf != preout)
+ swri_rematrix(s, preout, midbuf, out_count, preout==out);
+ }else{
+ if(postin != midbuf)
+ swri_rematrix(s, midbuf, postin, in_count, midbuf==out);
+ if(midbuf != preout)
+ out_count= resample(s, preout, out_count, midbuf, in_count);
+ }
+
+ if(preout != out){
+//FIXME packed doesnt need more than 1 chan here!
+ swri_audio_convert(s->out_convert, out, preout, out_count);
+ }
+ if(!in_arg)
+ s->in_buffer_count = 0;
+ return out_count;
+}
+