1 /*
2  *  Copyright (c) 2018 The WebRTC 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 
11 #include <stdio.h>
12 
13 #include <string>
14 
15 #include "api/scoped_refptr.h"
16 #include "api/video/i420_buffer.h"
17 #include "test/testsupport/file_utils.h"
18 #include "test/testsupport/frame_reader.h"
19 
20 namespace webrtc {
21 namespace test {
22 namespace {
23 
24 // Size of header: "YUV4MPEG2 W50 H20 F30:1 C420\n"
25 const size_t kFileHeaderSize = 29;
26 // Size of header: "FRAME\n"
27 const size_t kFrameHeaderSize = 6;
28 
29 }  // namespace
30 
Y4mFrameReaderImpl(std::string input_filename,int width,int height)31 Y4mFrameReaderImpl::Y4mFrameReaderImpl(std::string input_filename,
32                                        int width,
33                                        int height)
34     : YuvFrameReaderImpl(input_filename, width, height) {
35   frame_length_in_bytes_ += kFrameHeaderSize;
36   buffer_ = new uint8_t[kFileHeaderSize];
37 }
~Y4mFrameReaderImpl()38 Y4mFrameReaderImpl::~Y4mFrameReaderImpl() {
39   delete[] buffer_;
40 }
41 
Init()42 bool Y4mFrameReaderImpl::Init() {
43   if (width_ <= 0 || height_ <= 0) {
44     fprintf(stderr, "Frame width and height must be >0, was %d x %d\n", width_,
45             height_);
46     return false;
47   }
48   input_file_ = fopen(input_filename_.c_str(), "rb");
49   if (input_file_ == nullptr) {
50     fprintf(stderr, "Couldn't open input file for reading: %s\n",
51             input_filename_.c_str());
52     return false;
53   }
54   size_t source_file_size = GetFileSize(input_filename_);
55   if (source_file_size <= 0u) {
56     fprintf(stderr, "Found empty file: %s\n", input_filename_.c_str());
57     return false;
58   }
59   if (fread(buffer_, 1, kFileHeaderSize, input_file_) < kFileHeaderSize) {
60     fprintf(stderr, "Failed to read file header from input file: %s\n",
61             input_filename_.c_str());
62     return false;
63   }
64   // Calculate total number of frames.
65   number_of_frames_ = static_cast<int>((source_file_size - kFileHeaderSize) /
66                                        frame_length_in_bytes_);
67   return true;
68 }
69 
ReadFrame()70 rtc::scoped_refptr<I420Buffer> Y4mFrameReaderImpl::ReadFrame() {
71   if (input_file_ == nullptr) {
72     fprintf(stderr,
73             "Y4mFrameReaderImpl is not initialized (input file is NULL)\n");
74     return nullptr;
75   }
76   if (fread(buffer_, 1, kFrameHeaderSize, input_file_) < kFrameHeaderSize &&
77       ferror(input_file_)) {
78     fprintf(stderr, "Failed to read frame header from input file: %s\n",
79             input_filename_.c_str());
80     return nullptr;
81   }
82   return YuvFrameReaderImpl::ReadFrame();
83 }
84 
85 }  // namespace test
86 }  // namespace webrtc
87