Upload upstream chromium 108.0.5359.1
[platform/framework/web/chromium-efl.git] / media / filters / vpx_video_decoder_fuzzertest.cc
1 // Copyright 2016 The Chromium Authors
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #include <stddef.h>
6 #include <stdint.h>
7
8 #include <random>
9
10 #include "base/at_exit.h"
11 #include "base/bind.h"
12 #include "base/callback_helpers.h"
13 #include "base/command_line.h"
14 #include "base/logging.h"
15 #include "base/run_loop.h"
16 #include "base/test/task_environment.h"
17 #include "media/base/decoder_buffer.h"
18 #include "media/base/media.h"
19 #include "media/base/media_util.h"
20 #include "media/filters/vpx_video_decoder.h"
21
22 struct Env {
23   Env() {
24     media::InitializeMediaLibrary();
25     base::CommandLine::Init(0, nullptr);
26     logging::SetMinLogLevel(logging::LOG_FATAL);
27   }
28
29   base::AtExitManager at_exit_manager;
30   base::test::SingleThreadTaskEnvironment task_environment;
31 };
32
33 void OnDecodeComplete(base::OnceClosure quit_closure,
34                       media::DecoderStatus status) {
35   std::move(quit_closure).Run();
36 }
37
38 void OnInitDone(base::OnceClosure quit_closure,
39                 bool* success_dest,
40                 media::DecoderStatus status) {
41   *success_dest = status.is_ok();
42   std::move(quit_closure).Run();
43 }
44
45 void OnOutputComplete(scoped_refptr<media::VideoFrame> frame) {}
46
47 // Entry point for LibFuzzer.
48 extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
49   // Create Env on the first run of LLVMFuzzerTestOneInput otherwise
50   // message_loop will be created before this process forks when used with AFL,
51   // causing hangs.
52   [[maybe_unused]] static Env* env = new Env();
53   std::mt19937_64 rng;
54
55   {  // Seed rng from data.
56     std::string str = std::string(reinterpret_cast<const char*>(data), size);
57     std::size_t data_hash = std::hash<std::string>()(str);
58     rng.seed(data_hash);
59   }
60
61   // Compute randomized constants. Put all rng() usages here.
62   // Use only values that pass DCHECK in VpxVideoDecoder::ConfigureDecoder().
63   media::VideoCodec codec;
64
65   bool has_alpha = false;
66   if (rng() & 1) {
67     codec = media::VideoCodec::kVP8;
68     // non-Alpha VP8 decoding isn't supported by VpxVideoDecoder on Linux.
69     has_alpha = true;
70   } else {
71     codec = media::VideoCodec::kVP9;
72     has_alpha = rng() & 1;
73   }
74
75   auto profile = static_cast<media::VideoCodecProfile>(
76       rng() % media::VIDEO_CODEC_PROFILE_MAX);
77   auto color_space =
78       media::VideoColorSpace(rng() % 256, rng() % 256, rng() % 256,
79                              (rng() & 1) ? gfx::ColorSpace::RangeID::LIMITED
80                                          : gfx::ColorSpace::RangeID::FULL);
81   auto rotation =
82       static_cast<media::VideoRotation>(rng() % media::VIDEO_ROTATION_MAX);
83   auto coded_size = gfx::Size(1 + (rng() % 127), 1 + (rng() % 127));
84   auto visible_rect = gfx::Rect(coded_size);
85   auto natural_size = gfx::Size(1 + (rng() % 127), 1 + (rng() % 127));
86   uint8_t reflection = rng() % 4;
87
88   media::VideoDecoderConfig config(
89       codec, profile,
90       has_alpha ? media::VideoDecoderConfig::AlphaMode::kHasAlpha
91                 : media::VideoDecoderConfig::AlphaMode::kIsOpaque,
92       color_space, media::VideoTransformation(rotation, reflection), coded_size,
93       visible_rect, natural_size, media::EmptyExtraData(),
94       media::EncryptionScheme::kUnencrypted);
95
96   if (!config.IsValidConfig())
97     return 0;
98
99   media::VpxVideoDecoder decoder;
100
101   {
102     base::RunLoop run_loop;
103     bool success = false;
104     decoder.Initialize(
105         config, true /* low_delay */, nullptr /* cdm_context */,
106         base::BindOnce(&OnInitDone, run_loop.QuitClosure(), &success),
107         base::BindRepeating(&OnOutputComplete), base::NullCallback());
108     run_loop.Run();
109     if (!success)
110       return 0;
111   }
112
113   {
114     base::RunLoop run_loop;
115     auto buffer = media::DecoderBuffer::CopyFrom(data, size);
116     decoder.Decode(buffer,
117                    base::BindOnce(&OnDecodeComplete, run_loop.QuitClosure()));
118     run_loop.Run();
119   }
120
121   return 0;
122 }