File: av1_decoder_fuzzertest.cc

package info (click to toggle)
chromium 145.0.7632.159-1
  • links: PTS, VCS
  • area: main
  • in suites: sid
  • size: 5,976,224 kB
  • sloc: cpp: 36,198,469; ansic: 7,634,080; javascript: 3,564,060; python: 1,649,622; xml: 838,470; asm: 717,087; pascal: 185,708; sh: 88,786; perl: 88,718; objc: 79,984; sql: 59,811; cs: 42,452; fortran: 24,101; makefile: 21,144; tcl: 15,277; php: 14,022; yacc: 9,066; ruby: 7,553; awk: 3,720; lisp: 3,233; lex: 1,328; ada: 727; jsp: 228; sed: 36
file content (74 lines) | stat: -rw-r--r-- 2,733 bytes parent folder | download | duplicates (6)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
// Copyright 2021 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include <stddef.h>

#include <fuzzer/FuzzedDataProvider.h>

#include <tuple>

#include "base/logging.h"
#include "media/base/decoder_buffer.h"
#include "media/base/video_codecs.h"
#include "media/gpu/av1_decoder.h"
#include "media/gpu/av1_picture.h"

namespace {

class FakeAV1Accelerator : public media::AV1Decoder::AV1Accelerator {
 public:
  FakeAV1Accelerator() = default;
  ~FakeAV1Accelerator() override = default;
  FakeAV1Accelerator(const FakeAV1Accelerator&) = delete;
  FakeAV1Accelerator& operator=(const FakeAV1Accelerator&) = delete;

  // media::AV1Decoder::AV1Accelerator implementation.
  scoped_refptr<media::AV1Picture> CreateAV1Picture(bool apply_grain) override {
    return base::MakeRefCounted<media::AV1Picture>();
  }
  Status SubmitDecode(const media::AV1Picture& pic,
                      const libgav1::ObuSequenceHeader& sequence_header,
                      const media::AV1ReferenceFrameVector& ref_frames,
                      const libgav1::Vector<libgav1::TileBuffer>& tile_buffers,
                      base::span<const uint8_t> data) override {
    return Status::kOk;
  }
  bool OutputPicture(const media::AV1Picture& pic) override { return true; }
};

}  // namespace

// Entry point for LibFuzzer.
extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
  FuzzedDataProvider fuzzed_data_provider(data, size);
  media::AV1Decoder decoder(std::make_unique<FakeAV1Accelerator>(),
                            media::AV1PROFILE_PROFILE_MAIN);

  // Split the input in two: we'll create a DecoderBuffer from each half. This
  // allows us to Decode(), Reset(), and Decode() again for more coverage.
  for (int i = 0; i < 2; ++i) {
    size_t size_to_consume = i == 0 ? size / 2 : (size - size / 2);
    std::vector<uint8_t> decoder_buffer_data =
        fuzzed_data_provider.ConsumeBytes<uint8_t>(size_to_consume);
    if (decoder_buffer_data.empty())
      continue;
    // The *|decoder_buffer| can be destroyed at the end of each iteration
    // because Reset() is expected to ensure that the current DecoderBuffer
    // won't be needed after that.
    scoped_refptr<media::DecoderBuffer> decoder_buffer =
        media::DecoderBuffer::CopyFrom(decoder_buffer_data);
    decoder.SetStream(i, decoder_buffer);

    // Decode should consume all the data unless it returns kConfigChange, and
    // in that case it needs to be called again.
    while (true) {
      if (decoder.Decode() != media::AcceleratedVideoDecoder::kConfigChange)
        break;
    }
    decoder.Reset();
  }
  std::ignore = decoder.Flush();

  return 0;
}