free_temp(&s->midbuf);
free_temp(&s->preout);
free_temp(&s->in_buffer);
+ free_temp(&s->silence);
+ free_temp(&s->drop_temp);
free_temp(&s->dither.noise);
+ free_temp(&s->dither.temp);
swri_audio_convert_free(&s-> in_convert);
swri_audio_convert_free(&s->out_convert);
swri_audio_convert_free(&s->full_convert);
free_temp(&s->midbuf);
free_temp(&s->preout);
free_temp(&s->in_buffer);
+ free_temp(&s->silence);
+ free_temp(&s->drop_temp);
free_temp(&s->dither.noise);
+ free_temp(&s->dither.temp);
memset(s->in.ch, 0, sizeof(s->in.ch));
memset(s->out.ch, 0, sizeof(s->out.ch));
swri_audio_convert_free(&s-> in_convert);
s->resample_first= RSC*s->out.ch_count/s->in.ch_count - RSC < s->out_sample_rate/(float)s-> in_sample_rate - 1.0;
s->in_buffer= s->in;
+ s->silence = s->in;
+ s->drop_temp= s->out;
if(!s->resample && !s->rematrix && !s->channel_map && !s->dither.method){
s->full_convert = swri_audio_convert_alloc(s->out_sample_fmt,
s->out_convert= swri_audio_convert_alloc(s->out_sample_fmt,
s->int_sample_fmt, s->out.ch_count, NULL, 0);
+ if (!s->in_convert || !s->out_convert)
+ return AVERROR(ENOMEM);
s->postin= s->in;
s->preout= s->out;
if(s->resample_first ? !s->rematrix : !s->resample)
preout= midbuf;
- if (preout == in && s->dither.method) {
- av_assert1(postin == midbuf && midbuf == preout);
- postin = midbuf = preout = &preout_tmp;
- }
-
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 the end if this is needed or redundant
}
if(preout != out && out_count){
+ AudioData *conv_src = preout;
if(s->dither.method){
int ch;
int dither_count= FFMAX(out_count, 1<<16);
- av_assert0(preout != in);
+
+ 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;
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.dither_pos + out_count > s->dither.noise.count)
- s->dither.dither_pos = 0;
+ 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) {
if(len1)
for(ch=0; ch<preout->ch_count; ch++)
- s->mix_2_1_simd(preout->ch[ch], preout->ch[ch], s->dither.noise.ch[ch] + s->dither.noise.bps * s->dither.dither_pos, s->native_one, 0, 0, len1);
+ 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_one, 0, 0, len1);
if(out_count != len1)
for(ch=0; ch<preout->ch_count; ch++)
- s->mix_2_1_f(preout->ch[ch] + off, preout->ch[ch] + off, s->dither.noise.ch[ch] + s->dither.noise.bps * s->dither.dither_pos + off + len1, s->native_one, 0, 0, out_count - len1);
+ 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(preout->ch[ch], preout->ch[ch], s->dither.noise.ch[ch] + s->dither.noise.bps * s->dither.dither_pos, s->native_one, 0, 0, out_count);
+ 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, preout, &s->dither.noise, out_count); break;
- case AV_SAMPLE_FMT_S32P :swri_noise_shaping_int32(s, preout, &s->dither.noise, out_count); break;
- case AV_SAMPLE_FMT_FLTP :swri_noise_shaping_float(s, preout, &s->dither.noise, out_count); break;
- case AV_SAMPLE_FMT_DBLP :swri_noise_shaping_double(s,preout, &s->dither.noise, out_count); break;
+ 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.dither_pos += out_count;
+ s->dither.noise_pos += out_count;
}
//FIXME packed doesnt need more than 1 chan here!
- swri_audio_convert(s->out_convert, out, preout, out_count);
+ swri_audio_convert(s->out_convert, out, conv_src, out_count);
}
return out_count;
}
AudioData * in= &s->in;
AudioData *out= &s->out;
- if(s->drop_output > 0){
+ while(s->drop_output > 0){
int ret;
- AudioData tmp = s->out;
uint8_t *tmp_arg[SWR_CH_MAX];
- tmp.count = 0;
- tmp.data = NULL;
- if((ret=swri_realloc_audio(&tmp, s->drop_output))<0)
+#define MAX_DROP_STEP 16384
+ if((ret=swri_realloc_audio(&s->drop_temp, FFMIN(s->drop_output, MAX_DROP_STEP)))<0)
return ret;
- reversefill_audiodata(&tmp, tmp_arg);
+ reversefill_audiodata(&s->drop_temp, tmp_arg);
s->drop_output *= -1; //FIXME find a less hackish solution
- ret = swr_convert(s, tmp_arg, -s->drop_output, in_arg, in_count); //FIXME optimize but this is as good as never called so maybe it doesnt matter
+ ret = swr_convert(s, tmp_arg, FFMIN(-s->drop_output, MAX_DROP_STEP), in_arg, in_count); //FIXME optimize but this is as good as never called so maybe it doesnt matter
s->drop_output *= -1;
- if(ret>0)
+ in_count = 0;
+ if(ret>0) {
s->drop_output -= ret;
+ continue;
+ }
- av_freep(&tmp.data);
if(s->drop_output || !out_arg)
return 0;
- in_count = 0;
}
if(!in_arg){
int swr_inject_silence(struct SwrContext *s, int count){
int ret, i;
- AudioData silence = s->in;
uint8_t *tmp_arg[SWR_CH_MAX];
if(count <= 0)
return 0;
- silence.count = 0;
- silence.data = NULL;
- if((ret=swri_realloc_audio(&silence, count))<0)
+#define MAX_SILENCE_STEP 16384
+ while (count > MAX_SILENCE_STEP) {
+ if ((ret = swr_inject_silence(s, MAX_SILENCE_STEP)) < 0)
+ return ret;
+ count -= MAX_SILENCE_STEP;
+ }
+
+ if((ret=swri_realloc_audio(&s->silence, count))<0)
return ret;
- if(silence.planar) for(i=0; i<silence.ch_count; i++) {
- memset(silence.ch[i], silence.bps==1 ? 0x80 : 0, count*silence.bps);
+ if(s->silence.planar) for(i=0; i<s->silence.ch_count; i++) {
+ memset(s->silence.ch[i], s->silence.bps==1 ? 0x80 : 0, count*s->silence.bps);
} else
- memset(silence.ch[0], silence.bps==1 ? 0x80 : 0, count*silence.bps*silence.ch_count);
+ memset(s->silence.ch[0], s->silence.bps==1 ? 0x80 : 0, count*s->silence.bps*s->silence.ch_count);
- reversefill_audiodata(&silence, tmp_arg);
+ reversefill_audiodata(&s->silence, tmp_arg);
av_log(s, AV_LOG_VERBOSE, "adding %d audio samples of silence\n", count);
ret = swr_convert(s, NULL, 0, (const uint8_t**)tmp_arg, count);
- av_freep(&silence.data);
return ret;
}
if(s->min_compensation >= FLT_MAX) {
return (s->outpts = pts - swr_get_delay(s, s->in_sample_rate * (int64_t)s->out_sample_rate));
} else {
- int64_t delta = pts - swr_get_delay(s, s->in_sample_rate * (int64_t)s->out_sample_rate) - s->outpts;
+ int64_t delta = pts - swr_get_delay(s, s->in_sample_rate * (int64_t)s->out_sample_rate) - s->outpts + s->drop_output*(int64_t)s->in_sample_rate;
double fdelta = delta /(double)(s->in_sample_rate * (int64_t)s->out_sample_rate);
if(fabs(fdelta) > s->min_compensation) {