/* * Copyright (c) 2018 The WebRTC project authors. All Rights Reserved. * * Use of this source code is governed by a BSD-style license * that can be found in the LICENSE file in the root of the source * tree. An additional intellectual property rights grant can be found * in the file PATENTS. All contributing project authors may * be found in the AUTHORS file in the root of the source tree. */ #include "modules/video_coding/rtp_frame_reference_finder.h" #include "absl/memory/memory.h" #include "modules/video_coding/frame_object.h" #include "modules/video_coding/packet_buffer.h" #include "system_wrappers/include/clock.h" namespace webrtc { namespace { struct DataReader { 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); offset_ += num_bytes; size -= num_bytes; if (size > 0) memset(dest + num_bytes, 0, size); } template T GetNum() { T res; if (offset_ + sizeof(res) < size_) { memcpy(&res, data_ + offset_, sizeof(res)); offset_ += sizeof(res); return res; } offset_ = size_; return T(0); } bool MoreToRead() { return offset_ < size_; } const uint8_t* data_; size_t size_; size_t offset_ = 0; }; class NullCallback : public video_coding::OnCompleteFrameCallback { void OnCompleteFrame( 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; } } 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; } bool GetBitstream(const video_coding::RtpFrameObject& frame, uint8_t* destination) override { return true; } void ReturnFrame(video_coding::RtpFrameObject* frame) override {} private: std::map packets; VideoCodecType codec; DataReader* const reader; }; } // namespace void FuzzOneInput(const uint8_t* data, size_t size) { if (size > 20000) { return; } DataReader reader(data, size); rtc::scoped_refptr pb(new FuzzyPacketBuffer(&reader)); NullCallback cb; video_coding::RtpFrameReferenceFinder reference_finder(&cb); while (reader.MoreToRead()) { auto frame = absl::make_unique( pb, reader.GetNum(), reader.GetNum(), 0, 0, 0, 0); reference_finder.ManageFrame(std::move(frame)); } } } // namespace webrtc