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