| /* | |
| * Copyright (c) 2026 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_TESTSUPPORT_PENDULUM_FRAME_GENERATOR_H_ | |
| #define TEST_TESTSUPPORT_PENDULUM_FRAME_GENERATOR_H_ | |
| #include <cstddef> | |
| #include <cstdint> | |
| #include <memory> | |
| #include <optional> | |
| #include <string> | |
| #include "api/scoped_refptr.h" | |
| #include "api/test/frame_generator_interface.h" | |
| #include "api/video/i420_buffer.h" | |
| #include "test/testsupport/frame_reader.h" | |
| namespace webrtc { | |
| namespace test { | |
| // A synthetic frame generator that crops and scales a high-detail static image | |
| // along a smooth, erratic, non-repeating trajectory governed by double-pendulum | |
| // chaotic physics with dynamic zoom and optional luma noise. Designed as an | |
| // absolute stress test for video encoders. | |
| class PendulumFrameGenerator : public FrameGeneratorInterface { | |
| public: | |
| struct Config { | |
| // Path to an i420 static image file. | |
| std::string source_image_path = "resources/difficult_photo_1850_1110.yuv"; | |
| Resolution source_resolution = {.width = 1850, .height = 1110}; | |
| // Target output frame resolution. | |
| Resolution target_resolution = {.width = 1280, .height = 720}; | |
| // Target framerate (used for physics time step integration). | |
| int fps = 30; | |
| // Zoom limits (1.0 = maximum crop area fitting aspect ratio). | |
| double min_zoom = 1.2; | |
| double max_zoom = 3.0; | |
| // Base zoom cycle frequency in cycles per second. | |
| double zoom_speed = 0.3; | |
| // Luma white noise amplitude (+/- noise_level added to pixel values). | |
| // Set to 0 to disable noise. | |
| int noise_level = 20; | |
| }; | |
| explicit PendulumFrameGenerator(Config config); | |
| ~PendulumFrameGenerator() override = default; | |
| void ChangeResolution(size_t width, size_t height) override; | |
| VideoFrameData NextFrame() override; | |
| scoped_refptr<I420Buffer> NextI420Frame(); | |
| FrameGeneratorInterface::Resolution GetResolution() const override; | |
| std::optional<int> fps() const override { return config_.fps; } | |
| void Reset(); | |
| private: | |
| void StepPhysics(double dt); | |
| void LoadOrGenerateSourceImage(); | |
| void ApplyNoise(I420Buffer* buffer); | |
| Config config_; | |
| scoped_refptr<I420Buffer> source_image_; | |
| // Double pendulum state: angles (rad), angular velocities (rad/s) | |
| double th1_ = 0.5; | |
| double th2_ = 0.5; | |
| double w1_ = 0.0; | |
| double w2_ = 0.0; | |
| double sim_time_ = 0.0; | |
| // Zoom oscillation phase (rad) | |
| double zoom_phase_ = 0.0; | |
| // Fast PRNG state for additive luma noise | |
| uint32_t prng_state_ = 123456789; | |
| }; | |
| // Factory functions. | |
| std::unique_ptr<PendulumFrameGenerator> CreatePendulumFrameGenerator( | |
| const PendulumFrameGenerator::Config& config); | |
| std::unique_ptr<FrameReader> CreatePendulumFrameReader( | |
| const PendulumFrameGenerator::Config& config); | |
| } // namespace test | |
| } // namespace webrtc | |
| #endif // TEST_TESTSUPPORT_PENDULUM_FRAME_GENERATOR_H_ |