Subversion Repositories Kolibri OS

Rev

Blame | Last modification | View Log | RSS feed

  1. /*
  2.  * Copyright (C) 2011-2012 Michael Niedermayer (michaelni@gmx.at)
  3.  *
  4.  * This file is part of libswresample
  5.  *
  6.  * libswresample is free software; you can redistribute it and/or
  7.  * modify it under the terms of the GNU Lesser General Public
  8.  * License as published by the Free Software Foundation; either
  9.  * version 2.1 of the License, or (at your option) any later version.
  10.  *
  11.  * libswresample is distributed in the hope that it will be useful,
  12.  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  13.  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  14.  * Lesser General Public License for more details.
  15.  *
  16.  * You should have received a copy of the GNU Lesser General Public
  17.  * License along with libswresample; if not, write to the Free Software
  18.  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  19.  */
  20.  
  21. #include "swresample_internal.h"
  22. #include "libavutil/avassert.h"
  23. #include "libavutil/channel_layout.h"
  24.  
  25. #define TEMPLATE_REMATRIX_FLT
  26. #include "rematrix_template.c"
  27. #undef TEMPLATE_REMATRIX_FLT
  28.  
  29. #define TEMPLATE_REMATRIX_DBL
  30. #include "rematrix_template.c"
  31. #undef TEMPLATE_REMATRIX_DBL
  32.  
  33. #define TEMPLATE_REMATRIX_S16
  34. #include "rematrix_template.c"
  35. #undef TEMPLATE_REMATRIX_S16
  36.  
  37. #define TEMPLATE_REMATRIX_S32
  38. #include "rematrix_template.c"
  39. #undef TEMPLATE_REMATRIX_S32
  40.  
  41. #define FRONT_LEFT             0
  42. #define FRONT_RIGHT            1
  43. #define FRONT_CENTER           2
  44. #define LOW_FREQUENCY          3
  45. #define BACK_LEFT              4
  46. #define BACK_RIGHT             5
  47. #define FRONT_LEFT_OF_CENTER   6
  48. #define FRONT_RIGHT_OF_CENTER  7
  49. #define BACK_CENTER            8
  50. #define SIDE_LEFT              9
  51. #define SIDE_RIGHT             10
  52. #define TOP_CENTER             11
  53. #define TOP_FRONT_LEFT         12
  54. #define TOP_FRONT_CENTER       13
  55. #define TOP_FRONT_RIGHT        14
  56. #define TOP_BACK_LEFT          15
  57. #define TOP_BACK_CENTER        16
  58. #define TOP_BACK_RIGHT         17
  59. #define NUM_NAMED_CHANNELS     18
  60.  
  61. int swr_set_matrix(struct SwrContext *s, const double *matrix, int stride)
  62. {
  63.     int nb_in, nb_out, in, out;
  64.  
  65.     if (!s || s->in_convert) // s needs to be allocated but not initialized
  66.         return AVERROR(EINVAL);
  67.     memset(s->matrix, 0, sizeof(s->matrix));
  68.     nb_in  = av_get_channel_layout_nb_channels(s->user_in_ch_layout);
  69.     nb_out = av_get_channel_layout_nb_channels(s->user_out_ch_layout);
  70.     for (out = 0; out < nb_out; out++) {
  71.         for (in = 0; in < nb_in; in++)
  72.             s->matrix[out][in] = matrix[in];
  73.         matrix += stride;
  74.     }
  75.     s->rematrix_custom = 1;
  76.     return 0;
  77. }
  78.  
  79. static int even(int64_t layout){
  80.     if(!layout) return 1;
  81.     if(layout&(layout-1)) return 1;
  82.     return 0;
  83. }
  84.  
  85. static int clean_layout(SwrContext *s, int64_t layout){
  86.     if(layout && layout != AV_CH_FRONT_CENTER && !(layout&(layout-1))) {
  87.         char buf[128];
  88.         av_get_channel_layout_string(buf, sizeof(buf), -1, layout);
  89.         av_log(s, AV_LOG_VERBOSE, "Treating %s as mono\n", buf);
  90.         return AV_CH_FRONT_CENTER;
  91.     }
  92.  
  93.     return layout;
  94. }
  95.  
  96. static int sane_layout(int64_t layout){
  97.     if(!(layout & AV_CH_LAYOUT_SURROUND)) // at least 1 front speaker
  98.         return 0;
  99.     if(!even(layout & (AV_CH_FRONT_LEFT | AV_CH_FRONT_RIGHT))) // no asymetric front
  100.         return 0;
  101.     if(!even(layout & (AV_CH_SIDE_LEFT | AV_CH_SIDE_RIGHT)))   // no asymetric side
  102.         return 0;
  103.     if(!even(layout & (AV_CH_BACK_LEFT | AV_CH_BACK_RIGHT)))
  104.         return 0;
  105.     if(!even(layout & (AV_CH_FRONT_LEFT_OF_CENTER | AV_CH_FRONT_RIGHT_OF_CENTER)))
  106.         return 0;
  107.     if(av_get_channel_layout_nb_channels(layout) >= SWR_CH_MAX)
  108.         return 0;
  109.  
  110.     return 1;
  111. }
  112.  
  113. av_cold static int auto_matrix(SwrContext *s)
  114. {
  115.     int i, j, out_i;
  116.     double matrix[NUM_NAMED_CHANNELS][NUM_NAMED_CHANNELS]={{0}};
  117.     int64_t unaccounted, in_ch_layout, out_ch_layout;
  118.     double maxcoef=0;
  119.     char buf[128];
  120.     const int matrix_encoding = s->matrix_encoding;
  121.     float maxval;
  122.  
  123.     in_ch_layout = clean_layout(s, s->in_ch_layout);
  124.     out_ch_layout = clean_layout(s, s->out_ch_layout);
  125.  
  126.     if(   out_ch_layout == AV_CH_LAYOUT_STEREO_DOWNMIX
  127.        && (in_ch_layout & AV_CH_LAYOUT_STEREO_DOWNMIX) == 0
  128.     )
  129.         out_ch_layout = AV_CH_LAYOUT_STEREO;
  130.  
  131.     if(    in_ch_layout == AV_CH_LAYOUT_STEREO_DOWNMIX
  132.        && (out_ch_layout & AV_CH_LAYOUT_STEREO_DOWNMIX) == 0
  133.     )
  134.         in_ch_layout = AV_CH_LAYOUT_STEREO;
  135.  
  136.     if(!sane_layout(in_ch_layout)){
  137.         av_get_channel_layout_string(buf, sizeof(buf), -1, s->in_ch_layout);
  138.         av_log(s, AV_LOG_ERROR, "Input channel layout '%s' is not supported\n", buf);
  139.         return AVERROR(EINVAL);
  140.     }
  141.  
  142.     if(!sane_layout(out_ch_layout)){
  143.         av_get_channel_layout_string(buf, sizeof(buf), -1, s->out_ch_layout);
  144.         av_log(s, AV_LOG_ERROR, "Output channel layout '%s' is not supported\n", buf);
  145.         return AVERROR(EINVAL);
  146.     }
  147.  
  148.     memset(s->matrix, 0, sizeof(s->matrix));
  149.     for(i=0; i<FF_ARRAY_ELEMS(matrix); i++){
  150.         if(in_ch_layout & out_ch_layout & (1ULL<<i))
  151.             matrix[i][i]= 1.0;
  152.     }
  153.  
  154.     unaccounted= in_ch_layout & ~out_ch_layout;
  155.  
  156. //FIXME implement dolby surround
  157. //FIXME implement full ac3
  158.  
  159.  
  160.     if(unaccounted & AV_CH_FRONT_CENTER){
  161.         if((out_ch_layout & AV_CH_LAYOUT_STEREO) == AV_CH_LAYOUT_STEREO){
  162.             if(in_ch_layout & AV_CH_LAYOUT_STEREO) {
  163.                 matrix[ FRONT_LEFT][FRONT_CENTER]+= s->clev;
  164.                 matrix[FRONT_RIGHT][FRONT_CENTER]+= s->clev;
  165.             } else {
  166.                 matrix[ FRONT_LEFT][FRONT_CENTER]+= M_SQRT1_2;
  167.                 matrix[FRONT_RIGHT][FRONT_CENTER]+= M_SQRT1_2;
  168.             }
  169.         }else
  170.             av_assert0(0);
  171.     }
  172.     if(unaccounted & AV_CH_LAYOUT_STEREO){
  173.         if(out_ch_layout & AV_CH_FRONT_CENTER){
  174.             matrix[FRONT_CENTER][ FRONT_LEFT]+= M_SQRT1_2;
  175.             matrix[FRONT_CENTER][FRONT_RIGHT]+= M_SQRT1_2;
  176.             if(in_ch_layout & AV_CH_FRONT_CENTER)
  177.                 matrix[FRONT_CENTER][ FRONT_CENTER] = s->clev*sqrt(2);
  178.         }else
  179.             av_assert0(0);
  180.     }
  181.  
  182.     if(unaccounted & AV_CH_BACK_CENTER){
  183.         if(out_ch_layout & AV_CH_BACK_LEFT){
  184.             matrix[ BACK_LEFT][BACK_CENTER]+= M_SQRT1_2;
  185.             matrix[BACK_RIGHT][BACK_CENTER]+= M_SQRT1_2;
  186.         }else if(out_ch_layout & AV_CH_SIDE_LEFT){
  187.             matrix[ SIDE_LEFT][BACK_CENTER]+= M_SQRT1_2;
  188.             matrix[SIDE_RIGHT][BACK_CENTER]+= M_SQRT1_2;
  189.         }else if(out_ch_layout & AV_CH_FRONT_LEFT){
  190.             if (matrix_encoding == AV_MATRIX_ENCODING_DOLBY ||
  191.                 matrix_encoding == AV_MATRIX_ENCODING_DPLII) {
  192.                 if (unaccounted & (AV_CH_BACK_LEFT | AV_CH_SIDE_LEFT)) {
  193.                     matrix[FRONT_LEFT ][BACK_CENTER] -= s->slev * M_SQRT1_2;
  194.                     matrix[FRONT_RIGHT][BACK_CENTER] += s->slev * M_SQRT1_2;
  195.                 } else {
  196.                     matrix[FRONT_LEFT ][BACK_CENTER] -= s->slev;
  197.                     matrix[FRONT_RIGHT][BACK_CENTER] += s->slev;
  198.                 }
  199.             } else {
  200.                 matrix[ FRONT_LEFT][BACK_CENTER]+= s->slev*M_SQRT1_2;
  201.                 matrix[FRONT_RIGHT][BACK_CENTER]+= s->slev*M_SQRT1_2;
  202.             }
  203.         }else if(out_ch_layout & AV_CH_FRONT_CENTER){
  204.             matrix[ FRONT_CENTER][BACK_CENTER]+= s->slev*M_SQRT1_2;
  205.         }else
  206.             av_assert0(0);
  207.     }
  208.     if(unaccounted & AV_CH_BACK_LEFT){
  209.         if(out_ch_layout & AV_CH_BACK_CENTER){
  210.             matrix[BACK_CENTER][ BACK_LEFT]+= M_SQRT1_2;
  211.             matrix[BACK_CENTER][BACK_RIGHT]+= M_SQRT1_2;
  212.         }else if(out_ch_layout & AV_CH_SIDE_LEFT){
  213.             if(in_ch_layout & AV_CH_SIDE_LEFT){
  214.                 matrix[ SIDE_LEFT][ BACK_LEFT]+= M_SQRT1_2;
  215.                 matrix[SIDE_RIGHT][BACK_RIGHT]+= M_SQRT1_2;
  216.             }else{
  217.             matrix[ SIDE_LEFT][ BACK_LEFT]+= 1.0;
  218.             matrix[SIDE_RIGHT][BACK_RIGHT]+= 1.0;
  219.             }
  220.         }else if(out_ch_layout & AV_CH_FRONT_LEFT){
  221.             if (matrix_encoding == AV_MATRIX_ENCODING_DOLBY) {
  222.                 matrix[FRONT_LEFT ][BACK_LEFT ] -= s->slev * M_SQRT1_2;
  223.                 matrix[FRONT_LEFT ][BACK_RIGHT] -= s->slev * M_SQRT1_2;
  224.                 matrix[FRONT_RIGHT][BACK_LEFT ] += s->slev * M_SQRT1_2;
  225.                 matrix[FRONT_RIGHT][BACK_RIGHT] += s->slev * M_SQRT1_2;
  226.             } else if (matrix_encoding == AV_MATRIX_ENCODING_DPLII) {
  227.                 matrix[FRONT_LEFT ][BACK_LEFT ] -= s->slev * SQRT3_2;
  228.                 matrix[FRONT_LEFT ][BACK_RIGHT] -= s->slev * M_SQRT1_2;
  229.                 matrix[FRONT_RIGHT][BACK_LEFT ] += s->slev * M_SQRT1_2;
  230.                 matrix[FRONT_RIGHT][BACK_RIGHT] += s->slev * SQRT3_2;
  231.             } else {
  232.                 matrix[ FRONT_LEFT][ BACK_LEFT] += s->slev;
  233.                 matrix[FRONT_RIGHT][BACK_RIGHT] += s->slev;
  234.             }
  235.         }else if(out_ch_layout & AV_CH_FRONT_CENTER){
  236.             matrix[ FRONT_CENTER][BACK_LEFT ]+= s->slev*M_SQRT1_2;
  237.             matrix[ FRONT_CENTER][BACK_RIGHT]+= s->slev*M_SQRT1_2;
  238.         }else
  239.             av_assert0(0);
  240.     }
  241.  
  242.     if(unaccounted & AV_CH_SIDE_LEFT){
  243.         if(out_ch_layout & AV_CH_BACK_LEFT){
  244.             /* if back channels do not exist in the input, just copy side
  245.                channels to back channels, otherwise mix side into back */
  246.             if (in_ch_layout & AV_CH_BACK_LEFT) {
  247.                 matrix[BACK_LEFT ][SIDE_LEFT ] += M_SQRT1_2;
  248.                 matrix[BACK_RIGHT][SIDE_RIGHT] += M_SQRT1_2;
  249.             } else {
  250.                 matrix[BACK_LEFT ][SIDE_LEFT ] += 1.0;
  251.                 matrix[BACK_RIGHT][SIDE_RIGHT] += 1.0;
  252.             }
  253.         }else if(out_ch_layout & AV_CH_BACK_CENTER){
  254.             matrix[BACK_CENTER][ SIDE_LEFT]+= M_SQRT1_2;
  255.             matrix[BACK_CENTER][SIDE_RIGHT]+= M_SQRT1_2;
  256.         }else if(out_ch_layout & AV_CH_FRONT_LEFT){
  257.             if (matrix_encoding == AV_MATRIX_ENCODING_DOLBY) {
  258.                 matrix[FRONT_LEFT ][SIDE_LEFT ] -= s->slev * M_SQRT1_2;
  259.                 matrix[FRONT_LEFT ][SIDE_RIGHT] -= s->slev * M_SQRT1_2;
  260.                 matrix[FRONT_RIGHT][SIDE_LEFT ] += s->slev * M_SQRT1_2;
  261.                 matrix[FRONT_RIGHT][SIDE_RIGHT] += s->slev * M_SQRT1_2;
  262.             } else if (matrix_encoding == AV_MATRIX_ENCODING_DPLII) {
  263.                 matrix[FRONT_LEFT ][SIDE_LEFT ] -= s->slev * SQRT3_2;
  264.                 matrix[FRONT_LEFT ][SIDE_RIGHT] -= s->slev * M_SQRT1_2;
  265.                 matrix[FRONT_RIGHT][SIDE_LEFT ] += s->slev * M_SQRT1_2;
  266.                 matrix[FRONT_RIGHT][SIDE_RIGHT] += s->slev * SQRT3_2;
  267.             } else {
  268.                 matrix[ FRONT_LEFT][ SIDE_LEFT] += s->slev;
  269.                 matrix[FRONT_RIGHT][SIDE_RIGHT] += s->slev;
  270.             }
  271.         }else if(out_ch_layout & AV_CH_FRONT_CENTER){
  272.             matrix[ FRONT_CENTER][SIDE_LEFT ]+= s->slev*M_SQRT1_2;
  273.             matrix[ FRONT_CENTER][SIDE_RIGHT]+= s->slev*M_SQRT1_2;
  274.         }else
  275.             av_assert0(0);
  276.     }
  277.  
  278.     if(unaccounted & AV_CH_FRONT_LEFT_OF_CENTER){
  279.         if(out_ch_layout & AV_CH_FRONT_LEFT){
  280.             matrix[ FRONT_LEFT][ FRONT_LEFT_OF_CENTER]+= 1.0;
  281.             matrix[FRONT_RIGHT][FRONT_RIGHT_OF_CENTER]+= 1.0;
  282.         }else if(out_ch_layout & AV_CH_FRONT_CENTER){
  283.             matrix[ FRONT_CENTER][ FRONT_LEFT_OF_CENTER]+= M_SQRT1_2;
  284.             matrix[ FRONT_CENTER][FRONT_RIGHT_OF_CENTER]+= M_SQRT1_2;
  285.         }else
  286.             av_assert0(0);
  287.     }
  288.     /* mix LFE into front left/right or center */
  289.     if (unaccounted & AV_CH_LOW_FREQUENCY) {
  290.         if (out_ch_layout & AV_CH_FRONT_CENTER) {
  291.             matrix[FRONT_CENTER][LOW_FREQUENCY] += s->lfe_mix_level;
  292.         } else if (out_ch_layout & AV_CH_FRONT_LEFT) {
  293.             matrix[FRONT_LEFT ][LOW_FREQUENCY] += s->lfe_mix_level * M_SQRT1_2;
  294.             matrix[FRONT_RIGHT][LOW_FREQUENCY] += s->lfe_mix_level * M_SQRT1_2;
  295.         } else
  296.             av_assert0(0);
  297.     }
  298.  
  299.     for(out_i=i=0; i<64; i++){
  300.         double sum=0;
  301.         int in_i=0;
  302.         if((out_ch_layout & (1ULL<<i)) == 0)
  303.             continue;
  304.         for(j=0; j<64; j++){
  305.             if((in_ch_layout & (1ULL<<j)) == 0)
  306.                continue;
  307.             if (i < FF_ARRAY_ELEMS(matrix) && j < FF_ARRAY_ELEMS(matrix[0]))
  308.                 s->matrix[out_i][in_i]= matrix[i][j];
  309.             else
  310.                 s->matrix[out_i][in_i]= i == j && (in_ch_layout & out_ch_layout & (1ULL<<i));
  311.             sum += fabs(s->matrix[out_i][in_i]);
  312.             in_i++;
  313.         }
  314.         maxcoef= FFMAX(maxcoef, sum);
  315.         out_i++;
  316.     }
  317.     if(s->rematrix_volume  < 0)
  318.         maxcoef = -s->rematrix_volume;
  319.  
  320.     if (s->rematrix_maxval > 0) {
  321.         maxval = s->rematrix_maxval;
  322.     } else if (   av_get_packed_sample_fmt(s->out_sample_fmt) < AV_SAMPLE_FMT_FLT
  323.                || av_get_packed_sample_fmt(s->int_sample_fmt) < AV_SAMPLE_FMT_FLT) {
  324.         maxval = 1.0;
  325.     } else
  326.         maxval = INT_MAX;
  327.  
  328.     if(maxcoef > maxval || s->rematrix_volume  < 0){
  329.         maxcoef /= maxval;
  330.         for(i=0; i<SWR_CH_MAX; i++)
  331.             for(j=0; j<SWR_CH_MAX; j++){
  332.                 s->matrix[i][j] /= maxcoef;
  333.             }
  334.     }
  335.  
  336.     if(s->rematrix_volume > 0){
  337.         for(i=0; i<SWR_CH_MAX; i++)
  338.             for(j=0; j<SWR_CH_MAX; j++){
  339.                 s->matrix[i][j] *= s->rematrix_volume;
  340.             }
  341.     }
  342.  
  343.     for(i=0; i<av_get_channel_layout_nb_channels(out_ch_layout); i++){
  344.         for(j=0; j<av_get_channel_layout_nb_channels(in_ch_layout); j++){
  345.             av_log(NULL, AV_LOG_DEBUG, "%f ", s->matrix[i][j]);
  346.         }
  347.         av_log(NULL, AV_LOG_DEBUG, "\n");
  348.     }
  349.     return 0;
  350. }
  351.  
  352. av_cold int swri_rematrix_init(SwrContext *s){
  353.     int i, j;
  354.     int nb_in  = av_get_channel_layout_nb_channels(s->in_ch_layout);
  355.     int nb_out = av_get_channel_layout_nb_channels(s->out_ch_layout);
  356.  
  357.     s->mix_any_f = NULL;
  358.  
  359.     if (!s->rematrix_custom) {
  360.         int r = auto_matrix(s);
  361.         if (r)
  362.             return r;
  363.     }
  364.     if (s->midbuf.fmt == AV_SAMPLE_FMT_S16P){
  365.         s->native_matrix = av_calloc(nb_in * nb_out, sizeof(int));
  366.         s->native_one    = av_mallocz(sizeof(int));
  367.         if (!s->native_matrix || !s->native_one)
  368.             return AVERROR(ENOMEM);
  369.         for (i = 0; i < nb_out; i++)
  370.             for (j = 0; j < nb_in; j++)
  371.                 ((int*)s->native_matrix)[i * nb_in + j] = lrintf(s->matrix[i][j] * 32768);
  372.         *((int*)s->native_one) = 32768;
  373.         s->mix_1_1_f = (mix_1_1_func_type*)copy_s16;
  374.         s->mix_2_1_f = (mix_2_1_func_type*)sum2_s16;
  375.         s->mix_any_f = (mix_any_func_type*)get_mix_any_func_s16(s);
  376.     }else if(s->midbuf.fmt == AV_SAMPLE_FMT_FLTP){
  377.         s->native_matrix = av_calloc(nb_in * nb_out, sizeof(float));
  378.         s->native_one    = av_mallocz(sizeof(float));
  379.         if (!s->native_matrix || !s->native_one)
  380.             return AVERROR(ENOMEM);
  381.         for (i = 0; i < nb_out; i++)
  382.             for (j = 0; j < nb_in; j++)
  383.                 ((float*)s->native_matrix)[i * nb_in + j] = s->matrix[i][j];
  384.         *((float*)s->native_one) = 1.0;
  385.         s->mix_1_1_f = (mix_1_1_func_type*)copy_float;
  386.         s->mix_2_1_f = (mix_2_1_func_type*)sum2_float;
  387.         s->mix_any_f = (mix_any_func_type*)get_mix_any_func_float(s);
  388.     }else if(s->midbuf.fmt == AV_SAMPLE_FMT_DBLP){
  389.         s->native_matrix = av_calloc(nb_in * nb_out, sizeof(double));
  390.         s->native_one    = av_mallocz(sizeof(double));
  391.         if (!s->native_matrix || !s->native_one)
  392.             return AVERROR(ENOMEM);
  393.         for (i = 0; i < nb_out; i++)
  394.             for (j = 0; j < nb_in; j++)
  395.                 ((double*)s->native_matrix)[i * nb_in + j] = s->matrix[i][j];
  396.         *((double*)s->native_one) = 1.0;
  397.         s->mix_1_1_f = (mix_1_1_func_type*)copy_double;
  398.         s->mix_2_1_f = (mix_2_1_func_type*)sum2_double;
  399.         s->mix_any_f = (mix_any_func_type*)get_mix_any_func_double(s);
  400.     }else if(s->midbuf.fmt == AV_SAMPLE_FMT_S32P){
  401.         // Only for dithering currently
  402. //         s->native_matrix = av_calloc(nb_in * nb_out, sizeof(double));
  403.         s->native_one    = av_mallocz(sizeof(int));
  404.         if (!s->native_one)
  405.             return AVERROR(ENOMEM);
  406. //         for (i = 0; i < nb_out; i++)
  407. //             for (j = 0; j < nb_in; j++)
  408. //                 ((double*)s->native_matrix)[i * nb_in + j] = s->matrix[i][j];
  409.         *((int*)s->native_one) = 32768;
  410.         s->mix_1_1_f = (mix_1_1_func_type*)copy_s32;
  411.         s->mix_2_1_f = (mix_2_1_func_type*)sum2_s32;
  412.         s->mix_any_f = (mix_any_func_type*)get_mix_any_func_s32(s);
  413.     }else
  414.         av_assert0(0);
  415.     //FIXME quantize for integeres
  416.     for (i = 0; i < SWR_CH_MAX; i++) {
  417.         int ch_in=0;
  418.         for (j = 0; j < SWR_CH_MAX; j++) {
  419.             s->matrix32[i][j]= lrintf(s->matrix[i][j] * 32768);
  420.             if(s->matrix[i][j])
  421.                 s->matrix_ch[i][++ch_in]= j;
  422.         }
  423.         s->matrix_ch[i][0]= ch_in;
  424.     }
  425.  
  426.     if(HAVE_YASM && HAVE_MMX)
  427.         return swri_rematrix_init_x86(s);
  428.  
  429.     return 0;
  430. }
  431.  
  432. av_cold void swri_rematrix_free(SwrContext *s){
  433.     av_freep(&s->native_matrix);
  434.     av_freep(&s->native_one);
  435.     av_freep(&s->native_simd_matrix);
  436.     av_freep(&s->native_simd_one);
  437. }
  438.  
  439. int swri_rematrix(SwrContext *s, AudioData *out, AudioData *in, int len, int mustcopy){
  440.     int out_i, in_i, i, j;
  441.     int len1 = 0;
  442.     int off = 0;
  443.  
  444.     if(s->mix_any_f) {
  445.         s->mix_any_f(out->ch, (const uint8_t **)in->ch, s->native_matrix, len);
  446.         return 0;
  447.     }
  448.  
  449.     if(s->mix_2_1_simd || s->mix_1_1_simd){
  450.         len1= len&~15;
  451.         off = len1 * out->bps;
  452.     }
  453.  
  454.     av_assert0(!s->out_ch_layout || out->ch_count == av_get_channel_layout_nb_channels(s->out_ch_layout));
  455.     av_assert0(!s-> in_ch_layout || in ->ch_count == av_get_channel_layout_nb_channels(s-> in_ch_layout));
  456.  
  457.     for(out_i=0; out_i<out->ch_count; out_i++){
  458.         switch(s->matrix_ch[out_i][0]){
  459.         case 0:
  460.             if(mustcopy)
  461.                 memset(out->ch[out_i], 0, len * av_get_bytes_per_sample(s->int_sample_fmt));
  462.             break;
  463.         case 1:
  464.             in_i= s->matrix_ch[out_i][1];
  465.             if(s->matrix[out_i][in_i]!=1.0){
  466.                 if(s->mix_1_1_simd && len1)
  467.                     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);
  468.                 if(len != len1)
  469.                     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);
  470.             }else if(mustcopy){
  471.                 memcpy(out->ch[out_i], in->ch[in_i], len*out->bps);
  472.             }else{
  473.                 out->ch[out_i]= in->ch[in_i];
  474.             }
  475.             break;
  476.         case 2: {
  477.             int in_i1 = s->matrix_ch[out_i][1];
  478.             int in_i2 = s->matrix_ch[out_i][2];
  479.             if(s->mix_2_1_simd && len1)
  480.                 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);
  481.             else
  482.                 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);
  483.             if(len != len1)
  484.                 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);
  485.             break;}
  486.         default:
  487.             if(s->int_sample_fmt == AV_SAMPLE_FMT_FLTP){
  488.                 for(i=0; i<len; i++){
  489.                     float v=0;
  490.                     for(j=0; j<s->matrix_ch[out_i][0]; j++){
  491.                         in_i= s->matrix_ch[out_i][1+j];
  492.                         v+= ((float*)in->ch[in_i])[i] * s->matrix[out_i][in_i];
  493.                     }
  494.                     ((float*)out->ch[out_i])[i]= v;
  495.                 }
  496.             }else if(s->int_sample_fmt == AV_SAMPLE_FMT_DBLP){
  497.                 for(i=0; i<len; i++){
  498.                     double v=0;
  499.                     for(j=0; j<s->matrix_ch[out_i][0]; j++){
  500.                         in_i= s->matrix_ch[out_i][1+j];
  501.                         v+= ((double*)in->ch[in_i])[i] * s->matrix[out_i][in_i];
  502.                     }
  503.                     ((double*)out->ch[out_i])[i]= v;
  504.                 }
  505.             }else{
  506.                 for(i=0; i<len; i++){
  507.                     int v=0;
  508.                     for(j=0; j<s->matrix_ch[out_i][0]; j++){
  509.                         in_i= s->matrix_ch[out_i][1+j];
  510.                         v+= ((int16_t*)in->ch[in_i])[i] * s->matrix32[out_i][in_i];
  511.                     }
  512.                     ((int16_t*)out->ch[out_i])[i]= (v + 16384)>>15;
  513.                 }
  514.             }
  515.         }
  516.     }
  517.     return 0;
  518. }
  519.