webm_muxer_fuzzertest.cc 3.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101
  1. // Copyright 2016 The Chromium Authors. All rights reserved.
  2. // Use of this source code is governed by a BSD-style license that can be
  3. // found in the LICENSE file.
  4. #include <stddef.h>
  5. #include <stdint.h>
  6. #include <memory>
  7. #include <random>
  8. #include "base/bind.h"
  9. #include "base/logging.h"
  10. #include "base/run_loop.h"
  11. #include "base/strings/string_piece.h"
  12. #include "base/task/single_thread_task_executor.h"
  13. #include "media/base/audio_parameters.h"
  14. #include "media/base/video_frame.h"
  15. #include "media/muxers/live_webm_muxer_delegate.h"
  16. #include "media/muxers/webm_muxer.h"
  17. // Min and max number of encodec video/audio packets to send in the WebmMuxer.
  18. const int kMinNumIterations = 1;
  19. const int kMaxNumIterations = 10;
  20. static const media::VideoCodec kSupportedVideoCodecs[] = {
  21. media::VideoCodec::kVP8, media::VideoCodec::kVP9, media::VideoCodec::kH264};
  22. static const media::AudioCodec kSupportedAudioCodecs[] = {
  23. media::AudioCodec::kOpus, media::AudioCodec::kPCM};
  24. static const int kSampleRatesInKHz[] = {48, 24, 16, 12, 8};
  25. static struct {
  26. bool has_video;
  27. bool has_audio;
  28. } kVideoAudioInputTypes[] = {{true, false}, {false, true}, {true, true}};
  29. struct Env {
  30. Env() { logging::SetMinLogLevel(logging::LOG_FATAL); }
  31. base::SingleThreadTaskExecutor task_executor;
  32. };
  33. Env* env = new Env();
  34. void OnWriteCallback(base::StringPiece data) {}
  35. // Entry point for LibFuzzer.
  36. extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
  37. std::mt19937_64 rng;
  38. std::string str = std::string(reinterpret_cast<const char*>(data), size);
  39. { // Seed rng from data.
  40. std::size_t data_hash = std::hash<std::string>()(str);
  41. rng.seed(data_hash);
  42. }
  43. for (const auto& input_type : kVideoAudioInputTypes) {
  44. const auto video_codec =
  45. kSupportedVideoCodecs[rng() % std::size(kSupportedVideoCodecs)];
  46. const auto audio_codec =
  47. kSupportedAudioCodecs[rng() % std::size(kSupportedAudioCodecs)];
  48. media::WebmMuxer muxer(audio_codec, input_type.has_video,
  49. input_type.has_audio,
  50. std::make_unique<media::LiveWebmMuxerDelegate>(
  51. base::BindRepeating(&OnWriteCallback)));
  52. base::RunLoop().RunUntilIdle();
  53. int num_iterations = kMinNumIterations + rng() % kMaxNumIterations;
  54. do {
  55. if (input_type.has_video) {
  56. // VideoFrames cannot be arbitrarily small.
  57. const auto visible_rect = gfx::Size(16 + rng() % 128, 16 + rng() % 128);
  58. const auto video_frame =
  59. media::VideoFrame::CreateBlackFrame(visible_rect);
  60. const auto is_key_frame = rng() % 2;
  61. const auto has_alpha_frame = rng() % 4;
  62. auto parameters = media::WebmMuxer::VideoParameters(video_frame);
  63. parameters.codec = video_codec;
  64. muxer.OnEncodedVideo(parameters, str,
  65. has_alpha_frame ? str : std::string(),
  66. base::TimeTicks(), is_key_frame);
  67. base::RunLoop().RunUntilIdle();
  68. }
  69. if (input_type.has_audio) {
  70. const media::ChannelLayout layout = rng() % 2
  71. ? media::CHANNEL_LAYOUT_STEREO
  72. : media::CHANNEL_LAYOUT_MONO;
  73. const int sample_rate =
  74. kSampleRatesInKHz[rng() % std::size(kSampleRatesInKHz)];
  75. const media::AudioParameters params(
  76. media::AudioParameters::AUDIO_PCM_LOW_LATENCY, layout, sample_rate,
  77. 60 * sample_rate);
  78. muxer.OnEncodedAudio(params, str, base::TimeTicks());
  79. base::RunLoop().RunUntilIdle();
  80. }
  81. } while (num_iterations--);
  82. }
  83. return 0;
  84. }