summaryrefslogtreecommitdiff
path: root/test/video_source.h
blob: 3507ef0cd6e86d9c64245916c9907fa7af30ba81 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
/*
 *  Copyright (c) 2012 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_VIDEO_SOURCE_H_
#define TEST_VIDEO_SOURCE_H_
#include "vpx/vpx_encoder.h"

namespace libvpx_test {

// Abstract base class for test video sources, which provide a stream of
// vpx_image_t images with associated timestamps and duration.
class VideoSource {
 public:
  virtual ~VideoSource() {}

  // Prepare the stream for reading, rewind/open as necessary.
  virtual void Begin() = 0;

  // Advance the cursor to the next frame
  virtual void Next() = 0;

  // Get the current video frame, or NULL on End-Of-Stream.
  virtual vpx_image_t *img() const = 0;

  // Get the presentation timestamp of the current frame.
  virtual vpx_codec_pts_t pts() const = 0;

  // Get the current frame's duration
  virtual unsigned long duration() const = 0;

  // Get the timebase for the stream
  virtual vpx_rational_t timebase() const = 0;

  // Get the current frame counter, starting at 0.
  virtual unsigned int frame() const = 0;
};


class DummyVideoSource : public VideoSource {
 public:
  DummyVideoSource() : img_(NULL), limit_(100), width_(0), height_(0) {
    SetSize(80, 64);
  }

  virtual ~DummyVideoSource() { vpx_img_free(img_); }

  virtual void Begin() {
    frame_ = 0;
    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 = {1, 30};
    return t;
  }

  virtual unsigned int frame() const { return frame_; }

  void SetSize(unsigned int width, unsigned int height) {
    if (width != width_ || height != height_) {
      vpx_img_free(img_);
      raw_sz_ = ((width + 31)&~31) * height * 3 / 2;
      img_ = vpx_img_alloc(NULL, VPX_IMG_FMT_VPXI420, width, height, 32);
      width_ = width;
      height_ = height;
    }
  }

 protected:
  virtual void FillFrame() { memset(img_->img_data, 0, raw_sz_); }

  vpx_image_t *img_;
  size_t       raw_sz_;
  unsigned int limit_;
  unsigned int frame_;
  unsigned int width_;
  unsigned int height_;
};


class RandomVideoSource : public DummyVideoSource {
 protected:
  // 15 frames of noise, followed by 15 static frames. Reset to 0 rather
  // than holding previous frames to encourage keyframes to be thrown.
  virtual void FillFrame() {
    if (frame_ % 30 < 15)
      for (size_t i = 0; i < raw_sz_; ++i)
        img_->img_data[i] = rand();
    else
      memset(img_->img_data, 0, raw_sz_);
  }
};

}  // namespace libvpx_test

#endif  // TEST_VIDEO_SOURCE_H_