1818#include " webrtc/base/checks.h"
1919#include " webrtc/common_video/libyuv/include/webrtc_libyuv.h"
2020#include " webrtc/system_wrappers/include/clock.h"
21+ #include " libyuv/convert.h"
2122
2223namespace webrtc {
2324namespace test {
@@ -27,34 +28,40 @@ class ChromaGenerator : public FrameGenerator {
2728 public:
2829 ChromaGenerator (size_t width, size_t height)
2930 : angle_(0.0 ), width_(width), height_(height) {
30- assert (width > 0 );
31- assert (height > 0 );
31+ RTC_CHECK (width_ > 0 );
32+ RTC_CHECK (height_ > 0 );
33+ half_width_ = (width_ + 1 ) / 2 ;
34+ y_size_ = width_ * height_;
35+ uv_size_ = half_width_ * ((height_ + 1 ) / 2 );
3236 }
3337
3438 VideoFrame* NextFrame () override {
35- frame_.CreateEmptyFrame (static_cast <int >(width_),
36- static_cast <int >(height_),
37- static_cast <int >(width_),
38- static_cast <int >((width_ + 1 ) / 2 ),
39- static_cast <int >((width_ + 1 ) / 2 ));
4039 angle_ += 30.0 ;
4140 uint8_t u = fabs (sin (angle_)) * 0xFF ;
4241 uint8_t v = fabs (cos (angle_)) * 0xFF ;
4342
44- memset (frame_.video_frame_buffer ()->MutableDataY (), 0x80 ,
45- frame_.allocated_size (kYPlane ));
46- memset (frame_.video_frame_buffer ()->MutableDataU (), u,
47- frame_.allocated_size (kUPlane ));
48- memset (frame_.video_frame_buffer ()->MutableDataV (), v,
49- frame_.allocated_size (kVPlane ));
50- return &frame_;
43+ // Ensure stride == width.
44+ rtc::scoped_refptr<I420Buffer> buffer (I420Buffer::Create (
45+ static_cast <int >(width_), static_cast <int >(height_),
46+ static_cast <int >(width_), static_cast <int >(half_width_),
47+ static_cast <int >(half_width_)));
48+
49+ memset (buffer->MutableDataY (), 0x80 , y_size_);
50+ memset (buffer->MutableDataU (), u, uv_size_);
51+ memset (buffer->MutableDataV (), v, uv_size_);
52+
53+ frame_.reset (new VideoFrame (buffer, 0 , 0 , webrtc::kVideoRotation_0 ));
54+ return frame_.get ();
5155 }
5256
5357 private:
5458 double angle_;
5559 size_t width_;
5660 size_t height_;
57- VideoFrame frame_;
61+ size_t half_width_;
62+ size_t y_size_;
63+ size_t uv_size_;
64+ std::unique_ptr<VideoFrame> frame_;
5865};
5966
6067class YuvFileGenerator : public FrameGenerator {
@@ -89,15 +96,13 @@ class YuvFileGenerator : public FrameGenerator {
8996 if (++current_display_count_ >= frame_display_count_)
9097 current_display_count_ = 0 ;
9198
92- // If this is the last repeatition of this frame, it's OK to use the
93- // original instance, otherwise use a copy.
94- if (current_display_count_ == frame_display_count_)
95- return &last_read_frame_;
96-
97- temp_frame_copy_.CopyFrame (last_read_frame_);
98- return &temp_frame_copy_;
99+ temp_frame_.reset (
100+ new VideoFrame (last_read_buffer_, 0 , 0 , webrtc::kVideoRotation_0 ));
101+ return temp_frame_.get ();
99102 }
100103
104+ // TODO(nisse): Have a frame reader in one place. And read directly
105+ // into the planes of an I420Buffer, the extra copying below is silly.
101106 void ReadNextFrame () {
102107 size_t bytes_read =
103108 fread (frame_buffer_.get (), 1 , frame_size_, files_[file_index_]);
@@ -110,14 +115,21 @@ class YuvFileGenerator : public FrameGenerator {
110115 assert (bytes_read >= frame_size_);
111116 }
112117
113- last_read_frame_.CreateEmptyFrame (
118+ size_t half_width = (width_ + 1 ) / 2 ;
119+ size_t size_y = width_ * height_;
120+ size_t size_uv = half_width * ((height_ + 1 ) / 2 );
121+ last_read_buffer_ = I420Buffer::Create (
114122 static_cast <int >(width_), static_cast <int >(height_),
115- static_cast <int >(width_), static_cast <int >((width_ + 1 ) / 2 ),
116- static_cast <int >((width_ + 1 ) / 2 ));
117-
118- ConvertToI420 (kI420 , frame_buffer_.get (), 0 , 0 , static_cast <int >(width_),
119- static_cast <int >(height_), 0 , kVideoRotation_0 ,
120- &last_read_frame_);
123+ static_cast <int >(width_), static_cast <int >(half_width),
124+ static_cast <int >(half_width));
125+ libyuv::I420Copy (
126+ frame_buffer_.get (), static_cast <int >(width_),
127+ frame_buffer_.get () + size_y, static_cast <int >(half_width),
128+ frame_buffer_.get () + size_y + size_uv, static_cast <int >(half_width),
129+ last_read_buffer_->MutableDataY (), last_read_buffer_->StrideY (),
130+ last_read_buffer_->MutableDataU (), last_read_buffer_->StrideU (),
131+ last_read_buffer_->MutableDataV (), last_read_buffer_->StrideV (),
132+ static_cast <int >(width_), static_cast <int >(height_));
121133 }
122134
123135 private:
@@ -129,8 +141,8 @@ class YuvFileGenerator : public FrameGenerator {
129141 const std::unique_ptr<uint8_t []> frame_buffer_;
130142 const int frame_display_count_;
131143 int current_display_count_;
132- VideoFrame last_read_frame_ ;
133- VideoFrame temp_frame_copy_ ;
144+ rtc::scoped_refptr<I420Buffer> last_read_buffer_ ;
145+ std::unique_ptr< VideoFrame> temp_frame_ ;
134146};
135147
136148class ScrollingImageFrameGenerator : public FrameGenerator {
0 commit comments