Go to the documentation of this file.
25 #define TEMPLATE_REMATRIX_FLT
27 #undef TEMPLATE_REMATRIX_FLT
29 #define TEMPLATE_REMATRIX_DBL
31 #undef TEMPLATE_REMATRIX_DBL
33 #define TEMPLATE_REMATRIX_S16
38 #undef TEMPLATE_REMATRIX_S16
40 #define TEMPLATE_REMATRIX_S32
42 #undef TEMPLATE_REMATRIX_S32
46 #define FRONT_CENTER 2
47 #define LOW_FREQUENCY 3
50 #define FRONT_LEFT_OF_CENTER 6
51 #define FRONT_RIGHT_OF_CENTER 7
56 #define TOP_FRONT_LEFT 12
57 #define TOP_FRONT_CENTER 13
58 #define TOP_FRONT_RIGHT 14
59 #define TOP_BACK_LEFT 15
60 #define TOP_BACK_CENTER 16
61 #define TOP_BACK_RIGHT 17
62 #define NUM_NAMED_CHANNELS 18
66 int nb_in, nb_out,
in,
out;
68 if (!
s ||
s->in_convert)
70 memset(
s->matrix, 0,
sizeof(
s->matrix));
71 memset(
s->matrix_flt, 0,
sizeof(
s->matrix_flt));
72 nb_in = (
s->user_in_ch_count > 0) ?
s->user_in_ch_count :
74 nb_out = (
s->user_out_ch_count > 0) ?
s->user_out_ch_count :
77 for (
in = 0;
in < nb_in;
in++)
81 s->rematrix_custom = 1;
120 double center_mix_level,
double surround_mix_level,
121 double lfe_mix_level,
double maxval,
122 double rematrix_volume,
double *matrix_param,
127 int64_t unaccounted, in_ch_layout, out_ch_layout;
131 in_ch_layout =
clean_layout(log_context, in_ch_layout_param);
132 out_ch_layout =
clean_layout(log_context, out_ch_layout_param);
146 av_log(log_context,
AV_LOG_ERROR,
"Input channel layout '%s' is not supported\n", buf);
152 av_log(log_context,
AV_LOG_ERROR,
"Output channel layout '%s' is not supported\n", buf);
157 if(in_ch_layout & out_ch_layout & (1ULL<<
i))
161 unaccounted= in_ch_layout & ~out_ch_layout;
306 for(out_i=
i=0;
i<64;
i++){
309 if((out_ch_layout & (1ULL<<
i)) == 0)
312 if((in_ch_layout & (1ULL<<j)) == 0)
315 matrix_param[
stride*out_i + in_i] = matrix[
i][j];
317 matrix_param[
stride*out_i + in_i] =
i == j && (in_ch_layout & out_ch_layout & (1ULL<<
i));
318 sum += fabs(matrix_param[
stride*out_i + in_i]);
321 maxcoef=
FFMAX(maxcoef, sum);
324 if(rematrix_volume < 0)
325 maxcoef = -rematrix_volume;
327 if(maxcoef > maxval || rematrix_volume < 0){
331 matrix_param[
stride*
i + j] /= maxcoef;
335 if(rematrix_volume > 0){
338 matrix_param[
stride*
i + j] *= rematrix_volume;
361 if (
s->rematrix_maxval > 0) {
362 maxval =
s->rematrix_maxval;
369 memset(
s->matrix, 0,
sizeof(
s->matrix));
371 s->clev,
s->slev,
s->lfe_mix_level,
372 maxval,
s->rematrix_volume, (
double*)
s->matrix,
373 s->matrix[1] -
s->matrix[0],
s->matrix_encoding,
s);
379 s->matrix_flt[
i][j] =
s->matrix[
i][j];
387 int nb_in =
s->used_ch_count;
388 int nb_out =
s->out.ch_count;
392 if (!
s->rematrix_custom) {
399 s->native_matrix =
av_calloc(nb_in * nb_out,
sizeof(
int));
401 if (!
s->native_matrix || !
s->native_one)
403 for (
i = 0;
i < nb_out;
i++) {
407 for (j = 0; j < nb_in; j++) {
408 double target =
s->matrix[
i][j] * 32768 + rem;
409 ((
int*)
s->native_matrix)[
i * nb_in + j] =
lrintf(target);
410 rem += target - ((
int*)
s->native_matrix)[
i * nb_in + j];
411 sum +=
FFABS(((
int*)
s->native_matrix)[
i * nb_in + j]);
413 maxsum =
FFMAX(maxsum, sum);
415 *((
int*)
s->native_one) = 32768;
416 if (maxsum <= 32768) {
426 s->native_matrix =
av_calloc(nb_in * nb_out,
sizeof(
float));
428 if (!
s->native_matrix || !
s->native_one)
430 for (
i = 0;
i < nb_out;
i++)
431 for (j = 0; j < nb_in; j++)
432 ((
float*)
s->native_matrix)[
i * nb_in + j] =
s->matrix[
i][j];
433 *((
float*)
s->native_one) = 1.0;
438 s->native_matrix =
av_calloc(nb_in * nb_out,
sizeof(
double));
440 if (!
s->native_matrix || !
s->native_one)
442 for (
i = 0;
i < nb_out;
i++)
443 for (j = 0; j < nb_in; j++)
444 ((
double*)
s->native_matrix)[
i * nb_in + j] =
s->matrix[
i][j];
445 *((
double*)
s->native_one) = 1.0;
453 s->native_matrix =
av_calloc(nb_in * nb_out,
sizeof(
int));
454 if (!
s->native_matrix) {
458 for (
i = 0;
i < nb_out;
i++) {
461 for (j = 0; j < nb_in; j++) {
462 double target =
s->matrix[
i][j] * 32768 + rem;
463 ((
int*)
s->native_matrix)[
i * nb_in + j] =
lrintf(target);
464 rem += target - ((
int*)
s->native_matrix)[
i * nb_in + j];
467 *((
int*)
s->native_one) = 32768;
477 s->matrix32[
i][j]=
lrintf(
s->matrix[
i][j] * 32768);
479 s->matrix_ch[
i][++ch_in]= j;
481 s->matrix_ch[
i][0]= ch_in;
484 if(HAVE_X86ASM && HAVE_MMX)
498 int out_i, in_i,
i, j;
507 if(
s->mix_2_1_simd ||
s->mix_1_1_simd){
509 off = len1 *
out->bps;
515 for(out_i=0; out_i<
out->ch_count; out_i++){
516 switch(
s->matrix_ch[out_i][0]){
522 in_i=
s->matrix_ch[out_i][1];
523 if(
s->matrix[out_i][in_i]!=1.0){
524 if(
s->mix_1_1_simd && len1)
525 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);
527 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);
529 memcpy(
out->ch[out_i],
in->ch[in_i],
len*
out->bps);
531 out->ch[out_i]=
in->ch[in_i];
535 int in_i1 =
s->matrix_ch[out_i][1];
536 int in_i2 =
s->matrix_ch[out_i][2];
537 if(
s->mix_2_1_simd && len1)
538 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);
540 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);
542 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);
548 for(j=0; j<
s->matrix_ch[out_i][0]; j++){
549 in_i=
s->matrix_ch[out_i][1+j];
550 v+= ((
float*)
in->ch[in_i])[
i] *
s->matrix_flt[out_i][in_i];
552 ((
float*)
out->ch[out_i])[
i]= v;
557 for(j=0; j<
s->matrix_ch[out_i][0]; j++){
558 in_i=
s->matrix_ch[out_i][1+j];
559 v+= ((
double*)
in->ch[in_i])[
i] *
s->matrix[out_i][in_i];
561 ((
double*)
out->ch[out_i])[
i]= v;
566 for(j=0; j<
s->matrix_ch[out_i][0]; j++){
567 in_i=
s->matrix_ch[out_i][1+j];
568 v+= ((int16_t*)
in->ch[in_i])[
i] *
s->matrix32[out_i][in_i];
570 ((int16_t*)
out->ch[out_i])[
i]= (v + 16384)>>15;
void() mix_any_func_type(uint8_t **out, const uint8_t **in1, void *coeffp, integer len)
@ AV_SAMPLE_FMT_FLTP
float, planar
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 NUM_NAMED_CHANNELS
void av_get_channel_layout_string(char *buf, int buf_size, int nb_channels, uint64_t channel_layout)
Return a description of 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.
int swr_set_matrix(struct SwrContext *s, const double *matrix, int stride)
Set a customized remix matrix.
Audio buffer used for intermediate storage between conversion phases.
#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)
@ AV_MATRIX_ENCODING_DOLBY
#define AV_CH_LOW_FREQUENCY
#define AV_CH_LAYOUT_STEREO_DOWNMIX
#define av_assert0(cond)
assert() equivalent, that is always enabled.
const char * av_get_channel_name(uint64_t channel)
Get the name of a given channel.
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.
static av_cold int auto_matrix(SwrContext *s)
The libswresample context.
#define FFABS(a)
Absolute value, Note, INT_MIN / INT64_MIN result in undefined behavior as they are not representable ...
#define AV_CH_FRONT_CENTER
#define AV_CH_FRONT_LEFT_OF_CENTER
Undefined Behavior In the C some operations are like signed integer dereferencing freed accessing outside allocated Undefined Behavior must not occur in a C it is not safe even if the output of undefined operations is unused The unsafety may seem nit picking but Optimizing compilers have in fact optimized code on the assumption that no undefined Behavior occurs Optimizing code based on wrong assumptions can and has in some cases lead to effects beyond the output of computations The signed integer overflow problem in speed critical code Code which is highly optimized and works with signed integers sometimes has the problem that often the output of the computation does not c
int av_get_channel_layout_nb_channels(uint64_t channel_layout)
Return the number of channels in the channel layout.
void() mix_2_1_func_type(void *out, const void *in1, const void *in2, void *coeffp, integer index1, integer index2, integer len)
static int clean_layout(void *s, int64_t layout)
av_cold void swri_rematrix_free(SwrContext *s)
#define AV_CH_FRONT_RIGHT_OF_CENTER
@ AV_SAMPLE_FMT_S16P
signed 16 bits, planar
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
void() mix_1_1_func_type(void *out, const void *in, void *coeffp, integer index, integer len)
uint8_t pi<< 24) CONV_FUNC_GROUP(AV_SAMPLE_FMT_FLT, float, AV_SAMPLE_FMT_U8, uint8_t,(*(const uint8_t *) pi - 0x80) *(1.0f/(1<< 7))) CONV_FUNC_GROUP(AV_SAMPLE_FMT_DBL, double, AV_SAMPLE_FMT_U8, uint8_t,(*(const uint8_t *) pi - 0x80) *(1.0/(1<< 7))) CONV_FUNC_GROUP(AV_SAMPLE_FMT_U8, uint8_t, AV_SAMPLE_FMT_S16, int16_t,(*(const int16_t *) pi >> 8)+0x80) CONV_FUNC_GROUP(AV_SAMPLE_FMT_FLT, float, AV_SAMPLE_FMT_S16, int16_t, *(const int16_t *) pi *(1.0f/(1<< 15))) CONV_FUNC_GROUP(AV_SAMPLE_FMT_DBL, double, AV_SAMPLE_FMT_S16, int16_t, *(const int16_t *) pi *(1.0/(1<< 15))) CONV_FUNC_GROUP(AV_SAMPLE_FMT_U8, uint8_t, AV_SAMPLE_FMT_S32, int32_t,(*(const int32_t *) pi >> 24)+0x80) CONV_FUNC_GROUP(AV_SAMPLE_FMT_FLT, float, AV_SAMPLE_FMT_S32, int32_t, *(const int32_t *) pi *(1.0f/(1U<< 31))) CONV_FUNC_GROUP(AV_SAMPLE_FMT_DBL, double, AV_SAMPLE_FMT_S32, int32_t, *(const int32_t *) pi *(1.0/(1U<< 31))) CONV_FUNC_GROUP(AV_SAMPLE_FMT_U8, uint8_t, AV_SAMPLE_FMT_FLT, float, av_clip_uint8(lrintf(*(const float *) pi *(1<< 7))+0x80)) CONV_FUNC_GROUP(AV_SAMPLE_FMT_S16, int16_t, AV_SAMPLE_FMT_FLT, float, av_clip_int16(lrintf(*(const float *) pi *(1<< 15)))) CONV_FUNC_GROUP(AV_SAMPLE_FMT_S32, int32_t, AV_SAMPLE_FMT_FLT, float, av_clipl_int32(llrintf(*(const float *) pi *(1U<< 31)))) CONV_FUNC_GROUP(AV_SAMPLE_FMT_U8, uint8_t, AV_SAMPLE_FMT_DBL, double, av_clip_uint8(lrint(*(const double *) pi *(1<< 7))+0x80)) CONV_FUNC_GROUP(AV_SAMPLE_FMT_S16, int16_t, AV_SAMPLE_FMT_DBL, double, av_clip_int16(lrint(*(const double *) pi *(1<< 15)))) CONV_FUNC_GROUP(AV_SAMPLE_FMT_S32, int32_t, AV_SAMPLE_FMT_DBL, double, av_clipl_int32(llrint(*(const double *) pi *(1U<< 31)))) #define SET_CONV_FUNC_GROUP(ofmt, ifmt) static void set_generic_function(AudioConvert *ac) { } void ff_audio_convert_free(AudioConvert **ac) { if(! *ac) return;ff_dither_free(&(*ac) ->dc);av_freep(ac);} AudioConvert *ff_audio_convert_alloc(AVAudioResampleContext *avr, enum AVSampleFormat out_fmt, enum AVSampleFormat in_fmt, int channels, int sample_rate, int apply_map) { AudioConvert *ac;int in_planar, out_planar;ac=av_mallocz(sizeof(*ac));if(!ac) return NULL;ac->avr=avr;ac->out_fmt=out_fmt;ac->in_fmt=in_fmt;ac->channels=channels;ac->apply_map=apply_map;if(avr->dither_method !=AV_RESAMPLE_DITHER_NONE &&av_get_packed_sample_fmt(out_fmt)==AV_SAMPLE_FMT_S16 &&av_get_bytes_per_sample(in_fmt) > 2) { ac->dc=ff_dither_alloc(avr, out_fmt, in_fmt, channels, sample_rate, apply_map);if(!ac->dc) { av_free(ac);return NULL;} return ac;} in_planar=ff_sample_fmt_is_planar(in_fmt, channels);out_planar=ff_sample_fmt_is_planar(out_fmt, channels);if(in_planar==out_planar) { ac->func_type=CONV_FUNC_TYPE_FLAT;ac->planes=in_planar ? ac->channels :1;} else if(in_planar) ac->func_type=CONV_FUNC_TYPE_INTERLEAVE;else ac->func_type=CONV_FUNC_TYPE_DEINTERLEAVE;set_generic_function(ac);if(ARCH_AARCH64) ff_audio_convert_init_aarch64(ac);if(ARCH_ARM) ff_audio_convert_init_arm(ac);if(ARCH_X86) ff_audio_convert_init_x86(ac);return ac;} int ff_audio_convert(AudioConvert *ac, AudioData *out, AudioData *in) { int use_generic=1;int len=in->nb_samples;int p;if(ac->dc) { av_log(ac->avr, AV_LOG_TRACE, "%d samples - audio_convert: %s to %s (dithered)\n", len, av_get_sample_fmt_name(ac->in_fmt), av_get_sample_fmt_name(ac->out_fmt));return ff_convert_dither(ac-> in
#define FRONT_RIGHT_OF_CENTER
#define i(width, name, range_min, range_max)
int av_get_bytes_per_sample(enum AVSampleFormat sample_fmt)
Return number of bytes per sample.
uint64_t av_channel_layout_extract_channel(uint64_t channel_layout, int index)
Get the channel with the given index in channel_layout.
#define AV_CH_BACK_CENTER
void * av_mallocz(size_t size)
Allocate a memory block with alignment suitable for all memory accesses (including vectors if availab...
#define AV_CH_LAYOUT_SURROUND
#define FF_ARRAY_ELEMS(a)
void * av_calloc(size_t nmemb, size_t size)
Non-inlined equivalent of av_mallocz_array().
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
av_cold int swr_build_matrix(uint64_t in_ch_layout_param, uint64_t out_ch_layout_param, double center_mix_level, double surround_mix_level, double lfe_mix_level, double maxval, double rematrix_volume, double *matrix_param, int stride, enum AVMatrixEncoding matrix_encoding, void *log_context)
Generate a channel mixing matrix.
static int sane_layout(int64_t layout)
@ AV_MATRIX_ENCODING_DPLII