diff --git a/test/fuzzers/rtp_frame_reference_finder_fuzzer.cc b/test/fuzzers/rtp_frame_reference_finder_fuzzer.cc index f238138d76..0aa8e75a16 100644 --- a/test/fuzzers/rtp_frame_reference_finder_fuzzer.cc +++ b/test/fuzzers/rtp_frame_reference_finder_fuzzer.cc @@ -19,18 +19,22 @@ namespace webrtc { namespace { -struct DataReader { +class DataReader { + public: DataReader(const uint8_t* data, size_t size) : data_(data), size_(size) {} - void CopyTo(void* destination, size_t size) { - uint8_t* dest = reinterpret_cast(destination); - size_t num_bytes = std::min(size_ - offset_, size); - memcpy(dest, data_ + offset_, num_bytes); + template + void CopyTo(T* object) { + static_assert(std::is_pod(), ""); + uint8_t* destination = reinterpret_cast(object); + size_t object_size = sizeof(T); + size_t num_bytes = std::min(size_ - offset_, object_size); + memcpy(destination, data_ + offset_, num_bytes); offset_ += num_bytes; - size -= num_bytes; - if (size > 0) - memset(dest + num_bytes, 0, size); + // If we did not have enough data, fill the rest with 0. + object_size -= num_bytes; + memset(destination + num_bytes, 0, object_size); } template @@ -48,6 +52,7 @@ struct DataReader { bool MoreToRead() { return offset_ < size_; } + private: const uint8_t* data_; size_t size_; size_t offset_ = 0; @@ -58,76 +63,94 @@ class NullCallback : public video_coding::OnCompleteFrameCallback { std::unique_ptr frame) override {} }; -class FuzzyPacketBuffer : public video_coding::PacketBuffer { - public: - explicit FuzzyPacketBuffer(DataReader* reader) - : PacketBuffer(nullptr, 2, 4, nullptr), reader(reader) { - switch (reader->GetNum() % 3) { - case 0: - codec = kVideoCodecVP8; - break; - case 1: - codec = kVideoCodecVP9; - break; - case 2: - codec = kVideoCodecH264; - break; - } +RtpGenericFrameDescriptor GenerateRtpGenericFrameDescriptor( + DataReader* reader) { + RtpGenericFrameDescriptor res; + res.SetFirstPacketInSubFrame(true); + res.SetFrameId(reader->GetNum()); + + int spatial_layer = + reader->GetNum() % RtpGenericFrameDescriptor::kMaxSpatialLayers; + res.SetSpatialLayersBitmask(1 << spatial_layer); + res.SetTemporalLayer(reader->GetNum() % + RtpGenericFrameDescriptor::kMaxTemporalLayers); + + int num_diffs = (reader->GetNum() % + RtpGenericFrameDescriptor::kMaxNumFrameDependencies); + for (int i = 0; i < num_diffs; ++i) { + res.AddFrameDependencyDiff(reader->GetNum() % (1 << 14)); } - VCMPacket* GetPacket(uint16_t seq_num) override { - auto packet_it = packets.find(seq_num); - if (packet_it != packets.end()) - return &packet_it->second; - - VCMPacket* packet = &packets[seq_num]; - packet->video_header.codec = codec; - switch (codec) { - case kVideoCodecVP8: - packet->video_header.video_type_header.emplace(); - break; - case kVideoCodecVP9: - packet->video_header.video_type_header.emplace(); - break; - case kVideoCodecH264: - packet->video_header.video_type_header.emplace(); - break; - default: - RTC_NOTREACHED(); - } - packet->markerBit = true; - reader->CopyTo(packet, sizeof(packet)); - return packet; - } - - private: - std::map packets; - VideoCodecType codec; - DataReader* const reader; -}; + return res; +} } // namespace void FuzzOneInput(const uint8_t* data, size_t size) { - if (size > 20000) { - return; - } DataReader reader(data, size); - FuzzyPacketBuffer packet_buffer(&reader); NullCallback cb; video_coding::RtpFrameReferenceFinder reference_finder(&cb); + auto codec = static_cast(reader.GetNum() % 4); + while (reader.MoreToRead()) { - // Make sure that these packets fulfill the contract of RtpFrameObject. uint16_t first_seq_num = reader.GetNum(); uint16_t last_seq_num = reader.GetNum(); - VCMPacket* first_packet = packet_buffer.GetPacket(first_seq_num); - VCMPacket* last_packet = packet_buffer.GetPacket(last_seq_num); - first_packet->video_header.is_first_packet_in_frame = true; - last_packet->video_header.is_last_packet_in_frame = true; + bool marker_bit = reader.GetNum(); + RTPVideoHeader video_header; + switch (reader.GetNum() % 3) { + case 0: + video_header.frame_type = VideoFrameType::kEmptyFrame; + break; + case 1: + video_header.frame_type = VideoFrameType::kVideoFrameKey; + break; + case 2: + video_header.frame_type = VideoFrameType::kVideoFrameDelta; + break; + } + + switch (codec) { + case kVideoCodecVP8: + reader.CopyTo( + &video_header.video_type_header.emplace()); + break; + case kVideoCodecVP9: + reader.CopyTo( + &video_header.video_type_header.emplace()); + break; + case kVideoCodecH264: + reader.CopyTo( + &video_header.video_type_header.emplace()); + break; + default: + break; + } + + reader.CopyTo(&video_header.frame_marking); + + // clang-format off auto frame = std::make_unique( - &packet_buffer, first_seq_num, last_seq_num, 0, 0, 0, RtpPacketInfos(), + first_seq_num, + last_seq_num, + marker_bit, + /*times_nacked=*/0, + /*first_packet_received_time=*/0, + /*last_packet_received_time=*/0, + /*rtp_timestamp=*/0, + /*ntp_time_ms=*/0, + VideoSendTiming(), + /*payload_type=*/0, + codec, + kVideoRotation_0, + VideoContentType::UNSPECIFIED, + video_header, + /*color_space=*/absl::nullopt, + GenerateRtpGenericFrameDescriptor(&reader), + RtpPacketInfos(), EncodedImageBuffer::Create(/*size=*/0)); + // clang-format on + reference_finder.ManageFrame(std::move(frame)); } }