Home | History | Annotate | Download | only in test
      1 /*
      2  *  Copyright (c) 2014 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_YUV_VIDEO_SOURCE_H_
     11 #define TEST_YUV_VIDEO_SOURCE_H_
     12 
     13 #include <cstdio>
     14 #include <cstdlib>
     15 #include <string>
     16 
     17 #include "test/video_source.h"
     18 #include "vpx/vpx_image.h"
     19 
     20 namespace libvpx_test {
     21 
     22 // This class extends VideoSource to allow parsing of raw YUV
     23 // formats of various color sampling and bit-depths so that we can
     24 // do actual file encodes.
     25 class YUVVideoSource : public VideoSource {
     26  public:
     27   YUVVideoSource(const std::string &file_name, vpx_img_fmt format,
     28                  unsigned int width, unsigned int height,
     29                  int rate_numerator, int rate_denominator,
     30                  unsigned int start, int limit)
     31       : file_name_(file_name),
     32         input_file_(NULL),
     33         img_(NULL),
     34         start_(start),
     35         limit_(limit),
     36         frame_(0),
     37         width_(0),
     38         height_(0),
     39         format_(VPX_IMG_FMT_NONE),
     40         framerate_numerator_(rate_numerator),
     41         framerate_denominator_(rate_denominator) {
     42     // This initializes format_, raw_size_, width_, height_ and allocates img.
     43     SetSize(width, height, format);
     44   }
     45 
     46   virtual ~YUVVideoSource() {
     47     vpx_img_free(img_);
     48     if (input_file_)
     49       fclose(input_file_);
     50   }
     51 
     52   virtual void Begin() {
     53     if (input_file_)
     54       fclose(input_file_);
     55     input_file_ = OpenTestDataFile(file_name_);
     56     ASSERT_TRUE(input_file_ != NULL) << "Input file open failed. Filename: "
     57                                      << file_name_;
     58     if (start_)
     59       fseek(input_file_, static_cast<unsigned>(raw_size_) * start_, SEEK_SET);
     60 
     61     frame_ = start_;
     62     FillFrame();
     63   }
     64 
     65   virtual void Next() {
     66     ++frame_;
     67     FillFrame();
     68   }
     69 
     70   virtual vpx_image_t *img() const { return (frame_ < limit_) ? img_ : NULL;  }
     71 
     72   // Models a stream where Timebase = 1/FPS, so pts == frame.
     73   virtual vpx_codec_pts_t pts() const { return frame_; }
     74 
     75   virtual unsigned long duration() const { return 1; }
     76 
     77   virtual vpx_rational_t timebase() const {
     78     const vpx_rational_t t = { framerate_denominator_, framerate_numerator_ };
     79     return t;
     80   }
     81 
     82   virtual unsigned int frame() const { return frame_; }
     83 
     84   virtual unsigned int limit() const { return limit_; }
     85 
     86   virtual void SetSize(unsigned int width, unsigned int height,
     87                        vpx_img_fmt format) {
     88     if (width != width_ || height != height_ || format != format_) {
     89       vpx_img_free(img_);
     90       img_ = vpx_img_alloc(NULL, format, width, height, 1);
     91       ASSERT_TRUE(img_ != NULL);
     92       width_ = width;
     93       height_ = height;
     94       format_ = format;
     95       switch (format) {
     96         case VPX_IMG_FMT_I420:
     97           raw_size_ = width * height * 3 / 2;
     98           break;
     99         case VPX_IMG_FMT_I422:
    100           raw_size_ = width * height * 2;
    101           break;
    102         case VPX_IMG_FMT_I440:
    103           raw_size_ = width * height * 2;
    104           break;
    105         case VPX_IMG_FMT_I444:
    106           raw_size_ = width * height * 3;
    107           break;
    108         case VPX_IMG_FMT_I42016:
    109           raw_size_ = width * height * 3;
    110           break;
    111         case VPX_IMG_FMT_I42216:
    112           raw_size_ = width * height * 4;
    113           break;
    114         case VPX_IMG_FMT_I44016:
    115           raw_size_ = width * height * 4;
    116           break;
    117         case VPX_IMG_FMT_I44416:
    118           raw_size_ = width * height * 6;
    119           break;
    120         default:
    121           ASSERT_TRUE(0);
    122       }
    123     }
    124   }
    125 
    126   virtual void FillFrame() {
    127     ASSERT_TRUE(input_file_ != NULL);
    128     // Read a frame from input_file.
    129     if (fread(img_->img_data, raw_size_, 1, input_file_) == 0) {
    130       limit_ = frame_;
    131     }
    132   }
    133 
    134  protected:
    135   std::string file_name_;
    136   FILE *input_file_;
    137   vpx_image_t *img_;
    138   size_t raw_size_;
    139   unsigned int start_;
    140   unsigned int limit_;
    141   unsigned int frame_;
    142   unsigned int width_;
    143   unsigned int height_;
    144   vpx_img_fmt format_;
    145   int framerate_numerator_;
    146   int framerate_denominator_;
    147 };
    148 
    149 }  // namespace libvpx_test
    150 
    151 #endif  // TEST_YUV_VIDEO_SOURCE_H_
    152