libswr: allow to set custom matrices.

This commit is contained in:
Nicolas George 2012-02-16 11:26:32 +01:00
parent 016c7bb762
commit 560b224f53
5 changed files with 60 additions and 11 deletions

View File

@ -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.

View File

@ -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;

View File

@ -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)

View File

@ -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, \
@ -126,6 +126,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.
*/

View File

@ -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