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