mirror of
https://git.ffmpeg.org/ffmpeg.git
synced 2026-10-24 02:09:03 +03:00
swresample: keep integer samples if channels are only copied
With a matrix, samples of more than 16 bits are mixed in floating point, which takes the lowest bits of s32. A matrix that only copies channels computes nothing, so select the internal format like without a matrix. Layouts that differ in the order of their channels or in unused ones get such a matrix. The matrix is built before the format is selected for this. The limit for its coefficients no longer looks at the selected format. For mixing that is an integer format only if the output has one or if it was set, which is what the limit looks at now. s64 still goes through double, the matrix has no functions for it. Bump the micro version, as this and the previous commits change which custom layouts can be used. Signed-off-by: Kacper Michajłow <kasper93@gmail.com>
This commit is contained in:
@@ -697,7 +697,8 @@ av_cold static int auto_matrix(SwrContext *s)
|
||||
if (s->rematrix_maxval > 0) {
|
||||
maxval = s->rematrix_maxval;
|
||||
} else if ( av_get_packed_sample_fmt(s->out_sample_fmt) < AV_SAMPLE_FMT_FLT
|
||||
|| av_get_packed_sample_fmt(s->int_sample_fmt) < AV_SAMPLE_FMT_FLT) {
|
||||
|| (s->user_int_sample_fmt != AV_SAMPLE_FMT_NONE &&
|
||||
av_get_packed_sample_fmt(s->user_int_sample_fmt) < AV_SAMPLE_FMT_FLT)) {
|
||||
maxval = 1.0;
|
||||
} else
|
||||
maxval = INT_MAX;
|
||||
@@ -709,13 +710,12 @@ av_cold static int auto_matrix(SwrContext *s)
|
||||
s->matrix[1] - s->matrix[0], s->matrix_encoding, s);
|
||||
}
|
||||
|
||||
av_cold int swri_rematrix_init(SwrContext *s){
|
||||
av_cold int swri_rematrix_build(SwrContext *s)
|
||||
{
|
||||
int i, j;
|
||||
int nb_in = s->used_ch_layout.nb_channels;
|
||||
int nb_out = s->out.ch_count;
|
||||
|
||||
s->mix_any_f = NULL;
|
||||
|
||||
if (!s->rematrix_custom) {
|
||||
int r = auto_matrix(s);
|
||||
if (r)
|
||||
@@ -735,6 +735,34 @@ av_cold int swri_rematrix_init(SwrContext *s){
|
||||
av_log(s, AV_LOG_DEBUG, "\n");
|
||||
}
|
||||
}
|
||||
|
||||
/* a channel that is one channel of the input, or silent, is not mixed */
|
||||
for (i = 0; i < nb_out; i++) {
|
||||
int sources = 0;
|
||||
for (j = 0; j < nb_in; j++) {
|
||||
if (s->matrix[i][j] == 0.0)
|
||||
continue;
|
||||
if (s->matrix[i][j] != 1.0 || sources++)
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
av_cold int swri_rematrix_init(SwrContext *s){
|
||||
int i, j;
|
||||
int nb_in = s->used_ch_layout.nb_channels;
|
||||
int nb_out = s->out.ch_count;
|
||||
|
||||
s->mix_any_f = NULL;
|
||||
|
||||
/* a matrix that is applied was built by swri_rematrix_build() */
|
||||
if (!s->rematrix) {
|
||||
int r = auto_matrix(s);
|
||||
if (r)
|
||||
return r;
|
||||
}
|
||||
if (s->midbuf.fmt == AV_SAMPLE_FMT_S16P){
|
||||
int maxsum = 0;
|
||||
s->native_matrix = av_calloc(nb_in * nb_out, sizeof(int));
|
||||
|
||||
@@ -154,7 +154,7 @@ av_cold void swr_close(SwrContext *s){
|
||||
}
|
||||
|
||||
av_cold int swr_init(struct SwrContext *s){
|
||||
int ret;
|
||||
int ret, mixing;
|
||||
char l1[1024], l2[1024];
|
||||
|
||||
clear_context(s);
|
||||
@@ -232,6 +232,24 @@ av_cold int swr_init(struct SwrContext *s){
|
||||
s->rematrix_volume!=1.0 ||
|
||||
s->rematrix_custom;
|
||||
|
||||
av_channel_layout_describe(&s->out_ch_layout, l2, sizeof(l2));
|
||||
av_channel_layout_describe(&s->in_ch_layout, l1, sizeof(l1));
|
||||
if (( s->out_ch_layout.order == AV_CHANNEL_ORDER_UNSPEC
|
||||
|| s-> in_ch_layout.order == AV_CHANNEL_ORDER_UNSPEC) && s->used_ch_layout.nb_channels != s->out.ch_count && !s->rematrix_custom) {
|
||||
av_log(s, AV_LOG_ERROR, "Rematrix is needed between %s and %s "
|
||||
"but there is not enough information to do it\n", l1, l2);
|
||||
return AVERROR(EINVAL);
|
||||
}
|
||||
|
||||
/* a matrix that only copies channels leaves the samples as they are,
|
||||
* so the format in between is selected like without a matrix */
|
||||
mixing = 0;
|
||||
if (s->rematrix) {
|
||||
mixing = swri_rematrix_build(s);
|
||||
if (mixing < 0)
|
||||
return mixing;
|
||||
}
|
||||
|
||||
if(s->int_sample_fmt == AV_SAMPLE_FMT_NONE){
|
||||
// DSD to PCM conversion is done in floating point
|
||||
if( s->in_sample_fmt == AV_SAMPLE_FMT_DSD
|
||||
@@ -247,13 +265,13 @@ av_cold int swr_init(struct SwrContext *s){
|
||||
+av_get_bytes_per_sample(s->out_sample_fmt) <= 3 ) {
|
||||
s->int_sample_fmt= AV_SAMPLE_FMT_S16P;
|
||||
}else if( av_get_bytes_per_sample(s-> in_sample_fmt) <= 2
|
||||
&& !s->rematrix
|
||||
&& !mixing
|
||||
&& s->out_sample_rate==s->in_sample_rate
|
||||
&& !(s->flags & SWR_FLAG_RESAMPLE)){
|
||||
s->int_sample_fmt= AV_SAMPLE_FMT_S16P;
|
||||
}else if( av_get_planar_sample_fmt(s-> in_sample_fmt) == AV_SAMPLE_FMT_S32P
|
||||
&& av_get_planar_sample_fmt(s->out_sample_fmt) == AV_SAMPLE_FMT_S32P
|
||||
&& !s->rematrix
|
||||
&& !mixing
|
||||
&& s->out_sample_rate == s->in_sample_rate
|
||||
&& !(s->flags & SWR_FLAG_RESAMPLE)
|
||||
&& s->engine != SWR_ENGINE_SOXR){
|
||||
@@ -328,22 +346,12 @@ av_cold int swr_init(struct SwrContext *s){
|
||||
goto fail;
|
||||
}
|
||||
|
||||
av_channel_layout_describe(&s->out_ch_layout, l2, sizeof(l2));
|
||||
av_channel_layout_describe(&s->in_ch_layout, l1, sizeof(l1));
|
||||
if (s->in_ch_layout.order != AV_CHANNEL_ORDER_UNSPEC && s->used_ch_layout.nb_channels != s->in_ch_layout.nb_channels) {
|
||||
av_log(s, AV_LOG_ERROR, "Input channel layout %s mismatches specified channel count %d\n", l1, s->used_ch_layout.nb_channels);
|
||||
ret = AVERROR(EINVAL);
|
||||
goto fail;
|
||||
}
|
||||
|
||||
if (( s->out_ch_layout.order == AV_CHANNEL_ORDER_UNSPEC
|
||||
|| s-> in_ch_layout.order == AV_CHANNEL_ORDER_UNSPEC) && s->used_ch_layout.nb_channels != s->out.ch_count && !s->rematrix_custom) {
|
||||
av_log(s, AV_LOG_ERROR, "Rematrix is needed between %s and %s "
|
||||
"but there is not enough information to do it\n", l1, l2);
|
||||
ret = AVERROR(EINVAL);
|
||||
goto fail;
|
||||
}
|
||||
|
||||
av_assert0(s->used_ch_layout.nb_channels);
|
||||
av_assert0(s->out.ch_count);
|
||||
s->resample_first= RSC*s->out.ch_count/s->used_ch_layout.nb_channels - RSC < s->out_sample_rate/(float)s-> in_sample_rate - 1.0;
|
||||
|
||||
@@ -207,6 +207,8 @@ void swri_noise_shaping_int32 (SwrContext *s, AudioData *dsts, const AudioData *
|
||||
void swri_noise_shaping_float (SwrContext *s, AudioData *dsts, const AudioData *srcs, const AudioData *noises, int count);
|
||||
void swri_noise_shaping_double(SwrContext *s, AudioData *dsts, const AudioData *srcs, const AudioData *noises, int count);
|
||||
|
||||
av_warn_unused_result
|
||||
int swri_rematrix_build(SwrContext *s);
|
||||
av_warn_unused_result
|
||||
int swri_rematrix_init(SwrContext *s);
|
||||
void swri_rematrix_free(SwrContext *s);
|
||||
|
||||
@@ -31,7 +31,7 @@
|
||||
#include "version_major.h"
|
||||
|
||||
#define LIBSWRESAMPLE_VERSION_MINOR 3
|
||||
#define LIBSWRESAMPLE_VERSION_MICRO 100
|
||||
#define LIBSWRESAMPLE_VERSION_MICRO 101
|
||||
|
||||
#define LIBSWRESAMPLE_VERSION_INT AV_VERSION_INT(LIBSWRESAMPLE_VERSION_MAJOR, \
|
||||
LIBSWRESAMPLE_VERSION_MINOR, \
|
||||
|
||||
@@ -1106,6 +1106,16 @@ fate-swr-custom-rematrix: REF = 2a14a44deb4ae26e3b474ddbfbc048f8
|
||||
|
||||
FATE_SWR += $(FATE_SWR_CUSTOM_REMATRIX-yes)
|
||||
|
||||
FATE_SWR_S32_SRC = mod(n*$(1)\,4294967296)/2147483648-1
|
||||
FATE_SWR_S32_7_1 = $(call FATE_SWR_S32_SRC,1103515245)|$(call FATE_SWR_S32_SRC,22695477)|$(call FATE_SWR_S32_SRC,214013)|$(call FATE_SWR_S32_SRC,1664525)|$(call FATE_SWR_S32_SRC,134775813)|$(call FATE_SWR_S32_SRC,69069)|$(call FATE_SWR_S32_SRC,1812433253)|$(call FATE_SWR_S32_SRC,2654435761)
|
||||
|
||||
FATE_SWR_CUSTOM_REORDER-$(call ENCMUX, PCM_S32LE, PCM_S32LE, AEVALSRC_FILTER ARESAMPLE_FILTER AFORMAT_FILTER FILE_PROTOCOL) += fate-swr-custom-reorder
|
||||
fate-swr-custom-reorder: CMD = md5 -filter_complex "aevalsrc=$(FATE_SWR_S32_7_1):c=7.1:d=0.5,aresample,aformat=f=s32:cl=7.1,aresample,aformat=f=s32:cl=FR+FL+FC+LFE+SL+SR+BL+BR[OUT]" -map [OUT] -f s32le
|
||||
fate-swr-custom-reorder: CMP = oneline
|
||||
fate-swr-custom-reorder: REF = 3621f90f05eb313858791b3915b9ca18
|
||||
|
||||
FATE_SWR += $(FATE_SWR_CUSTOM_REORDER-yes)
|
||||
|
||||
FATE_SWR_22_2_LAYOUTS = 9.1.6 9.1.4 7.2.3 7.1.6 7.1.4 7.1.2 5.1.6 5.1.4 5.1.2 7.1 5.1 stereo mono
|
||||
FATE_SWR_9_1_6_LAYOUTS = 9.1.4 7.2.3 7.1.6 7.1.4 7.1.2 5.1.6 5.1.4 5.1.2 7.1 5.1 stereo mono
|
||||
FATE_SWR_9_1_4_LAYOUTS = 7.2.3 7.1.4 7.1.2 5.1.4 5.1.2 7.1 5.1 stereo mono
|
||||
|
||||
Reference in New Issue
Block a user