blob: 0aa8e75a16ba5e008b9343856a735ab2027a9e7a [file] [log] [blame]
philipelc1ee9d52018-05-16 12:06:131/*
2 * Copyright (c) 2018 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
Mirko Bonadei317a1f02019-09-17 15:06:1811#include <memory>
12
Chen Xingf00bf422019-06-20 08:05:5513#include "api/rtp_packet_infos.h"
philipelc1ee9d52018-05-16 12:06:1314#include "modules/video_coding/frame_object.h"
15#include "modules/video_coding/packet_buffer.h"
Jonas Olssona4d87372019-07-05 17:08:3316#include "modules/video_coding/rtp_frame_reference_finder.h"
philipelc1ee9d52018-05-16 12:06:1317#include "system_wrappers/include/clock.h"
18
19namespace webrtc {
20
21namespace {
philipel2f7d7792019-09-30 14:16:3222class DataReader {
23 public:
philipelc1ee9d52018-05-16 12:06:1324 DataReader(const uint8_t* data, size_t size) : data_(data), size_(size) {}
25
philipel2f7d7792019-09-30 14:16:3226 template <typename T>
27 void CopyTo(T* object) {
28 static_assert(std::is_pod<T>(), "");
29 uint8_t* destination = reinterpret_cast<uint8_t*>(object);
30 size_t object_size = sizeof(T);
31 size_t num_bytes = std::min(size_ - offset_, object_size);
32 memcpy(destination, data_ + offset_, num_bytes);
philipelc1ee9d52018-05-16 12:06:1333 offset_ += num_bytes;
34
philipel2f7d7792019-09-30 14:16:3235 // If we did not have enough data, fill the rest with 0.
36 object_size -= num_bytes;
37 memset(destination + num_bytes, 0, object_size);
philipelc1ee9d52018-05-16 12:06:1338 }
39
40 template <typename T>
41 T GetNum() {
42 T res;
43 if (offset_ + sizeof(res) < size_) {
44 memcpy(&res, data_ + offset_, sizeof(res));
45 offset_ += sizeof(res);
46 return res;
47 }
48
49 offset_ = size_;
50 return T(0);
51 }
52
53 bool MoreToRead() { return offset_ < size_; }
54
philipel2f7d7792019-09-30 14:16:3255 private:
philipelc1ee9d52018-05-16 12:06:1356 const uint8_t* data_;
57 size_t size_;
58 size_t offset_ = 0;
59};
60
61class NullCallback : public video_coding::OnCompleteFrameCallback {
62 void OnCompleteFrame(
63 std::unique_ptr<video_coding::EncodedFrame> frame) override {}
64};
65
philipel2f7d7792019-09-30 14:16:3266RtpGenericFrameDescriptor GenerateRtpGenericFrameDescriptor(
67 DataReader* reader) {
68 RtpGenericFrameDescriptor res;
69 res.SetFirstPacketInSubFrame(true);
70 res.SetFrameId(reader->GetNum<uint16_t>());
71
72 int spatial_layer =
73 reader->GetNum<uint8_t>() % RtpGenericFrameDescriptor::kMaxSpatialLayers;
74 res.SetSpatialLayersBitmask(1 << spatial_layer);
75 res.SetTemporalLayer(reader->GetNum<uint8_t>() %
76 RtpGenericFrameDescriptor::kMaxTemporalLayers);
77
78 int num_diffs = (reader->GetNum<uint8_t>() %
79 RtpGenericFrameDescriptor::kMaxNumFrameDependencies);
80 for (int i = 0; i < num_diffs; ++i) {
81 res.AddFrameDependencyDiff(reader->GetNum<uint16_t>() % (1 << 14));
philipelc1ee9d52018-05-16 12:06:1382 }
83
philipel2f7d7792019-09-30 14:16:3284 return res;
85}
philipelc1ee9d52018-05-16 12:06:1386} // namespace
87
88void FuzzOneInput(const uint8_t* data, size_t size) {
89 DataReader reader(data, size);
philipelc1ee9d52018-05-16 12:06:1390 NullCallback cb;
91 video_coding::RtpFrameReferenceFinder reference_finder(&cb);
92
philipel2f7d7792019-09-30 14:16:3293 auto codec = static_cast<VideoCodecType>(reader.GetNum<uint8_t>() % 4);
94
philipelc1ee9d52018-05-16 12:06:1395 while (reader.MoreToRead()) {
Johannes Kron10da4a02019-08-05 10:31:3896 uint16_t first_seq_num = reader.GetNum<uint16_t>();
97 uint16_t last_seq_num = reader.GetNum<uint16_t>();
philipel2f7d7792019-09-30 14:16:3298 bool marker_bit = reader.GetNum<uint8_t>();
Johannes Kron10da4a02019-08-05 10:31:3899
philipel2f7d7792019-09-30 14:16:32100 RTPVideoHeader video_header;
101 switch (reader.GetNum<uint8_t>() % 3) {
102 case 0:
103 video_header.frame_type = VideoFrameType::kEmptyFrame;
104 break;
105 case 1:
106 video_header.frame_type = VideoFrameType::kVideoFrameKey;
107 break;
108 case 2:
109 video_header.frame_type = VideoFrameType::kVideoFrameDelta;
110 break;
111 }
112
113 switch (codec) {
114 case kVideoCodecVP8:
115 reader.CopyTo(
116 &video_header.video_type_header.emplace<RTPVideoHeaderVP8>());
117 break;
118 case kVideoCodecVP9:
119 reader.CopyTo(
120 &video_header.video_type_header.emplace<RTPVideoHeaderVP9>());
121 break;
122 case kVideoCodecH264:
123 reader.CopyTo(
124 &video_header.video_type_header.emplace<RTPVideoHeaderH264>());
125 break;
126 default:
127 break;
128 }
129
130 reader.CopyTo(&video_header.frame_marking);
131
132 // clang-format off
Mirko Bonadei317a1f02019-09-17 15:06:18133 auto frame = std::make_unique<video_coding::RtpFrameObject>(
philipel2f7d7792019-09-30 14:16:32134 first_seq_num,
135 last_seq_num,
136 marker_bit,
137 /*times_nacked=*/0,
138 /*first_packet_received_time=*/0,
139 /*last_packet_received_time=*/0,
140 /*rtp_timestamp=*/0,
141 /*ntp_time_ms=*/0,
142 VideoSendTiming(),
143 /*payload_type=*/0,
144 codec,
145 kVideoRotation_0,
146 VideoContentType::UNSPECIFIED,
147 video_header,
148 /*color_space=*/absl::nullopt,
149 GenerateRtpGenericFrameDescriptor(&reader),
150 RtpPacketInfos(),
philipelb5e47852019-09-20 09:30:12151 EncodedImageBuffer::Create(/*size=*/0));
philipel2f7d7792019-09-30 14:16:32152 // clang-format on
153
philipelc1ee9d52018-05-16 12:06:13154 reference_finder.ManageFrame(std::move(frame));
155 }
156}
157
158} // namespace webrtc