Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(596)

Side by Side Diff: content/renderer/media/gpu/rtc_video_encoder_unittest.cc

Issue 2182183007: Handle scaling frames in RTCVideoEncoder (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: posciak@ comments. Created 4 years, 4 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « content/renderer/media/gpu/rtc_video_encoder.cc ('k') | media/BUILD.gn » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(Empty)
1 // Copyright 2016 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #include <stdint.h>
6
7 #include "base/bind.h"
8 #include "base/memory/ptr_util.h"
9 #include "base/single_thread_task_runner.h"
10 #include "base/synchronization/waitable_event.h"
11 #include "base/threading/thread.h"
12 #include "content/renderer/media/gpu/rtc_video_encoder.h"
13 #include "media/renderers/mock_gpu_video_accelerator_factories.h"
14 #include "media/video/mock_video_encode_accelerator.h"
15 #include "testing/gtest/include/gtest/gtest.h"
16 #include "third_party/libyuv/include/libyuv/planar_functions.h"
17 #include "third_party/webrtc/modules/video_coding/include/video_codec_interface. h"
18
19 using ::testing::_;
20 using ::testing::Invoke;
21 using ::testing::Return;
22 using ::testing::SaveArg;
23 using ::testing::Values;
24 using ::testing::WithArgs;
25
26 namespace content {
27
28 namespace {
29
30 const int kInputFrameFillY = 12;
31 const int kInputFrameFillU = 23;
32 const int kInputFrameFillV = 34;
33 const unsigned short kInputFrameHeight = 234;
34 const unsigned short kInputFrameWidth = 345;
35 const unsigned short kStartBitrate = 100;
36
37 } // anonymous namespace
38
39 class RTCVideoEncoderTest
40 : public ::testing::TestWithParam<webrtc::VideoCodecType> {
41 public:
42 RTCVideoEncoderTest()
43 : mock_gpu_factories_(
44 new media::MockGpuVideoAcceleratorFactories(nullptr)),
45 encoder_thread_("vea_thread"),
46 idle_waiter_(base::WaitableEvent::ResetPolicy::AUTOMATIC,
47 base::WaitableEvent::InitialState::NOT_SIGNALED) {}
48
49 void SetUp() override {
50 DVLOG(3) << __FUNCTION__;
51 ASSERT_TRUE(encoder_thread_.Start());
52 mock_vea_ = new media::MockVideoEncodeAccelerator();
53
54 EXPECT_CALL(*mock_gpu_factories_.get(), GetTaskRunner())
55 .WillRepeatedly(Return(encoder_thread_.task_runner()));
56 EXPECT_CALL(*mock_gpu_factories_.get(), DoCreateVideoEncodeAccelerator())
57 .WillRepeatedly(Return(mock_vea_));
58 EXPECT_CALL(*mock_vea_, Initialize(_, _, _, _, _))
59 .WillOnce(Invoke(this, &RTCVideoEncoderTest::Initialize));
60 EXPECT_CALL(*mock_vea_, UseOutputBitstreamBuffer(_)).Times(3);
61 EXPECT_CALL(*mock_vea_, Destroy()).Times(1);
62 }
63
64 void TearDown() override {
65 DVLOG(3) << __FUNCTION__;
66 EXPECT_TRUE(encoder_thread_.IsRunning());
67 RunUntilIdle();
68 rtc_encoder_->Release();
69 RunUntilIdle();
70 encoder_thread_.Stop();
71 }
72
73 void RunUntilIdle() {
74 DVLOG(3) << __FUNCTION__;
75 encoder_thread_.task_runner()->PostTask(
76 FROM_HERE, base::Bind(&base::WaitableEvent::Signal,
77 base::Unretained(&idle_waiter_)));
78 idle_waiter_.Wait();
79 }
80
81 void CreateEncoder(webrtc::VideoCodecType codec_type) {
82 DVLOG(3) << __FUNCTION__;
83 rtc_encoder_ = base::WrapUnique(
84 new RTCVideoEncoder(codec_type, mock_gpu_factories_.get()));
85 }
86
87 // media::VideoEncodeAccelerator implementation.
88 bool Initialize(media::VideoPixelFormat input_format,
89 const gfx::Size& input_visible_size,
90 media::VideoCodecProfile output_profile,
91 uint32_t initial_bitrate,
92 media::VideoEncodeAccelerator::Client* client) {
93 DVLOG(3) << __FUNCTION__;
94 client->RequireBitstreamBuffers(0, input_visible_size,
95 input_visible_size.GetArea());
96 return true;
97 }
98
99 webrtc::VideoCodec GetDefaultCodec() {
100 webrtc::VideoCodec codec = {};
101 memset(&codec, 0, sizeof(codec));
102 codec.width = kInputFrameWidth;
103 codec.height = kInputFrameHeight;
104 codec.codecType = webrtc::kVideoCodecVP8;
105 codec.startBitrate = kStartBitrate;
106 return codec;
107 }
108
109 void FillFrameBuffer(rtc::scoped_refptr<webrtc::I420Buffer> frame) {
110 CHECK(libyuv::I420Rect(frame->MutableDataY(), frame->StrideY(),
111 frame->MutableDataU(), frame->StrideU(),
112 frame->MutableDataV(), frame->StrideV(), 0, 0,
113 frame->width(), frame->height(), kInputFrameFillY,
114 kInputFrameFillU, kInputFrameFillV) == 0);
115 }
116
117 void VerifyEncodedFrame(const scoped_refptr<media::VideoFrame>& frame,
118 bool force_keyframe) {
119 DVLOG(3) << __FUNCTION__;
120 EXPECT_EQ(kInputFrameWidth, frame->visible_rect().width());
121 EXPECT_EQ(kInputFrameHeight, frame->visible_rect().height());
122 EXPECT_EQ(kInputFrameFillY,
123 frame->visible_data(media::VideoFrame::kYPlane)[0]);
124 EXPECT_EQ(kInputFrameFillU,
125 frame->visible_data(media::VideoFrame::kUPlane)[0]);
126 EXPECT_EQ(kInputFrameFillV,
127 frame->visible_data(media::VideoFrame::kVPlane)[0]);
128 }
129
130 protected:
131 media::MockVideoEncodeAccelerator* mock_vea_;
132 std::unique_ptr<RTCVideoEncoder> rtc_encoder_;
133
134 private:
135 std::unique_ptr<media::MockGpuVideoAcceleratorFactories> mock_gpu_factories_;
136 base::Thread encoder_thread_;
137 base::WaitableEvent idle_waiter_;
138 };
139
140 TEST_P(RTCVideoEncoderTest, CreateAndInitSucceeds) {
141 const webrtc::VideoCodecType codec_type = GetParam();
142 CreateEncoder(codec_type);
143 webrtc::VideoCodec codec = GetDefaultCodec();
144 codec.codecType = codec_type;
145 EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK, rtc_encoder_->InitEncode(&codec, 1, 12345));
146 }
147
148 TEST_F(RTCVideoEncoderTest, EncodeScaledFrame) {
149 const webrtc::VideoCodecType codec_type = webrtc::kVideoCodecVP8;
150 CreateEncoder(codec_type);
151 webrtc::VideoCodec codec = GetDefaultCodec();
152 EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK, rtc_encoder_->InitEncode(&codec, 1, 12345));
153
154 EXPECT_CALL(*mock_vea_, Encode(_, _))
155 .Times(2)
156 .WillRepeatedly(Invoke(this, &RTCVideoEncoderTest::VerifyEncodedFrame));
157
158 const rtc::scoped_refptr<webrtc::I420Buffer> buffer =
159 webrtc::I420Buffer::Create(kInputFrameWidth, kInputFrameHeight);
160 FillFrameBuffer(buffer);
161 std::vector<webrtc::FrameType> frame_types;
162 EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK,
163 rtc_encoder_->Encode(
164 webrtc::VideoFrame(buffer, 0, 0, webrtc::kVideoRotation_0),
165 nullptr, &frame_types));
166
167 const rtc::scoped_refptr<webrtc::I420Buffer> upscaled_buffer =
168 webrtc::I420Buffer::Create(2 * kInputFrameWidth, 2 * kInputFrameHeight);
169 FillFrameBuffer(upscaled_buffer);
170 EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK,
171 rtc_encoder_->Encode(webrtc::VideoFrame(upscaled_buffer, 0, 0,
172 webrtc::kVideoRotation_0),
173 nullptr, &frame_types));
174 }
175
176 INSTANTIATE_TEST_CASE_P(CodecProfiles,
177 RTCVideoEncoderTest,
178 Values(webrtc::kVideoCodecVP8,
179 webrtc::kVideoCodecH264));
180 } // namespace content
OLDNEW
« no previous file with comments | « content/renderer/media/gpu/rtc_video_encoder.cc ('k') | media/BUILD.gn » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698