summaryrefslogtreecommitdiff
path: root/libavresample/utils.c
diff options
context:
space:
mode:
authorJustin Ruggles <justin.ruggles@gmail.com>2012-11-29 14:53:04 -0500
committerJustin Ruggles <justin.ruggles@gmail.com>2012-12-11 14:00:32 -0500
commit14758e3211d34a97c42b07acae117ce5627d7f57 (patch)
tree9f502994fb29743424c2789727b468ca7055c0dc /libavresample/utils.c
parent887d4c05c9126d3598d72a19417296253d59752d (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.c71
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);