1 /*
2 * Copyright (c) 2017 The WebRTC project authors. All Rights Reserved.
3 *
4 * Use of this source code is governed by a BSD-style license
5 * that can be found in the LICENSE file in the root of the source
6 * tree. An additional intellectual property rights grant can be found
7 * in the file PATENTS. All contributing project authors may
8 * be found in the AUTHORS file in the root of the source tree.
9 */
10
11 #include <memory>
12
13 #include "api/task_queue/task_queue_base.h"
14 #include "modules/video_coding/frame_buffer2.h"
15 #include "modules/video_coding/timing/timing.h"
16 #include "test/scoped_key_value_config.h"
17 #include "test/time_controller/simulated_time_controller.h"
18
19 namespace webrtc {
20
21 namespace {
22
23 // When DataReader runs out of data provided in the constructor it will
24 // just set/return 0 instead.
25 struct DataReader {
DataReaderwebrtc::__anon4e6ccfe30111::DataReader26 DataReader(const uint8_t* data, size_t size) : data_(data), size_(size) {}
27
CopyTowebrtc::__anon4e6ccfe30111::DataReader28 void CopyTo(void* destination, size_t dest_size) {
29 memset(destination, 0, dest_size);
30
31 size_t bytes_to_copy = std::min(size_ - offset_, dest_size);
32 memcpy(destination, data_ + offset_, bytes_to_copy);
33 offset_ += bytes_to_copy;
34 }
35
36 template <typename T>
GetNumwebrtc::__anon4e6ccfe30111::DataReader37 T GetNum() {
38 T res;
39 if (offset_ + sizeof(res) < size_) {
40 memcpy(&res, data_ + offset_, sizeof(res));
41 offset_ += sizeof(res);
42 return res;
43 }
44
45 offset_ = size_;
46 return T(0);
47 }
48
MoreToReadwebrtc::__anon4e6ccfe30111::DataReader49 bool MoreToRead() { return offset_ < size_; }
50
51 const uint8_t* const data_;
52 size_t size_;
53 size_t offset_ = 0;
54 };
55
56 class FuzzyFrameObject : public EncodedFrame {
57 public:
FuzzyFrameObject()58 FuzzyFrameObject() {}
~FuzzyFrameObject()59 ~FuzzyFrameObject() {}
60
ReceivedTime() const61 int64_t ReceivedTime() const override { return 0; }
RenderTime() const62 int64_t RenderTime() const override { return _renderTimeMs; }
63 };
64 } // namespace
65
FuzzOneInput(const uint8_t * data,size_t size)66 void FuzzOneInput(const uint8_t* data, size_t size) {
67 if (size > 10000) {
68 return;
69 }
70 DataReader reader(data, size);
71 GlobalSimulatedTimeController time_controller(Timestamp::Seconds(0));
72 std::unique_ptr<TaskQueueBase, TaskQueueDeleter> task_queue =
73 time_controller.GetTaskQueueFactory()->CreateTaskQueue(
74 "time_tq", TaskQueueFactory::Priority::NORMAL);
75 test::ScopedKeyValueConfig field_trials;
76 VCMTiming timing(time_controller.GetClock(), field_trials);
77 video_coding::FrameBuffer frame_buffer(time_controller.GetClock(), &timing,
78 field_trials);
79
80 bool next_frame_task_running = false;
81
82 while (reader.MoreToRead()) {
83 if (reader.GetNum<uint8_t>() % 2) {
84 std::unique_ptr<FuzzyFrameObject> frame(new FuzzyFrameObject());
85 frame->SetId(reader.GetNum<int64_t>());
86 frame->SetSpatialIndex(reader.GetNum<uint8_t>() % 5);
87 frame->SetTimestamp(reader.GetNum<uint32_t>());
88 frame->num_references =
89 reader.GetNum<uint8_t>() % EncodedFrame::kMaxFrameReferences;
90
91 for (size_t r = 0; r < frame->num_references; ++r)
92 frame->references[r] = reader.GetNum<int64_t>();
93
94 frame_buffer.InsertFrame(std::move(frame));
95 } else {
96 if (!next_frame_task_running) {
97 next_frame_task_running = true;
98 bool keyframe_required = reader.GetNum<uint8_t>() % 2;
99 int max_wait_time_ms = reader.GetNum<uint8_t>();
100 task_queue->PostTask([&task_queue, &frame_buffer,
101 &next_frame_task_running, keyframe_required,
102 max_wait_time_ms] {
103 frame_buffer.NextFrame(
104 max_wait_time_ms, keyframe_required, task_queue.get(),
105 [&next_frame_task_running](std::unique_ptr<EncodedFrame> frame) {
106 next_frame_task_running = false;
107 });
108 });
109 }
110 }
111
112 time_controller.AdvanceTime(TimeDelta::Millis(reader.GetNum<uint8_t>()));
113 }
114 }
115
116 } // namespace webrtc
117