26#define TEMPLATE_REMATRIX_FLT
28#undef TEMPLATE_REMATRIX_FLT
30#define TEMPLATE_REMATRIX_DBL
32#undef TEMPLATE_REMATRIX_DBL
34#define TEMPLATE_REMATRIX_S16
39#undef TEMPLATE_REMATRIX_S16
41#define TEMPLATE_REMATRIX_S32
43#undef TEMPLATE_REMATRIX_S32
48#define LOW_FREQUENCY 3
51#define FRONT_LEFT_OF_CENTER 6
52#define FRONT_RIGHT_OF_CENTER 7
57#define TOP_FRONT_LEFT 12
58#define TOP_FRONT_CENTER 13
59#define TOP_FRONT_RIGHT 14
60#define TOP_BACK_LEFT 15
61#define TOP_BACK_CENTER 16
62#define TOP_BACK_RIGHT 17
63#define LOW_FREQUENCY_2 35
64#define TOP_SIDE_LEFT 36
65#define TOP_SIDE_RIGHT 37
66#define BOTTOM_FRONT_CENTER 38
67#define BOTTOM_FRONT_LEFT 39
68#define BOTTOM_FRONT_RIGHT 40
69#define NUM_NAMED_CHANNELS 41
73 int nb_in, nb_out, in,
out;
75 if (!
s ||
s->in_convert ||
80 memset(
s->matrix, 0,
sizeof(
s->matrix));
82 nb_in =
s->user_in_chlayout.nb_channels;
83 nb_out =
s->user_out_chlayout.nb_channels;
85 for (in = 0; in < nb_in; in++)
89 s->rematrix_custom = 1;
152 double center_mix_level,
double surround_mix_level,
153 double lfe_mix_level,
double maxval,
double rematrix_volume,
double *matrix_param,
159 uint64_t unaccounted = in_mask & ~out_mask;
169 matrix_param[
stride *
i + j] = 0.0;
180 matrix_param[
stride *
i + j] = 0.0;
186 if (in_mask & out_mask & (1ULL <<
i))
543 for (
i = 0;
i < 64;
i++) {
555 matrix_param[
stride*out_i + in_i] =
i == j && (in_mask & out_mask & (1ULL <<
i));
556 sum +=
fabs(matrix_param[
stride*out_i + in_i]);
558 maxcoef=
FFMAX(maxcoef, sum);
560 if(rematrix_volume < 0)
561 maxcoef = -rematrix_volume;
563 if(maxcoef > maxval || rematrix_volume < 0){
567 matrix_param[
stride*
i + j] /= maxcoef;
573 double center_mix_level,
double surround_mix_level,
574 double lfe_mix_level,
double maxval,
575 double rematrix_volume,
double *matrix_param,
582 ret =
clean_layout(&in_ch_layout, in_layout, log_context);
583 ret |=
clean_layout(&out_ch_layout, out_layout, log_context);
607 av_log(log_context,
AV_LOG_ERROR,
"Input channel layout '%s' is not supported\n", buf);
619 av_log(log_context,
AV_LOG_ERROR,
"Output channel layout '%s' is not supported\n", buf);
624 build_matrix(&in_ch_layout, &out_ch_layout, center_mix_level,
625 surround_mix_level, lfe_mix_level, maxval, rematrix_volume,
626 matrix_param,
stride, matrix_encoding);
628 if(rematrix_volume > 0){
631 matrix_param[
stride*
i + j] *= rematrix_volume;
636 for (
i = 0;
i < out_ch_layout.nb_channels;
i++){
658 if (
s->rematrix_maxval > 0) {
659 maxval =
s->rematrix_maxval;
666 memset(
s->matrix, 0,
sizeof(
s->matrix));
668 s->clev,
s->slev,
s->lfe_mix_level,
669 maxval,
s->rematrix_volume, (
double*)
s->matrix,
670 s->matrix[1] -
s->matrix[0],
s->matrix_encoding,
s);
675 int nb_in =
s->used_ch_layout.nb_channels;
676 int nb_out =
s->out.ch_count;
680 if (!
s->rematrix_custom) {
687 double *matrix_param = (
double*)
s->matrix;
688 ptrdiff_t
stride =
s->matrix[1] -
s->matrix[0];
689 for (
i = 0;
i <
s->out_ch_layout.nb_channels;
i++) {
692 for (j = 0; j <
s->in_ch_layout.nb_channels; j++){
701 s->native_matrix =
av_calloc(nb_in * nb_out,
sizeof(
int));
702 if (!
s->native_matrix)
704 for (
i = 0;
i < nb_out;
i++) {
708 for (j = 0; j < nb_in; j++) {
709 double target =
s->matrix[
i][j] * 32768 + rem;
710 ((
int*)
s->native_matrix)[
i * nb_in + j] =
lrintf(target);
711 rem += target - ((
int*)
s->native_matrix)[
i * nb_in + j];
712 sum +=
FFABS(((
int*)
s->native_matrix)[
i * nb_in + j]);
714 maxsum =
FFMAX(maxsum, sum);
716 s->native_one.i = 32768;
717 if (maxsum <= 32768) {
718 s->mix_1_1_f = copy_s16;
719 s->mix_2_1_f = sum2_s16;
720 s->mix_any_f = get_mix_any_func_s16(
s);
722 s->mix_1_1_f = copy_clip_s16;
723 s->mix_2_1_f = sum2_clip_s16;
724 s->mix_any_f = get_mix_any_func_clip_s16(
s);
727 s->native_matrix =
av_calloc(nb_in * nb_out,
sizeof(
float));
728 if (!
s->native_matrix)
730 for (
i = 0;
i < nb_out;
i++)
731 for (j = 0; j < nb_in; j++)
732 ((
float*)
s->native_matrix)[
i * nb_in + j] =
s->matrix[
i][j];
733 s->native_one.f = 1.0;
734 s->mix_1_1_f = copy_float;
735 s->mix_2_1_f = sum2_float;
736 s->mix_any_f = get_mix_any_func_float(
s);
738 s->native_matrix =
av_calloc(nb_in * nb_out,
sizeof(
double));
739 if (!
s->native_matrix)
741 for (
i = 0;
i < nb_out;
i++)
742 for (j = 0; j < nb_in; j++)
743 ((
double*)
s->native_matrix)[
i * nb_in + j] =
s->matrix[
i][j];
744 s->native_one.d = 1.0;
745 s->mix_1_1_f = copy_double;
746 s->mix_2_1_f = sum2_double;
747 s->mix_any_f = get_mix_any_func_double(
s);
749 s->native_matrix =
av_calloc(nb_in * nb_out,
sizeof(
int));
750 if (!
s->native_matrix)
752 for (
i = 0;
i < nb_out;
i++) {
755 for (j = 0; j < nb_in; j++) {
756 double target =
s->matrix[
i][j] * 32768 + rem;
757 ((
int*)
s->native_matrix)[
i * nb_in + j] =
lrintf(target);
758 rem += target - ((
int*)
s->native_matrix)[
i * nb_in + j];
761 s->native_one.i = 32768;
762 s->mix_1_1_f = copy_s32;
763 s->mix_2_1_f = sum2_s32;
764 s->mix_any_f = get_mix_any_func_s32(
s);
771 const double coeff =
s->matrix[
i][j];
773 s->matrix_ch[
i][++ch_in]= j;
774 switch (
s->int_sample_fmt) {
785 s->matrix_ch[
i][0]= ch_in;
788#if ARCH_X86 && HAVE_X86ASM
801 int out_i, in_i,
i, j;
806 s->mix_any_f(
out->ch, (
const uint8_t *
const *)in->
ch,
s->native_matrix,
len);
810 if(
s->mix_2_1_simd ||
s->mix_1_1_simd){
812 off = len1 *
out->bps;
818 for(out_i=0; out_i<
out->ch_count; out_i++){
819 switch(
s->matrix_ch[out_i][0]){
825 in_i=
s->matrix_ch[out_i][1];
826 if(
s->matrix[out_i][in_i]!=1.0){
827 if(
s->mix_1_1_simd && len1)
828 s->mix_1_1_simd(
out->ch[out_i] , in->
ch[in_i] ,
s->native_simd_matrix, in->
ch_count*out_i + in_i, len1);
830 s->mix_1_1_f (
out->ch[out_i]+off, in->
ch[in_i]+off,
s->native_matrix, in->
ch_count*out_i + in_i,
len-len1);
832 memcpy(
out->ch[out_i], in->
ch[in_i],
len*
out->bps);
834 out->ch[out_i]= in->
ch[in_i];
838 int in_i1 =
s->matrix_ch[out_i][1];
839 int in_i2 =
s->matrix_ch[out_i][2];
840 if(
s->mix_2_1_simd && len1)
841 s->mix_2_1_simd(
out->ch[out_i] , in->
ch[in_i1] , in->
ch[in_i2] ,
s->native_simd_matrix, in->
ch_count*out_i + in_i1, in->
ch_count*out_i + in_i2, len1);
843 s->mix_2_1_f (
out->ch[out_i] , in->
ch[in_i1] , in->
ch[in_i2] ,
s->native_matrix, in->
ch_count*out_i + in_i1, in->
ch_count*out_i + in_i2, len1);
845 s->mix_2_1_f (
out->ch[out_i]+off, in->
ch[in_i1]+off, in->
ch[in_i2]+off,
s->native_matrix, in->
ch_count*out_i + in_i1, in->
ch_count*out_i + in_i2,
len-len1);
851 for(j=0; j<
s->matrix_ch[out_i][0]; j++){
852 in_i=
s->matrix_ch[out_i][1+j];
853 v+= ((
float*)in->
ch[in_i])[
i] *
s->matrix_flt[out_i][in_i];
855 ((
float*)
out->ch[out_i])[
i]= v;
860 for(j=0; j<
s->matrix_ch[out_i][0]; j++){
861 in_i=
s->matrix_ch[out_i][1+j];
862 v+= ((
double*)in->
ch[in_i])[
i] *
s->matrix[out_i][in_i];
864 ((
double*)
out->ch[out_i])[
i]= v;
869 for(j=0; j<
s->matrix_ch[out_i][0]; j++){
870 in_i=
s->matrix_ch[out_i][1+j];
871 v+= ((int16_t*)in->
ch[in_i])[
i] *
s->matrix32[out_i][in_i];
873 ((int16_t*)
out->ch[out_i])[
i]= (v + 16384)>>15;
simple assert() macros that are a bit more flexible than ISO C assert().
#define av_assert0(cond)
assert() equivalent, that is always enabled.
#define i(width, name, range_min, range_max)
Public libavutil channel layout APIs header.
#define FFABS(a)
Absolute value, Note, INT_MIN / INT64_MIN result in undefined behavior as they are not representable ...
static __device__ float fabs(float a)
#define AV_CH_LAYOUT_STEREO_DOWNMIX
#define AV_CH_LAYOUT_SURROUND
#define AV_CH_LAYOUT_STEREO
@ AV_MATRIX_ENCODING_DOLBY
@ AV_MATRIX_ENCODING_DPLII
#define AV_CH_TOP_FRONT_LEFT
#define AV_CH_FRONT_RIGHT
#define AV_CH_TOP_BACK_CENTER
#define AV_CH_BOTTOM_FRONT_CENTER
#define AV_CH_FRONT_RIGHT_OF_CENTER
#define AV_CH_BACK_CENTER
#define AV_CH_TOP_FRONT_CENTER
#define AV_CH_FRONT_LEFT_OF_CENTER
#define AV_CH_LOW_FREQUENCY_2
#define AV_CH_TOP_SIDE_RIGHT
#define AV_CH_FRONT_CENTER
#define AV_CH_TOP_BACK_RIGHT
#define AV_CH_TOP_SIDE_LEFT
#define AV_CH_TOP_BACK_LEFT
#define AV_CH_LOW_FREQUENCY
#define AV_CH_BOTTOM_FRONT_RIGHT
#define AV_CH_TOP_FRONT_RIGHT
#define AV_CH_BOTTOM_FRONT_LEFT
int av_channel_layout_index_from_channel(const AVChannelLayout *channel_layout, enum AVChannel channel)
Get the index of a given channel in a channel layout.
#define AV_CHANNEL_LAYOUT_STEREO
int av_channel_layout_compare(const AVChannelLayout *chl, const AVChannelLayout *chl1)
Check whether two channel layouts are semantically the same, i.e.
int av_channel_name(char *buf, size_t buf_size, enum AVChannel channel_id)
Get a human readable string in an abbreviated form describing a given channel.
#define AV_CHANNEL_LAYOUT_MONO
enum AVChannel av_channel_layout_channel_from_index(const AVChannelLayout *channel_layout, unsigned int idx)
Get the channel with the given index in a channel layout.
void av_channel_layout_uninit(AVChannelLayout *channel_layout)
Free any allocated data in the channel layout and reset the channel count to 0.
int av_channel_layout_describe(const AVChannelLayout *channel_layout, char *buf, size_t buf_size)
Get a human-readable string describing the channel layout properties.
int av_channel_layout_check(const AVChannelLayout *channel_layout)
Check whether a channel layout is valid, i.e.
int av_channel_layout_copy(AVChannelLayout *dst, const AVChannelLayout *src)
Make a copy of a channel layout.
#define AV_CHANNEL_LAYOUT_STEREO_DOWNMIX
uint64_t av_channel_layout_subset(const AVChannelLayout *channel_layout, uint64_t mask)
Find out what channels from a given set are present in a channel layout, without regard for their pos...
@ AV_CHANNEL_ORDER_NATIVE
The native channel order, i.e.
@ AV_CHANNEL_ORDER_CUSTOM
The channel order does not correspond to any other predefined order and is stored as an explicit map.
@ AV_CHANNEL_ORDER_UNSPEC
Only the channel count is specified, without any further information about the channel order.
@ AV_CHAN_UNUSED
Channel is empty can be safely skipped.
#define AV_LOG_DEBUG
Stuff which is only useful for libav* developers.
#define AV_LOG_VERBOSE
Detailed information.
#define AV_LOG_ERROR
Something went wrong and cannot losslessly be recovered.
int av_get_bytes_per_sample(enum AVSampleFormat sample_fmt)
Return number of bytes per sample.
enum AVSampleFormat av_get_packed_sample_fmt(enum AVSampleFormat sample_fmt)
Get the packed alternative form of the given sample format.
@ AV_SAMPLE_FMT_FLTP
float, planar
@ AV_SAMPLE_FMT_S16P
signed 16 bits, planar
@ AV_SAMPLE_FMT_S32P
signed 32 bits, planar
@ AV_SAMPLE_FMT_DBLP
double, planar
av_cold int swr_build_matrix2(const AVChannelLayout *in_layout, const AVChannelLayout *out_layout, double center_mix_level, double surround_mix_level, double lfe_mix_level, double maxval, double rematrix_volume, double *matrix_param, ptrdiff_t stride, enum AVMatrixEncoding matrix_encoding, void *log_context)
Generate a channel mixing matrix.
int swr_set_matrix(struct SwrContext *s, const double *matrix, int stride)
Set a customized remix matrix.
static const uint16_t mask[17]
void * av_calloc(size_t nmemb, size_t size)
Memory handling functions.
int swri_rematrix(SwrContext *s, AudioData *out, AudioData *in, int len, int mustcopy)
#define BOTTOM_FRONT_LEFT
av_cold int swri_rematrix_init(SwrContext *s)
#define FRONT_LEFT_OF_CENTER
static int even(int64_t layout)
static void build_matrix(const AVChannelLayout *in_ch_layout, const AVChannelLayout *out_ch_layout, double center_mix_level, double surround_mix_level, double lfe_mix_level, double maxval, double rematrix_volume, double *matrix_param, ptrdiff_t stride, enum AVMatrixEncoding matrix_encoding)
#define BOTTOM_FRONT_RIGHT
#define NUM_NAMED_CHANNELS
static int clean_layout(AVChannelLayout *out, const AVChannelLayout *in, void *s)
static av_cold int auto_matrix(SwrContext *s)
#define FRONT_RIGHT_OF_CENTER
static int sane_layout(const AVChannelLayout *ch_layout)
#define BOTTOM_FRONT_CENTER
av_cold void swri_rematrix_free(SwrContext *s)
#define FF_ARRAY_ELEMS(a)
An AVChannelLayout holds information about the channel layout of audio data.
enum AVChannelOrder order
Channel order used in this layout.
union AVChannelLayout::@162063043056170047076125117143030261346263330336 u
Details about which channels are present in this layout.
int nb_channels
Number of channels in this layout.
AVChannelCustom * map
This member must be used when the channel order is AV_CHANNEL_ORDER_CUSTOM.
int ch_count
number of channels
uint8_t * ch[SWR_CH_MAX]
samples buffer per channel
The libswresample context.
int swri_check_chlayout(struct SwrContext *s, const AVChannelLayout *chl, const char *name)
int swri_rematrix_init_x86(struct SwrContext *s)
static const double coeff[2][5]