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