diff options
Diffstat (limited to 'third_party/libwebrtc/test/testsupport/frame_reader.h')
-rw-r--r-- | third_party/libwebrtc/test/testsupport/frame_reader.h | 149 |
1 files changed, 149 insertions, 0 deletions
diff --git a/third_party/libwebrtc/test/testsupport/frame_reader.h b/third_party/libwebrtc/test/testsupport/frame_reader.h new file mode 100644 index 0000000000..7856476ca0 --- /dev/null +++ b/third_party/libwebrtc/test/testsupport/frame_reader.h @@ -0,0 +1,149 @@ +/* + * Copyright (c) 2011 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_FRAME_READER_H_ +#define TEST_TESTSUPPORT_FRAME_READER_H_ + +#include <stdio.h> + +#include <string> + +#include "absl/types/optional.h" +#include "api/scoped_refptr.h" +#include "api/video/resolution.h" + +namespace webrtc { +class I420Buffer; +namespace test { + +// Handles reading of I420 frames from video files. +class FrameReader { + public: + struct Ratio { + int num = 1; + int den = 1; + }; + + static constexpr Ratio kNoScale = Ratio({.num = 1, .den = 1}); + + virtual ~FrameReader() {} + + // Reads and returns next frame. Returns `nullptr` if reading failed or end of + // stream is reached. + virtual rtc::scoped_refptr<I420Buffer> PullFrame() = 0; + + // Reads and returns next frame. `frame_num` stores unwrapped frame number + // which can be passed to `ReadFrame` to re-read this frame later. Returns + // `nullptr` if reading failed or end of stream is reached. + virtual rtc::scoped_refptr<I420Buffer> PullFrame(int* frame_num) = 0; + + // Reads and returns frame specified by `frame_num`. Returns `nullptr` if + // reading failed. + virtual rtc::scoped_refptr<I420Buffer> ReadFrame(int frame_num) = 0; + + // Reads next frame, resizes and returns it. `frame_num` stores unwrapped + // frame number which can be passed to `ReadFrame` to re-read this frame + // later. `resolution` specifies resolution of the returned frame. + // `framerate_scale` specifies frame rate scale factor. Frame rate scaling is + // done by skipping or repeating frames. + virtual rtc::scoped_refptr<I420Buffer> PullFrame(int* frame_num, + Resolution resolution, + Ratio framerate_scale) = 0; + + // Reads frame specified by `frame_num`, resizes and returns it. Returns + // `nullptr` if reading failed. + virtual rtc::scoped_refptr<I420Buffer> ReadFrame(int frame_num, + Resolution resolution) = 0; + + // Total number of retrievable frames. + virtual int num_frames() const = 0; +}; + +class YuvFrameReaderImpl : public FrameReader { + public: + enum class RepeatMode { kSingle, kRepeat, kPingPong }; + + // Creates the frame reader for a YUV file specified by `filepath`. + // `resolution` specifies width and height of frames in pixels. `repeat_mode` + // specifies behaviour of the reader at reaching the end of file (stop, read + // it over from the beginning or read in reverse order). The file is assumed + // to exist, be readable and to contain at least 1 frame. + YuvFrameReaderImpl(std::string filepath, + Resolution resolution, + RepeatMode repeat_mode); + + ~YuvFrameReaderImpl() override; + + virtual void Init(); + + rtc::scoped_refptr<I420Buffer> PullFrame() override; + + rtc::scoped_refptr<I420Buffer> PullFrame(int* frame_num) override; + + rtc::scoped_refptr<I420Buffer> PullFrame(int* frame_num, + Resolution resolution, + Ratio framerate_scale) override; + + rtc::scoped_refptr<I420Buffer> ReadFrame(int frame_num) override; + + rtc::scoped_refptr<I420Buffer> ReadFrame(int frame_num, + Resolution resolution) override; + + int num_frames() const override { return num_frames_; } + + protected: + class RateScaler { + public: + int Skip(Ratio framerate_scale); + + private: + absl::optional<int> ticks_; + }; + + const std::string filepath_; + Resolution resolution_; + const RepeatMode repeat_mode_; + int num_frames_; + int frame_num_; + int frame_size_bytes_; + int header_size_bytes_; + FILE* file_; + RateScaler framerate_scaler_; +}; + +class Y4mFrameReaderImpl : public YuvFrameReaderImpl { + public: + // Creates the frame reader for a Y4M file specified by `filepath`. + // `repeat_mode` specifies behaviour of the reader at reaching the end of file + // (stop, read it over from the beginning or read in reverse order). The file + // is assumed to exist, be readable and to contain at least 1 frame. + Y4mFrameReaderImpl(std::string filepath, RepeatMode repeat_mode); + + void Init() override; +}; + +std::unique_ptr<FrameReader> CreateYuvFrameReader(std::string filepath, + Resolution resolution); + +std::unique_ptr<FrameReader> CreateYuvFrameReader( + std::string filepath, + Resolution resolution, + YuvFrameReaderImpl::RepeatMode repeat_mode); + +std::unique_ptr<FrameReader> CreateY4mFrameReader(std::string filepath); + +std::unique_ptr<FrameReader> CreateY4mFrameReader( + std::string filepath, + YuvFrameReaderImpl::RepeatMode repeat_mode); + +} // namespace test +} // namespace webrtc + +#endif // TEST_TESTSUPPORT_FRAME_READER_H_ |