[FFmpeg-devel] [PATCH 1/2] libswr: allow to set custom matrices.

Nicolas George nicolas.george at normalesup.org
Thu Feb 16 20:06:18 CET 2012


Signed-off-by: Nicolas George <nicolas.george at normalesup.org>
---
 doc/APIchanges                      |    3 ++
 libswresample/rematrix.c            |   51 ++++++++++++++++++++++++++++------
 libswresample/swresample.c          |    3 +-
 libswresample/swresample.h          |   13 ++++++++-
 libswresample/swresample_internal.h |    1 +
 5 files changed, 60 insertions(+), 11 deletions(-)


As stated in the other mail, compared with the previous version, this
version adds

	memset(s->matrix, 0, sizeof(s->matrix));

near the start of swr_set_matrix and auto_matrix.

The resulting code has the same output for swresample_test as the original
code.

Regards,

-- 
  Nicolas George


diff --git a/doc/APIchanges b/doc/APIchanges
index 87e1aab..1e94be4 100644
--- a/doc/APIchanges
+++ b/doc/APIchanges
@@ -13,6 +13,9 @@ libavutil:   2011-04-18
 
 API changes, most recent first:
 
+2012-02-16 - xxxxxxx - libswr 0.7.100
+  Add swr_set_matrix() function.
+
 2012-02-09 - xxxxxxx - lavu 51.39.100
   Add a new installed header libavutil/timestamp.h with timestamp
   utilities.
diff --git a/libswresample/rematrix.c b/libswresample/rematrix.c
index 0e4d963..da817e1 100644
--- a/libswresample/rematrix.c
+++ b/libswresample/rematrix.c
@@ -61,6 +61,24 @@
 #define TOP_BACK_CENTER        16
 #define TOP_BACK_RIGHT         17
 
