blob: b7eada90ed5eb290c9a073f2a0a067c2680c42f8 [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.org131bea82015-02-18 12:46:06 +000072 ReadNextFrame();
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.org131bea82015-02-18 12:46:06 +000081 if (frame_display_count_ > 0) {
82 if (current_display_count_ < frame_display_count_) {
83 ++current_display_count_;
84 } else {
85 ReadNextFrame();
86 current_display_count_ = 0;
87 }
andresp@webrtc.orgab654952013-09-19 12:14:03 +000088 }
89
sprang@webrtc.org131bea82015-02-18 12:46:06 +000090 current_frame_.CopyFrame(last_read_frame_);
91 return &current_frame_;
92 }
pbos@webrtc.org724947b2013-12-11 16:26:16 +000093
sprang@webrtc.org131bea82015-02-18 12:46:06 +000094 void ReadNextFrame() {
95 size_t bytes_read =
96 fread(frame_buffer_.get(), 1, frame_size_, files_[file_index_]);
97 if (bytes_read < frame_size_) {
98 // No more frames to read in this file, rewind and move to next file.
99 rewind(files_[file_index_]);
100 file_index_ = (file_index_ + 1) % files_.size();
101 bytes_read = fread(frame_buffer_.get(), 1, frame_size_,
102 files_[file_index_]);
103 assert(bytes_read >= frame_size_);
104 }
105
106 last_read_frame_.CreateEmptyFrame(
107 static_cast<int>(width_), static_cast<int>(height_),
108 static_cast<int>(width_), static_cast<int>((width_ + 1) / 2),
109 static_cast<int>((width_ + 1) / 2));
110
111 ConvertToI420(kI420, frame_buffer_.get(), 0, 0, static_cast<int>(width_),
112 static_cast<int>(height_), 0, kRotateNone, &last_read_frame_);
andresp@webrtc.orgab654952013-09-19 12:14:03 +0000113 }
114
115 private:
sprang@webrtc.org131bea82015-02-18 12:46:06 +0000116 size_t file_index_;
117 const std::vector<FILE*> files_;
118 const size_t width_;
119 const size_t height_;
120 const size_t frame_size_;
121 const scoped_ptr<uint8_t[]> frame_buffer_;
122 const int frame_display_count_;
123 int current_display_count_;
124 I420VideoFrame current_frame_;
125 I420VideoFrame last_read_frame_;
andresp@webrtc.orgab654952013-09-19 12:14:03 +0000126};
127} // namespace
128
sprang@webrtc.org131bea82015-02-18 12:46:06 +0000129FrameGenerator* FrameGenerator::CreateChromaGenerator(size_t width,
130 size_t height) {
pbos@webrtc.org266c7b32013-10-15 09:15:47 +0000131 return new ChromaGenerator(width, height);
132}
133
sprang@webrtc.org131bea82015-02-18 12:46:06 +0000134FrameGenerator* FrameGenerator::CreateFromYuvFile(
135 std::vector<std::string> filenames,
136 size_t width,
137 size_t height,
138 int frame_repeat_count) {
139 assert(!filenames.empty());
140 std::vector<FILE*> files;
141 for (const std::string& filename : filenames) {
142 FILE* file = fopen(filename.c_str(), "rb");
143 DCHECK(file != nullptr);
144 files.push_back(file);
145 }
146
147 return new YuvFileGenerator(files, width, height, frame_repeat_count);
andresp@webrtc.orgab654952013-09-19 12:14:03 +0000148}
149
150} // namespace test
151} // namespace webrtc