mirror of
https://github.com/FFmpeg/FFmpeg.git
synced 2024-12-23 12:43:46 +02:00
libswr: allow to set custom matrices.
This commit is contained in:
parent
016c7bb762
commit
560b224f53
@ -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.
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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)
|
||||
|
@ -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.
|
||||
*/
|
||||
|
@ -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
|
||||
|
Loading…
Reference in New Issue
Block a user