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

Side by Side Diff: webrtc/modules/video_coding/codecs/test/videoprocessor.cc

Issue 2997283002: VideoProcessorIntegrationTest: make it runnable on a task queue. (Closed)
Patch Set: Rebase. Created 3 years, 3 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 /* 1 /*
2 * Copyright (c) 2012 The WebRTC project authors. All Rights Reserved. 2 * Copyright (c) 2012 The WebRTC project authors. All Rights Reserved.
3 * 3 *
4 * Use of this source code is governed by a BSD-style license 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 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 6 * tree. An additional intellectual property rights grant can be found
7 * in the file PATENTS. All contributing project authors may 7 * in the file PATENTS. All contributing project authors may
8 * be found in the AUTHORS file in the root of the source tree. 8 * be found in the AUTHORS file in the root of the source tree.
9 */ 9 */
10 10
(...skipping 120 matching lines...) Expand 10 before | Expand all | Expand 10 after
131 packet_manipulator_(packet_manipulator), 131 packet_manipulator_(packet_manipulator),
132 analysis_frame_reader_(analysis_frame_reader), 132 analysis_frame_reader_(analysis_frame_reader),
133 analysis_frame_writer_(analysis_frame_writer), 133 analysis_frame_writer_(analysis_frame_writer),
134 encoded_frame_writer_(encoded_frame_writer), 134 encoded_frame_writer_(encoded_frame_writer),
135 decoded_frame_writer_(decoded_frame_writer), 135 decoded_frame_writer_(decoded_frame_writer),
136 last_encoded_frame_num_(-1), 136 last_encoded_frame_num_(-1),
137 last_decoded_frame_num_(-1), 137 last_decoded_frame_num_(-1),
138 first_key_frame_has_been_excluded_(false), 138 first_key_frame_has_been_excluded_(false),
139 last_decoded_frame_buffer_(analysis_frame_reader->FrameLength()), 139 last_decoded_frame_buffer_(analysis_frame_reader->FrameLength()),
140 stats_(stats), 140 stats_(stats),
141 num_dropped_frames_(0), 141 rate_update_index_(-1) {
142 num_spatial_resizes_(0) {
143 RTC_DCHECK(encoder); 142 RTC_DCHECK(encoder);
144 RTC_DCHECK(decoder); 143 RTC_DCHECK(decoder);
145 RTC_DCHECK(packet_manipulator); 144 RTC_DCHECK(packet_manipulator);
146 RTC_DCHECK(analysis_frame_reader); 145 RTC_DCHECK(analysis_frame_reader);
147 RTC_DCHECK(analysis_frame_writer); 146 RTC_DCHECK(analysis_frame_writer);
148 RTC_DCHECK(stats); 147 RTC_DCHECK(stats);
149 frame_infos_.reserve(analysis_frame_reader->NumberOfFrames()); 148 frame_infos_.reserve(analysis_frame_reader->NumberOfFrames());
150 } 149 }
151 150
152 VideoProcessor::~VideoProcessor() = default; 151 VideoProcessor::~VideoProcessor() = default;
(...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after
212 void VideoProcessor::ProcessFrame(int frame_number) { 211 void VideoProcessor::ProcessFrame(int frame_number) {
213 RTC_DCHECK_CALLED_SEQUENTIALLY(&sequence_checker_); 212 RTC_DCHECK_CALLED_SEQUENTIALLY(&sequence_checker_);
214 RTC_DCHECK_EQ(frame_number, frame_infos_.size()) 213 RTC_DCHECK_EQ(frame_number, frame_infos_.size())
215 << "Must process frames in sequence."; 214 << "Must process frames in sequence.";
216 RTC_DCHECK(initialized_) << "VideoProcessor not initialized."; 215 RTC_DCHECK(initialized_) << "VideoProcessor not initialized.";
217 216
218 // Get frame from file. 217 // Get frame from file.
219 rtc::scoped_refptr<I420BufferInterface> buffer( 218 rtc::scoped_refptr<I420BufferInterface> buffer(
220 analysis_frame_reader_->ReadFrame()); 219 analysis_frame_reader_->ReadFrame());
221 RTC_CHECK(buffer) << "Tried to read too many frames from the file."; 220 RTC_CHECK(buffer) << "Tried to read too many frames from the file.";
221 // Use the frame number as the basis for timestamp to identify frames. Let the
222 // first timestamp be non-zero, to not make the IvfFileWriter believe that we
223 // want to use capture timestamps in the IVF files.
224 const uint32_t rtp_timestamp = (frame_number + 1) * kRtpClockRateHz /
225 config_.codec_settings.maxFramerate;
226 rtp_timestamp_to_frame_num_[rtp_timestamp] = frame_number;
222 const int64_t kNoRenderTime = 0; 227 const int64_t kNoRenderTime = 0;
223 VideoFrame source_frame(buffer, FrameNumberToTimestamp(frame_number), 228 VideoFrame source_frame(buffer, rtp_timestamp, kNoRenderTime,
224 kNoRenderTime, webrtc::kVideoRotation_0); 229 webrtc::kVideoRotation_0);
225 230
226 // Decide if we are going to force a keyframe. 231 // Decide if we are going to force a keyframe.
227 std::vector<FrameType> frame_types(1, kVideoFrameDelta); 232 std::vector<FrameType> frame_types(1, kVideoFrameDelta);
228 if (config_.keyframe_interval > 0 && 233 if (config_.keyframe_interval > 0 &&
229 frame_number % config_.keyframe_interval == 0) { 234 frame_number % config_.keyframe_interval == 0) {
230 frame_types[0] = kVideoFrameKey; 235 frame_types[0] = kVideoFrameKey;
231 } 236 }
232 237
233 // Store frame information during the different stages of encode and decode. 238 // Store frame information during the different stages of encode and decode.
234 frame_infos_.emplace_back(); 239 frame_infos_.emplace_back();
(...skipping 10 matching lines...) Expand all
245 250
246 if (frame_stat->encode_return_code != WEBRTC_VIDEO_CODEC_OK) { 251 if (frame_stat->encode_return_code != WEBRTC_VIDEO_CODEC_OK) {
247 LOG(LS_WARNING) << "Failed to encode frame " << frame_number 252 LOG(LS_WARNING) << "Failed to encode frame " << frame_number
248 << ", return code: " << frame_stat->encode_return_code 253 << ", return code: " << frame_stat->encode_return_code
249 << "."; 254 << ".";
250 } 255 }
251 } 256 }
252 257
253 void VideoProcessor::SetRates(int bitrate_kbps, int framerate_fps) { 258 void VideoProcessor::SetRates(int bitrate_kbps, int framerate_fps) {
254 RTC_DCHECK_CALLED_SEQUENTIALLY(&sequence_checker_); 259 RTC_DCHECK_CALLED_SEQUENTIALLY(&sequence_checker_);
255
256 config_.codec_settings.maxFramerate = framerate_fps; 260 config_.codec_settings.maxFramerate = framerate_fps;
257 int set_rates_result = encoder_->SetRateAllocation( 261 int set_rates_result = encoder_->SetRateAllocation(
258 bitrate_allocator_->GetAllocation(bitrate_kbps * 1000, framerate_fps), 262 bitrate_allocator_->GetAllocation(bitrate_kbps * 1000, framerate_fps),
259 framerate_fps); 263 framerate_fps);
260 RTC_DCHECK_GE(set_rates_result, 0) 264 RTC_DCHECK_GE(set_rates_result, 0)
261 << "Failed to update encoder with new rate " << bitrate_kbps << "."; 265 << "Failed to update encoder with new rate " << bitrate_kbps << ".";
262 num_dropped_frames_ = 0; 266 ++rate_update_index_;
263 num_spatial_resizes_ = 0; 267 num_dropped_frames_.push_back(0);
268 num_spatial_resizes_.push_back(0);
264 } 269 }
265 270
266 int VideoProcessor::GetQpFromEncoder(int frame_number) const { 271 int VideoProcessor::GetQpFromEncoder(int frame_number) const {
267 RTC_DCHECK_CALLED_SEQUENTIALLY(&sequence_checker_); 272 RTC_DCHECK_CALLED_SEQUENTIALLY(&sequence_checker_);
268 RTC_CHECK_LT(frame_number, frame_infos_.size()); 273 RTC_CHECK_LT(frame_number, frame_infos_.size());
269 return frame_infos_[frame_number].qp_encoder; 274 return frame_infos_[frame_number].qp_encoder;
270 } 275 }
271 276
272 int VideoProcessor::GetQpFromBitstream(int frame_number) const { 277 int VideoProcessor::GetQpFromBitstream(int frame_number) const {
273 RTC_DCHECK_CALLED_SEQUENTIALLY(&sequence_checker_); 278 RTC_DCHECK_CALLED_SEQUENTIALLY(&sequence_checker_);
274 RTC_CHECK_LT(frame_number, frame_infos_.size()); 279 RTC_CHECK_LT(frame_number, frame_infos_.size());
275 return frame_infos_[frame_number].qp_bitstream; 280 return frame_infos_[frame_number].qp_bitstream;
276 } 281 }
277 282
278 int VideoProcessor::NumberDroppedFrames() { 283 std::vector<int> VideoProcessor::NumberDroppedFramesPerRateUpdate() const {
279 RTC_DCHECK_CALLED_SEQUENTIALLY(&sequence_checker_); 284 RTC_DCHECK_CALLED_SEQUENTIALLY(&sequence_checker_);
280 return num_dropped_frames_; 285 return num_dropped_frames_;
281 } 286 }
282 287
283 int VideoProcessor::NumberSpatialResizes() { 288 std::vector<int> VideoProcessor::NumberSpatialResizesPerRateUpdate() const {
284 RTC_DCHECK_CALLED_SEQUENTIALLY(&sequence_checker_); 289 RTC_DCHECK_CALLED_SEQUENTIALLY(&sequence_checker_);
285 return num_spatial_resizes_; 290 return num_spatial_resizes_;
286 } 291 }
287 292
288 void VideoProcessor::FrameEncoded(webrtc::VideoCodecType codec, 293 void VideoProcessor::FrameEncoded(webrtc::VideoCodecType codec,
289 const EncodedImage& encoded_image) { 294 const EncodedImage& encoded_image) {
290 RTC_DCHECK_CALLED_SEQUENTIALLY(&sequence_checker_); 295 RTC_DCHECK_CALLED_SEQUENTIALLY(&sequence_checker_);
291 296
292 // For the highest measurement accuracy of the encode time, the start/stop 297 // For the highest measurement accuracy of the encode time, the start/stop
293 // time recordings should wrap the Encode call as tightly as possible. 298 // time recordings should wrap the Encode call as tightly as possible.
294 int64_t encode_stop_ns = rtc::TimeNanos(); 299 int64_t encode_stop_ns = rtc::TimeNanos();
295 300
296 if (encoded_frame_writer_) { 301 if (encoded_frame_writer_) {
297 RTC_CHECK(encoded_frame_writer_->WriteFrame(encoded_image, codec)); 302 RTC_CHECK(encoded_frame_writer_->WriteFrame(encoded_image, codec));
298 } 303 }
299 304
300 // Timestamp is proportional to frame number, so this gives us number of 305 // Check for dropped frames.
301 // dropped frames. 306 const int frame_number =
302 int frame_number = TimestampToFrameNumber(encoded_image._timeStamp); 307 rtp_timestamp_to_frame_num_[encoded_image._timeStamp];
303 bool last_frame_missing = false; 308 bool last_frame_missing = false;
304 if (frame_number > 0) { 309 if (frame_number > 0) {
305 RTC_DCHECK_GE(last_encoded_frame_num_, 0); 310 RTC_DCHECK_GE(last_encoded_frame_num_, 0);
306 int num_dropped_from_last_encode = 311 int num_dropped_from_last_encode =
307 frame_number - last_encoded_frame_num_ - 1; 312 frame_number - last_encoded_frame_num_ - 1;
308 RTC_DCHECK_GE(num_dropped_from_last_encode, 0); 313 RTC_DCHECK_GE(num_dropped_from_last_encode, 0);
309 num_dropped_frames_ += num_dropped_from_last_encode; 314 RTC_CHECK_GE(rate_update_index_, 0);
315 num_dropped_frames_[rate_update_index_] += num_dropped_from_last_encode;
310 if (num_dropped_from_last_encode > 0) { 316 if (num_dropped_from_last_encode > 0) {
311 // For dropped frames, we write out the last decoded frame to avoid 317 // For dropped frames, we write out the last decoded frame to avoid
312 // getting out of sync for the computation of PSNR and SSIM. 318 // getting out of sync for the computation of PSNR and SSIM.
313 for (int i = 0; i < num_dropped_from_last_encode; i++) { 319 for (int i = 0; i < num_dropped_from_last_encode; i++) {
314 RTC_DCHECK_EQ(last_decoded_frame_buffer_.size(), 320 RTC_DCHECK_EQ(last_decoded_frame_buffer_.size(),
315 analysis_frame_writer_->FrameLength()); 321 analysis_frame_writer_->FrameLength());
316 RTC_CHECK(analysis_frame_writer_->WriteFrame( 322 RTC_CHECK(analysis_frame_writer_->WriteFrame(
317 last_decoded_frame_buffer_.data())); 323 last_decoded_frame_buffer_.data()));
318 if (decoded_frame_writer_) { 324 if (decoded_frame_writer_) {
319 RTC_DCHECK_EQ(last_decoded_frame_buffer_.size(), 325 RTC_DCHECK_EQ(last_decoded_frame_buffer_.size(),
320 decoded_frame_writer_->FrameLength()); 326 decoded_frame_writer_->FrameLength());
321 RTC_CHECK(decoded_frame_writer_->WriteFrame( 327 RTC_CHECK(decoded_frame_writer_->WriteFrame(
322 last_decoded_frame_buffer_.data())); 328 last_decoded_frame_buffer_.data()));
323 } 329 }
324 } 330 }
325 } 331 }
326
327 last_frame_missing = 332 last_frame_missing =
328 (frame_infos_[last_encoded_frame_num_].manipulated_length == 0); 333 (frame_infos_[last_encoded_frame_num_].manipulated_length == 0);
329 } 334 }
330 // Ensure strict monotonicity. 335 // Ensure strict monotonicity.
331 RTC_CHECK_GT(frame_number, last_encoded_frame_num_); 336 RTC_CHECK_GT(frame_number, last_encoded_frame_num_);
332 last_encoded_frame_num_ = frame_number; 337 last_encoded_frame_num_ = frame_number;
333 338
334 // Frame is not dropped, so update frame information and statistics. 339 // Update frame information and statistics.
335 RTC_CHECK_LT(frame_number, frame_infos_.size()); 340 RTC_CHECK_LT(frame_number, frame_infos_.size());
336 FrameInfo* frame_info = &frame_infos_[frame_number]; 341 FrameInfo* frame_info = &frame_infos_[frame_number];
337 frame_info->qp_encoder = encoded_image.qp_; 342 frame_info->qp_encoder = encoded_image.qp_;
338 if (codec == kVideoCodecVP8) { 343 if (codec == kVideoCodecVP8) {
339 vp8::GetQp(encoded_image._buffer, encoded_image._length, 344 vp8::GetQp(encoded_image._buffer, encoded_image._length,
340 &frame_info->qp_bitstream); 345 &frame_info->qp_bitstream);
341 } else if (codec == kVideoCodecVP9) { 346 } else if (codec == kVideoCodecVP9) {
342 vp9::GetQp(encoded_image._buffer, encoded_image._length, 347 vp9::GetQp(encoded_image._buffer, encoded_image._length,
343 &frame_info->qp_bitstream); 348 &frame_info->qp_bitstream);
344 } 349 }
(...skipping 70 matching lines...) Expand 10 before | Expand all | Expand 10 after
415 } 420 }
416 421
417 void VideoProcessor::FrameDecoded(const VideoFrame& image) { 422 void VideoProcessor::FrameDecoded(const VideoFrame& image) {
418 RTC_DCHECK_CALLED_SEQUENTIALLY(&sequence_checker_); 423 RTC_DCHECK_CALLED_SEQUENTIALLY(&sequence_checker_);
419 424
420 // For the highest measurement accuracy of the decode time, the start/stop 425 // For the highest measurement accuracy of the decode time, the start/stop
421 // time recordings should wrap the Decode call as tightly as possible. 426 // time recordings should wrap the Decode call as tightly as possible.
422 int64_t decode_stop_ns = rtc::TimeNanos(); 427 int64_t decode_stop_ns = rtc::TimeNanos();
423 428
424 // Update frame information and statistics. 429 // Update frame information and statistics.
425 int frame_number = TimestampToFrameNumber(image.timestamp()); 430 const int frame_number = rtp_timestamp_to_frame_num_[image.timestamp()];
426 RTC_DCHECK_LT(frame_number, frame_infos_.size()); 431 RTC_CHECK_LT(frame_number, frame_infos_.size());
427 FrameInfo* frame_info = &frame_infos_[frame_number]; 432 FrameInfo* frame_info = &frame_infos_[frame_number];
428 frame_info->decoded_width = image.width(); 433 frame_info->decoded_width = image.width();
429 frame_info->decoded_height = image.height(); 434 frame_info->decoded_height = image.height();
430 FrameStatistic* frame_stat = &stats_->stats_[frame_number]; 435 FrameStatistic* frame_stat = &stats_->stats_[frame_number];
431 frame_stat->decode_time_in_us = 436 frame_stat->decode_time_in_us =
432 GetElapsedTimeMicroseconds(frame_info->decode_start_ns, decode_stop_ns); 437 GetElapsedTimeMicroseconds(frame_info->decode_start_ns, decode_stop_ns);
433 frame_stat->decoding_successful = true; 438 frame_stat->decoding_successful = true;
434 439
435 // Check if the codecs have resized the frame since previously decoded frame. 440 // Check if the codecs have resized the frame since previously decoded frame.
436 if (frame_number > 0) { 441 if (frame_number > 0) {
437 RTC_DCHECK_GE(last_decoded_frame_num_, 0); 442 RTC_CHECK_GE(last_decoded_frame_num_, 0);
438 const FrameInfo& last_decoded_frame_info = 443 const FrameInfo& last_decoded_frame_info =
439 frame_infos_[last_decoded_frame_num_]; 444 frame_infos_[last_decoded_frame_num_];
440 if (static_cast<int>(image.width()) != 445 if (static_cast<int>(image.width()) !=
441 last_decoded_frame_info.decoded_width || 446 last_decoded_frame_info.decoded_width ||
442 static_cast<int>(image.height()) != 447 static_cast<int>(image.height()) !=
443 last_decoded_frame_info.decoded_height) { 448 last_decoded_frame_info.decoded_height) {
444 ++num_spatial_resizes_; 449 RTC_CHECK_GE(rate_update_index_, 0);
450 ++num_spatial_resizes_[rate_update_index_];
445 } 451 }
446 } 452 }
447 // Ensure strict monotonicity. 453 // Ensure strict monotonicity.
448 RTC_CHECK_GT(frame_number, last_decoded_frame_num_); 454 RTC_CHECK_GT(frame_number, last_decoded_frame_num_);
449 last_decoded_frame_num_ = frame_number; 455 last_decoded_frame_num_ = frame_number;
450 456
451 // Check if codec size is different from the original size, and if so, 457 // Check if codec size is different from the original size, and if so,
452 // scale back to original size. This is needed for the PSNR and SSIM 458 // scale back to original size. This is needed for the PSNR and SSIM
453 // calculations. 459 // calculations.
454 size_t extracted_length; 460 size_t extracted_length;
(...skipping 22 matching lines...) Expand all
477 RTC_DCHECK_EQ(extracted_length, analysis_frame_writer_->FrameLength()); 483 RTC_DCHECK_EQ(extracted_length, analysis_frame_writer_->FrameLength());
478 RTC_CHECK(analysis_frame_writer_->WriteFrame(extracted_buffer.data())); 484 RTC_CHECK(analysis_frame_writer_->WriteFrame(extracted_buffer.data()));
479 if (decoded_frame_writer_) { 485 if (decoded_frame_writer_) {
480 RTC_DCHECK_EQ(extracted_length, decoded_frame_writer_->FrameLength()); 486 RTC_DCHECK_EQ(extracted_length, decoded_frame_writer_->FrameLength());
481 RTC_CHECK(decoded_frame_writer_->WriteFrame(extracted_buffer.data())); 487 RTC_CHECK(decoded_frame_writer_->WriteFrame(extracted_buffer.data()));
482 } 488 }
483 489
484 last_decoded_frame_buffer_ = std::move(extracted_buffer); 490 last_decoded_frame_buffer_ = std::move(extracted_buffer);
485 } 491 }
486 492
487 uint32_t VideoProcessor::FrameNumberToTimestamp(int frame_number) const { 493 int VideoProcessor::LastDecodedFrameNumber() const {
488 RTC_DCHECK_CALLED_SEQUENTIALLY(&sequence_checker_); 494 RTC_DCHECK_CALLED_SEQUENTIALLY(&sequence_checker_);
489 495 return last_decoded_frame_num_;
490 RTC_DCHECK_GE(frame_number, 0);
491 const int ticks_per_frame =
492 kRtpClockRateHz / config_.codec_settings.maxFramerate;
493 return (frame_number + 1) * ticks_per_frame;
494 }
495
496 int VideoProcessor::TimestampToFrameNumber(uint32_t timestamp) const {
497 RTC_DCHECK_CALLED_SEQUENTIALLY(&sequence_checker_);
498
499 RTC_DCHECK_GT(timestamp, 0);
500 const int ticks_per_frame =
501 kRtpClockRateHz / config_.codec_settings.maxFramerate;
502 RTC_DCHECK_EQ(timestamp % ticks_per_frame, 0);
503 return (timestamp / ticks_per_frame) - 1;
504 } 496 }
505 497
506 } // namespace test 498 } // namespace test
507 } // namespace webrtc 499 } // namespace webrtc
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698