|
|
|
@ -240,6 +240,7 @@ av_assert0(s->out.ch_count); |
|
|
|
|
s-> in.bps= av_get_bytes_per_sample(s-> in_sample_fmt); |
|
|
|
|
s->int_bps= av_get_bytes_per_sample(s->int_sample_fmt); |
|
|
|
|
s->out.bps= av_get_bytes_per_sample(s->out_sample_fmt); |
|
|
|
|
s->in_buffer= s->in; |
|
|
|
|
|
|
|
|
|
if(!s->resample && !s->rematrix && !s->channel_map){ |
|
|
|
|
s->full_convert = swri_audio_convert_alloc(s->out_sample_fmt, |
|
|
|
@ -256,20 +257,26 @@ av_assert0(s->out.ch_count); |
|
|
|
|
s->postin= s->in; |
|
|
|
|
s->preout= s->out; |
|
|
|
|
s->midbuf= s->in; |
|
|
|
|
s->in_buffer= s->in; |
|
|
|
|
|
|
|
|
|
if(s->channel_map){ |
|
|
|
|
s->postin.ch_count= |
|
|
|
|
s->midbuf.ch_count= |
|
|
|
|
s->in_buffer.ch_count= s->used_ch_count; |
|
|
|
|
s->midbuf.ch_count= s->used_ch_count; |
|
|
|
|
if(s->resample) |
|
|
|
|
s->in_buffer.ch_count= s->used_ch_count; |
|
|
|
|
} |
|
|
|
|
if(!s->resample_first){ |
|
|
|
|
s->midbuf.ch_count= s->out.ch_count; |
|
|
|
|
s->in_buffer.ch_count = s->out.ch_count; |
|
|
|
|
if(s->resample) |
|
|
|
|
s->in_buffer.ch_count = s->out.ch_count; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
s->in_buffer.bps = s->postin.bps = s->midbuf.bps = s->preout.bps = s->int_bps; |
|
|
|
|
s->in_buffer.planar = s->postin.planar = s->midbuf.planar = s->preout.planar = 1; |
|
|
|
|
s->postin.bps = s->midbuf.bps = s->preout.bps = s->int_bps; |
|
|
|
|
s->postin.planar = s->midbuf.planar = s->preout.planar = 1; |
|
|
|
|
|
|
|
|
|
if(s->resample){ |
|
|
|
|
s->in_buffer.bps = s->int_bps; |
|
|
|
|
s->in_buffer.planar = 1; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
if(s->rematrix) |
|
|
|
|
return swri_rematrix_init(s); |
|
|
|
@ -421,45 +428,12 @@ static int resample(SwrContext *s, AudioData *out_param, int out_count, |
|
|
|
|
return ret_sum; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
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){ |
|
|
|
|
static int swr_convert_internal(struct SwrContext *s, AudioData *out[SWR_CH_MAX], int out_count, |
|
|
|
|
AudioData *in [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){ |
|
|
|
|
if (!s->flushed) { |
|
|
|
|
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; |
|
|
|
|
s->flushed = 1; |
|
|
|
|
} |
|
|
|
|
}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); |
|
|
|
@ -534,3 +508,89 @@ int swr_convert(struct SwrContext *s, uint8_t *out_arg[SWR_CH_MAX], int out_coun |
|
|
|
|
return out_count; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
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 * in= &s->in; |
|
|
|
|
AudioData *out= &s->out; |
|
|
|
|
|
|
|
|
|
if(!in_arg){ |
|
|
|
|
if(s->in_buffer_count){ |
|
|
|
|
if (s->resample && !s->flushed) { |
|
|
|
|
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; |
|
|
|
|
s->flushed = 1; |
|
|
|
|
} |
|
|
|
|
}else{ |
|
|
|
|
return 0; |
|
|
|
|
} |
|
|
|
|
}else |
|
|
|
|
fill_audiodata(in , (void*)in_arg); |
|
|
|
|
|
|
|
|
|
fill_audiodata(out, out_arg); |
|
|
|
|
|
|
|
|
|
if(s->resample){ |
|
|
|
|
return swr_convert_internal(s, out, out_count, in, in_count); |
|
|
|
|
}else{ |
|
|
|
|
AudioData tmp= *in; |
|
|
|
|
int ret2=0; |
|
|
|
|
int ret, size; |
|
|
|
|
int in_buffer_count= s->in_buffer_count; |
|
|
|
|
size = FFMIN(out_count, s->in_buffer_count); |
|
|
|
|
if(size){ |
|
|
|
|
buf_set(&tmp, &s->in_buffer, s->in_buffer_index); |
|
|
|
|
ret= swr_convert_internal(s, out, size, &tmp, size); |
|
|
|
|
if(ret<0) |
|
|
|
|
return ret; |
|
|
|
|
ret2= ret; |
|
|
|
|
s->in_buffer_count -= ret; |
|
|
|
|
s->in_buffer_index += ret; |
|
|
|
|
buf_set(out, out, ret); |
|
|
|
|
out_count -= ret; |
|
|
|
|
if(!s->in_buffer_count) |
|
|
|
|
s->in_buffer_index = 0; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
if(in_count){ |
|
|
|
|
size= s->in_buffer_index + s->in_buffer_count + in_count - out_count; |
|
|
|
|
|
|
|
|
|
if(in_count > out_count) { //FIXME move after swr_convert_internal
|
|
|
|
|
if( size > s->in_buffer.count |
|
|
|
|
&& s->in_buffer_count + in_count - out_count <= s->in_buffer_index){ |
|
|
|
|
buf_set(&tmp, &s->in_buffer, s->in_buffer_index); |
|
|
|
|
copy(&s->in_buffer, &tmp, s->in_buffer_count); |
|
|
|
|
s->in_buffer_index=0; |
|
|
|
|
}else |
|
|
|
|
if((ret=realloc_audio(&s->in_buffer, size)) < 0) |
|
|
|
|
return ret; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
if(out_count){ |
|
|
|
|
size = FFMIN(in_count, out_count); |
|
|
|
|
ret= swr_convert_internal(s, out, size, in, size); |
|
|
|
|
if(ret<0) |
|
|
|
|
return ret; |
|
|
|
|
buf_set(in, in, ret); |
|
|
|
|
in_count -= ret; |
|
|
|
|
ret2 += ret; |
|
|
|
|
} |
|
|
|
|
if(in_count){ |
|
|
|
|
buf_set(&tmp, &s->in_buffer, s->in_buffer_index); |
|
|
|
|
copy(&tmp, in, in_count); |
|
|
|
|
s->in_buffer_count += in_count; |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
return ret2; |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|