/* * Copyright (c) 2014 The WebM project authors. All Rights Reserved. * * Use of this source code is governed by a BSD-style license * that can be found in the LICENSE file in the root of the source * tree. An additional intellectual property rights grant can be found * in the file PATENTS. All contributing project authors may * be found in the AUTHORS file in the root of the source tree. */ #ifndef TEST_YUV_VIDEO_SOURCE_H_ #define TEST_YUV_VIDEO_SOURCE_H_ #include #include #include #include "test/video_source.h" #include "vpx/vpx_image.h" namespace libvpx_test { // This class extends VideoSource to allow parsing of raw YUV // formats of various color sampling and bit-depths so that we can // do actual file encodes. class YUVVideoSource : public VideoSource { public: YUVVideoSource(const std::string &file_name, vpx_img_fmt format, unsigned int width, unsigned int height, int rate_numerator, int rate_denominator, unsigned int start, int limit) : file_name_(file_name), input_file_(NULL), img_(NULL), start_(start), limit_(limit), frame_(0), width_(0), height_(0), format_(VPX_IMG_FMT_NONE), framerate_numerator_(rate_numerator), framerate_denominator_(rate_denominator) { // This initializes format_, raw_size_, width_, height_ and allocates img. SetSize(width, height, format); } virtual ~YUVVideoSource() { vpx_img_free(img_); if (input_file_) fclose(input_file_); } virtual void Begin() { if (input_file_) fclose(input_file_); input_file_ = OpenTestDataFile(file_name_); ASSERT_TRUE(input_file_ != NULL) << "Input file open failed. Filename: " << file_name_; if (start_) fseek(input_file_, static_cast(raw_size_) * start_, SEEK_SET); frame_ = start_; FillFrame(); } virtual void Next() { ++frame_; FillFrame(); } virtual vpx_image_t *img() const { return (frame_ < limit_) ? img_ : NULL; } // Models a stream where Timebase = 1/FPS, so pts == frame. virtual vpx_codec_pts_t pts() const { return frame_; } virtual unsigned long duration() const { return 1; } virtual vpx_rational_t timebase() const { const vpx_rational_t t = { framerate_denominator_, framerate_numerator_ }; return t; } virtual unsigned int frame() const { return frame_; } virtual unsigned int limit() const { return limit_; } virtual void SetSize(unsigned int width, unsigned int height, vpx_img_fmt format) { if (width != width_ || height != height_ || format != format_) { vpx_img_free(img_); img_ = vpx_img_alloc(NULL, format, width, height, 1); ASSERT_TRUE(img_ != NULL); width_ = width; height_ = height; format_ = format; switch (format) { case VPX_IMG_FMT_I420: raw_size_ = width * height * 3 / 2; break; case VPX_IMG_FMT_I422: raw_size_ = width * height * 2; break; case VPX_IMG_FMT_I440: raw_size_ = width * height * 2; break; case VPX_IMG_FMT_I444: raw_size_ = width * height * 3; break; case VPX_IMG_FMT_I42016: raw_size_ = width * height * 3; break; case VPX_IMG_FMT_I42216: raw_size_ = width * height * 4; break; case VPX_IMG_FMT_I44016: raw_size_ = width * height * 4; break; case VPX_IMG_FMT_I44416: raw_size_ = width * height * 6; break; default: ASSERT_TRUE(0); } } } virtual void FillFrame() { ASSERT_TRUE(input_file_ != NULL); // Read a frame from input_file. if (fread(img_->img_data, raw_size_, 1, input_file_) == 0) { limit_ = frame_; } } protected: std::string file_name_; FILE *input_file_; vpx_image_t *img_; size_t raw_size_; unsigned int start_; unsigned int limit_; unsigned int frame_; unsigned int width_; unsigned int height_; vpx_img_fmt format_; int framerate_numerator_; int framerate_denominator_; }; } // namespace libvpx_test #endif // TEST_YUV_VIDEO_SOURCE_H_