| /* | |
| * Copyright 2024 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 VIDEO_CORRUPTION_DETECTION_HALTON_FRAME_SAMPLER_H_ | |
| #define VIDEO_CORRUPTION_DETECTION_HALTON_FRAME_SAMPLER_H_ | |
| #include <cstdint> | |
| #include <optional> | |
| #include <vector> | |
| #include "api/scoped_refptr.h" | |
| #include "api/video/video_frame.h" | |
| #include "api/video/video_frame_buffer.h" | |
| #include "video/corruption_detection/halton_sequence.h" | |
| #include "video/corruption_detection/video_frame_sampler.h" | |
| namespace webrtc { | |
| enum class ImagePlane { kLuma, kChroma }; | |
| struct FilteredSample { | |
| double value; | |
| ImagePlane plane; | |
| }; | |
| // Determines if a frame should be sampled and, based on the 2 dimensional | |
| // Halton sequence, finds the coordinates for those samples. | |
| class HaltonFrameSampler { | |
| public: | |
| struct Coordinates { | |
| double row = 0; | |
| double column = 0; | |
| }; | |
| HaltonFrameSampler(); | |
| HaltonFrameSampler(const HaltonFrameSampler&) = default; | |
| HaltonFrameSampler(HaltonFrameSampler&&) = default; | |
| HaltonFrameSampler& operator=(const HaltonFrameSampler&) = default; | |
| HaltonFrameSampler& operator=(HaltonFrameSampler&&) = default; | |
| std::vector<Coordinates> GetSampleCoordinatesForFrameIfFrameShouldBeSampled( | |
| bool is_key_frame, | |
| uint32_t rtp_timestamp, | |
| int num_samples); | |
| std::vector<Coordinates> GetSampleCoordinatesForFrame(int num_samples); | |
| void Restart(); | |
| int GetCurrentIndex() const; | |
| void SetCurrentIndex(int index); | |
| private: | |
| Coordinates GetNextSampleCoordinates(); | |
| HaltonSequence coordinate_sampler_prng_; | |
| std::optional<uint32_t> rtp_timestamp_last_frame_sampled_; | |
| int frames_sampled_ = 0; | |
| int frames_until_next_sample_ = 0; | |
| }; | |
| // 1. Scale the frame buffer to the resolution given by `scaled_width` and | |
| // `scaled_height`. | |
| // 2. Scale the `sample_coordinates` to the frame's resolution. | |
| // 3. Apply the Gaussian filtering given by `std_dev_gaussian_blur`. | |
| // 4. Fetch the values at the scaled coordinates in the filtered frame. | |
| std::vector<FilteredSample> GetSampleValuesForFrame( | |
| const VideoFrame& frame, | |
| std::vector<HaltonFrameSampler::Coordinates> sample_coordinates, | |
| int scaled_width, | |
| int scaled_height, | |
| double std_dev_gaussian_blur); | |
| // For backwards compatiblity only. | |
| // TODO(bugs.webrtc.org/398100): Remove when downstream usage is gone. | |
| [[deprecated]] std::vector<FilteredSample> GetSampleValuesForFrame( | |
| scoped_refptr<I420BufferInterface> i420_frame_buffer, | |
| std::vector<HaltonFrameSampler::Coordinates> sample_coordinates, | |
| int scaled_width, | |
| int scaled_height, | |
| double std_dev_gaussian_blur); | |
| // Returns the blurred value. The minimum half-kernel size is 3 pixels. | |
| double GetFilteredElement(const VideoFrameSampler& frame_sampler, | |
| VideoFrameSampler::ChannelType channel, | |
| int row, | |
| int column, | |
| double std_dev); | |
| } // namespace webrtc | |
| #endif // VIDEO_CORRUPTION_DETECTION_HALTON_FRAME_SAMPLER_H_ |