Yunqing Wang | 15dffcf | 2012-10-04 12:59:36 -0700 | [diff] [blame] | 1 | /* |
Yaowu Xu | 2ab7ff0 | 2016-09-02 12:04:54 -0700 | [diff] [blame] | 2 | * Copyright (c) 2016, Alliance for Open Media. All rights reserved |
Yunqing Wang | 15dffcf | 2012-10-04 12:59:36 -0700 | [diff] [blame] | 3 | * |
Yaowu Xu | 2ab7ff0 | 2016-09-02 12:04:54 -0700 | [diff] [blame] | 4 | * This source code is subject to the terms of the BSD 2 Clause License and |
| 5 | * the Alliance for Open Media Patent License 1.0. If the BSD 2 Clause License |
| 6 | * was not distributed with this source code in the LICENSE file, you can |
| 7 | * obtain it at www.aomedia.org/license/software. If the Alliance for Open |
| 8 | * Media Patent License 1.0 was not distributed with this source code in the |
| 9 | * PATENTS file, you can obtain it at www.aomedia.org/license/patent. |
Yunqing Wang | 15dffcf | 2012-10-04 12:59:36 -0700 | [diff] [blame] | 10 | */ |
| 11 | #ifndef TEST_IVF_VIDEO_SOURCE_H_ |
| 12 | #define TEST_IVF_VIDEO_SOURCE_H_ |
| 13 | #include <cstdio> |
| 14 | #include <cstdlib> |
| 15 | #include <new> |
| 16 | #include <string> |
| 17 | #include "test/video_source.h" |
| 18 | |
Yaowu Xu | c27fc14 | 2016-08-22 16:08:15 -0700 | [diff] [blame] | 19 | namespace libaom_test { |
Yunqing Wang | 15dffcf | 2012-10-04 12:59:36 -0700 | [diff] [blame] | 20 | const unsigned int kCodeBufferSize = 256 * 1024; |
| 21 | const unsigned int kIvfFileHdrSize = 32; |
| 22 | const unsigned int kIvfFrameHdrSize = 12; |
| 23 | |
| 24 | static unsigned int MemGetLe32(const uint8_t *mem) { |
| 25 | return (mem[3] << 24) | (mem[2] << 16) | (mem[1] << 8) | (mem[0]); |
| 26 | } |
| 27 | |
| 28 | // This class extends VideoSource to allow parsing of ivf files, |
| 29 | // so that we can do actual file decodes. |
| 30 | class IVFVideoSource : public CompressedVideoSource { |
| 31 | public: |
Yaowu Xu | afffa3d | 2013-09-05 08:45:56 -0700 | [diff] [blame] | 32 | explicit IVFVideoSource(const std::string &file_name) |
clang-format | 3a826f1 | 2016-08-11 17:46:05 -0700 | [diff] [blame] | 33 | : file_name_(file_name), input_file_(NULL), compressed_frame_buf_(NULL), |
| 34 | frame_sz_(0), frame_(0), end_of_file_(false) {} |
Yunqing Wang | 15dffcf | 2012-10-04 12:59:36 -0700 | [diff] [blame] | 35 | |
| 36 | virtual ~IVFVideoSource() { |
| 37 | delete[] compressed_frame_buf_; |
| 38 | |
clang-format | 3a826f1 | 2016-08-11 17:46:05 -0700 | [diff] [blame] | 39 | if (input_file_) fclose(input_file_); |
Yunqing Wang | 15dffcf | 2012-10-04 12:59:36 -0700 | [diff] [blame] | 40 | } |
| 41 | |
| 42 | virtual void Init() { |
| 43 | // Allocate a buffer for read in the compressed video frame. |
Yaowu Xu | c27fc14 | 2016-08-22 16:08:15 -0700 | [diff] [blame] | 44 | compressed_frame_buf_ = new uint8_t[libaom_test::kCodeBufferSize]; |
James Zern | 104dbbb | 2013-07-18 16:13:39 -0700 | [diff] [blame] | 45 | ASSERT_TRUE(compressed_frame_buf_ != NULL) |
| 46 | << "Allocate frame buffer failed"; |
Yunqing Wang | 15dffcf | 2012-10-04 12:59:36 -0700 | [diff] [blame] | 47 | } |
| 48 | |
| 49 | virtual void Begin() { |
| 50 | input_file_ = OpenTestDataFile(file_name_); |
James Zern | 66c7dff | 2013-06-25 17:55:28 -0700 | [diff] [blame] | 51 | ASSERT_TRUE(input_file_ != NULL) << "Input file open failed. Filename: " |
clang-format | 3a826f1 | 2016-08-11 17:46:05 -0700 | [diff] [blame] | 52 | << file_name_; |
Yunqing Wang | 15dffcf | 2012-10-04 12:59:36 -0700 | [diff] [blame] | 53 | |
| 54 | // Read file header |
| 55 | uint8_t file_hdr[kIvfFileHdrSize]; |
| 56 | ASSERT_EQ(kIvfFileHdrSize, fread(file_hdr, 1, kIvfFileHdrSize, input_file_)) |
| 57 | << "File header read failed."; |
| 58 | // Check file header |
clang-format | 3a826f1 | 2016-08-11 17:46:05 -0700 | [diff] [blame] | 59 | ASSERT_TRUE(file_hdr[0] == 'D' && file_hdr[1] == 'K' && |
| 60 | file_hdr[2] == 'I' && file_hdr[3] == 'F') |
| 61 | << "Input is not an IVF file."; |
Yunqing Wang | 15dffcf | 2012-10-04 12:59:36 -0700 | [diff] [blame] | 62 | |
| 63 | FillFrame(); |
| 64 | } |
| 65 | |
| 66 | virtual void Next() { |
| 67 | ++frame_; |
| 68 | FillFrame(); |
| 69 | } |
| 70 | |
| 71 | void FillFrame() { |
James Zern | 66c7dff | 2013-06-25 17:55:28 -0700 | [diff] [blame] | 72 | ASSERT_TRUE(input_file_ != NULL); |
Yunqing Wang | 15dffcf | 2012-10-04 12:59:36 -0700 | [diff] [blame] | 73 | uint8_t frame_hdr[kIvfFrameHdrSize]; |
| 74 | // Check frame header and read a frame from input_file. |
clang-format | 3a826f1 | 2016-08-11 17:46:05 -0700 | [diff] [blame] | 75 | if (fread(frame_hdr, 1, kIvfFrameHdrSize, input_file_) != |
| 76 | kIvfFrameHdrSize) { |
Yunqing Wang | 15dffcf | 2012-10-04 12:59:36 -0700 | [diff] [blame] | 77 | end_of_file_ = true; |
| 78 | } else { |
| 79 | end_of_file_ = false; |
| 80 | |
| 81 | frame_sz_ = MemGetLe32(frame_hdr); |
| 82 | ASSERT_LE(frame_sz_, kCodeBufferSize) |
| 83 | << "Frame is too big for allocated code buffer"; |
| 84 | ASSERT_EQ(frame_sz_, |
| 85 | fread(compressed_frame_buf_, 1, frame_sz_, input_file_)) |
| 86 | << "Failed to read complete frame"; |
| 87 | } |
| 88 | } |
| 89 | |
| 90 | virtual const uint8_t *cxdata() const { |
| 91 | return end_of_file_ ? NULL : compressed_frame_buf_; |
| 92 | } |
Tom Finegan | eb2325e | 2014-02-19 14:17:55 -0800 | [diff] [blame] | 93 | virtual size_t frame_size() const { return frame_sz_; } |
| 94 | virtual unsigned int frame_number() const { return frame_; } |
Yunqing Wang | 15dffcf | 2012-10-04 12:59:36 -0700 | [diff] [blame] | 95 | |
| 96 | protected: |
| 97 | std::string file_name_; |
| 98 | FILE *input_file_; |
| 99 | uint8_t *compressed_frame_buf_; |
Tom Finegan | eb2325e | 2014-02-19 14:17:55 -0800 | [diff] [blame] | 100 | size_t frame_sz_; |
Yunqing Wang | 15dffcf | 2012-10-04 12:59:36 -0700 | [diff] [blame] | 101 | unsigned int frame_; |
| 102 | bool end_of_file_; |
| 103 | }; |
| 104 | |
Yaowu Xu | c27fc14 | 2016-08-22 16:08:15 -0700 | [diff] [blame] | 105 | } // namespace libaom_test |
Yunqing Wang | 15dffcf | 2012-10-04 12:59:36 -0700 | [diff] [blame] | 106 | |
| 107 | #endif // TEST_IVF_VIDEO_SOURCE_H_ |