Calling a function via a different function pointer type is undefined behavior (C11, 6.3.2.3 8); two pointer parameters of different type are not equivalent in this regard, although it happens to work in practice; the current code relies on this. This patch brings the code in line with the spec. This fixes the following FATE-tests when run with Clang-UBSan: ac3-fixed-encode-2 audiomatch-afconvert-{16000,44100}-mono-he-{adts,m4a} audiomatch-dolby-44100-mono-he-mp4 filter-metadata-avf-aphase-meter-mono filter-pan-{downmix1,downmix2,mono2,stereo2,stereo3,stereo4,upmix1,upmix2} lavf-dv_{pal,ntsc} matroska-encoding-delay The error was something like src/libswresample/rematrix.c:621:17: runtime error: call to function sum2_float through pointer to incorrect function type 'void (*)(void *, const void *, const void *, void *, int, int, int)
Unified · Split
| @@ -494,13 +494,13 @@ av_cold int swri_rematrix_init(SwrContext *s){ · 493 unmodified lines | |||
| 494 | } | 494 | } |
| 495 | *((int*)s->native_one) = 32768; | 495 | *((int*)s->native_one) = 32768; |
| 496 | if (maxsum <= 32768) { | 496 | if (maxsum <= 32768) { |
| 497 | s->mix_1_1_f = (mix_1_1_func_type*)copy_s16; | 497 | s->mix_1_1_f = copy_s16; |
| 498 | s->mix_2_1_f = (mix_2_1_func_type*)sum2_s16; | 498 | s->mix_2_1_f = sum2_s16; |
| 499 | s->mix_any_f = (mix_any_func_type*)get_mix_any_func_s16(s); | 499 | s->mix_any_f = get_mix_any_func_s16(s); |
| 500 | } else { | 500 | } else { |
| 501 | s->mix_1_1_f = (mix_1_1_func_type*)copy_clip_s16; | 501 | s->mix_1_1_f = copy_clip_s16; |
| 502 | s->mix_2_1_f = (mix_2_1_func_type*)sum2_clip_s16; | 502 | s->mix_2_1_f = sum2_clip_s16; |
| 503 | s->mix_any_f = (mix_any_func_type*)get_mix_any_func_clip_s16(s); | 503 | s->mix_any_f = get_mix_any_func_clip_s16(s); |
| 504 | } | 504 | } |
| 505 | }else if(s->midbuf.fmt == AV_SAMPLE_FMT_FLTP){ | 505 | }else if(s->midbuf.fmt == AV_SAMPLE_FMT_FLTP){ |
| 506 | s->native_matrix = av_calloc(nb_in * nb_out, sizeof(float)); | 506 | s->native_matrix = av_calloc(nb_in * nb_out, sizeof(float)); |
| @@ -511,9 +511,9 @@ av_cold int swri_rematrix_init(SwrContext *s){ · 4 unmodified lines | |||
| 511 | for (j = 0; j < nb_in; j++) | 511 | for (j = 0; j < nb_in; j++) |
| 512 | ((float*)s->native_matrix)[i * nb_in + j] = s->matrix[i][j]; | 512 | ((float*)s->native_matrix)[i * nb_in + j] = s->matrix[i][j]; |
| 513 | *((float*)s->native_one) = 1.0; | 513 | *((float*)s->native_one) = 1.0; |
| 514 | s->mix_1_1_f = (mix_1_1_func_type*)copy_float; | 514 | s->mix_1_1_f = copy_float; |
| 515 | s->mix_2_1_f = (mix_2_1_func_type*)sum2_float; | 515 | s->mix_2_1_f = sum2_float; |
| 516 | s->mix_any_f = (mix_any_func_type*)get_mix_any_func_float(s); | 516 | s->mix_any_f = get_mix_any_func_float(s); |
| 517 | }else if(s->midbuf.fmt == AV_SAMPLE_FMT_DBLP){ | 517 | }else if(s->midbuf.fmt == AV_SAMPLE_FMT_DBLP){ |
| 518 | s->native_matrix = av_calloc(nb_in * nb_out, sizeof(double)); | 518 | s->native_matrix = av_calloc(nb_in * nb_out, sizeof(double)); |
| 519 | s->native_one = av_mallocz(sizeof(double)); | 519 | s->native_one = av_mallocz(sizeof(double)); |
| @@ -523,9 +523,9 @@ av_cold int swri_rematrix_init(SwrContext *s){ · 3 unmodified lines | |||
| 523 | for (j = 0; j < nb_in; j++) | 523 | for (j = 0; j < nb_in; j++) |
| 524 | ((double*)s->native_matrix)[i * nb_in + j] = s->matrix[i][j]; | 524 | ((double*)s->native_matrix)[i * nb_in + j] = s->matrix[i][j]; |
| 525 | *((double*)s->native_one) = 1.0; | 525 | *((double*)s->native_one) = 1.0; |
| 526 | s->mix_1_1_f = (mix_1_1_func_type*)copy_double; | 526 | s->mix_1_1_f = copy_double; |
| 527 | s->mix_2_1_f = (mix_2_1_func_type*)sum2_double; | 527 | s->mix_2_1_f = sum2_double; |
| 528 | s->mix_any_f = (mix_any_func_type*)get_mix_any_func_double(s); | 528 | s->mix_any_f = get_mix_any_func_double(s); |
| 529 | }else if(s->midbuf.fmt == AV_SAMPLE_FMT_S32P){ | 529 | }else if(s->midbuf.fmt == AV_SAMPLE_FMT_S32P){ |
| 530 | s->native_one = av_mallocz(sizeof(int)); | 530 | s->native_one = av_mallocz(sizeof(int)); |
| 531 | if (!s->native_one) | 531 | if (!s->native_one) |
| @@ -545,9 +545,9 @@ av_cold int swri_rematrix_init(SwrContext *s){ · 13 unmodified lines | |||
| 545 | } | 545 | } |
| 546 | } | 546 | } |
| 547 | *((int*)s->native_one) = 32768; | 547 | *((int*)s->native_one) = 32768; |
| 548 | s->mix_1_1_f = (mix_1_1_func_type*)copy_s32; | 548 | s->mix_1_1_f = copy_s32; |
| 549 | s->mix_2_1_f = (mix_2_1_func_type*)sum2_s32; | 549 | s->mix_2_1_f = sum2_s32; |
| 550 | s->mix_any_f = (mix_any_func_type*)get_mix_any_func_s32(s); | 550 | s->mix_any_f = get_mix_any_func_s32(s); |
| 551 | }else | 551 | }else |
| 552 | av_assert0(0); | 552 | av_assert0(0); |
| 553 | //FIXME quantize for integeres | 553 | //FIXME quantize for integeres |
| @@ -49,9 +49,12 @@ · 48 unmodified lines | |||
| 49 | # define RENAME(x) x ## _s32 | 49 | # define RENAME(x) x ## _s32 |
| 50 | #endif | 50 | #endif |
| 51 | 51 | ||
| 52 | typedef void (RENAME(mix_any_func_type))(SAMPLE **out, const SAMPLE **in1, COEFF *coeffp, integer len); | 52 | static void RENAME(sum2)(void *out_, const void *in1_, const void *in2_, |
| 53 | 53 | void *coeffp_, integer index1, integer index2, integer len) | |
| 54 | static void RENAME(sum2)(SAMPLE *out, const SAMPLE *in1, const SAMPLE *in2, COEFF *coeffp, integer index1, integer index2, integer len){ | 54 | { |
| 55 | const SAMPLE *in1 = in1_, *in2 = in2_; | ||
| 56 | const COEFF *coeffp = coeffp_; | ||
| 57 | SAMPLE *out = out_; | ||
| 55 | int i; | 58 | int i; |
| 56 | INTER coeff1 = coeffp[index1]; | 59 | INTER coeff1 = coeffp[index1]; |
| 57 | INTER coeff2 = coeffp[index2]; | 60 | INTER coeff2 = coeffp[index2]; |
| @@ -60,14 +63,22 @@ static void RENAME(sum2)(SAMPLE *out, const SAMPLE *in1, const SAMPLE *in2, COEF · 2 unmodified lines | |||
| 60 | out[i] = R(coeff1*in1[i] + coeff2*in2[i]); | 63 | out[i] = R(coeff1*in1[i] + coeff2*in2[i]); |
| 61 | } | 64 | } |
| 62 | 65 | ||
| 63 | static void RENAME(copy)(SAMPLE *out, const SAMPLE *in, COEFF *coeffp, integer index, integer len){ | 66 | static void RENAME(copy)(void *out_, const void *in_, void *coeffp_, integer index, integer len) |
| 67 | { | ||
| 68 | const COEFF *coeffp = coeffp_; | ||
| 69 | const SAMPLE *in = in_; | ||
| 70 | SAMPLE *out = out_; | ||
| 64 | int i; | 71 | int i; |
| 65 | INTER coeff = coeffp[index]; | 72 | INTER coeff = coeffp[index]; |
| 66 | for(i=0; i<len; i++) | 73 | for(i=0; i<len; i++) |
| 67 | out[i] = R(coeff*in[i]); | 74 | out[i] = R(coeff*in[i]); |
| 68 | } | 75 | } |
| 69 | 76 | ||
| 70 | static void RENAME(mix6to2)(SAMPLE **out, const SAMPLE **in, COEFF *coeffp, integer len){ | 77 | static void RENAME(mix6to2)(uint8_t **out_, const uint8_t **in_, void *coeffp_, integer len) |
| 78 | { | ||
| 79 | const SAMPLE *const *const in = (const SAMPLE *const *)in_; | ||
| 80 | SAMPLE *const *const out = (SAMPLE *const*)out_; | ||
| 81 | const COEFF *coeffp = coeffp_; | ||
| 71 | int i; | 82 | int i; |
| 72 | 83 | ||
| 73 | for(i=0; i<len; i++) { | 84 | for(i=0; i<len; i++) { |
| @@ -77,7 +88,11 @@ static void RENAME(mix6to2)(SAMPLE **out, const SAMPLE **in, COEFF *coeffp, inte · 3 unmodified lines | |||
| 77 | } | 88 | } |
| 78 | } | 89 | } |
| 79 | 90 | ||
| 80 | static void RENAME(mix8to2)(SAMPLE **out, const SAMPLE **in, COEFF *coeffp, integer len){ | 91 | static void RENAME(mix8to2)(uint8_t **out_, const uint8_t **in_, void *coeffp_, integer len) |
| 92 | { | ||
| 93 | const SAMPLE *const *const in = (const SAMPLE *const *)in_; | ||
| 94 | SAMPLE *const *const out = (SAMPLE *const*)out_; | ||
| 95 | const COEFF *coeffp = coeffp_; | ||
| 81 | int i; | 96 | int i; |
| 82 | 97 | ||
| 83 | for(i=0; i<len; i++) { | 98 | for(i=0; i<len; i++) { |
| @@ -87,7 +102,8 @@ static void RENAME(mix8to2)(SAMPLE **out, const SAMPLE **in, COEFF *coeffp, inte · 3 unmodified lines | |||
| 87 | } | 102 | } |
| 88 | } | 103 | } |
| 89 | 104 | ||
| 90 | static RENAME(mix_any_func_type) *RENAME(get_mix_any_func)(SwrContext *s){ | 105 | static mix_any_func_type *RENAME(get_mix_any_func)(SwrContext *s) |
| 106 | { | ||
| 91 | if ( !av_channel_layout_compare(&s->out_ch_layout, &(AVChannelLayout)AV_CHANNEL_LAYOUT_STEREO) | 107 | if ( !av_channel_layout_compare(&s->out_ch_layout, &(AVChannelLayout)AV_CHANNEL_LAYOUT_STEREO) |
| 92 | && ( !av_channel_layout_compare(&s->in_ch_layout, &(AVChannelLayout)AV_CHANNEL_LAYOUT_5POINT1) | 108 | && ( !av_channel_layout_compare(&s->in_ch_layout, &(AVChannelLayout)AV_CHANNEL_LAYOUT_5POINT1) |
| 93 | || !av_channel_layout_compare(&s->in_ch_layout, &(AVChannelLayout)AV_CHANNEL_LAYOUT_5POINT1_BACK)) | 109 | || !av_channel_layout_compare(&s->in_ch_layout, &(AVChannelLayout)AV_CHANNEL_LAYOUT_5POINT1_BACK)) |