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

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

Issue 2435693004: Reland: Use webrtc::VideoFrame timestamp in RTCVideoEncoder (Closed)
Patch Set: Created 3 years, 8 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
OLDNEW
1 // Copyright 2016 The Chromium Authors. All rights reserved. 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 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include <stdint.h> 5 #include <stdint.h>
6 6
7 #include "base/bind.h" 7 #include "base/bind.h"
8 #include "base/memory/ptr_util.h" 8 #include "base/memory/ptr_util.h"
9 #include "base/single_thread_task_runner.h" 9 #include "base/single_thread_task_runner.h"
10 #include "base/synchronization/waitable_event.h" 10 #include "base/synchronization/waitable_event.h"
11 #include "base/threading/thread.h" 11 #include "base/threading/thread.h"
12 #include "content/renderer/media/gpu/rtc_video_encoder.h" 12 #include "content/renderer/media/gpu/rtc_video_encoder.h"
13 #include "media/renderers/mock_gpu_video_accelerator_factories.h" 13 #include "media/renderers/mock_gpu_video_accelerator_factories.h"
14 #include "media/video/mock_video_encode_accelerator.h" 14 #include "media/video/mock_video_encode_accelerator.h"
15 #include "testing/gtest/include/gtest/gtest.h" 15 #include "testing/gtest/include/gtest/gtest.h"
16 #include "third_party/libyuv/include/libyuv/planar_functions.h" 16 #include "third_party/libyuv/include/libyuv/planar_functions.h"
17 #include "third_party/webrtc/modules/video_coding/include/video_codec_interface. h" 17 #include "third_party/webrtc/modules/video_coding/include/video_codec_interface. h"
18 #include "third_party/webrtc/video_encoder.h"
18 19
19 using ::testing::_; 20 using ::testing::_;
21 using ::testing::AtLeast;
20 using ::testing::Invoke; 22 using ::testing::Invoke;
21 using ::testing::Return; 23 using ::testing::Return;
22 using ::testing::SaveArg; 24 using ::testing::SaveArg;
23 using ::testing::Values; 25 using ::testing::Values;
24 using ::testing::WithArgs; 26 using ::testing::WithArgs;
25 27
26 namespace content { 28 namespace content {
27 29
28 namespace { 30 namespace {
29 31
30 const int kInputFrameFillY = 12; 32 const int kInputFrameFillY = 12;
31 const int kInputFrameFillU = 23; 33 const int kInputFrameFillU = 23;
32 const int kInputFrameFillV = 34; 34 const int kInputFrameFillV = 34;
33 const unsigned short kInputFrameHeight = 234; 35 const unsigned short kInputFrameHeight = 234;
34 const unsigned short kInputFrameWidth = 345; 36 const unsigned short kInputFrameWidth = 345;
35 const unsigned short kStartBitrate = 100; 37 const unsigned short kStartBitrate = 100;
36 38
39 class EncodedImageCallbackWrapper : public webrtc::EncodedImageCallback {
40 public:
41 using EncodedCallback =
42 base::Callback<void(const webrtc::EncodedImage& encoded_image,
43 const webrtc::CodecSpecificInfo* codec_specific_info,
44 const webrtc::RTPFragmentationHeader* fragmentation)>;
45
46 EncodedImageCallbackWrapper(const EncodedCallback& encoded_callback)
47 : encoded_callback_(encoded_callback) {}
48
49 Result OnEncodedImage(
50 const webrtc::EncodedImage& encoded_image,
51 const webrtc::CodecSpecificInfo* codec_specific_info,
52 const webrtc::RTPFragmentationHeader* fragmentation) override {
53 encoded_callback_.Run(encoded_image, codec_specific_info, fragmentation);
54 return Result(Result::OK);
55 };
56
57 private:
58 EncodedCallback encoded_callback_;
59 };
37 } // anonymous namespace 60 } // anonymous namespace
38 61
39 class RTCVideoEncoderTest 62 class RTCVideoEncoderTest
40 : public ::testing::TestWithParam<webrtc::VideoCodecType> { 63 : public ::testing::TestWithParam<webrtc::VideoCodecType> {
41 public: 64 public:
42 RTCVideoEncoderTest() 65 RTCVideoEncoderTest()
43 : mock_gpu_factories_( 66 : mock_gpu_factories_(
44 new media::MockGpuVideoAcceleratorFactories(nullptr)), 67 new media::MockGpuVideoAcceleratorFactories(nullptr)),
45 encoder_thread_("vea_thread"), 68 encoder_thread_("vea_thread"),
46 idle_waiter_(base::WaitableEvent::ResetPolicy::AUTOMATIC, 69 idle_waiter_(base::WaitableEvent::ResetPolicy::AUTOMATIC,
47 base::WaitableEvent::InitialState::NOT_SIGNALED) {} 70 base::WaitableEvent::InitialState::NOT_SIGNALED) {}
48 71
49 media::MockVideoEncodeAccelerator* ExpectCreateInitAndDestroyVEA() { 72 media::MockVideoEncodeAccelerator* ExpectCreateInitAndDestroyVEA() {
50 // The VEA will be owned by the RTCVideoEncoder once 73 // The VEA will be owned by the RTCVideoEncoder once
51 // factory.CreateVideoEncodeAccelerator() is called. 74 // factory.CreateVideoEncodeAccelerator() is called.
52 media::MockVideoEncodeAccelerator* mock_vea = 75 media::MockVideoEncodeAccelerator* mock_vea =
53 new media::MockVideoEncodeAccelerator(); 76 new media::MockVideoEncodeAccelerator();
54 77
55 EXPECT_CALL(*mock_gpu_factories_.get(), DoCreateVideoEncodeAccelerator()) 78 EXPECT_CALL(*mock_gpu_factories_.get(), DoCreateVideoEncodeAccelerator())
56 .WillRepeatedly(Return(mock_vea)); 79 .WillRepeatedly(Return(mock_vea));
57 EXPECT_CALL(*mock_vea, Initialize(_, _, _, _, _)) 80 EXPECT_CALL(*mock_vea, Initialize(_, _, _, _, _))
58 .WillOnce(Invoke(this, &RTCVideoEncoderTest::Initialize)); 81 .WillOnce(Invoke(this, &RTCVideoEncoderTest::Initialize));
59 EXPECT_CALL(*mock_vea, UseOutputBitstreamBuffer(_)).Times(3); 82 EXPECT_CALL(*mock_vea, UseOutputBitstreamBuffer(_)).Times(AtLeast(3));
60 EXPECT_CALL(*mock_vea, Destroy()).Times(1); 83 EXPECT_CALL(*mock_vea, Destroy()).Times(1);
61 return mock_vea; 84 return mock_vea;
62 } 85 }
63 86
64 void SetUp() override { 87 void SetUp() override {
65 DVLOG(3) << __func__; 88 DVLOG(3) << __func__;
66 ASSERT_TRUE(encoder_thread_.Start()); 89 ASSERT_TRUE(encoder_thread_.Start());
67 90
68 EXPECT_CALL(*mock_gpu_factories_.get(), GetTaskRunner()) 91 EXPECT_CALL(*mock_gpu_factories_.get(), GetTaskRunner())
69 .WillRepeatedly(Return(encoder_thread_.task_runner())); 92 .WillRepeatedly(Return(encoder_thread_.task_runner()));
(...skipping 23 matching lines...) Expand all
93 mock_gpu_factories_.get()); 116 mock_gpu_factories_.get());
94 } 117 }
95 118
96 // media::VideoEncodeAccelerator implementation. 119 // media::VideoEncodeAccelerator implementation.
97 bool Initialize(media::VideoPixelFormat input_format, 120 bool Initialize(media::VideoPixelFormat input_format,
98 const gfx::Size& input_visible_size, 121 const gfx::Size& input_visible_size,
99 media::VideoCodecProfile output_profile, 122 media::VideoCodecProfile output_profile,
100 uint32_t initial_bitrate, 123 uint32_t initial_bitrate,
101 media::VideoEncodeAccelerator::Client* client) { 124 media::VideoEncodeAccelerator::Client* client) {
102 DVLOG(3) << __func__; 125 DVLOG(3) << __func__;
103 client->RequireBitstreamBuffers(0, input_visible_size, 126 client_ = client;
104 input_visible_size.GetArea()); 127 client_->RequireBitstreamBuffers(0, input_visible_size,
128 input_visible_size.GetArea());
105 return true; 129 return true;
106 } 130 }
107 131
132 void RegisterEncodeCompleteCallback(
133 const EncodedImageCallbackWrapper::EncodedCallback& callback) {
134 callback_wrapper_.reset(new EncodedImageCallbackWrapper(callback));
135 rtc_encoder_->RegisterEncodeCompleteCallback(callback_wrapper_.get());
136 }
137
108 webrtc::VideoCodec GetDefaultCodec() { 138 webrtc::VideoCodec GetDefaultCodec() {
109 webrtc::VideoCodec codec = {}; 139 webrtc::VideoCodec codec = {};
110 memset(&codec, 0, sizeof(codec)); 140 memset(&codec, 0, sizeof(codec));
111 codec.width = kInputFrameWidth; 141 codec.width = kInputFrameWidth;
112 codec.height = kInputFrameHeight; 142 codec.height = kInputFrameHeight;
113 codec.codecType = webrtc::kVideoCodecVP8; 143 codec.codecType = webrtc::kVideoCodecVP8;
114 codec.startBitrate = kStartBitrate; 144 codec.startBitrate = kStartBitrate;
115 return codec; 145 return codec;
116 } 146 }
117 147
(...skipping 11 matching lines...) Expand all
129 EXPECT_EQ(kInputFrameWidth, frame->visible_rect().width()); 159 EXPECT_EQ(kInputFrameWidth, frame->visible_rect().width());
130 EXPECT_EQ(kInputFrameHeight, frame->visible_rect().height()); 160 EXPECT_EQ(kInputFrameHeight, frame->visible_rect().height());
131 EXPECT_EQ(kInputFrameFillY, 161 EXPECT_EQ(kInputFrameFillY,
132 frame->visible_data(media::VideoFrame::kYPlane)[0]); 162 frame->visible_data(media::VideoFrame::kYPlane)[0]);
133 EXPECT_EQ(kInputFrameFillU, 163 EXPECT_EQ(kInputFrameFillU,
134 frame->visible_data(media::VideoFrame::kUPlane)[0]); 164 frame->visible_data(media::VideoFrame::kUPlane)[0]);
135 EXPECT_EQ(kInputFrameFillV, 165 EXPECT_EQ(kInputFrameFillV,
136 frame->visible_data(media::VideoFrame::kVPlane)[0]); 166 frame->visible_data(media::VideoFrame::kVPlane)[0]);
137 } 167 }
138 168
169 void ReturnFrameWithTimeStamp(const scoped_refptr<media::VideoFrame>& frame,
170 bool force_keyframe) {
171 client_->BitstreamBufferReady(0, 0, force_keyframe, frame->timestamp());
172 }
173
174 void VerifyTimestamp(uint32_t rtp_timestamp,
175 const webrtc::EncodedImage& encoded_image,
176 const webrtc::CodecSpecificInfo* codec_specific_info,
177 const webrtc::RTPFragmentationHeader* fragmentation) {
178 DVLOG(3) << __func__;
179 EXPECT_EQ(rtp_timestamp, encoded_image._timeStamp);
180 }
181
139 protected: 182 protected:
140 media::MockVideoEncodeAccelerator* mock_vea_; 183 media::MockVideoEncodeAccelerator* mock_vea_;
141 std::unique_ptr<RTCVideoEncoder> rtc_encoder_; 184 std::unique_ptr<RTCVideoEncoder> rtc_encoder_;
142 185
143 private: 186 private:
144 std::unique_ptr<media::MockGpuVideoAcceleratorFactories> mock_gpu_factories_; 187 std::unique_ptr<media::MockGpuVideoAcceleratorFactories> mock_gpu_factories_;
188 media::VideoEncodeAccelerator::Client* client_;
189 std::unique_ptr<EncodedImageCallbackWrapper> callback_wrapper_;
145 base::Thread encoder_thread_; 190 base::Thread encoder_thread_;
146 base::WaitableEvent idle_waiter_; 191 base::WaitableEvent idle_waiter_;
147 }; 192 };
148 193
149 TEST_P(RTCVideoEncoderTest, CreateAndInitSucceeds) { 194 TEST_P(RTCVideoEncoderTest, CreateAndInitSucceeds) {
150 const webrtc::VideoCodecType codec_type = GetParam(); 195 const webrtc::VideoCodecType codec_type = GetParam();
151 CreateEncoder(codec_type); 196 CreateEncoder(codec_type);
152 webrtc::VideoCodec codec = GetDefaultCodec(); 197 webrtc::VideoCodec codec = GetDefaultCodec();
153 codec.codecType = codec_type; 198 codec.codecType = codec_type;
154 EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK, rtc_encoder_->InitEncode(&codec, 1, 12345)); 199 EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK, rtc_encoder_->InitEncode(&codec, 1, 12345));
(...skipping 25 matching lines...) Expand all
180 FillFrameBuffer(buffer); 225 FillFrameBuffer(buffer);
181 std::vector<webrtc::FrameType> frame_types; 226 std::vector<webrtc::FrameType> frame_types;
182 EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK, 227 EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK,
183 rtc_encoder_->Encode( 228 rtc_encoder_->Encode(
184 webrtc::VideoFrame(buffer, 0, 0, webrtc::kVideoRotation_0), 229 webrtc::VideoFrame(buffer, 0, 0, webrtc::kVideoRotation_0),
185 nullptr, &frame_types)); 230 nullptr, &frame_types));
186 231
187 const rtc::scoped_refptr<webrtc::I420Buffer> upscaled_buffer = 232 const rtc::scoped_refptr<webrtc::I420Buffer> upscaled_buffer =
188 webrtc::I420Buffer::Create(2 * kInputFrameWidth, 2 * kInputFrameHeight); 233 webrtc::I420Buffer::Create(2 * kInputFrameWidth, 2 * kInputFrameHeight);
189 FillFrameBuffer(upscaled_buffer); 234 FillFrameBuffer(upscaled_buffer);
235 webrtc::VideoFrame rtc_frame(upscaled_buffer, 0, 0, webrtc::kVideoRotation_0);
236 rtc_frame.set_ntp_time_ms(123456);
190 EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK, 237 EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK,
191 rtc_encoder_->Encode(webrtc::VideoFrame(upscaled_buffer, 0, 0, 238 rtc_encoder_->Encode(rtc_frame, nullptr, &frame_types));
192 webrtc::kVideoRotation_0), 239 }
193 nullptr, &frame_types)); 240
241 // We cannot run this test on Android because AndroidVideoEncodeAccelerator does
242 // not preserve timestamps.
243 #if defined(OS_ANDROID)
244 #define MAYBE_PreserveTimestamps DISABLED_PreserveTimestamps
245 #else
246 #define MAYBE_PreserveTimestamps PreserveTimestamps
247 #endif // defined(OS_ANDROID)
248
249 TEST_F(RTCVideoEncoderTest, MAYBE_PreserveTimestamps) {
250 const webrtc::VideoCodecType codec_type = webrtc::kVideoCodecVP8;
251 CreateEncoder(codec_type);
252 webrtc::VideoCodec codec = GetDefaultCodec();
253 EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK, rtc_encoder_->InitEncode(&codec, 1, 12345));
254
255 const uint32_t rtp_timestamp = 1234567;
256 RegisterEncodeCompleteCallback(
257 base::Bind(&RTCVideoEncoderTest::VerifyTimestamp, base::Unretained(this),
258 rtp_timestamp));
259
260 EXPECT_CALL(*mock_vea_, Encode(_, _))
261 .WillOnce(Invoke(this, &RTCVideoEncoderTest::ReturnFrameWithTimeStamp));
262 const rtc::scoped_refptr<webrtc::I420Buffer> buffer =
263 webrtc::I420Buffer::Create(kInputFrameWidth, kInputFrameHeight);
264 FillFrameBuffer(buffer);
265 std::vector<webrtc::FrameType> frame_types;
266 webrtc::VideoFrame rtc_frame(buffer, rtp_timestamp, 0,
267 webrtc::kVideoRotation_0);
268 // We need to set ntp_time_ms because it will be used to derive
269 // media::VideoFrame timestamp.
270 rtc_frame.set_ntp_time_ms(4567891);
271 EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK,
272 rtc_encoder_->Encode(rtc_frame, nullptr, &frame_types));
194 } 273 }
195 274
196 INSTANTIATE_TEST_CASE_P(CodecProfiles, 275 INSTANTIATE_TEST_CASE_P(CodecProfiles,
197 RTCVideoEncoderTest, 276 RTCVideoEncoderTest,
198 Values(webrtc::kVideoCodecVP8, 277 Values(webrtc::kVideoCodecVP8,
199 webrtc::kVideoCodecH264)); 278 webrtc::kVideoCodecH264));
200 } // namespace content 279 } // namespace content
OLDNEW
« no previous file with comments | « content/renderer/media/gpu/rtc_video_encoder.cc ('k') | media/gpu/android_video_encode_accelerator.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698