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