Upstream version 9.38.198.0
[platform/framework/web/crosswalk.git] / src / third_party / libvpx / source / libvpx / test / video_source.h
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_VIDEO_SOURCE_H_
11 #define TEST_VIDEO_SOURCE_H_
12
13 #if defined(_WIN32)
14 #include <windows.h>
15 #endif
16 #include <cstdio>
17 #include <cstdlib>
18 #include <string>
19 #include "test/acm_random.h"
20 #include "vpx/vpx_encoder.h"
21
22 namespace libvpx_test {
23
24 // Helper macros to ensure LIBVPX_TEST_DATA_PATH is a quoted string.
25 // These are undefined right below GetDataPath
26 // NOTE: LIBVPX_TEST_DATA_PATH MUST NOT be a quoted string before
27 // Stringification or the GetDataPath will fail at runtime
28 #define TO_STRING(S) #S
29 #define STRINGIFY(S) TO_STRING(S)
30
31 // A simple function to encapsulate cross platform retrieval of test data path
32 static std::string GetDataPath() {
33   const char *const data_path = getenv("LIBVPX_TEST_DATA_PATH");
34   if (data_path == NULL) {
35 #ifdef LIBVPX_TEST_DATA_PATH
36     // In some environments, we cannot set environment variables
37     // Instead, we set the data path by using a preprocessor symbol
38     // which can be set from make files
39     return STRINGIFY(LIBVPX_TEST_DATA_PATH);
40 #else
41     return ".";
42 #endif
43   }
44   return data_path;
45 }
46
47 // Undefining stringification macros because they are not used elsewhere
48 #undef TO_STRING
49 #undef STRINGIFY
50
51 static FILE *OpenTestDataFile(const std::string& file_name) {
52   const std::string path_to_source = GetDataPath() + "/" + file_name;
53   return fopen(path_to_source.c_str(), "rb");
54 }
55
56 static FILE *OpenTestOutFile(const std::string& file_name) {
57   const std::string path_to_source = GetDataPath() + "/" + file_name;
58   return fopen(path_to_source.c_str(), "wb");
59 }
60
61 static std::string GetTempOutFilename() {
62   std::string basename;
63 #if defined(_WIN32)
64   char fname[MAX_PATH];
65   // Assume for now that the filename generated is unique per process
66   const UINT ret = GetTempFileNameA(
67       GetDataPath().c_str(), "lvx", 0, fname);
68   if (ret != 0) {
69     const char *slash = strrchr(fname, '\\');
70     if (slash == NULL) slash = strrchr(fname, '/');
71     if (slash == NULL)
72       basename.assign(fname);
73     else
74       basename.assign(slash + 1);
75   } else {
76     basename.clear();
77   }
78 #else
79   char fname[256];
80   const std::string templ = GetDataPath() + "/libvpx_test_XXXXXX";
81   strncpy(fname, templ.c_str(), templ.size());
82   fname[templ.size()] = '\0';
83   const int fd = mkstemp(fname);
84   if (fd != -1) {
85     close(fd);
86     basename.assign(strrchr(fname, '/') + 1);
87   } else {
88     basename.clear();
89   }
90 #endif
91   return basename;
92 }
93
94 class TempOutFile {
95  public:
96   TempOutFile() {
97     file_name_ = GetTempOutFilename();
98     file_ = OpenTestOutFile(file_name_);
99   }
100   ~TempOutFile() {
101     CloseFile();
102     if (!file_name_.empty()) {
103       const std::string path_to_source = GetDataPath() + "/" + file_name_;
104       EXPECT_EQ(0, remove(path_to_source.c_str()));
105     }
106   }
107   FILE *file() {
108     return file_;
109   }
110   const std::string& file_name() {
111     return file_name_;
112   }
113   void CloseFile() {
114     if (file_) {
115       fclose(file_);
116       file_ = NULL;
117     }
118   }
119
120  protected:
121   FILE *file_;
122   std::string file_name_;
123 };
124
125 // Abstract base class for test video sources, which provide a stream of
126 // vpx_image_t images with associated timestamps and duration.
127 class VideoSource {
128  public:
129   virtual ~VideoSource() {}
130
131   // Prepare the stream for reading, rewind/open as necessary.
132   virtual void Begin() = 0;
133
134   // Advance the cursor to the next frame
135   virtual void Next() = 0;
136
137   // Get the current video frame, or NULL on End-Of-Stream.
138   virtual vpx_image_t *img() const = 0;
139
140   // Get the presentation timestamp of the current frame.
141   virtual vpx_codec_pts_t pts() const = 0;
142
143   // Get the current frame's duration
144   virtual unsigned long duration() const = 0;
145
146   // Get the timebase for the stream
147   virtual vpx_rational_t timebase() const = 0;
148
149   // Get the current frame counter, starting at 0.
150   virtual unsigned int frame() const = 0;
151
152   // Get the current file limit.
153   virtual unsigned int limit() const = 0;
154 };
155
156
157 class DummyVideoSource : public VideoSource {
158  public:
159   DummyVideoSource() : img_(NULL), limit_(100), width_(0), height_(0) {
160     SetSize(80, 64);
161   }
162
163   virtual ~DummyVideoSource() { vpx_img_free(img_); }
164
165   virtual void Begin() {
166     frame_ = 0;
167     FillFrame();
168   }
169
170   virtual void Next() {
171     ++frame_;
172     FillFrame();
173   }
174
175   virtual vpx_image_t *img() const {
176     return (frame_ < limit_) ? img_ : NULL;
177   }
178
179   // Models a stream where Timebase = 1/FPS, so pts == frame.
180   virtual vpx_codec_pts_t pts() const { return frame_; }
181
182   virtual unsigned long duration() const { return 1; }
183
184   virtual vpx_rational_t timebase() const {
185     const vpx_rational_t t = {1, 30};
186     return t;
187   }
188
189   virtual unsigned int frame() const { return frame_; }
190
191   virtual unsigned int limit() const { return limit_; }
192
193   void set_limit(unsigned int limit) {
194     limit_ = limit;
195   }
196
197   void SetSize(unsigned int width, unsigned int height) {
198     if (width != width_ || height != height_) {
199       vpx_img_free(img_);
200       raw_sz_ = ((width + 31)&~31) * height * 3 / 2;
201       img_ = vpx_img_alloc(NULL, VPX_IMG_FMT_I420, width, height, 32);
202       width_ = width;
203       height_ = height;
204     }
205   }
206
207  protected:
208   virtual void FillFrame() { if (img_) memset(img_->img_data, 0, raw_sz_); }
209
210   vpx_image_t *img_;
211   size_t       raw_sz_;
212   unsigned int limit_;
213   unsigned int frame_;
214   unsigned int width_;
215   unsigned int height_;
216 };
217
218
219 class RandomVideoSource : public DummyVideoSource {
220  public:
221   RandomVideoSource(int seed = ACMRandom::DeterministicSeed())
222       : rnd_(seed),
223         seed_(seed) { }
224
225  protected:
226   // Reset the RNG to get a matching stream for the second pass
227   virtual void Begin() {
228     frame_ = 0;
229     rnd_.Reset(seed_);
230     FillFrame();
231   }
232
233   // 15 frames of noise, followed by 15 static frames. Reset to 0 rather
234   // than holding previous frames to encourage keyframes to be thrown.
235   virtual void FillFrame() {
236     if (img_) {
237       if (frame_ % 30 < 15)
238         for (size_t i = 0; i < raw_sz_; ++i)
239           img_->img_data[i] = rnd_.Rand8();
240       else
241         memset(img_->img_data, 0, raw_sz_);
242     }
243   }
244
245   ACMRandom rnd_;
246   int seed_;
247 };
248
249 // Abstract base class for test video sources, which provide a stream of
250 // decompressed images to the decoder.
251 class CompressedVideoSource {
252  public:
253   virtual ~CompressedVideoSource() {}
254
255   virtual void Init() = 0;
256
257   // Prepare the stream for reading, rewind/open as necessary.
258   virtual void Begin() = 0;
259
260   // Advance the cursor to the next frame
261   virtual void Next() = 0;
262
263   virtual const uint8_t *cxdata() const = 0;
264
265   virtual size_t frame_size() const = 0;
266
267   virtual unsigned int frame_number() const = 0;
268 };
269
270 }  // namespace libvpx_test
271
272 #endif  // TEST_VIDEO_SOURCE_H_