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