target_swr_fuzzer.c 5.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154
  1. /*
  2. * Copyright (c) 2024 Michael Niedermayer <michael-ffmpeg@niedermayer.cc>
  3. *
  4. * This file is part of FFmpeg.
  5. *
  6. * FFmpeg 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. * FFmpeg 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 FFmpeg; if not, write to the Free Software
  18. * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  19. */
  20. #include "config.h"
  21. #include "libavutil/avassert.h"
  22. #include "libavutil/avstring.h"
  23. #include "libavutil/cpu.h"
  24. #include "libavutil/imgutils.h"
  25. #include "libavutil/intreadwrite.h"
  26. #include "libavutil/mem.h"
  27. #include "libavutil/opt.h"
  28. #include "libavcodec/bytestream.h"
  29. #include "libswresample/swresample.h"
  30. #define SWR_CH_MAX 32
  31. int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size);
  32. static const enum AVSampleFormat formats[] = {
  33. AV_SAMPLE_FMT_U8,
  34. AV_SAMPLE_FMT_U8P,
  35. AV_SAMPLE_FMT_S16,
  36. AV_SAMPLE_FMT_S16P,
  37. AV_SAMPLE_FMT_S32,
  38. AV_SAMPLE_FMT_S32P,
  39. AV_SAMPLE_FMT_FLT,
  40. AV_SAMPLE_FMT_FLTP,
  41. AV_SAMPLE_FMT_DBL,
  42. AV_SAMPLE_FMT_DBLP,
  43. };
  44. static const AVChannelLayout layouts[]={
  45. AV_CHANNEL_LAYOUT_MONO ,
  46. AV_CHANNEL_LAYOUT_STEREO ,
  47. AV_CHANNEL_LAYOUT_2_1 ,
  48. AV_CHANNEL_LAYOUT_SURROUND ,
  49. AV_CHANNEL_LAYOUT_4POINT0 ,
  50. AV_CHANNEL_LAYOUT_2_2 ,
  51. AV_CHANNEL_LAYOUT_QUAD ,
  52. AV_CHANNEL_LAYOUT_5POINT0 ,
  53. AV_CHANNEL_LAYOUT_5POINT1 ,
  54. AV_CHANNEL_LAYOUT_5POINT0_BACK ,
  55. AV_CHANNEL_LAYOUT_5POINT1_BACK ,
  56. AV_CHANNEL_LAYOUT_7POINT0 ,
  57. AV_CHANNEL_LAYOUT_7POINT1 ,
  58. AV_CHANNEL_LAYOUT_7POINT1_WIDE ,
  59. AV_CHANNEL_LAYOUT_22POINT2 ,
  60. AV_CHANNEL_LAYOUT_5POINT1POINT2_BACK ,
  61. };
  62. int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) {
  63. struct SwrContext * swr= NULL;
  64. AVChannelLayout in_ch_layout = AV_CHANNEL_LAYOUT_MONO, out_ch_layout = AV_CHANNEL_LAYOUT_MONO;
  65. enum AVSampleFormat in_sample_fmt = AV_SAMPLE_FMT_S16P;
  66. enum AVSampleFormat out_sample_fmt = AV_SAMPLE_FMT_S16P;
  67. int in_sample_rate = 44100;
  68. int out_sample_rate = 44100;
  69. int in_ch_count, out_ch_count;
  70. char in_layout_string[256];
  71. char out_layout_string[256];
  72. uint8_t * ain[SWR_CH_MAX];
  73. uint8_t *aout[SWR_CH_MAX];
  74. uint8_t *out_data;
  75. int in_sample_nb;
  76. int out_sample_nb = size;
  77. int count;
  78. int ret;
  79. if (size > 128) {
  80. GetByteContext gbc;
  81. int64_t flags64;
  82. size -= 128;
  83. bytestream2_init(&gbc, data + size, 128);
  84. in_sample_rate = bytestream2_get_le16(&gbc) + 1;
  85. out_sample_rate = bytestream2_get_le16(&gbc) + 1;
  86. in_sample_fmt = formats[bytestream2_get_byte(&gbc) % FF_ARRAY_ELEMS(formats)];
  87. out_sample_fmt = formats[bytestream2_get_byte(&gbc) % FF_ARRAY_ELEMS(formats)];
  88. av_channel_layout_copy(& in_ch_layout, &layouts[bytestream2_get_byte(&gbc) % FF_ARRAY_ELEMS(layouts)]);
  89. av_channel_layout_copy(&out_ch_layout, &layouts[bytestream2_get_byte(&gbc) % FF_ARRAY_ELEMS(layouts)]);
  90. out_sample_nb = bytestream2_get_le32(&gbc);
  91. flags64 = bytestream2_get_le64(&gbc);
  92. if (flags64 & 0x10)
  93. av_force_cpu_flags(0);
  94. }
  95. in_ch_count= in_ch_layout.nb_channels;
  96. out_ch_count= out_ch_layout.nb_channels;
  97. av_channel_layout_describe(& in_ch_layout, in_layout_string, sizeof( in_layout_string));
  98. av_channel_layout_describe(&out_ch_layout, out_layout_string, sizeof(out_layout_string));
  99. fprintf(stderr, "%s %d %s -> %s %d %s\n",
  100. av_get_sample_fmt_name( in_sample_fmt), in_sample_rate, in_layout_string,
  101. av_get_sample_fmt_name(out_sample_fmt), out_sample_rate, out_layout_string);
  102. if (swr_alloc_set_opts2(&swr, &out_ch_layout, out_sample_fmt, out_sample_rate,
  103. &in_ch_layout, in_sample_fmt, in_sample_rate,
  104. 0, 0) < 0) {
  105. fprintf(stderr, "Failed swr_alloc_set_opts2()\n");
  106. goto end;
  107. }
  108. if (swr_init(swr) < 0) {
  109. fprintf(stderr, "Failed swr_init()\n");
  110. goto end;
  111. }
  112. in_sample_nb = size / (in_ch_count * av_get_bytes_per_sample(in_sample_fmt));
  113. out_sample_nb = out_sample_nb % (av_rescale(in_sample_nb, 2*out_sample_rate, in_sample_rate) + 1);
  114. if (in_sample_nb > 1000*1000 || out_sample_nb > 1000*1000)
  115. goto end;
  116. out_data = av_malloc(out_sample_nb * out_ch_count * av_get_bytes_per_sample(out_sample_fmt));
  117. if (!out_data)
  118. goto end;
  119. ret = av_samples_fill_arrays(ain , NULL, data, in_ch_count, in_sample_nb, in_sample_fmt, 1);
  120. if (ret < 0)
  121. goto end;
  122. ret = av_samples_fill_arrays(aout, NULL, out_data, out_ch_count, out_sample_nb, out_sample_fmt, 1);
  123. if (ret < 0)
  124. goto end;
  125. count = swr_convert(swr, aout, out_sample_nb, (const uint8_t **)ain, in_sample_nb);
  126. av_freep(&out_data);
  127. end:
  128. swr_free(&swr);
  129. return 0;
  130. }