summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNicolas George <nicolas.george@normalesup.org>2012-02-16 11:26:32 +0100
committerNicolas George <nicolas.george@normalesup.org>2012-02-20 20:46:35 +0100
commit560b224f53fd553262790216d18c64665ebf436d (patch)
tree74c87cf7cc43391b7517c001b980856a2ea95bbc
parent016c7bb762edded8d64f986e40b6f4cd739dd597 (diff)
libswr: allow to set custom matrices.
-rw-r--r--doc/APIchanges3
-rw-r--r--libswresample/rematrix.c51
-rw-r--r--libswresample/swresample.c3
-rw-r--r--libswresample/swresample.h13
-rw-r--r--libswresample/swresample_internal.h1
5 files changed, 60 insertions, 11 deletions
diff --git a/doc/APIchanges b/doc/APIchanges
index 87e1aab865..1e94be42b2 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 0e4d9630c8..da817e1455 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 84d0f40232..7fb1ee8c2c 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 8dc4e1f348..4a3f451aba 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 0fc1c6b6a6..f53ccd76fe 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