summaryrefslogtreecommitdiff
path: root/libswresample
diff options
context:
space:
mode:
authorMichael Niedermayer <michaelni@gmx.at>2012-03-25 21:04:48 +0200
committerMichael Niedermayer <michaelni@gmx.at>2012-03-25 21:49:42 +0200
commit1b0fcf33b80d72d1e48287feda5cea9fdf906ee0 (patch)
tree5238d407b7cbcd534814f70c942e318244fbc12a /libswresample
parente479013ae41050ad9b76429d8c6ab70684cddc93 (diff)
swr: More flexible and convenient buffering
Signed-off-by: Michael Niedermayer <michaelni@gmx.at>
Diffstat (limited to 'libswresample')
-rw-r--r--libswresample/swresample.c142
-rw-r--r--libswresample/swresample.h4
2 files changed, 105 insertions, 41 deletions
diff --git a/libswresample/swresample.c b/libswresample/swresample.c
index eb83aa2934..a1dcf2a203 100644
--- a/libswresample/swresample.c
+++ b/libswresample/swresample.c
@@ -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;
+ }
+}
+
diff --git a/libswresample/swresample.h b/libswresample/swresample.h
index f860f7cdd6..f912bac042 100644
--- a/libswresample/swresample.h
+++ b/libswresample/swresample.h
@@ -102,6 +102,10 @@ void swr_free(struct SwrContext **s);
* in and in_count can be set to 0 to flush the last few samples out at the
* end.
*
+ * If more input is provided than output space then the input will be buffered.
+ * You can avoid this buffering by providing more output space than input.
+ * Convertion will run directly without copying whenever possible.
+ *
* @param s allocated Swr context, with parameters set
* @param out output buffers, only the first one need be set in case of packed audio
* @param out_count amount of space available for output in samples per channel