blob: fe6b1b1a0521760ccb04fee8110499645cedbda4 [file] [log] [blame]
andresp@webrtc.orgab654952013-09-19 12:14:03 +00001/*
2 * Copyright (c) 2013 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 */
pbos@webrtc.org724947b2013-12-11 16:26:16 +000010#include "webrtc/test/frame_generator.h"
andresp@webrtc.orgab654952013-09-19 12:14:03 +000011
pbos@webrtc.org266c7b32013-10-15 09:15:47 +000012#include <math.h>
andresp@webrtc.orgab654952013-09-19 12:14:03 +000013#include <stdio.h>
pbos@webrtc.org266c7b32013-10-15 09:15:47 +000014#include <string.h>
andresp@webrtc.orgab654952013-09-19 12:14:03 +000015
sprang@webrtc.org131bea82015-02-18 12:46:06 +000016#include "webrtc/base/checks.h"
andresp@webrtc.orgab654952013-09-19 12:14:03 +000017#include "webrtc/common_video/libyuv/include/webrtc_libyuv.h"
18
19namespace webrtc {
20namespace test {
21namespace {
22
pbos@webrtc.org266c7b32013-10-15 09:15:47 +000023class ChromaGenerator : public FrameGenerator {
24 public:
pbos@webrtc.org724947b2013-12-11 16:26:16 +000025 ChromaGenerator(size_t width, size_t height)
26 : angle_(0.0), width_(width), height_(height) {
pbos@webrtc.org266c7b32013-10-15 09:15:47 +000027 assert(width > 0);
28 assert(height > 0);
pbos@webrtc.org266c7b32013-10-15 09:15:47 +000029 }
30
pbos@webrtc.org724947b2013-12-11 16:26:16 +000031 virtual I420VideoFrame* NextFrame() OVERRIDE {
32 frame_.CreateEmptyFrame(static_cast<int>(width_),
33 static_cast<int>(height_),
34 static_cast<int>(width_),
35 static_cast<int>((width_ + 1) / 2),
36 static_cast<int>((width_ + 1) / 2));
pbos@webrtc.org266c7b32013-10-15 09:15:47 +000037 angle_ += 30.0;
38 uint8_t u = fabs(sin(angle_)) * 0xFF;
39 uint8_t v = fabs(cos(angle_)) * 0xFF;
40
pbos@webrtc.org724947b2013-12-11 16:26:16 +000041 memset(frame_.buffer(kYPlane), 0x80, frame_.allocated_size(kYPlane));
pbos@webrtc.org266c7b32013-10-15 09:15:47 +000042 memset(frame_.buffer(kUPlane), u, frame_.allocated_size(kUPlane));
43 memset(frame_.buffer(kVPlane), v, frame_.allocated_size(kVPlane));
pbos@webrtc.org724947b2013-12-11 16:26:16 +000044 return &frame_;
pbos@webrtc.org266c7b32013-10-15 09:15:47 +000045 }
46
47 private:
48 double angle_;
pbos@webrtc.org724947b2013-12-11 16:26:16 +000049 size_t width_;
50 size_t height_;
pbos@webrtc.org266c7b32013-10-15 09:15:47 +000051 I420VideoFrame frame_;
52};
53
andresp@webrtc.orgab654952013-09-19 12:14:03 +000054class YuvFileGenerator : public FrameGenerator {
55 public:
sprang@webrtc.org131bea82015-02-18 12:46:06 +000056 YuvFileGenerator(std::vector<FILE*> files,
57 size_t width,
58 size_t height,
59 int frame_repeat_count)
60 : file_index_(0),
61 files_(files),
62 width_(width),
63 height_(height),
64 frame_size_(CalcBufferSize(kI420,
65 static_cast<int>(width_),
66 static_cast<int>(height_))),
67 frame_buffer_(new uint8_t[frame_size_]),
68 frame_display_count_(frame_repeat_count),
69 current_display_count_(0) {
andresp@webrtc.orgab654952013-09-19 12:14:03 +000070 assert(width > 0);
71 assert(height > 0);
sprang@webrtc.org25dd1db2015-03-02 11:55:45 +000072 assert(frame_repeat_count > 0);
andresp@webrtc.orgab654952013-09-19 12:14:03 +000073 }
74
75 virtual ~YuvFileGenerator() {
sprang@webrtc.org131bea82015-02-18 12:46:06 +000076 for (FILE* file : files_)
77 fclose(file);
andresp@webrtc.orgab654952013-09-19 12:14:03 +000078 }
79
pbos@webrtc.org724947b2013-12-11 16:26:16 +000080 virtual I420VideoFrame* NextFrame() OVERRIDE {
sprang@webrtc.org25dd1db2015-03-02 11:55:45 +000081 if (current_display_count_ == 0)
82 ReadNextFrame();
83 if (++current_display_count_ >= frame_display_count_)
84 current_display_count_ = 0;
andresp@webrtc.orgab654952013-09-19 12:14:03 +000085
sprang@webrtc.org25dd1db2015-03-02 11:55:45 +000086 // If this is the last repeatition of this frame, it's OK to use the
87 // original instance, otherwise use a copy.
88 if (current_display_count_ == frame_display_count_)
89 return &last_read_frame_;
90
91 temp_frame_copy_.CopyFrame(last_read_frame_);
92 return &temp_frame_copy_;
sprang@webrtc.org131bea82015-02-18 12:46:06 +000093 }
pbos@webrtc.org724947b2013-12-11 16:26:16 +000094
sprang@webrtc.org131bea82015-02-18 12:46:06 +000095 void ReadNextFrame() {
96 size_t bytes_read =
97 fread(frame_buffer_.get(), 1, frame_size_, files_[file_index_]);
98 if (bytes_read < frame_size_) {
99 // No more frames to read in this file, rewind and move to next file.
100 rewind(files_[file_index_]);
101 file_index_ = (file_index_ + 1) % files_.size();
102 bytes_read = fread(frame_buffer_.get(), 1, frame_size_,
103 files_[file_index_]);
104 assert(bytes_read >= frame_size_);
105 }
106
107 last_read_frame_.CreateEmptyFrame(
108 static_cast<int>(width_), static_cast<int>(height_),
109 static_cast<int>(width_), static_cast<int>((width_ + 1) / 2),
110 static_cast<int>((width_ + 1) / 2));
111
112 ConvertToI420(kI420, frame_buffer_.get(), 0, 0, static_cast<int>(width_),
113 static_cast<int>(height_), 0, kRotateNone, &last_read_frame_);
andresp@webrtc.orgab654952013-09-19 12:14:03 +0000114 }
115
116 private:
sprang@webrtc.org131bea82015-02-18 12:46:06 +0000117 size_t file_index_;
118 const std::vector<FILE*> files_;
119 const size_t width_;
120 const size_t height_;
121 const size_t frame_size_;
kwiberg@webrtc.org00b8f6b2015-02-26 14:34:55 +0000122 const rtc::scoped_ptr<uint8_t[]> frame_buffer_;
sprang@webrtc.org131bea82015-02-18 12:46:06 +0000123 const int frame_display_count_;
124 int current_display_count_;
sprang@webrtc.org131bea82015-02-18 12:46:06 +0000125 I420VideoFrame last_read_frame_;
sprang@webrtc.org25dd1db2015-03-02 11:55:45 +0000126 I420VideoFrame temp_frame_copy_;
andresp@webrtc.orgab654952013-09-19 12:14:03 +0000127};
128} // namespace
129
sprang@webrtc.org131bea82015-02-18 12:46:06 +0000130FrameGenerator* FrameGenerator::CreateChromaGenerator(size_t width,
131 size_t height) {
pbos@webrtc.org266c7b32013-10-15 09:15:47 +0000132 return new ChromaGenerator(width, height);
133}
134
sprang@webrtc.org131bea82015-02-18 12:46:06 +0000135FrameGenerator* FrameGenerator::CreateFromYuvFile(
136 std::vector<std::string> filenames,
137 size_t width,
138 size_t height,
139 int frame_repeat_count) {
140 assert(!filenames.empty());
141 std::vector<FILE*> files;
142 for (const std::string& filename : filenames) {
143 FILE* file = fopen(filename.c_str(), "rb");
144 DCHECK(file != nullptr);
145 files.push_back(file);
146 }
147
148 return new YuvFileGenerator(files, width, height, frame_repeat_count);
andresp@webrtc.orgab654952013-09-19 12:14:03 +0000149}
150
151} // namespace test
152} // namespace webrtc