+int swr_set_matrix(struct SwrContext *s, const double *matrix, int stride)
+{
+    int nb_in, nb_out, in, out;
+
+    if (!s || s->in_convert) // s needs to be allocated but not initialized
+        return AVERROR(EINVAL);
+    memset(s->matrix, 0, sizeof(s->matrix));
+    nb_in  = av_get_channel_layout_nb_channels(s->in_ch_layout);
+    nb_out = av_get_channel_layout_nb_channels(s->out_ch_layout);
+    for (out = 0; out < nb_out; out++) {
+        for (in = 0; in < nb_in; in++)
+            s->matrix[out][in] = matrix[in];
+        matrix += stride;
+    }
+    s->rematrix_custom = 1;
+    return 0;
+}
+
 static int even(int64_t layout){
     if(!layout) return 1;
     if(layout&(layout-1)) return 1;
@@ -84,12 +102,14 @@ static int sane_layout(int64_t layout){
     return 1;
 }
 
-int swri_rematrix_init(SwrContext *s){
+static int auto_matrix(SwrContext *s)
+{
     int i, j, out_i;
     double matrix[64][64]={{0}};
     int64_t unaccounted= s->in_ch_layout & ~s->out_ch_layout;
     double maxcoef=0;
 
+    memset(s->matrix, 0, sizeof(s->matrix));
     for(i=0; i<64; i++){
         if(s->in_ch_layout & s->out_ch_layout & (1LL<<i))
             matrix[i][i]= 1.0;
@@ -189,23 +209,17 @@ int swri_rematrix_init(SwrContext *s){
         }else
             av_assert0(0);
     }
-
-    //FIXME quantize for integeres
     for(out_i=i=0; i<64; i++){
         double sum=0;
         int in_i=0;
-        int ch_in=0;
         for(j=0; j<64; j++){
             s->matrix[out_i][in_i]= matrix[i][j];
-            s->matrix32[out_i][in_i]= lrintf(matrix[i][j] * 32768);
             if(matrix[i][j]){
-                s->matrix_ch[out_i][++ch_in]= in_i;
                 sum += fabs(matrix[i][j]);
             }
             if(s->in_ch_layout & (1ULL<<j))
                 in_i++;
         }
-        s->matrix_ch[out_i][0]= ch_in;
         maxcoef= FFMAX(maxcoef, sum);
         if(s->out_ch_layout & (1ULL<<i))
             out_i++;
@@ -218,7 +232,6 @@ int swri_rematrix_init(SwrContext *s){
         for(i=0; i<SWR_CH_MAX; i++)
             for(j=0; j<SWR_CH_MAX; j++){
                 s->matrix[i][j] /= maxcoef;
-                s->matrix32[i][j]= lrintf(s->matrix[i][j] * 32768);
             }
     }
 
@@ -226,7 +239,6 @@ int swri_rematrix_init(SwrContext *s){
         for(i=0; i<SWR_CH_MAX; i++)
             for(j=0; j<SWR_CH_MAX; j++){
                 s->matrix[i][j] *= s->rematrix_volume;
-                s->matrix32[i][j]= lrintf(s->matrix[i][j] * 32768);
             }
     }
 
@@ -239,6 +251,27 @@ int swri_rematrix_init(SwrContext *s){
     return 0;
 }
 
+int swri_rematrix_init(SwrContext *s){
+    int i, j;
+
+    if (!s->rematrix_custom) {
+        int r = auto_matrix(s);
+        if (r)
+            return r;
+    }
+    //FIXME quantize for integeres
+    for (i = 0; i < SWR_CH_MAX; i++) {
+        int ch_in=0;
+        for (j = 0; j < SWR_CH_MAX; j++) {
+            s->matrix32[i][j]= lrintf(s->matrix[i][j] * 32768);
+            if(s->matrix[i][j])
+                s->matrix_ch[i][++ch_in]= j;
+        }
+        s->matrix_ch[i][0]= ch_in;
+    }
+    return 0;
+}
+
 int swri_rematrix(SwrContext *s, AudioData *out, AudioData *in, int len, int mustcopy){
     int out_i, in_i, i, j;
 
diff --git a/libswresample/swresample.c b/libswresample/swresample.c
index 84d0f40..7fb1ee8 100644
--- a/libswresample/swresample.c
+++ b/libswresample/swresample.c
@@ -209,7 +209,8 @@ int swr_init(struct SwrContext *s){
     if(!s->out_ch_layout)
         s->out_ch_layout= av_get_default_channel_layout(s->out.ch_count);
 
-    s->rematrix= s->out_ch_layout  !=s->in_ch_layout || s->rematrix_volume!=1.0;
+    s->rematrix= s->out_ch_layout  !=s->in_ch_layout || s->rematrix_volume!=1.0 ||
+                 s->rematrix_custom;
 
 #define RSC 1 //FIXME finetune
     if(!s-> in.ch_count)
diff --git a/libswresample/swresample.h b/libswresample/swresample.h
index 8dc4e1f..4a3f451 100644
--- a/libswresample/swresample.h
+++ b/libswresample/swresample.h
@@ -30,7 +30,7 @@
 #include "libavutil/samplefmt.h"
 
 #define LIBSWRESAMPLE_VERSION_MAJOR 0
-#define LIBSWRESAMPLE_VERSION_MINOR 6
+#define LIBSWRESAMPLE_VERSION_MINOR 7
 #define LIBSWRESAMPLE_VERSION_MICRO 100
 
 #define LIBSWRESAMPLE_VERSION_INT  AV_VERSION_INT(LIBSWRESAMPLE_VERSION_MAJOR, \
@@ -127,6 +127,17 @@ int swr_set_compensation(struct SwrContext *s, int sample_delta, int compensatio
 int swr_set_channel_mapping(struct SwrContext *s, const int *channel_map);
 
 /**
+ * Set a customized remix matrix.
+ *
+ * @param s       allocated Swr context, not yet initialized
+ * @param matrix  remix coefficients; matrix[i + stride * o] is
+ *                the weight of input channel i in output channel o
+ * @param stride  offset between lines of the matrix
+ * @return  AVERROR error code in case of failure.
+ */
+int swr_set_matrix(struct SwrContext *s, const double *matrix, int stride);
+
+/**
  * Return the LIBSWRESAMPLE_VERSION_INT constant.
  */
 unsigned swresample_version(void);
diff --git a/libswresample/swresample_internal.h b/libswresample/swresample_internal.h
index 0fc1c6b..f53ccd7 100644
--- a/libswresample/swresample_internal.h
+++ b/libswresample/swresample_internal.h
@@ -53,6 +53,7 @@ typedef struct SwrContext {
     int int_bps;                                    ///< internal bytes per sample
     int resample_first;                             ///< 1 if resampling must come first, 0 if rematrixing
     int rematrix;                                   ///< flag to indicate if rematrixing is needed (basically if input and output layouts mismatch)
+    int rematrix_custom;                            ///< flag to indicate that a custom matrix has been defined
 
     AudioData in;                                   ///< input audio data
     AudioData postin;                               ///< post-input audio data: used for rematrix/resample
-- 
1.7.9



More information about the ffmpeg-devel mailing list