From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from ffbox0-bg.mplayerhq.hu (ffbox0-bg.ffmpeg.org [79.124.17.100]) by master.gitmailbox.com (Postfix) with ESMTPS id 77F334BD06 for ; Sun, 2 Feb 2025 21:47:08 +0000 (UTC) Received: from [127.0.1.1] (localhost [127.0.0.1]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTP id 5875F68C097; Sun, 2 Feb 2025 23:47:05 +0200 (EET) Received: from mail-pl1-f176.google.com (mail-pl1-f176.google.com [209.85.214.176]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTPS id 907B368BDBF for ; Sun, 2 Feb 2025 23:46:58 +0200 (EET) Received: by mail-pl1-f176.google.com with SMTP id d9443c01a7336-21669fd5c7cso62649165ad.3 for ; Sun, 02 Feb 2025 13:46:58 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1738532816; x=1739137616; darn=ffmpeg.org; h=content-transfer-encoding:mime-version:message-id:date:subject:to :from:from:to:cc:subject:date:message-id:reply-to; bh=W0+iITL5NGYwQgLvY6iyRD/4piZUG77RRyt88T53MvA=; b=FRx3KJmxwf3kaf48xlTkPYDi22dCAALBnNqHHdRXE4cwSykrGglE0YnDe6fTgAvXYq hyJEACPdCRxVtUJz/IErkmpUGmB0+bosPKeU0OGSGokNVPHHCCTk0bLH4zUceoBpp77y zVHNUjVzFRRn+CyGhh6Ad0Wq3Gp8el7GpIK7D61jVCnbKrB8Mzs0gypCr3s1uC3xn640 hsGqLbHk6WXBSjl4Mc+Ah3Bs72sCsxcSYEpgRHTgmbWcIfeYcOt6kpxgqpmyCUdGjdss 5Akvw2V31Eq3lACfR6huvAqmRdRjdDpllVrgvRk33ixS5ndKg1WjjaeOn3DUoVGwa/CE In5w== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1738532816; x=1739137616; h=content-transfer-encoding:mime-version:message-id:date:subject:to :from:x-gm-message-state:from:to:cc:subject:date:message-id:reply-to; bh=W0+iITL5NGYwQgLvY6iyRD/4piZUG77RRyt88T53MvA=; b=D0xol3BXurEutup83edltUi5vwrILCxq7V6xR5dGLve0TXq5jyBk7jKNz1mCM9qLva MSHfVwPXfLv2yzvR7Zw42mGn4uUfPPF1LJVj0KlEYzK5dFv68bySO+wNWY+g2GpJ5HOl KTo/VDlq7vNq3eRZbbduPA7ugXGQ5+zAMdP25zAbJPfYt7LqHhhN+cvDIwGNkIusuv1h fgh8wbO0DK1ZELL4UsEbNUe5NoON7jU/joON4aj+lARzzC7jl84qApcEpLAfhpeph8a2 6jXFJNRqIRYI+duvtp6bA9ZiFL49QinAKIPMe1QEFIHFfwdrynaMJE/LAvM+Ju8sYlz7 HShw== X-Gm-Message-State: AOJu0Yzn8yOUS3ptYEOQwJhLgbmSpbn0364Gd5M4UH3PCsTRHfmMbWBF 5rIibGPicUDeT7RvY0PSsjIhTtykDSgCHoumK9PQtO7Q9wW6SzG+k2JRdPUM X-Gm-Gg: ASbGnctmc61owqdhIlCstuNG8Vblso+XlftKnZywks4nEUHCrwvOOQoXqPcmDzZSwE7 RuontBVGoz89zftQHuTOJZ6hcqmTRbzB3QpNNQc++qlaDQ6ZRk7hqeBm43gG8GUG0zbmQ3oF8tZ CEg0/v9u7vYSuxjo41uXhsKLfhzW5cQzSVUyYx5+kESFQYzPqkzJxS0EwUJatHLdNslmWVI4HWM QW1G4vkI5MXxYpP8SpCsZOJFcKibt8FFFC7OHBRFEdCsa/NTsIadcc+7CX/WEldjQcl1DSSCbZ1 kNj3mkDDVWy3HuoJ0Qk8/SlrYdolxCEE X-Google-Smtp-Source: AGHT+IEGRbcK64KpvYvzVQm+9KArny5X/e9L/sAGdOku/a04uUr+lfGVe3UlDhxbwJPo/dXcPNtgwg== X-Received: by 2002:a05:6a00:4652:b0:728:e906:e466 with SMTP id d2e1a72fcca58-72fd0c7c6b2mr28123346b3a.21.1738532815394; Sun, 02 Feb 2025 13:46:55 -0800 (PST) Received: from localhost.localdomain ([2800:2121:b040:c:511c:7b61:5388:930d]) by smtp.gmail.com with ESMTPSA id d2e1a72fcca58-72fe653ab3asm7000029b3a.82.2025.02.02.13.46.54 for (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sun, 02 Feb 2025 13:46:54 -0800 (PST) From: James Almer To: ffmpeg-devel@ffmpeg.org Date: Sun, 2 Feb 2025 18:46:41 -0300 Message-ID: <20250202214642.5316-1-jamrial@gmail.com> X-Mailer: git-send-email 2.48.1 MIME-Version: 1.0 Subject: [FFmpeg-devel] [PATCH 1/2] swresample/rematrix: split filling the matrix array into its own function X-BeenThere: ffmpeg-devel@ffmpeg.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: FFmpeg development discussions and patches List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Reply-To: FFmpeg development discussions and patches Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: 7bit Errors-To: ffmpeg-devel-bounces@ffmpeg.org Sender: "ffmpeg-devel" Archived-At: List-Archive: List-Post: Signed-off-by: James Almer --- libswresample/rematrix.c | 202 ++++++++++++++++++++------------------- 1 file changed, 106 insertions(+), 96 deletions(-) diff --git a/libswresample/rematrix.c b/libswresample/rematrix.c index b9bf4dcac0..8b6e8ae1c5 100644 --- a/libswresample/rematrix.c +++ b/libswresample/rematrix.c @@ -124,85 +124,28 @@ static int sane_layout(AVChannelLayout *ch_layout) { return 1; } -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) +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) { - int i, j, out_i, ret; - AVChannelLayout in_ch_layout = { 0 }, out_ch_layout = { 0 }; double matrix[NUM_NAMED_CHANNELS][NUM_NAMED_CHANNELS]={{0}}; - int64_t unaccounted; + uint64_t unaccounted = in_ch_layout->u.mask & ~out_ch_layout->u.mask; double maxcoef=0; - char buf[128]; - - ret = clean_layout(&in_ch_layout, in_layout, log_context); - ret |= clean_layout(&out_ch_layout, out_layout, log_context); - if (ret < 0) - goto fail; - - if( !av_channel_layout_compare(&out_ch_layout, &(AVChannelLayout)AV_CHANNEL_LAYOUT_STEREO_DOWNMIX) - && !av_channel_layout_subset(&in_ch_layout, AV_CH_LAYOUT_STEREO_DOWNMIX) - ) { - av_channel_layout_uninit(&out_ch_layout); - out_ch_layout = (AVChannelLayout)AV_CHANNEL_LAYOUT_STEREO; - } - if( !av_channel_layout_compare(&in_ch_layout, &(AVChannelLayout)AV_CHANNEL_LAYOUT_STEREO_DOWNMIX) - && !av_channel_layout_subset(&out_ch_layout, AV_CH_LAYOUT_STEREO_DOWNMIX) - ) { - av_channel_layout_uninit(&in_ch_layout); - in_ch_layout = (AVChannelLayout)AV_CHANNEL_LAYOUT_STEREO; - } - if (!av_channel_layout_compare(&in_ch_layout, &(AVChannelLayout)AV_CHANNEL_LAYOUT_22POINT2) && - av_channel_layout_compare(&out_ch_layout, &(AVChannelLayout)AV_CHANNEL_LAYOUT_22POINT2)) { - av_channel_layout_from_mask(&in_ch_layout, (AV_CH_LAYOUT_7POINT1_WIDE_BACK|AV_CH_BACK_CENTER)); - av_channel_layout_describe(&in_ch_layout, buf, sizeof(buf)); - av_log(log_context, AV_LOG_WARNING, - "Full-on remixing from 22.2 has not yet been implemented! " - "Processing the input as '%s'\n", - buf); - } - - if(!av_channel_layout_check(&in_ch_layout)) { - av_log(log_context, AV_LOG_ERROR, "Input channel layout is invalid\n"); - ret = AVERROR(EINVAL); - goto fail; - } - if(!sane_layout(&in_ch_layout)) { - av_channel_layout_describe(&in_ch_layout, buf, sizeof(buf)); - av_log(log_context, AV_LOG_ERROR, "Input channel layout '%s' is not supported\n", buf); - ret = AVERROR(EINVAL); - goto fail; - } - - if(!av_channel_layout_check(&out_ch_layout)) { - av_log(log_context, AV_LOG_ERROR, "Output channel layout is invalid\n"); - ret = AVERROR(EINVAL); - goto fail; - } - if(!sane_layout(&out_ch_layout)) { - av_channel_layout_describe(&out_ch_layout, buf, sizeof(buf)); - av_log(log_context, AV_LOG_ERROR, "Output channel layout '%s' is not supported\n", buf); - ret = AVERROR(EINVAL); - goto fail; - } + int i, j, out_i; for(i=0; i= 0 - && av_channel_layout_index_from_channel(&out_ch_layout, i) >= 0) + if( av_channel_layout_index_from_channel(in_ch_layout, i) >= 0 + && av_channel_layout_index_from_channel(out_ch_layout, i) >= 0) matrix[i][i]= 1.0; } - unaccounted = in_ch_layout.u.mask & ~out_ch_layout.u.mask; - //FIXME implement dolby surround //FIXME implement full ac3 - if(unaccounted & AV_CH_FRONT_CENTER){ - if (av_channel_layout_subset(&out_ch_layout, AV_CH_LAYOUT_STEREO) == AV_CH_LAYOUT_STEREO) { - if (av_channel_layout_subset(&in_ch_layout, AV_CH_LAYOUT_STEREO)) { + if (av_channel_layout_subset(out_ch_layout, AV_CH_LAYOUT_STEREO) == AV_CH_LAYOUT_STEREO) { + if (av_channel_layout_subset(in_ch_layout, AV_CH_LAYOUT_STEREO)) { matrix[ FRONT_LEFT][FRONT_CENTER]+= center_mix_level; matrix[FRONT_RIGHT][FRONT_CENTER]+= center_mix_level; } else { @@ -213,23 +156,23 @@ av_cold int swr_build_matrix2(const AVChannelLayout *in_layout, const AVChannelL av_assert0(0); } if(unaccounted & AV_CH_LAYOUT_STEREO){ - if (av_channel_layout_index_from_channel(&out_ch_layout, AV_CHAN_FRONT_CENTER) >= 0) { + if (av_channel_layout_index_from_channel(out_ch_layout, AV_CHAN_FRONT_CENTER) >= 0) { matrix[FRONT_CENTER][ FRONT_LEFT]+= M_SQRT1_2; matrix[FRONT_CENTER][FRONT_RIGHT]+= M_SQRT1_2; - if (av_channel_layout_index_from_channel(&in_ch_layout, AV_CHAN_FRONT_CENTER) >= 0) + if (av_channel_layout_index_from_channel(in_ch_layout, AV_CHAN_FRONT_CENTER) >= 0) matrix[FRONT_CENTER][ FRONT_CENTER] = center_mix_level*sqrt(2); }else av_assert0(0); } if(unaccounted & AV_CH_BACK_CENTER){ - if (av_channel_layout_index_from_channel(&out_ch_layout, AV_CHAN_BACK_LEFT) >= 0) { + if (av_channel_layout_index_from_channel(out_ch_layout, AV_CHAN_BACK_LEFT) >= 0) { matrix[ BACK_LEFT][BACK_CENTER]+= M_SQRT1_2; matrix[BACK_RIGHT][BACK_CENTER]+= M_SQRT1_2; - } else if (av_channel_layout_index_from_channel(&out_ch_layout, AV_CHAN_SIDE_LEFT) >= 0) { + } else if (av_channel_layout_index_from_channel(out_ch_layout, AV_CHAN_SIDE_LEFT) >= 0) { matrix[ SIDE_LEFT][BACK_CENTER]+= M_SQRT1_2; matrix[SIDE_RIGHT][BACK_CENTER]+= M_SQRT1_2; - } else if (av_channel_layout_index_from_channel(&out_ch_layout, AV_CHAN_FRONT_LEFT) >= 0) { + } else if (av_channel_layout_index_from_channel(out_ch_layout, AV_CHAN_FRONT_LEFT) >= 0) { if (matrix_encoding == AV_MATRIX_ENCODING_DOLBY || matrix_encoding == AV_MATRIX_ENCODING_DPLII) { if (unaccounted & (AV_CH_BACK_LEFT | AV_CH_SIDE_LEFT)) { @@ -243,24 +186,24 @@ av_cold int swr_build_matrix2(const AVChannelLayout *in_layout, const AVChannelL matrix[ FRONT_LEFT][BACK_CENTER]+= surround_mix_level * M_SQRT1_2; matrix[FRONT_RIGHT][BACK_CENTER]+= surround_mix_level * M_SQRT1_2; } - } else if (av_channel_layout_index_from_channel(&out_ch_layout, AV_CHAN_FRONT_CENTER) >= 0) { + } else if (av_channel_layout_index_from_channel(out_ch_layout, AV_CHAN_FRONT_CENTER) >= 0) { matrix[ FRONT_CENTER][BACK_CENTER]+= surround_mix_level * M_SQRT1_2; }else av_assert0(0); } if(unaccounted & AV_CH_BACK_LEFT){ - if (av_channel_layout_index_from_channel(&out_ch_layout, AV_CHAN_BACK_CENTER) >= 0) { + if (av_channel_layout_index_from_channel(out_ch_layout, AV_CHAN_BACK_CENTER) >= 0) { matrix[BACK_CENTER][ BACK_LEFT]+= M_SQRT1_2; matrix[BACK_CENTER][BACK_RIGHT]+= M_SQRT1_2; - } else if (av_channel_layout_index_from_channel(&out_ch_layout, AV_CHAN_SIDE_LEFT) >= 0) { - if (av_channel_layout_index_from_channel(&in_ch_layout, AV_CHAN_SIDE_LEFT) >= 0) { + } else if (av_channel_layout_index_from_channel(out_ch_layout, AV_CHAN_SIDE_LEFT) >= 0) { + if (av_channel_layout_index_from_channel(in_ch_layout, AV_CHAN_SIDE_LEFT) >= 0) { matrix[ SIDE_LEFT][ BACK_LEFT]+= M_SQRT1_2; matrix[SIDE_RIGHT][BACK_RIGHT]+= M_SQRT1_2; }else{ matrix[ SIDE_LEFT][ BACK_LEFT]+= 1.0; matrix[SIDE_RIGHT][BACK_RIGHT]+= 1.0; } - } else if (av_channel_layout_index_from_channel(&out_ch_layout, AV_CHAN_FRONT_LEFT) >= 0) { + } else if (av_channel_layout_index_from_channel(out_ch_layout, AV_CHAN_FRONT_LEFT) >= 0) { if (matrix_encoding == AV_MATRIX_ENCODING_DOLBY) { matrix[FRONT_LEFT ][BACK_LEFT ] -= surround_mix_level * M_SQRT1_2; matrix[FRONT_LEFT ][BACK_RIGHT] -= surround_mix_level * M_SQRT1_2; @@ -275,7 +218,7 @@ av_cold int swr_build_matrix2(const AVChannelLayout *in_layout, const AVChannelL matrix[ FRONT_LEFT][ BACK_LEFT] += surround_mix_level; matrix[FRONT_RIGHT][BACK_RIGHT] += surround_mix_level; } - } else if (av_channel_layout_index_from_channel(&out_ch_layout, AV_CHAN_FRONT_CENTER) >= 0) { + } else if (av_channel_layout_index_from_channel(out_ch_layout, AV_CHAN_FRONT_CENTER) >= 0) { matrix[ FRONT_CENTER][BACK_LEFT ]+= surround_mix_level*M_SQRT1_2; matrix[ FRONT_CENTER][BACK_RIGHT]+= surround_mix_level*M_SQRT1_2; }else @@ -283,20 +226,20 @@ av_cold int swr_build_matrix2(const AVChannelLayout *in_layout, const AVChannelL } if(unaccounted & AV_CH_SIDE_LEFT){ - if (av_channel_layout_index_from_channel(&out_ch_layout, AV_CHAN_BACK_LEFT) >= 0) { + if (av_channel_layout_index_from_channel(out_ch_layout, AV_CHAN_BACK_LEFT) >= 0) { /* if back channels do not exist in the input, just copy side channels to back channels, otherwise mix side into back */ - if (av_channel_layout_index_from_channel(&in_ch_layout, AV_CHAN_BACK_LEFT) >= 0) { + if (av_channel_layout_index_from_channel(in_ch_layout, AV_CHAN_BACK_LEFT) >= 0) { matrix[BACK_LEFT ][SIDE_LEFT ] += M_SQRT1_2; matrix[BACK_RIGHT][SIDE_RIGHT] += M_SQRT1_2; } else { matrix[BACK_LEFT ][SIDE_LEFT ] += 1.0; matrix[BACK_RIGHT][SIDE_RIGHT] += 1.0; } - } else if (av_channel_layout_index_from_channel(&out_ch_layout, AV_CHAN_BACK_CENTER) >= 0) { + } else if (av_channel_layout_index_from_channel(out_ch_layout, AV_CHAN_BACK_CENTER) >= 0) { matrix[BACK_CENTER][ SIDE_LEFT]+= M_SQRT1_2; matrix[BACK_CENTER][SIDE_RIGHT]+= M_SQRT1_2; - } else if (av_channel_layout_index_from_channel(&out_ch_layout, AV_CHAN_FRONT_LEFT) >= 0) { + } else if (av_channel_layout_index_from_channel(out_ch_layout, AV_CHAN_FRONT_LEFT) >= 0) { if (matrix_encoding == AV_MATRIX_ENCODING_DOLBY) { matrix[FRONT_LEFT ][SIDE_LEFT ] -= surround_mix_level * M_SQRT1_2; matrix[FRONT_LEFT ][SIDE_RIGHT] -= surround_mix_level * M_SQRT1_2; @@ -311,7 +254,7 @@ av_cold int swr_build_matrix2(const AVChannelLayout *in_layout, const AVChannelL matrix[ FRONT_LEFT][ SIDE_LEFT] += surround_mix_level; matrix[FRONT_RIGHT][SIDE_RIGHT] += surround_mix_level; } - } else if (av_channel_layout_index_from_channel(&out_ch_layout, AV_CHAN_FRONT_CENTER) >= 0) { + } else if (av_channel_layout_index_from_channel(out_ch_layout, AV_CHAN_FRONT_CENTER) >= 0) { matrix[ FRONT_CENTER][SIDE_LEFT ]+= surround_mix_level * M_SQRT1_2; matrix[ FRONT_CENTER][SIDE_RIGHT]+= surround_mix_level * M_SQRT1_2; }else @@ -319,10 +262,10 @@ av_cold int swr_build_matrix2(const AVChannelLayout *in_layout, const AVChannelL } if(unaccounted & AV_CH_FRONT_LEFT_OF_CENTER){ - if (av_channel_layout_index_from_channel(&out_ch_layout, AV_CHAN_FRONT_LEFT) >= 0) { + if (av_channel_layout_index_from_channel(out_ch_layout, AV_CHAN_FRONT_LEFT) >= 0) { matrix[ FRONT_LEFT][ FRONT_LEFT_OF_CENTER]+= 1.0; matrix[FRONT_RIGHT][FRONT_RIGHT_OF_CENTER]+= 1.0; - } else if (av_channel_layout_index_from_channel(&out_ch_layout, AV_CHAN_FRONT_CENTER) >= 0) { + } else if (av_channel_layout_index_from_channel(out_ch_layout, AV_CHAN_FRONT_CENTER) >= 0) { matrix[ FRONT_CENTER][ FRONT_LEFT_OF_CENTER]+= M_SQRT1_2; matrix[ FRONT_CENTER][FRONT_RIGHT_OF_CENTER]+= M_SQRT1_2; }else @@ -330,20 +273,20 @@ av_cold int swr_build_matrix2(const AVChannelLayout *in_layout, const AVChannelL } if (unaccounted & AV_CH_TOP_FRONT_LEFT) { - if (av_channel_layout_index_from_channel(&out_ch_layout, AV_CHAN_TOP_FRONT_CENTER) >= 0) { + if (av_channel_layout_index_from_channel(out_ch_layout, AV_CHAN_TOP_FRONT_CENTER) >= 0) { matrix[TOP_FRONT_CENTER][TOP_FRONT_LEFT ] += M_SQRT1_2; matrix[TOP_FRONT_CENTER][TOP_FRONT_RIGHT] += M_SQRT1_2; - if (av_channel_layout_index_from_channel(&in_ch_layout, AV_CHAN_TOP_FRONT_CENTER) >= 0) + if (av_channel_layout_index_from_channel(in_ch_layout, AV_CHAN_TOP_FRONT_CENTER) >= 0) matrix[TOP_FRONT_CENTER][TOP_FRONT_CENTER] = center_mix_level * sqrt(2); - } else if (av_channel_layout_index_from_channel(&out_ch_layout, AV_CHAN_FRONT_LEFT) >= 0) { - if (av_channel_layout_index_from_channel(&in_ch_layout, AV_CHAN_FRONT_LEFT) >= 0) { + } else if (av_channel_layout_index_from_channel(out_ch_layout, AV_CHAN_FRONT_LEFT) >= 0) { + if (av_channel_layout_index_from_channel(in_ch_layout, AV_CHAN_FRONT_LEFT) >= 0) { matrix[FRONT_LEFT ][TOP_FRONT_LEFT ] += M_SQRT1_2; matrix[FRONT_RIGHT][TOP_FRONT_RIGHT] += M_SQRT1_2; } else { matrix[FRONT_LEFT ][TOP_FRONT_LEFT ] += 1.0; matrix[FRONT_RIGHT][TOP_FRONT_RIGHT] += 1.0; } - } else if (av_channel_layout_index_from_channel(&out_ch_layout, AV_CHAN_FRONT_CENTER) >= 0) { + } else if (av_channel_layout_index_from_channel(out_ch_layout, AV_CHAN_FRONT_CENTER) >= 0) { matrix[FRONT_CENTER][TOP_FRONT_LEFT ] += M_SQRT1_2; matrix[FRONT_CENTER][TOP_FRONT_RIGHT] += M_SQRT1_2; } else @@ -352,29 +295,30 @@ av_cold int swr_build_matrix2(const AVChannelLayout *in_layout, const AVChannelL /* mix LFE into front left/right or center */ if (unaccounted & AV_CH_LOW_FREQUENCY) { - if (av_channel_layout_index_from_channel(&out_ch_layout, AV_CHAN_FRONT_CENTER) >= 0) { + if (av_channel_layout_index_from_channel(out_ch_layout, AV_CHAN_FRONT_CENTER) >= 0) { matrix[FRONT_CENTER][LOW_FREQUENCY] += lfe_mix_level; - } else if (av_channel_layout_index_from_channel(&out_ch_layout, AV_CHAN_FRONT_LEFT) >= 0) { + } else if (av_channel_layout_index_from_channel(out_ch_layout, AV_CHAN_FRONT_LEFT) >= 0) { matrix[FRONT_LEFT ][LOW_FREQUENCY] += lfe_mix_level * M_SQRT1_2; matrix[FRONT_RIGHT][LOW_FREQUENCY] += lfe_mix_level * M_SQRT1_2; } else av_assert0(0); } + for(out_i=i=0; i<64; i++){ double sum=0; int in_i=0; - if (av_channel_layout_index_from_channel(&out_ch_layout, i) < 0) + if (av_channel_layout_index_from_channel(out_ch_layout, i) < 0) continue; for(j=0; j<64; j++){ - if (av_channel_layout_index_from_channel(&in_ch_layout, j) < 0) + if (av_channel_layout_index_from_channel(in_ch_layout, j) < 0) continue; if (i < FF_ARRAY_ELEMS(matrix) && j < FF_ARRAY_ELEMS(matrix[0])) matrix_param[stride*out_i + in_i] = matrix[i][j]; else matrix_param[stride*out_i + in_i] = i == j && - ( av_channel_layout_index_from_channel(&in_ch_layout, i) >= 0 - && av_channel_layout_index_from_channel(&out_ch_layout, i) >= 0); + ( av_channel_layout_index_from_channel(in_ch_layout, i) >= 0 + && av_channel_layout_index_from_channel(out_ch_layout, i) >= 0); sum += fabs(matrix_param[stride*out_i + in_i]); in_i++; } @@ -391,6 +335,72 @@ av_cold int swr_build_matrix2(const AVChannelLayout *in_layout, const AVChannelL matrix_param[stride*i + j] /= maxcoef; } } +} + +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) +{ + int i, j, ret; + AVChannelLayout in_ch_layout = { 0 }, out_ch_layout = { 0 }; + char buf[128]; + + ret = clean_layout(&in_ch_layout, in_layout, log_context); + ret |= clean_layout(&out_ch_layout, out_layout, log_context); + if (ret < 0) + goto fail; + + if( !av_channel_layout_compare(&out_ch_layout, &(AVChannelLayout)AV_CHANNEL_LAYOUT_STEREO_DOWNMIX) + && !av_channel_layout_subset(&in_ch_layout, AV_CH_LAYOUT_STEREO_DOWNMIX) + ) { + av_channel_layout_uninit(&out_ch_layout); + out_ch_layout = (AVChannelLayout)AV_CHANNEL_LAYOUT_STEREO; + } + if( !av_channel_layout_compare(&in_ch_layout, &(AVChannelLayout)AV_CHANNEL_LAYOUT_STEREO_DOWNMIX) + && !av_channel_layout_subset(&out_ch_layout, AV_CH_LAYOUT_STEREO_DOWNMIX) + ) { + av_channel_layout_uninit(&in_ch_layout); + in_ch_layout = (AVChannelLayout)AV_CHANNEL_LAYOUT_STEREO; + } + if (!av_channel_layout_compare(&in_ch_layout, &(AVChannelLayout)AV_CHANNEL_LAYOUT_22POINT2) && + av_channel_layout_compare(&out_ch_layout, &(AVChannelLayout)AV_CHANNEL_LAYOUT_22POINT2)) { + av_channel_layout_from_mask(&in_ch_layout, (AV_CH_LAYOUT_7POINT1_WIDE_BACK|AV_CH_BACK_CENTER)); + av_channel_layout_describe(&in_ch_layout, buf, sizeof(buf)); + av_log(log_context, AV_LOG_WARNING, + "Full-on remixing from 22.2 has not yet been implemented! " + "Processing the input as '%s'\n", + buf); + } + + if(!av_channel_layout_check(&in_ch_layout)) { + av_log(log_context, AV_LOG_ERROR, "Input channel layout is invalid\n"); + ret = AVERROR(EINVAL); + goto fail; + } + if(!sane_layout(&in_ch_layout)) { + av_channel_layout_describe(&in_ch_layout, buf, sizeof(buf)); + av_log(log_context, AV_LOG_ERROR, "Input channel layout '%s' is not supported\n", buf); + ret = AVERROR(EINVAL); + goto fail; + } + + if(!av_channel_layout_check(&out_ch_layout)) { + av_log(log_context, AV_LOG_ERROR, "Output channel layout is invalid\n"); + ret = AVERROR(EINVAL); + goto fail; + } + if(!sane_layout(&out_ch_layout)) { + av_channel_layout_describe(&out_ch_layout, buf, sizeof(buf)); + av_log(log_context, AV_LOG_ERROR, "Output channel layout '%s' is not supported\n", buf); + ret = AVERROR(EINVAL); + goto fail; + } + + build_matrix(&in_ch_layout, &out_ch_layout, center_mix_level, + surround_mix_level, lfe_mix_level, maxval, rematrix_volume, + matrix_param, stride, matrix_encoding); if(rematrix_volume > 0){ for(i=0; i