| /* | 
 |  *  Copyright (c) 2017 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/frame_buffer2.h" | 
 | #include "modules/video_coding/timing.h" | 
 | #include "system_wrappers/include/clock.h" | 
 |  | 
 | namespace webrtc { | 
 |  | 
 | namespace { | 
 |  | 
 | // When DataReader runs out of data provided in the constructor it will | 
 | // just set/return 0 instead. | 
 | struct DataReader { | 
 |   DataReader(const uint8_t* data, size_t size) : data_(data), size_(size) {} | 
 |  | 
 |   void CopyTo(void* destination, size_t dest_size) { | 
 |     memset(destination, 0, dest_size); | 
 |  | 
 |     size_t bytes_to_copy = std::min(size_ - offset_, dest_size); | 
 |     memcpy(destination, data_ + offset_, bytes_to_copy); | 
 |     offset_ += bytes_to_copy; | 
 |   } | 
 |  | 
 |   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* const data_; | 
 |   size_t size_; | 
 |   size_t offset_ = 0; | 
 | }; | 
 |  | 
 | class FuzzyFrameObject : public video_coding::EncodedFrame { | 
 |  public: | 
 |   FuzzyFrameObject() {} | 
 |   ~FuzzyFrameObject() {} | 
 |  | 
 |   int64_t ReceivedTime() const override { return 0; } | 
 |   int64_t RenderTime() const override { return _renderTimeMs; } | 
 | }; | 
 | }  // namespace | 
 |  | 
 | void FuzzOneInput(const uint8_t* data, size_t size) { | 
 |   if (size > 10000) { | 
 |     return; | 
 |   } | 
 |   DataReader reader(data, size); | 
 |   Clock* clock = Clock::GetRealTimeClock(); | 
 |   VCMTiming timing(clock); | 
 |   video_coding::FrameBuffer frame_buffer(clock, &timing, nullptr); | 
 |  | 
 |   while (reader.MoreToRead()) { | 
 |     if (reader.GetNum<uint8_t>() & 1) { | 
 |       std::unique_ptr<FuzzyFrameObject> frame(new FuzzyFrameObject()); | 
 |       frame->id.picture_id = reader.GetNum<int64_t>(); | 
 |       frame->id.spatial_layer = reader.GetNum<uint8_t>(); | 
 |       frame->SetTimestamp(reader.GetNum<uint32_t>()); | 
 |       frame->num_references = reader.GetNum<uint8_t>() % | 
 |                               video_coding::EncodedFrame::kMaxFrameReferences; | 
 |  | 
 |       for (size_t r = 0; r < frame->num_references; ++r) | 
 |         frame->references[r] = reader.GetNum<int64_t>(); | 
 |  | 
 |       frame_buffer.InsertFrame(std::move(frame)); | 
 |     } else { | 
 |       // Since we are not trying to trigger race conditions it does not make | 
 |       // sense to have a wait time > 0. | 
 |       const int kWaitTimeMs = 0; | 
 |  | 
 |       std::unique_ptr<video_coding::EncodedFrame> frame(new FuzzyFrameObject()); | 
 |       bool keyframe_required = reader.GetNum<uint8_t>() % 2; | 
 |       frame_buffer.NextFrame(kWaitTimeMs, &frame, keyframe_required); | 
 |     } | 
 |   } | 
 | } | 
 |  | 
 | }  // namespace webrtc |