]> git.sesse.net Git - ffmpeg/blobdiff - libavresample/utils.c
Merge commit 'a0b7e289075dccf223b7f407790d8a86fc5d77e8'
[ffmpeg] / libavresample / utils.c
index 5591f1575e7c8543313232fb944be2a8089a8ac7..8f6583d6e8e31c3b0b22b04f60ad3848878f486e 100644 (file)
@@ -49,7 +49,7 @@ int avresample_open(AVAudioResampleContext *avr)
     avr->resample_channels = FFMIN(avr->in_channels, avr->out_channels);
     avr->downmix_needed    = avr->in_channels  > avr->out_channels;
     avr->upmix_needed      = avr->out_channels > avr->in_channels ||
-                             (!avr->downmix_needed && (avr->am->matrix ||
+                             (!avr->downmix_needed && (avr->mix_matrix ||
                               avr->in_channel_layout != avr->out_channel_layout));
     avr->mixing_needed     = avr->downmix_needed || avr->upmix_needed;
 
@@ -142,7 +142,8 @@ int avresample_open(AVAudioResampleContext *avr)
     /* setup contexts */
     if (avr->in_convert_needed) {
         avr->ac_in = ff_audio_convert_alloc(avr, avr->internal_sample_fmt,
-                                            avr->in_sample_fmt, avr->in_channels);
+                                            avr->in_sample_fmt, avr->in_channels,
+                                            avr->in_sample_rate);
         if (!avr->ac_in) {
             ret = AVERROR(ENOMEM);
             goto error;
@@ -155,7 +156,8 @@ int avresample_open(AVAudioResampleContext *avr)
         else
             src_fmt = avr->in_sample_fmt;
         avr->ac_out = ff_audio_convert_alloc(avr, avr->out_sample_fmt, src_fmt,
-                                             avr->out_channels);
+                                             avr->out_channels,
+                                             avr->out_sample_rate);
         if (!avr->ac_out) {
             ret = AVERROR(ENOMEM);
             goto error;
@@ -169,9 +171,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;
@@ -188,11 +192,11 @@ void avresample_close(AVAudioResampleContext *avr)
     ff_audio_data_free(&avr->out_buffer);
     av_audio_fifo_free(avr->out_fifo);
     avr->out_fifo = NULL;
-    av_freep(&avr->ac_in);
-    av_freep(&avr->ac_out);
+    ff_audio_convert_free(&avr->ac_in);
+    ff_audio_convert_free(&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 +204,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 +407,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);