diff options
author | Justin Ruggles <justin.ruggles@gmail.com> | 2012-11-29 23:53:04 +0400 |
---|---|---|
committer | Justin Ruggles <justin.ruggles@gmail.com> | 2012-12-11 23:00:32 +0400 |
commit | 14758e3211d34a97c42b07acae117ce5627d7f57 (patch) | |
tree | 9f502994fb29743424c2789727b468ca7055c0dc /libavresample/utils.c | |
parent | 887d4c05c9126d3598d72a19417296253d59752d (diff) |
lavr: temporarily store custom matrix in AVAudioResampleContext
This allows AudioMix to be treated the same way as other conversion contexts
and removes the requirement to allocate it at the same time as the
AVAudioResampleContext.
The current matrix get/set functions are split between the public interface
and AudioMix private functions.
Diffstat (limited to 'libavresample/utils.c')
-rw-r--r-- | libavresample/utils.c | 71 |
1 files changed, 66 insertions, 5 deletions
diff --git a/libavresample/utils.c b/libavresample/utils.c index 3fdeeb8cc0..8245e6a345 100644 --- a/libavresample/utils.c +++ b/libavresample/utils.c @@ -169,9 +169,11 @@ int avresample_open(AVAudioResampleContext *avr) } } if (avr->mixing_needed) { - ret = ff_audio_mix_init(avr); - if (ret < 0) + avr->am = ff_audio_mix_alloc(avr); + if (!avr->am) { + ret = AVERROR(ENOMEM); goto error; + } } return 0; @@ -191,8 +193,8 @@ void avresample_close(AVAudioResampleContext *avr) av_freep(&avr->ac_in); av_freep(&avr->ac_out); ff_audio_resample_free(&avr->resample); - ff_audio_mix_close(avr->am); - return; + ff_audio_mix_free(&avr->am); + av_freep(&avr->mix_matrix); } void avresample_free(AVAudioResampleContext **avr) @@ -200,7 +202,6 @@ void avresample_free(AVAudioResampleContext **avr) if (!*avr) return; avresample_close(*avr); - av_freep(&(*avr)->am); av_opt_free(*avr); av_freep(avr); } @@ -404,6 +405,66 @@ int attribute_align_arg avresample_convert(AVAudioResampleContext *avr, current_buffer); } +int avresample_get_matrix(AVAudioResampleContext *avr, double *matrix, + int stride) +{ + int in_channels, out_channels, i, o; + + if (avr->am) + return ff_audio_mix_get_matrix(avr->am, matrix, stride); + + in_channels = av_get_channel_layout_nb_channels(avr->in_channel_layout); + out_channels = av_get_channel_layout_nb_channels(avr->out_channel_layout); + + if ( in_channels <= 0 || in_channels > AVRESAMPLE_MAX_CHANNELS || + out_channels <= 0 || out_channels > AVRESAMPLE_MAX_CHANNELS) { + av_log(avr, AV_LOG_ERROR, "Invalid channel layouts\n"); + return AVERROR(EINVAL); + } + + if (!avr->mix_matrix) { + av_log(avr, AV_LOG_ERROR, "matrix is not set\n"); + return AVERROR(EINVAL); + } + + for (o = 0; o < out_channels; o++) + for (i = 0; i < in_channels; i++) + matrix[o * stride + i] = avr->mix_matrix[o * in_channels + i]; + + return 0; +} + +int avresample_set_matrix(AVAudioResampleContext *avr, const double *matrix, + int stride) +{ + int in_channels, out_channels, i, o; + + if (avr->am) + return ff_audio_mix_set_matrix(avr->am, matrix, stride); + + in_channels = av_get_channel_layout_nb_channels(avr->in_channel_layout); + out_channels = av_get_channel_layout_nb_channels(avr->out_channel_layout); + + if ( in_channels <= 0 || in_channels > AVRESAMPLE_MAX_CHANNELS || + out_channels <= 0 || out_channels > AVRESAMPLE_MAX_CHANNELS) { + av_log(avr, AV_LOG_ERROR, "Invalid channel layouts\n"); + return AVERROR(EINVAL); + } + + if (avr->mix_matrix) + av_freep(&avr->mix_matrix); + avr->mix_matrix = av_malloc(in_channels * out_channels * + sizeof(*avr->mix_matrix)); + if (!avr->mix_matrix) + return AVERROR(ENOMEM); + + for (o = 0; o < out_channels; o++) + for (i = 0; i < in_channels; i++) + avr->mix_matrix[o * in_channels + i] = matrix[o * stride + i]; + + return 0; +} + int avresample_available(AVAudioResampleContext *avr) { return av_audio_fifo_size(avr->out_fifo); |