static int swr_convert_internal(struct SwrContext *s, AudioData *out, int out_count, AudioData *in , int in_count){ AudioData *postin, *midbuf, *preout; int ret/*, in_max*/; AudioData preout_tmp, midbuf_tmp; 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=swri_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=swri_realloc_audio(&s->midbuf, out_count))<0) return ret; }else{ av_assert0(s->midbuf.ch_count == s->out.ch_count); if((ret=swri_realloc_audio(&s->midbuf, in_count))<0) return ret; } if((ret=swri_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 && !s->channel_map) 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 && !(s->out_sample_fmt==AV_SAMPLE_FMT_S32P && (s->dither.output_sample_bits&31))){ if(preout==in){ out_count= FFMIN(out_count, in_count); //TODO check at the 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 && out_count){ AudioData *conv_src = preout; if(s->dither.method){ int ch; int dither_count= FFMAX(out_count, 1<<16); if (preout == in) { conv_src = &s->dither.temp; if((ret=swri_realloc_audio(&s->dither.temp, dither_count))<0) return ret; } if((ret=swri_realloc_audio(&s->dither.noise, dither_count))<0) return ret; if(ret) for(ch=0; ch<s->dither.noise.ch_count; ch++) swri_get_dither(s, s->dither.noise.ch[ch], s->dither.noise.count, 12345678913579<<ch, s->dither.noise.fmt); av_assert0(s->dither.noise.ch_count == preout->ch_count); if(s->dither.noise_pos + out_count > s->dither.noise.count) s->dither.noise_pos = 0; if (s->dither.method < SWR_DITHER_NS){ if (s->mix_2_1_simd) { int len1= out_count&~15; int off = len1 * preout->bps; if(len1) for(ch=0; ch<preout->ch_count; ch++) s->mix_2_1_simd(conv_src->ch[ch], preout->ch[ch], s->dither.noise.ch[ch] + s->dither.noise.bps * s->dither.noise_pos, s->native_simd_one, 0, 0, len1); if(out_count != len1) for(ch=0; ch<preout->ch_count; ch++) s->mix_2_1_f(conv_src->ch[ch] + off, preout->ch[ch] + off, s->dither.noise.ch[ch] + s->dither.noise.bps * s->dither.noise_pos + off + len1, s->native_one, 0, 0, out_count - len1); } else { for(ch=0; ch<preout->ch_count; ch++) s->mix_2_1_f(conv_src->ch[ch], preout->ch[ch], s->dither.noise.ch[ch] + s->dither.noise.bps * s->dither.noise_pos, s->native_one, 0, 0, out_count); } } else { switch(s->int_sample_fmt) { case AV_SAMPLE_FMT_S16P :swri_noise_shaping_int16(s, conv_src, preout, &s->dither.noise, out_count); break; case AV_SAMPLE_FMT_S32P :swri_noise_shaping_int32(s, conv_src, preout, &s->dither.noise, out_count); break; case AV_SAMPLE_FMT_FLTP :swri_noise_shaping_float(s, conv_src, preout, &s->dither.noise, out_count); break; case AV_SAMPLE_FMT_DBLP :swri_noise_shaping_double(s,conv_src, preout, &s->dither.noise, out_count); break; } } s->dither.noise_pos += out_count; } //FIXME packed doesn't need more than 1 chan here! swri_audio_convert(s->out_convert, out, conv_src, out_count); } return out_count; }