| /* | 
 |  *  Copyright (c) 2013 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. | 
 |  */ | 
 |  | 
 | #ifndef TEST_FAKE_ENCODER_H_ | 
 | #define TEST_FAKE_ENCODER_H_ | 
 |  | 
 | #include <stddef.h> | 
 | #include <stdint.h> | 
 |  | 
 | #include <memory> | 
 | #include <vector> | 
 |  | 
 | #include "api/fec_controller_override.h" | 
 | #include "api/task_queue/task_queue_factory.h" | 
 | #include "api/video/encoded_image.h" | 
 | #include "api/video/video_bitrate_allocation.h" | 
 | #include "api/video/video_frame.h" | 
 | #include "api/video_codecs/video_codec.h" | 
 | #include "api/video_codecs/video_encoder.h" | 
 | #include "modules/include/module_common_types.h" | 
 | #include "modules/video_coding/include/video_codec_interface.h" | 
 | #include "rtc_base/critical_section.h" | 
 | #include "rtc_base/synchronization/sequence_checker.h" | 
 | #include "rtc_base/thread_annotations.h" | 
 | #include "system_wrappers/include/clock.h" | 
 |  | 
 | namespace webrtc { | 
 | namespace test { | 
 |  | 
 | class FakeEncoder : public VideoEncoder { | 
 |  public: | 
 |   explicit FakeEncoder(Clock* clock); | 
 |   virtual ~FakeEncoder() = default; | 
 |  | 
 |   // Sets max bitrate. Not thread-safe, call before registering the encoder. | 
 |   void SetMaxBitrate(int max_kbps); | 
 |   void SetQp(int qp); | 
 |  | 
 |   void SetFecControllerOverride( | 
 |       FecControllerOverride* fec_controller_override) override; | 
 |  | 
 |   int32_t InitEncode(const VideoCodec* config, | 
 |                      const Settings& settings) override; | 
 |   int32_t Encode(const VideoFrame& input_image, | 
 |                  const std::vector<VideoFrameType>* frame_types) override; | 
 |   int32_t RegisterEncodeCompleteCallback( | 
 |       EncodedImageCallback* callback) override; | 
 |   int32_t Release() override; | 
 |   void SetRates(const RateControlParameters& parameters) override; | 
 |   int GetConfiguredInputFramerate() const; | 
 |   EncoderInfo GetEncoderInfo() const override; | 
 |  | 
 |   static const char* kImplementationName; | 
 |  | 
 |  protected: | 
 |   struct FrameInfo { | 
 |     bool keyframe; | 
 |     struct SpatialLayer { | 
 |       SpatialLayer() = default; | 
 |       SpatialLayer(int size, int temporal_id) | 
 |           : size(size), temporal_id(temporal_id) {} | 
 |       // Size of a current frame in the layer. | 
 |       int size = 0; | 
 |       // Temporal index of a current frame in the layer. | 
 |       int temporal_id = 0; | 
 |     }; | 
 |     std::vector<SpatialLayer> layers; | 
 |   }; | 
 |  | 
 |   FrameInfo NextFrame(const std::vector<VideoFrameType>* frame_types, | 
 |                       bool keyframe, | 
 |                       uint8_t num_simulcast_streams, | 
 |                       const VideoBitrateAllocation& target_bitrate, | 
 |                       SimulcastStream simulcast_streams[kMaxSimulcastStreams], | 
 |                       int framerate); | 
 |  | 
 |   // Called before the frame is passed to callback_->OnEncodedImage, to let | 
 |   // subclasses fill out codec_specific, possibly modify encodedImage. | 
 |   // Returns an RTPFragmentationHeader, if needed by the codec. | 
 |   virtual std::unique_ptr<RTPFragmentationHeader> EncodeHook( | 
 |       EncodedImage* encoded_image, | 
 |       CodecSpecificInfo* codec_specific); | 
 |  | 
 |   FrameInfo last_frame_info_ RTC_GUARDED_BY(crit_sect_); | 
 |   Clock* const clock_; | 
 |  | 
 |   VideoCodec config_ RTC_GUARDED_BY(crit_sect_); | 
 |   EncodedImageCallback* callback_ RTC_GUARDED_BY(crit_sect_); | 
 |   RateControlParameters current_rate_settings_ RTC_GUARDED_BY(crit_sect_); | 
 |   int max_target_bitrate_kbps_ RTC_GUARDED_BY(crit_sect_); | 
 |   bool pending_keyframe_ RTC_GUARDED_BY(crit_sect_); | 
 |   uint32_t counter_ RTC_GUARDED_BY(crit_sect_); | 
 |   rtc::CriticalSection crit_sect_; | 
 |   bool used_layers_[kMaxSimulcastStreams]; | 
 |   absl::optional<int> qp_ RTC_GUARDED_BY(crit_sect_); | 
 |  | 
 |   // Current byte debt to be payed over a number of frames. | 
 |   // The debt is acquired by keyframes overshooting the bitrate target. | 
 |   size_t debt_bytes_; | 
 | }; | 
 |  | 
 | class FakeH264Encoder : public FakeEncoder { | 
 |  public: | 
 |   explicit FakeH264Encoder(Clock* clock); | 
 |   virtual ~FakeH264Encoder() = default; | 
 |  | 
 |  private: | 
 |   std::unique_ptr<RTPFragmentationHeader> EncodeHook( | 
 |       EncodedImage* encoded_image, | 
 |       CodecSpecificInfo* codec_specific) override; | 
 |  | 
 |   int idr_counter_ RTC_GUARDED_BY(local_crit_sect_); | 
 |   rtc::CriticalSection local_crit_sect_; | 
 | }; | 
 |  | 
 | class DelayedEncoder : public test::FakeEncoder { | 
 |  public: | 
 |   DelayedEncoder(Clock* clock, int delay_ms); | 
 |   virtual ~DelayedEncoder() = default; | 
 |  | 
 |   void SetDelay(int delay_ms); | 
 |   int32_t Encode(const VideoFrame& input_image, | 
 |                  const std::vector<VideoFrameType>* frame_types) override; | 
 |  | 
 |  private: | 
 |   int delay_ms_ RTC_GUARDED_BY(sequence_checker_); | 
 |   SequenceChecker sequence_checker_; | 
 | }; | 
 |  | 
 | // This class implements a multi-threaded fake encoder by posting | 
 | // FakeH264Encoder::Encode(.) tasks to |queue1_| and |queue2_|, in an | 
 | // alternating fashion. The class itself does not need to be thread safe, | 
 | // as it is called from the task queue in VideoStreamEncoder. | 
 | class MultithreadedFakeH264Encoder : public test::FakeH264Encoder { | 
 |  public: | 
 |   MultithreadedFakeH264Encoder(Clock* clock, | 
 |                                TaskQueueFactory* task_queue_factory); | 
 |   virtual ~MultithreadedFakeH264Encoder() = default; | 
 |  | 
 |   int32_t InitEncode(const VideoCodec* config, | 
 |                      const Settings& settings) override; | 
 |  | 
 |   int32_t Encode(const VideoFrame& input_image, | 
 |                  const std::vector<VideoFrameType>* frame_types) override; | 
 |  | 
 |   int32_t EncodeCallback(const VideoFrame& input_image, | 
 |                          const std::vector<VideoFrameType>* frame_types); | 
 |  | 
 |   int32_t Release() override; | 
 |  | 
 |  protected: | 
 |   class EncodeTask; | 
 |  | 
 |   TaskQueueFactory* const task_queue_factory_; | 
 |   int current_queue_ RTC_GUARDED_BY(sequence_checker_); | 
 |   std::unique_ptr<TaskQueueBase, TaskQueueDeleter> queue1_ | 
 |       RTC_GUARDED_BY(sequence_checker_); | 
 |   std::unique_ptr<TaskQueueBase, TaskQueueDeleter> queue2_ | 
 |       RTC_GUARDED_BY(sequence_checker_); | 
 |   SequenceChecker sequence_checker_; | 
 | }; | 
 |  | 
 | }  // namespace test | 
 | }  // namespace webrtc | 
 |  | 
 | #endif  // TEST_FAKE_ENCODER_H_ |