xref: /aosp_15_r20/external/libaom/test/y4m_video_source.h (revision 77c1e3ccc04c968bd2bc212e87364f250e820521)
1*77c1e3ccSAndroid Build Coastguard Worker /*
2*77c1e3ccSAndroid Build Coastguard Worker  * Copyright (c) 2016, Alliance for Open Media. All rights reserved.
3*77c1e3ccSAndroid Build Coastguard Worker  *
4*77c1e3ccSAndroid Build Coastguard Worker  * This source code is subject to the terms of the BSD 2 Clause License and
5*77c1e3ccSAndroid Build Coastguard Worker  * the Alliance for Open Media Patent License 1.0. If the BSD 2 Clause License
6*77c1e3ccSAndroid Build Coastguard Worker  * was not distributed with this source code in the LICENSE file, you can
7*77c1e3ccSAndroid Build Coastguard Worker  * obtain it at www.aomedia.org/license/software. If the Alliance for Open
8*77c1e3ccSAndroid Build Coastguard Worker  * Media Patent License 1.0 was not distributed with this source code in the
9*77c1e3ccSAndroid Build Coastguard Worker  * PATENTS file, you can obtain it at www.aomedia.org/license/patent.
10*77c1e3ccSAndroid Build Coastguard Worker  */
11*77c1e3ccSAndroid Build Coastguard Worker #ifndef AOM_TEST_Y4M_VIDEO_SOURCE_H_
12*77c1e3ccSAndroid Build Coastguard Worker #define AOM_TEST_Y4M_VIDEO_SOURCE_H_
13*77c1e3ccSAndroid Build Coastguard Worker #include <algorithm>
14*77c1e3ccSAndroid Build Coastguard Worker #include <memory>
15*77c1e3ccSAndroid Build Coastguard Worker #include <string>
16*77c1e3ccSAndroid Build Coastguard Worker 
17*77c1e3ccSAndroid Build Coastguard Worker #include "common/y4minput.h"
18*77c1e3ccSAndroid Build Coastguard Worker #include "test/video_source.h"
19*77c1e3ccSAndroid Build Coastguard Worker 
20*77c1e3ccSAndroid Build Coastguard Worker namespace libaom_test {
21*77c1e3ccSAndroid Build Coastguard Worker 
22*77c1e3ccSAndroid Build Coastguard Worker // This class extends VideoSource to allow parsing of raw yv12
23*77c1e3ccSAndroid Build Coastguard Worker // so that we can do actual file encodes.
24*77c1e3ccSAndroid Build Coastguard Worker class Y4mVideoSource : public VideoSource {
25*77c1e3ccSAndroid Build Coastguard Worker  public:
Y4mVideoSource(const std::string & file_name,unsigned int start,int limit)26*77c1e3ccSAndroid Build Coastguard Worker   Y4mVideoSource(const std::string &file_name, unsigned int start, int limit)
27*77c1e3ccSAndroid Build Coastguard Worker       : file_name_(file_name), input_file_(nullptr), img_(new aom_image_t()),
28*77c1e3ccSAndroid Build Coastguard Worker         start_(start), limit_(limit), frame_(0), framerate_numerator_(0),
29*77c1e3ccSAndroid Build Coastguard Worker         framerate_denominator_(0), y4m_() {}
30*77c1e3ccSAndroid Build Coastguard Worker 
~Y4mVideoSource()31*77c1e3ccSAndroid Build Coastguard Worker   ~Y4mVideoSource() override {
32*77c1e3ccSAndroid Build Coastguard Worker     aom_img_free(img_.get());
33*77c1e3ccSAndroid Build Coastguard Worker     CloseSource();
34*77c1e3ccSAndroid Build Coastguard Worker   }
35*77c1e3ccSAndroid Build Coastguard Worker 
OpenSource()36*77c1e3ccSAndroid Build Coastguard Worker   virtual void OpenSource() {
37*77c1e3ccSAndroid Build Coastguard Worker     CloseSource();
38*77c1e3ccSAndroid Build Coastguard Worker     input_file_ = OpenTestDataFile(file_name_);
39*77c1e3ccSAndroid Build Coastguard Worker     ASSERT_NE(input_file_, nullptr)
40*77c1e3ccSAndroid Build Coastguard Worker         << "Input file open failed. Filename: " << file_name_;
41*77c1e3ccSAndroid Build Coastguard Worker   }
42*77c1e3ccSAndroid Build Coastguard Worker 
ReadSourceToStart()43*77c1e3ccSAndroid Build Coastguard Worker   virtual void ReadSourceToStart() {
44*77c1e3ccSAndroid Build Coastguard Worker     ASSERT_NE(input_file_, nullptr);
45*77c1e3ccSAndroid Build Coastguard Worker     ASSERT_FALSE(
46*77c1e3ccSAndroid Build Coastguard Worker         y4m_input_open(&y4m_, input_file_, nullptr, 0, AOM_CSP_UNKNOWN, 0));
47*77c1e3ccSAndroid Build Coastguard Worker     framerate_numerator_ = y4m_.fps_n;
48*77c1e3ccSAndroid Build Coastguard Worker     framerate_denominator_ = y4m_.fps_d;
49*77c1e3ccSAndroid Build Coastguard Worker     frame_ = 0;
50*77c1e3ccSAndroid Build Coastguard Worker     for (unsigned int i = 0; i < start_; i++) {
51*77c1e3ccSAndroid Build Coastguard Worker       Next();
52*77c1e3ccSAndroid Build Coastguard Worker     }
53*77c1e3ccSAndroid Build Coastguard Worker     FillFrame();
54*77c1e3ccSAndroid Build Coastguard Worker   }
55*77c1e3ccSAndroid Build Coastguard Worker 
Begin()56*77c1e3ccSAndroid Build Coastguard Worker   void Begin() override {
57*77c1e3ccSAndroid Build Coastguard Worker     OpenSource();
58*77c1e3ccSAndroid Build Coastguard Worker     ReadSourceToStart();
59*77c1e3ccSAndroid Build Coastguard Worker   }
60*77c1e3ccSAndroid Build Coastguard Worker 
Next()61*77c1e3ccSAndroid Build Coastguard Worker   void Next() override {
62*77c1e3ccSAndroid Build Coastguard Worker     ++frame_;
63*77c1e3ccSAndroid Build Coastguard Worker     FillFrame();
64*77c1e3ccSAndroid Build Coastguard Worker   }
65*77c1e3ccSAndroid Build Coastguard Worker 
img()66*77c1e3ccSAndroid Build Coastguard Worker   aom_image_t *img() const override {
67*77c1e3ccSAndroid Build Coastguard Worker     return (frame_ < limit_) ? img_.get() : nullptr;
68*77c1e3ccSAndroid Build Coastguard Worker   }
69*77c1e3ccSAndroid Build Coastguard Worker 
70*77c1e3ccSAndroid Build Coastguard Worker   // Models a stream where Timebase = 1/FPS, so pts == frame.
pts()71*77c1e3ccSAndroid Build Coastguard Worker   aom_codec_pts_t pts() const override { return frame_; }
72*77c1e3ccSAndroid Build Coastguard Worker 
duration()73*77c1e3ccSAndroid Build Coastguard Worker   unsigned long duration() const override { return 1; }
74*77c1e3ccSAndroid Build Coastguard Worker 
timebase()75*77c1e3ccSAndroid Build Coastguard Worker   aom_rational_t timebase() const override {
76*77c1e3ccSAndroid Build Coastguard Worker     const aom_rational_t t = { framerate_denominator_, framerate_numerator_ };
77*77c1e3ccSAndroid Build Coastguard Worker     return t;
78*77c1e3ccSAndroid Build Coastguard Worker   }
79*77c1e3ccSAndroid Build Coastguard Worker 
frame()80*77c1e3ccSAndroid Build Coastguard Worker   unsigned int frame() const override { return frame_; }
81*77c1e3ccSAndroid Build Coastguard Worker 
limit()82*77c1e3ccSAndroid Build Coastguard Worker   unsigned int limit() const override { return limit_; }
83*77c1e3ccSAndroid Build Coastguard Worker 
FillFrame()84*77c1e3ccSAndroid Build Coastguard Worker   virtual void FillFrame() {
85*77c1e3ccSAndroid Build Coastguard Worker     ASSERT_NE(input_file_, nullptr);
86*77c1e3ccSAndroid Build Coastguard Worker     // Read a frame from input_file.
87*77c1e3ccSAndroid Build Coastguard Worker     y4m_input_fetch_frame(&y4m_, input_file_, img_.get());
88*77c1e3ccSAndroid Build Coastguard Worker   }
89*77c1e3ccSAndroid Build Coastguard Worker 
90*77c1e3ccSAndroid Build Coastguard Worker   // Swap buffers with another y4m source. This allows reading a new frame
91*77c1e3ccSAndroid Build Coastguard Worker   // while keeping the old frame around. A whole Y4mSource is required and
92*77c1e3ccSAndroid Build Coastguard Worker   // not just a aom_image_t because of how the y4m reader manipulates
93*77c1e3ccSAndroid Build Coastguard Worker   // aom_image_t internals,
SwapBuffers(Y4mVideoSource * other)94*77c1e3ccSAndroid Build Coastguard Worker   void SwapBuffers(Y4mVideoSource *other) {
95*77c1e3ccSAndroid Build Coastguard Worker     std::swap(other->y4m_.dst_buf, y4m_.dst_buf);
96*77c1e3ccSAndroid Build Coastguard Worker     aom_image_t *tmp;
97*77c1e3ccSAndroid Build Coastguard Worker     tmp = other->img_.release();
98*77c1e3ccSAndroid Build Coastguard Worker     other->img_.reset(img_.release());
99*77c1e3ccSAndroid Build Coastguard Worker     img_.reset(tmp);
100*77c1e3ccSAndroid Build Coastguard Worker   }
101*77c1e3ccSAndroid Build Coastguard Worker 
102*77c1e3ccSAndroid Build Coastguard Worker  protected:
CloseSource()103*77c1e3ccSAndroid Build Coastguard Worker   void CloseSource() {
104*77c1e3ccSAndroid Build Coastguard Worker     y4m_input_close(&y4m_);
105*77c1e3ccSAndroid Build Coastguard Worker     y4m_ = y4m_input();
106*77c1e3ccSAndroid Build Coastguard Worker     if (input_file_ != nullptr) {
107*77c1e3ccSAndroid Build Coastguard Worker       fclose(input_file_);
108*77c1e3ccSAndroid Build Coastguard Worker       input_file_ = nullptr;
109*77c1e3ccSAndroid Build Coastguard Worker     }
110*77c1e3ccSAndroid Build Coastguard Worker   }
111*77c1e3ccSAndroid Build Coastguard Worker 
112*77c1e3ccSAndroid Build Coastguard Worker   std::string file_name_;
113*77c1e3ccSAndroid Build Coastguard Worker   FILE *input_file_;
114*77c1e3ccSAndroid Build Coastguard Worker   std::unique_ptr<aom_image_t> img_;
115*77c1e3ccSAndroid Build Coastguard Worker   unsigned int start_;
116*77c1e3ccSAndroid Build Coastguard Worker   unsigned int limit_;
117*77c1e3ccSAndroid Build Coastguard Worker   unsigned int frame_;
118*77c1e3ccSAndroid Build Coastguard Worker   int framerate_numerator_;
119*77c1e3ccSAndroid Build Coastguard Worker   int framerate_denominator_;
120*77c1e3ccSAndroid Build Coastguard Worker   y4m_input y4m_;
121*77c1e3ccSAndroid Build Coastguard Worker };
122*77c1e3ccSAndroid Build Coastguard Worker 
123*77c1e3ccSAndroid Build Coastguard Worker }  // namespace libaom_test
124*77c1e3ccSAndroid Build Coastguard Worker 
125*77c1e3ccSAndroid Build Coastguard Worker #endif  // AOM_TEST_Y4M_VIDEO_SOURCE_H_
126