mirror of
https://github.com/mollyim/webrtc.git
synced 2025-05-14 06:10:40 +01:00

Purposes of this refactoring: 1. Add functionality for reading a specified frame. 2. Change resolution and frame rate on per-frame basis. Both features are needed for https://webrtc-review.googlesource.com/c/src/+/283525 Bug: b/261160916 Change-Id: I6d60e62dbc3913c43b5c1b491690f5cb4a8632dd Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/285483 Reviewed-by: Erik Språng <sprang@webrtc.org> Commit-Queue: Sergey Silkin <ssilkin@webrtc.org> Cr-Commit-Position: refs/heads/main@{#38829}
149 lines
5 KiB
C++
149 lines
5 KiB
C++
/*
|
|
* 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_
|