1ed759d81a39febed3a8a395386639d54307504aagrunell@chromium.org/*
2ed759d81a39febed3a8a395386639d54307504aagrunell@chromium.org *  Copyright (c) 2012 The WebM project authors. All Rights Reserved.
3ed759d81a39febed3a8a395386639d54307504aagrunell@chromium.org *
4ed759d81a39febed3a8a395386639d54307504aagrunell@chromium.org *  Use of this source code is governed by a BSD-style license
5ed759d81a39febed3a8a395386639d54307504aagrunell@chromium.org *  that can be found in the LICENSE file in the root of the source
6ed759d81a39febed3a8a395386639d54307504aagrunell@chromium.org *  tree. An additional intellectual property rights grant can be found
7ed759d81a39febed3a8a395386639d54307504aagrunell@chromium.org *  in the file PATENTS.  All contributing project authors may
8ed759d81a39febed3a8a395386639d54307504aagrunell@chromium.org *  be found in the AUTHORS file in the root of the source tree.
9ed759d81a39febed3a8a395386639d54307504aagrunell@chromium.org */
10ed759d81a39febed3a8a395386639d54307504aagrunell@chromium.org#ifndef TEST_I420_VIDEO_SOURCE_H_
11ed759d81a39febed3a8a395386639d54307504aagrunell@chromium.org#define TEST_I420_VIDEO_SOURCE_H_
12ed759d81a39febed3a8a395386639d54307504aagrunell@chromium.org#include <cstdio>
13ed759d81a39febed3a8a395386639d54307504aagrunell@chromium.org#include <cstdlib>
14f9586bb54d74c97d07b09eb2512f8569c9c1c025fgalligan@chromium.org#include <string>
15ed759d81a39febed3a8a395386639d54307504aagrunell@chromium.org
16ed759d81a39febed3a8a395386639d54307504aagrunell@chromium.org#include "test/video_source.h"
17ed759d81a39febed3a8a395386639d54307504aagrunell@chromium.org
18ed759d81a39febed3a8a395386639d54307504aagrunell@chromium.orgnamespace libvpx_test {
19ed759d81a39febed3a8a395386639d54307504aagrunell@chromium.org
20ed759d81a39febed3a8a395386639d54307504aagrunell@chromium.org// This class extends VideoSource to allow parsing of raw yv12
21ed759d81a39febed3a8a395386639d54307504aagrunell@chromium.org// so that we can do actual file encodes.
22ed759d81a39febed3a8a395386639d54307504aagrunell@chromium.orgclass I420VideoSource : public VideoSource {
23ed759d81a39febed3a8a395386639d54307504aagrunell@chromium.org public:
24ed759d81a39febed3a8a395386639d54307504aagrunell@chromium.org  I420VideoSource(const std::string &file_name,
25ed759d81a39febed3a8a395386639d54307504aagrunell@chromium.org                  unsigned int width, unsigned int height,
26ed759d81a39febed3a8a395386639d54307504aagrunell@chromium.org                  int rate_numerator, int rate_denominator,
27ed759d81a39febed3a8a395386639d54307504aagrunell@chromium.org                  unsigned int start, int limit)
28ed759d81a39febed3a8a395386639d54307504aagrunell@chromium.org      : file_name_(file_name),
29ed759d81a39febed3a8a395386639d54307504aagrunell@chromium.org        input_file_(NULL),
30ed759d81a39febed3a8a395386639d54307504aagrunell@chromium.org        img_(NULL),
31ed759d81a39febed3a8a395386639d54307504aagrunell@chromium.org        start_(start),
32ed759d81a39febed3a8a395386639d54307504aagrunell@chromium.org        limit_(limit),
33ed759d81a39febed3a8a395386639d54307504aagrunell@chromium.org        frame_(0),
34ed759d81a39febed3a8a395386639d54307504aagrunell@chromium.org        width_(0),
35ed759d81a39febed3a8a395386639d54307504aagrunell@chromium.org        height_(0),
36ed759d81a39febed3a8a395386639d54307504aagrunell@chromium.org        framerate_numerator_(rate_numerator),
37ed759d81a39febed3a8a395386639d54307504aagrunell@chromium.org        framerate_denominator_(rate_denominator) {
38ed759d81a39febed3a8a395386639d54307504aagrunell@chromium.org    // This initializes raw_sz_, width_, height_ and allocates an img.
39ed759d81a39febed3a8a395386639d54307504aagrunell@chromium.org    SetSize(width, height);
40ed759d81a39febed3a8a395386639d54307504aagrunell@chromium.org  }
41ed759d81a39febed3a8a395386639d54307504aagrunell@chromium.org
42ed759d81a39febed3a8a395386639d54307504aagrunell@chromium.org  virtual ~I420VideoSource() {
43ed759d81a39febed3a8a395386639d54307504aagrunell@chromium.org    vpx_img_free(img_);
44ed759d81a39febed3a8a395386639d54307504aagrunell@chromium.org    if (input_file_)
45ed759d81a39febed3a8a395386639d54307504aagrunell@chromium.org      fclose(input_file_);
46ed759d81a39febed3a8a395386639d54307504aagrunell@chromium.org  }
47ed759d81a39febed3a8a395386639d54307504aagrunell@chromium.org
48ed759d81a39febed3a8a395386639d54307504aagrunell@chromium.org  virtual void Begin() {
49ed759d81a39febed3a8a395386639d54307504aagrunell@chromium.org    if (input_file_)
50ed759d81a39febed3a8a395386639d54307504aagrunell@chromium.org      fclose(input_file_);
51ed759d81a39febed3a8a395386639d54307504aagrunell@chromium.org    input_file_ = OpenTestDataFile(file_name_);
5247265f8fe3a36a426773454ad90d20c9aa616c24johannkoenig@chromium.org    ASSERT_TRUE(input_file_ != NULL) << "Input file open failed. Filename: "
53ed759d81a39febed3a8a395386639d54307504aagrunell@chromium.org        << file_name_;
54ed759d81a39febed3a8a395386639d54307504aagrunell@chromium.org    if (start_) {
5576e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.org      fseek(input_file_, static_cast<unsigned>(raw_sz_) * start_, SEEK_SET);
56ed759d81a39febed3a8a395386639d54307504aagrunell@chromium.org    }
57ed759d81a39febed3a8a395386639d54307504aagrunell@chromium.org
58ed759d81a39febed3a8a395386639d54307504aagrunell@chromium.org    frame_ = start_;
59ed759d81a39febed3a8a395386639d54307504aagrunell@chromium.org    FillFrame();
60ed759d81a39febed3a8a395386639d54307504aagrunell@chromium.org  }
61ed759d81a39febed3a8a395386639d54307504aagrunell@chromium.org
62ed759d81a39febed3a8a395386639d54307504aagrunell@chromium.org  virtual void Next() {
63ed759d81a39febed3a8a395386639d54307504aagrunell@chromium.org    ++frame_;
64ed759d81a39febed3a8a395386639d54307504aagrunell@chromium.org    FillFrame();
65ed759d81a39febed3a8a395386639d54307504aagrunell@chromium.org  }
66ed759d81a39febed3a8a395386639d54307504aagrunell@chromium.org
67ed759d81a39febed3a8a395386639d54307504aagrunell@chromium.org  virtual vpx_image_t *img() const { return (frame_ < limit_) ? img_ : NULL;  }
68ed759d81a39febed3a8a395386639d54307504aagrunell@chromium.org
69ed759d81a39febed3a8a395386639d54307504aagrunell@chromium.org  // Models a stream where Timebase = 1/FPS, so pts == frame.
70ed759d81a39febed3a8a395386639d54307504aagrunell@chromium.org  virtual vpx_codec_pts_t pts() const { return frame_; }
71ed759d81a39febed3a8a395386639d54307504aagrunell@chromium.org
72ed759d81a39febed3a8a395386639d54307504aagrunell@chromium.org  virtual unsigned long duration() const { return 1; }
73ed759d81a39febed3a8a395386639d54307504aagrunell@chromium.org
74ed759d81a39febed3a8a395386639d54307504aagrunell@chromium.org  virtual vpx_rational_t timebase() const {
75ed759d81a39febed3a8a395386639d54307504aagrunell@chromium.org    const vpx_rational_t t = { framerate_denominator_, framerate_numerator_ };
76ed759d81a39febed3a8a395386639d54307504aagrunell@chromium.org    return t;
77ed759d81a39febed3a8a395386639d54307504aagrunell@chromium.org  }
78ed759d81a39febed3a8a395386639d54307504aagrunell@chromium.org
79ed759d81a39febed3a8a395386639d54307504aagrunell@chromium.org  virtual unsigned int frame() const { return frame_; }
80ed759d81a39febed3a8a395386639d54307504aagrunell@chromium.org
81ed759d81a39febed3a8a395386639d54307504aagrunell@chromium.org  virtual unsigned int limit() const { return limit_; }
82ed759d81a39febed3a8a395386639d54307504aagrunell@chromium.org
83ed759d81a39febed3a8a395386639d54307504aagrunell@chromium.org  void SetSize(unsigned int width, unsigned int height) {
84ed759d81a39febed3a8a395386639d54307504aagrunell@chromium.org    if (width != width_ || height != height_) {
85ed759d81a39febed3a8a395386639d54307504aagrunell@chromium.org      vpx_img_free(img_);
8610a9a0d835561a7f2300c561c514efcf374554d6fgalligan@chromium.org      img_ = vpx_img_alloc(NULL, VPX_IMG_FMT_I420, width, height, 1);
87ed759d81a39febed3a8a395386639d54307504aagrunell@chromium.org      ASSERT_TRUE(img_ != NULL);
88ed759d81a39febed3a8a395386639d54307504aagrunell@chromium.org      width_ = width;
89ed759d81a39febed3a8a395386639d54307504aagrunell@chromium.org      height_ = height;
90ed759d81a39febed3a8a395386639d54307504aagrunell@chromium.org      raw_sz_ = width * height * 3 / 2;
91ed759d81a39febed3a8a395386639d54307504aagrunell@chromium.org    }
92ed759d81a39febed3a8a395386639d54307504aagrunell@chromium.org  }
93ed759d81a39febed3a8a395386639d54307504aagrunell@chromium.org
94ed759d81a39febed3a8a395386639d54307504aagrunell@chromium.org  virtual void FillFrame() {
9547265f8fe3a36a426773454ad90d20c9aa616c24johannkoenig@chromium.org    ASSERT_TRUE(input_file_ != NULL);
96ed759d81a39febed3a8a395386639d54307504aagrunell@chromium.org    // Read a frame from input_file.
97ed759d81a39febed3a8a395386639d54307504aagrunell@chromium.org    if (fread(img_->img_data, raw_sz_, 1, input_file_) == 0) {
98ed759d81a39febed3a8a395386639d54307504aagrunell@chromium.org      limit_ = frame_;
99ed759d81a39febed3a8a395386639d54307504aagrunell@chromium.org    }
100ed759d81a39febed3a8a395386639d54307504aagrunell@chromium.org  }
101ed759d81a39febed3a8a395386639d54307504aagrunell@chromium.org
102ed759d81a39febed3a8a395386639d54307504aagrunell@chromium.org protected:
103ed759d81a39febed3a8a395386639d54307504aagrunell@chromium.org  std::string file_name_;
104ed759d81a39febed3a8a395386639d54307504aagrunell@chromium.org  FILE *input_file_;
105ed759d81a39febed3a8a395386639d54307504aagrunell@chromium.org  vpx_image_t *img_;
106ed759d81a39febed3a8a395386639d54307504aagrunell@chromium.org  size_t raw_sz_;
107ed759d81a39febed3a8a395386639d54307504aagrunell@chromium.org  unsigned int start_;
108ed759d81a39febed3a8a395386639d54307504aagrunell@chromium.org  unsigned int limit_;
109ed759d81a39febed3a8a395386639d54307504aagrunell@chromium.org  unsigned int frame_;
110ed759d81a39febed3a8a395386639d54307504aagrunell@chromium.org  unsigned int width_;
111ed759d81a39febed3a8a395386639d54307504aagrunell@chromium.org  unsigned int height_;
11247265f8fe3a36a426773454ad90d20c9aa616c24johannkoenig@chromium.org  int framerate_numerator_;
11347265f8fe3a36a426773454ad90d20c9aa616c24johannkoenig@chromium.org  int framerate_denominator_;
114ed759d81a39febed3a8a395386639d54307504aagrunell@chromium.org};
115ed759d81a39febed3a8a395386639d54307504aagrunell@chromium.org
116ed759d81a39febed3a8a395386639d54307504aagrunell@chromium.org}  // namespace libvpx_test
117ed759d81a39febed3a8a395386639d54307504aagrunell@chromium.org
118ed759d81a39febed3a8a395386639d54307504aagrunell@chromium.org#endif  // TEST_I420_VIDEO_SOURCE_H_
119