blob: 29f4773962eab8d7fc5f58e0d6ca41668bc479a9 [file] [log] [blame]
/*
* 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 <optional>
#include <string>
#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:
std::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_