Go to the documentation of this file.
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
47 #define FRONT_CENTER 2
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;
119 if (ch_layout->
u.
map[
i].
id >= 64)
148 double center_mix_level,
double surround_mix_level,
149 double lfe_mix_level,
double maxval,
double rematrix_volume,
double *matrix_param,
155 uint64_t unaccounted = in_mask & ~out_mask;
160 if (in_mask & out_mask & (1ULL <<
i))
517 for (
i = 0;
i < 64;
i++) {
529 matrix_param[
stride*out_i + in_i] =
i == j && (in_mask & out_mask & (1ULL <<
i));
530 sum +=
fabs(matrix_param[
stride*out_i + in_i]);
532 maxcoef=
FFMAX(maxcoef, sum);
534 if(rematrix_volume < 0)
535 maxcoef = -rematrix_volume;
537 if(maxcoef > maxval || rematrix_volume < 0){
541 matrix_param[
stride*
i + j] /= maxcoef;
547 double center_mix_level,
double surround_mix_level,
548 double lfe_mix_level,
double maxval,
549 double rematrix_volume,
double *matrix_param,
581 av_log(log_context,
AV_LOG_ERROR,
"Input channel layout '%s' is not supported\n", buf);
593 av_log(log_context,
AV_LOG_ERROR,
"Output channel layout '%s' is not supported\n", buf);
598 build_matrix(&in_ch_layout, &out_ch_layout, center_mix_level,
599 surround_mix_level, lfe_mix_level, maxval, rematrix_volume,
600 matrix_param,
stride, matrix_encoding);
602 if(rematrix_volume > 0){
605 matrix_param[
stride*
i + j] *= rematrix_volume;
610 for (
i = 0;
i < out_ch_layout.nb_channels;
i++){
632 if (
s->rematrix_maxval > 0) {
633 maxval =
s->rematrix_maxval;
640 memset(
s->matrix, 0,
sizeof(
s->matrix));
642 s->clev,
s->slev,
s->lfe_mix_level,
643 maxval,
s->rematrix_volume, (
double*)
s->matrix,
644 s->matrix[1] -
s->matrix[0],
s->matrix_encoding,
s);
649 int nb_in =
s->used_ch_layout.nb_channels;
650 int nb_out =
s->out.ch_count;
654 if (!
s->rematrix_custom) {
661 double *matrix_param = (
double*)
s->matrix;
662 ptrdiff_t
stride =
s->matrix[1] -
s->matrix[0];
663 for (
i = 0;
i <
s->out_ch_layout.nb_channels;
i++) {
666 for (j = 0; j <
s->in_ch_layout.nb_channels; j++){
675 s->native_matrix =
av_calloc(nb_in * nb_out,
sizeof(
int));
676 if (!
s->native_matrix)
678 for (
i = 0;
i < nb_out;
i++) {
682 for (j = 0; j < nb_in; j++) {
683 double target =
s->matrix[
i][j] * 32768 + rem;
684 ((
int*)
s->native_matrix)[
i * nb_in + j] =
lrintf(target);
685 rem += target - ((
int*)
s->native_matrix)[
i * nb_in + j];
686 sum +=
FFABS(((
int*)
s->native_matrix)[
i * nb_in + j]);
688 maxsum =
FFMAX(maxsum, sum);
690 s->native_one.i = 32768;
691 if (maxsum <= 32768) {
692 s->mix_1_1_f = copy_s16;
693 s->mix_2_1_f = sum2_s16;
694 s->mix_any_f = get_mix_any_func_s16(
s);
696 s->mix_1_1_f = copy_clip_s16;
697 s->mix_2_1_f = sum2_clip_s16;
698 s->mix_any_f = get_mix_any_func_clip_s16(
s);
701 s->native_matrix =
av_calloc(nb_in * nb_out,
sizeof(
float));
702 if (!
s->native_matrix)
704 for (
i = 0;
i < nb_out;
i++)
705 for (j = 0; j < nb_in; j++)
706 ((
float*)
s->native_matrix)[
i * nb_in + j] =
s->matrix[
i][j];
707 s->native_one.f = 1.0;
708 s->mix_1_1_f = copy_float;
709 s->mix_2_1_f = sum2_float;
710 s->mix_any_f = get_mix_any_func_float(
s);
712 s->native_matrix =
av_calloc(nb_in * nb_out,
sizeof(
double));
713 if (!
s->native_matrix)
715 for (
i = 0;
i < nb_out;
i++)
716 for (j = 0; j < nb_in; j++)
717 ((
double*)
s->native_matrix)[
i * nb_in + j] =
s->matrix[
i][j];
718 s->native_one.d = 1.0;
719 s->mix_1_1_f = copy_double;
720 s->mix_2_1_f = sum2_double;
721 s->mix_any_f = get_mix_any_func_double(
s);
723 s->native_matrix =
av_calloc(nb_in * nb_out,
sizeof(
int));
724 if (!
s->native_matrix)
726 for (
i = 0;
i < nb_out;
i++) {
729 for (j = 0; j < nb_in; j++) {
730 double target =
s->matrix[
i][j] * 32768 + rem;
731 ((
int*)
s->native_matrix)[
i * nb_in + j] =
lrintf(target);
732 rem += target - ((
int*)
s->native_matrix)[
i * nb_in + j];
735 s->native_one.i = 32768;
736 s->mix_1_1_f = copy_s32;
737 s->mix_2_1_f = sum2_s32;
738 s->mix_any_f = get_mix_any_func_s32(
s);
745 const double coeff =
s->matrix[
i][j];
747 s->matrix_ch[
i][++ch_in]= j;
748 switch (
s->int_sample_fmt) {
759 s->matrix_ch[
i][0]= ch_in;
762 #if ARCH_X86 && HAVE_X86ASM
775 int out_i, in_i,
i, j;
780 s->mix_any_f(
out->ch, (
const uint8_t *
const *)in->
ch,
s->native_matrix,
len);
784 if(
s->mix_2_1_simd ||
s->mix_1_1_simd){
786 off = len1 *
out->bps;
792 for(out_i=0; out_i<
out->ch_count; out_i++){
793 switch(
s->matrix_ch[out_i][0]){
799 in_i=
s->matrix_ch[out_i][1];
800 if(
s->matrix[out_i][in_i]!=1.0){
801 if(
s->mix_1_1_simd && len1)
802 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);
804 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);
806 memcpy(
out->ch[out_i], in->
ch[in_i],
len*
out->bps);
808 out->ch[out_i]= in->
ch[in_i];
812 int in_i1 =
s->matrix_ch[out_i][1];
813 int in_i2 =
s->matrix_ch[out_i][2];
814 if(
s->mix_2_1_simd && len1)
815 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);
817 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);
819 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);
825 for(j=0; j<
s->matrix_ch[out_i][0]; j++){
826 in_i=
s->matrix_ch[out_i][1+j];
827 v+= ((
float*)in->
ch[in_i])[
i] *
s->matrix_flt[out_i][in_i];
829 ((
float*)
out->ch[out_i])[
i]= v;
834 for(j=0; j<
s->matrix_ch[out_i][0]; j++){
835 in_i=
s->matrix_ch[out_i][1+j];
836 v+= ((
double*)in->
ch[in_i])[
i] *
s->matrix[out_i][in_i];
838 ((
double*)
out->ch[out_i])[
i]= v;
843 for(j=0; j<
s->matrix_ch[out_i][0]; j++){
844 in_i=
s->matrix_ch[out_i][1+j];
845 v+= ((int16_t*)in->
ch[in_i])[
i] *
s->matrix32[out_i][in_i];
847 ((int16_t*)
out->ch[out_i])[
i]= (v + 16384)>>15;
@ AV_SAMPLE_FMT_FLTP
float, planar
#define AV_CHANNEL_LAYOUT_STEREO_DOWNMIX
Filter the word “frame” indicates either a video frame or a group of audio as stored in an AVFrame structure Format for each input and each output the list of supported formats For video that means pixel format For audio that means channel sample they are references to shared objects When the negotiation mechanism computes the intersection of the formats supported at each end of a all references to both lists are replaced with a reference to the intersection And when a single format is eventually chosen for a link amongst the remaining all references to the list are updated That means that if a filter requires that its input and output have the same format amongst a supported all it has to do is use a reference to the same list of formats query_formats can leave some formats unset and return AVERROR(EAGAIN) to cause the negotiation mechanism toagain later. That can be used by filters with complex requirements to use the format negotiated on one link to set the formats supported on another. Frame references ownership and permissions
#define AV_CH_TOP_SIDE_LEFT
#define AV_CH_TOP_FRONT_CENTER
#define AV_CHANNEL_LAYOUT_STEREO
#define AV_CH_LOW_FREQUENCY_2
#define NUM_NAMED_CHANNELS
AVChannelCustom * map
This member must be used when the channel order is AV_CHANNEL_ORDER_CUSTOM.
#define AV_CH_TOP_FRONT_RIGHT
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.
@ AV_SAMPLE_FMT_S32P
signed 32 bits, planar
int swri_rematrix_init_x86(struct SwrContext *s)
#define AV_LOG_VERBOSE
Detailed information.
static int sane_layout(AVChannelLayout *ch_layout)
#define AV_CH_TOP_FRONT_LEFT
enum AVChannelOrder order
Channel order used in this layout.
int nb_channels
Number of channels in this layout.
int swr_set_matrix(struct SwrContext *s, const double *matrix, int stride)
Set a customized remix matrix.
#define AV_CH_BOTTOM_FRONT_LEFT
#define AV_CH_TOP_BACK_LEFT
#define BOTTOM_FRONT_LEFT
#define AV_CH_TOP_BACK_CENTER
#define BOTTOM_FRONT_RIGHT
#define FRONT_LEFT_OF_CENTER
#define AV_CH_LAYOUT_STEREO
#define AV_LOG_ERROR
Something went wrong and cannot losslessly be recovered.
static int even(int64_t layout)
#define FF_ARRAY_ELEMS(a)
@ AV_MATRIX_ENCODING_DOLBY
#define AV_CH_LOW_FREQUENCY
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.
@ AV_CHANNEL_ORDER_UNSPEC
Only the channel count is specified, without any further information about the channel order.
#define AV_CH_LAYOUT_STEREO_DOWNMIX
#define av_assert0(cond)
assert() equivalent, that is always enabled.
int swri_rematrix(SwrContext *s, AudioData *out, AudioData *in, int len, int mustcopy)
#define AV_LOG_DEBUG
Stuff which is only useful for libav* developers.
#define AV_CH_TOP_SIDE_RIGHT
static av_cold int auto_matrix(SwrContext *s)
The libswresample context.
uint8_t * ch[SWR_CH_MAX]
samples buffer per channel
#define FFABS(a)
Absolute value, Note, INT_MIN / INT64_MIN result in undefined behavior as they are not representable ...
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.
static __device__ float fabs(float a)
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 AV_CH_FRONT_CENTER
#define AV_CH_FRONT_LEFT_OF_CENTER
#define AV_CH_BOTTOM_FRONT_CENTER
int ch_count
number of channels
An AVChannelLayout holds information about the channel layout of audio data.
#define i(width, name, range_min, range_max)
#define BOTTOM_FRONT_CENTER
av_cold void swri_rematrix_free(SwrContext *s)
#define AV_CH_TOP_BACK_RIGHT
@ AV_CHANNEL_ORDER_NATIVE
The native channel order, i.e.
#define AV_CH_FRONT_RIGHT_OF_CENTER
@ AV_SAMPLE_FMT_S16P
signed 16 bits, planar
int av_channel_layout_compare(const AVChannelLayout *chl, const AVChannelLayout *chl1)
Check whether two channel layouts are semantically the same, i.e.
Filter the word “frame” indicates either a video frame or a group of audio as stored in an AVFrame structure Format for each input and each output the list of supported formats For video that means pixel format For audio that means channel layout
#define FRONT_RIGHT_OF_CENTER
int av_get_bytes_per_sample(enum AVSampleFormat sample_fmt)
Return number of bytes per sample.
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_CH_BACK_CENTER
int swri_check_chlayout(struct SwrContext *s, const AVChannelLayout *chl, const char *name)
void * av_calloc(size_t nmemb, size_t size)
#define AV_CH_LAYOUT_SURROUND
int av_channel_layout_check(const AVChannelLayout *channel_layout)
Check whether a channel layout is valid, i.e.
@ AV_CHANNEL_ORDER_CUSTOM
The channel order does not correspond to any other predefined order and is stored as an explicit map.
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...
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_CH_BOTTOM_FRONT_RIGHT
void av_channel_layout_uninit(AVChannelLayout *channel_layout)
Free any allocated data in the channel layout and reset the channel count to 0.
enum AVSampleFormat av_get_packed_sample_fmt(enum AVSampleFormat sample_fmt)
Get the packed alternative form of the given sample format.
@ AV_SAMPLE_FMT_DBLP
double, planar
av_cold int swri_rematrix_init(SwrContext *s)
#define AV_CH_FRONT_RIGHT
int av_channel_layout_copy(AVChannelLayout *dst, const AVChannelLayout *src)
Make a copy of a channel layout.
#define AV_CHANNEL_LAYOUT_MONO
static const double coeff[2][5]
union AVChannelLayout::@530 u
Details about which channels are present in this layout.
@ AV_MATRIX_ENCODING_DPLII
static int clean_layout(AVChannelLayout *out, const AVChannelLayout *in, void *s)