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