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 "modules/video_coding/frame_buffer2.h"
12 #include "modules/video_coding/timing.h"
13 #include "test/time_controller/simulated_time_controller.h"
14
15 namespace webrtc {
16
17 namespace {
18
19 // When DataReader runs out of data provided in the constructor it will
20 // just set/return 0 instead.
21 struct DataReader {
DataReaderwebrtc::__anonbd579c9a0111::DataReader22 DataReader(const uint8_t* data, size_t size) : data_(data), size_(size) {}
23
CopyTowebrtc::__anonbd579c9a0111::DataReader24 void CopyTo(void* destination, size_t dest_size) {
25 memset(destination, 0, dest_size);
26
27 size_t bytes_to_copy = std::min(size_ - offset_, dest_size);
28 memcpy(destination, data_ + offset_, bytes_to_copy);
29 offset_ += bytes_to_copy;
30 }
31
32 template <typename T>
GetNumwebrtc::__anonbd579c9a0111::DataReader33 T GetNum() {
34 T res;
35 if (offset_ + sizeof(res) < size_) {
36 memcpy(&res, data_ + offset_, sizeof(res));
37 offset_ += sizeof(res);
38 return res;
39 }
40
41 offset_ = size_;
42 return T(0);
43 }
44
MoreToReadwebrtc::__anonbd579c9a0111::DataReader45 bool MoreToRead() { return offset_ < size_; }
46
47 const uint8_t* const data_;
48 size_t size_;
49 size_t offset_ = 0;
50 };
51
52 class FuzzyFrameObject : public video_coding::EncodedFrame {
53 public:
FuzzyFrameObject()54 FuzzyFrameObject() {}
~FuzzyFrameObject()55 ~FuzzyFrameObject() {}
56
ReceivedTime() const57 int64_t ReceivedTime() const override { return 0; }
RenderTime() const58 int64_t RenderTime() const override { return _renderTimeMs; }
59 };
60 } // namespace
61
FuzzOneInput(const uint8_t * data,size_t size)62 void FuzzOneInput(const uint8_t* data, size_t size) {
63 if (size > 10000) {
64 return;
65 }
66 DataReader reader(data, size);
67 GlobalSimulatedTimeController time_controller(Timestamp::Seconds(0));
68 rtc::TaskQueue task_queue(
69 time_controller.GetTaskQueueFactory()->CreateTaskQueue(
70 "time_tq", TaskQueueFactory::Priority::NORMAL));
71 VCMTiming timing(time_controller.GetClock());
72 video_coding::FrameBuffer frame_buffer(time_controller.GetClock(), &timing,
73 nullptr);
74
75 bool next_frame_task_running = false;
76
77 while (reader.MoreToRead()) {
78 if (reader.GetNum<uint8_t>() % 2) {
79 std::unique_ptr<FuzzyFrameObject> frame(new FuzzyFrameObject());
80 frame->id.picture_id = reader.GetNum<int64_t>();
81 frame->id.spatial_layer = reader.GetNum<uint8_t>() % 5;
82 frame->SetTimestamp(reader.GetNum<uint32_t>());
83 frame->num_references = reader.GetNum<uint8_t>() %
84 video_coding::EncodedFrame::kMaxFrameReferences;
85
86 for (size_t r = 0; r < frame->num_references; ++r)
87 frame->references[r] = reader.GetNum<int64_t>();
88
89 frame_buffer.InsertFrame(std::move(frame));
90 } else {
91 if (!next_frame_task_running) {
92 next_frame_task_running = true;
93 bool keyframe_required = reader.GetNum<uint8_t>() % 2;
94 int max_wait_time_ms = reader.GetNum<uint8_t>();
95 task_queue.PostTask([&task_queue, &frame_buffer,
96 &next_frame_task_running, keyframe_required,
97 max_wait_time_ms] {
98 frame_buffer.NextFrame(
99 max_wait_time_ms, keyframe_required, &task_queue,
100 [&next_frame_task_running](
101 std::unique_ptr<video_coding::EncodedFrame> frame,
102 video_coding::FrameBuffer::ReturnReason res) {
103 next_frame_task_running = false;
104 });
105 });
106 }
107 }
108
109 time_controller.AdvanceTime(TimeDelta::Millis(reader.GetNum<uint8_t>()));
110 }
111 }
112
113 } // namespace webrtc
114