| /* |
| * 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<uint8_t*>(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 <typename T> |
| 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<video_coding::EncodedFrame> frame) override {} |
| }; |
| |
| class FuzzyPacketBuffer : public video_coding::PacketBuffer { |
| public: |
| explicit FuzzyPacketBuffer(DataReader* reader) |
| : PacketBuffer(nullptr, 2, 4, nullptr), reader(reader) { |
| switch (reader->GetNum<uint8_t>() % 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<RTPVideoHeaderVP8>(); |
| break; |
| case kVideoCodecVP9: |
| packet->video_header.video_type_header.emplace<RTPVideoHeaderVP9>(); |
| break; |
| case kVideoCodecH264: |
| packet->video_header.video_type_header.emplace<RTPVideoHeaderH264>(); |
| 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<uint16_t, VCMPacket> 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<FuzzyPacketBuffer> pb(new FuzzyPacketBuffer(&reader)); |
| NullCallback cb; |
| video_coding::RtpFrameReferenceFinder reference_finder(&cb); |
| |
| while (reader.MoreToRead()) { |
| auto frame = absl::make_unique<video_coding::RtpFrameObject>( |
| pb, reader.GetNum<uint16_t>(), reader.GetNum<uint16_t>(), 0, 0, 0, 0); |
| reference_finder.ManageFrame(std::move(frame)); |
| } |
| } |
| |
| } // namespace webrtc |