diff --git a/webrtc/modules/video_coding/codecs/test/plot_videoprocessor_integrationtest.cc b/webrtc/modules/video_coding/codecs/test/plot_videoprocessor_integrationtest.cc index 9061495568..d4152e0c74 100644 --- a/webrtc/modules/video_coding/codecs/test/plot_videoprocessor_integrationtest.cc +++ b/webrtc/modules/video_coding/codecs/test/plot_videoprocessor_integrationtest.cc @@ -48,8 +48,8 @@ class PlotVideoProcessorIntegrationTest 0, // update_index bitrate_, framerate_, 0); // frame_index_rate_update - rate_profile.frame_index_rate_update[1] = kNbrFramesLong + 1; - rate_profile.num_frames = kNbrFramesLong; + rate_profile.frame_index_rate_update[1] = kNumFramesLong + 1; + rate_profile.num_frames = kNumFramesLong; // Codec/network settings. CodecConfigPars process_settings; SetCodecParameters(&process_settings, codec_type_, kPacketLoss, diff --git a/webrtc/modules/video_coding/codecs/test/videoprocessor.cc b/webrtc/modules/video_coding/codecs/test/videoprocessor.cc index 3df8a042f0..6fb4491415 100644 --- a/webrtc/modules/video_coding/codecs/test/videoprocessor.cc +++ b/webrtc/modules/video_coding/codecs/test/videoprocessor.cc @@ -29,6 +29,18 @@ namespace webrtc { namespace test { +const char* ExcludeFrameTypesToStr(ExcludeFrameTypes e) { + switch (e) { + case kExcludeOnlyFirstKeyFrame: + return "ExcludeOnlyFirstKeyFrame"; + case kExcludeAllKeyFrames: + return "ExcludeAllKeyFrames"; + default: + RTC_NOTREACHED(); + return "Unknown"; + } +} + TestConfig::TestConfig() : name(""), description(""), @@ -89,18 +101,19 @@ VideoProcessorImpl::VideoProcessorImpl(webrtc::VideoEncoder* encoder, } bool VideoProcessorImpl::Init() { - // Calculate a factor used for bit rate calculations: + // Calculate a factor used for bit rate calculations. bit_rate_factor_ = config_.codec_settings->maxFramerate * 0.001 * 8; // bits - // Initialize data structures used by the encoder/decoder APIs + // Initialize data structures used by the encoder/decoder APIs. size_t frame_length_in_bytes = frame_reader_->FrameLength(); last_successful_frame_buffer_.reset(new uint8_t[frame_length_in_bytes]); + // Set fixed properties common for all frames. // To keep track of spatial resize actions by encoder. last_encoder_frame_width_ = config_.codec_settings->width; last_encoder_frame_height_ = config_.codec_settings->height; - // Setup required callbacks for the encoder/decoder: + // Setup required callbacks for the encoder/decoder. encode_callback_.reset(new VideoProcessorEncodeCompleteCallback(this)); decode_callback_.reset(new VideoProcessorDecodeCompleteCallback(this)); RTC_CHECK_EQ(encoder_->RegisterEncodeCompleteCallback(encode_callback_.get()), @@ -110,24 +123,24 @@ bool VideoProcessorImpl::Init() { WEBRTC_VIDEO_CODEC_OK) << "Failed to register decode complete callback"; - // Init the encoder and decoder - uint32_t nbr_of_cores = 1; + // Init the encoder and decoder. + uint32_t num_cores = 1; if (!config_.use_single_core) { - nbr_of_cores = CpuInfo::DetectNumberOfCores(); + num_cores = CpuInfo::DetectNumberOfCores(); } RTC_CHECK_EQ( - encoder_->InitEncode(config_.codec_settings, nbr_of_cores, + encoder_->InitEncode(config_.codec_settings, num_cores, config_.networking_config.max_payload_size_in_bytes), WEBRTC_VIDEO_CODEC_OK) << "Failed to initialize VideoEncoder"; - RTC_CHECK_EQ(decoder_->InitDecode(config_.codec_settings, nbr_of_cores), + RTC_CHECK_EQ(decoder_->InitDecode(config_.codec_settings, num_cores), WEBRTC_VIDEO_CODEC_OK) << "Failed to initialize VideoDecoder"; if (config_.verbose) { printf("Video Processor:\n"); - printf(" #CPU cores used : %d\n", nbr_of_cores); + printf(" #CPU cores used : %d\n", num_cores); printf(" Total # of frames: %d\n", frame_reader_->NumberOfFrames()); printf(" Codec settings:\n"); printf(" Start bitrate : %d kbps\n", @@ -198,17 +211,18 @@ bool VideoProcessorImpl::ProcessFrame(int frame_number) { if (frame_number == 0) { prev_time_stamp_ = -1; } + rtc::scoped_refptr buffer(frame_reader_->ReadFrame()); if (buffer) { - // Use the frame number as "timestamp" to identify frames + // Use the frame number as "timestamp" to identify frames. VideoFrame source_frame(buffer, frame_number, 0, webrtc::kVideoRotation_0); - // Ensure we have a new statistics data object we can fill: + // Ensure we have a new statistics data object we can fill. FrameStatistic& stat = stats_->NewFrame(frame_number); encode_start_ns_ = rtc::TimeNanos(); - // Decide if we're going to force a keyframe: + // Decide if we are going to force a keyframe. std::vector frame_types(1, kVideoFrameDelta); if (config_.keyframe_interval > 0 && frame_number % config_.keyframe_interval == 0) { @@ -227,9 +241,11 @@ bool VideoProcessorImpl::ProcessFrame(int frame_number) { frame_number, encode_result); } stat.encode_return_code = encode_result; + return true; } else { - return false; // we've reached the last frame + // Last frame has been reached. + return false; } } @@ -252,11 +268,11 @@ void VideoProcessorImpl::FrameEncoded( // Frame is not dropped, so update the encoded frame size // (encoder callback is only called for non-zero length frames). encoded_frame_size_ = encoded_image._length; - encoded_frame_type_ = encoded_image._frameType; int64_t encode_stop_ns = rtc::TimeNanos(); int frame_number = encoded_image._timeStamp; + FrameStatistic& stat = stats_->stats_[frame_number]; stat.encode_time_in_us = GetElapsedTimeMicroseconds(encode_start_ns_, encode_stop_ns); @@ -269,9 +285,9 @@ void VideoProcessorImpl::FrameEncoded( encoded_image._length / config_.networking_config.packet_size_in_bytes + 1; - // Perform packet loss if criteria is fullfilled: + // Simulate packet loss. bool exclude_this_frame = false; - // Only keyframes can be excluded + // Only keyframes can be excluded. if (encoded_image._frameType == kVideoFrameKey) { switch (config_.exclude_frame_types) { case kExcludeOnlyFirstKeyFrame: @@ -305,32 +321,35 @@ void VideoProcessorImpl::FrameEncoded( } // Keep track of if frames are lost due to packet loss so we can tell - // this to the encoder (this is handled by the RTP logic in the full stack) + // this to the encoder (this is handled by the RTP logic in the full stack). decode_start_ns_ = rtc::TimeNanos(); // TODO(kjellander): Pass fragmentation header to the decoder when // CL 172001 has been submitted and PacketManipulator supports this. int32_t decode_result = decoder_->Decode(copied_image, last_frame_missing_, nullptr); stat.decode_return_code = decode_result; + if (decode_result != WEBRTC_VIDEO_CODEC_OK) { // Write the last successful frame the output file to avoid getting it out - // of sync with the source file for SSIM and PSNR comparisons: + // of sync with the source file for SSIM and PSNR comparisons. frame_writer_->WriteFrame(last_successful_frame_buffer_.get()); } - // save status for losses so we can inform the decoder for the next frame: + + // Save status for losses so we can inform the decoder for the next frame. last_frame_missing_ = copied_image._length == 0; } void VideoProcessorImpl::FrameDecoded(const VideoFrame& image) { int64_t decode_stop_ns = rtc::TimeNanos(); + + // Report stats. int frame_number = image.timestamp(); - // Report stats FrameStatistic& stat = stats_->stats_[frame_number]; stat.decode_time_in_us = GetElapsedTimeMicroseconds(decode_start_ns_, decode_stop_ns); stat.decoding_successful = true; - // Check for resize action (either down or up): + // Check for resize action (either down or up). if (static_cast(image.width()) != last_encoder_frame_width_ || static_cast(image.height()) != last_encoder_frame_height_) { ++num_spatial_resizes_; @@ -338,7 +357,8 @@ void VideoProcessorImpl::FrameDecoded(const VideoFrame& image) { last_encoder_frame_height_ = image.height(); } // Check if codec size is different from native/original size, and if so, - // upsample back to original size: needed for PSNR and SSIM computations. + // upsample back to original size. This is needed for PSNR and SSIM + // calculations. if (image.width() != config_.codec_settings->width || image.height() != config_.codec_settings->height) { rtc::scoped_refptr up_image( @@ -354,7 +374,7 @@ void VideoProcessorImpl::FrameDecoded(const VideoFrame& image) { std::unique_ptr image_buffer(new uint8_t[length]); int extracted_length = ExtractBuffer(up_image, length, image_buffer.get()); RTC_DCHECK_GT(extracted_length, 0); - // Update our copy of the last successful frame: + // Update our copy of the last successful frame. memcpy(last_successful_frame_buffer_.get(), image_buffer.get(), extracted_length); bool write_success = frame_writer_->WriteFrame(image_buffer.get()); @@ -363,7 +383,7 @@ void VideoProcessorImpl::FrameDecoded(const VideoFrame& image) { fprintf(stderr, "Failed to write frame %d to disk!", frame_number); } } else { // No resize. - // Update our copy of the last successful frame: + // Update our copy of the last successful frame. // TODO(mikhal): Add as a member function, so won't be allocated per frame. size_t length = CalcBufferSize(kI420, image.width(), image.height()); std::unique_ptr image_buffer(new uint8_t[length]); @@ -388,37 +408,5 @@ int VideoProcessorImpl::GetElapsedTimeMicroseconds(int64_t start, return static_cast(encode_time); } -const char* ExcludeFrameTypesToStr(ExcludeFrameTypes e) { - switch (e) { - case kExcludeOnlyFirstKeyFrame: - return "ExcludeOnlyFirstKeyFrame"; - case kExcludeAllKeyFrames: - return "ExcludeAllKeyFrames"; - default: - RTC_NOTREACHED(); - return "Unknown"; - } -} - -// Callbacks -EncodedImageCallback::Result -VideoProcessorImpl::VideoProcessorEncodeCompleteCallback::OnEncodedImage( - const EncodedImage& encoded_image, - const webrtc::CodecSpecificInfo* codec_specific_info, - const webrtc::RTPFragmentationHeader* fragmentation) { - // Forward to parent class. - RTC_CHECK(codec_specific_info); - video_processor_->FrameEncoded(codec_specific_info->codecType, - encoded_image, - fragmentation); - return Result(Result::OK, 0); -} -int32_t VideoProcessorImpl::VideoProcessorDecodeCompleteCallback::Decoded( - VideoFrame& image) { - // Forward to parent class. - video_processor_->FrameDecoded(image); - return 0; -} - } // namespace test } // namespace webrtc diff --git a/webrtc/modules/video_coding/codecs/test/videoprocessor.h b/webrtc/modules/video_coding/codecs/test/videoprocessor.h index 6290d8bee5..736acc64c0 100644 --- a/webrtc/modules/video_coding/codecs/test/videoprocessor.h +++ b/webrtc/modules/video_coding/codecs/test/videoprocessor.h @@ -38,10 +38,11 @@ enum ExcludeFrameTypes { // sequence they occur. kExcludeAllKeyFrames }; + // Returns a string representation of the enum value. const char* ExcludeFrameTypesToStr(ExcludeFrameTypes e); -// Test configuration for a test run +// Test configuration for a test run. struct TestConfig { TestConfig(); ~TestConfig(); @@ -136,7 +137,7 @@ class VideoProcessor { // Processes a single frame. Returns true as long as there's more frames // available in the source clip. - // Frame number must be an integer >=0. + // Frame number must be an integer >= 0. virtual bool ProcessFrame(int frame_number) = 0; // Updates the encoder with the target bit rate and the frame rate. @@ -170,59 +171,6 @@ class VideoProcessorImpl : public VideoProcessor { bool ProcessFrame(int frame_number) override; private: - // Invoked by the callback when a frame has completed encoding. - void FrameEncoded(webrtc::VideoCodecType codec, - const webrtc::EncodedImage& encodedImage, - const webrtc::RTPFragmentationHeader* fragmentation); - // Invoked by the callback when a frame has completed decoding. - void FrameDecoded(const webrtc::VideoFrame& image); - // Used for getting a 32-bit integer representing time - // (checks the size is within signed 32-bit bounds before casting it) - int GetElapsedTimeMicroseconds(int64_t start, int64_t stop); - // Updates the encoder with the target bit rate and the frame rate. - void SetRates(int bit_rate, int frame_rate) override; - // Return the size of the encoded frame in bytes. - size_t EncodedFrameSize() override; - // Return the encoded frame type (key or delta). - FrameType EncodedFrameType() override; - // Return the number of dropped frames. - int NumberDroppedFrames() override; - // Return the number of spatial resizes. - int NumberSpatialResizes() override; - - webrtc::VideoEncoder* const encoder_; - webrtc::VideoDecoder* const decoder_; - std::unique_ptr bitrate_allocator_; - FrameReader* const frame_reader_; - FrameWriter* const frame_writer_; - PacketManipulator* const packet_manipulator_; - const TestConfig& config_; - Stats* stats_; - - std::unique_ptr encode_callback_; - std::unique_ptr decode_callback_; - // Keep track of the last successful frame, since we need to write that - // when decoding fails: - std::unique_ptr last_successful_frame_buffer_; - // To keep track of if we have excluded the first key frame from packet loss: - bool first_key_frame_has_been_excluded_; - // To tell the decoder previous frame have been dropped due to packet loss: - bool last_frame_missing_; - // If Init() has executed successfully. - bool initialized_; - size_t encoded_frame_size_; - FrameType encoded_frame_type_; - int prev_time_stamp_; - int num_dropped_frames_; - int num_spatial_resizes_; - int last_encoder_frame_width_; - int last_encoder_frame_height_; - - // Statistics - double bit_rate_factor_; // multiply frame length with this to get bit rate - int64_t encode_start_ns_; - int64_t decode_start_ns_; - // Callback class required to implement according to the VideoEncoder API. class VideoProcessorEncodeCompleteCallback : public webrtc::EncodedImageCallback { @@ -232,7 +180,13 @@ class VideoProcessorImpl : public VideoProcessor { Result OnEncodedImage( const webrtc::EncodedImage& encoded_image, const webrtc::CodecSpecificInfo* codec_specific_info, - const webrtc::RTPFragmentationHeader* fragmentation) override; + const webrtc::RTPFragmentationHeader* fragmentation) override { + // Forward to parent class. + RTC_CHECK(codec_specific_info); + video_processor_->FrameEncoded(codec_specific_info->codecType, + encoded_image, fragmentation); + return Result(Result::OK, 0); + } private: VideoProcessorImpl* const video_processor_; @@ -244,7 +198,11 @@ class VideoProcessorImpl : public VideoProcessor { public: explicit VideoProcessorDecodeCompleteCallback(VideoProcessorImpl* vp) : video_processor_(vp) {} - int32_t Decoded(webrtc::VideoFrame& image) override; + int32_t Decoded(webrtc::VideoFrame& image) override { + // Forward to parent class. + video_processor_->FrameDecoded(image); + return 0; + } int32_t Decoded(webrtc::VideoFrame& image, int64_t decode_time_ms) override { RTC_NOTREACHED(); @@ -259,6 +217,67 @@ class VideoProcessorImpl : public VideoProcessor { private: VideoProcessorImpl* const video_processor_; }; + + // Invoked by the callback when a frame has completed encoding. + void FrameEncoded(webrtc::VideoCodecType codec, + const webrtc::EncodedImage& encodedImage, + const webrtc::RTPFragmentationHeader* fragmentation); + + // Invoked by the callback when a frame has completed decoding. + void FrameDecoded(const webrtc::VideoFrame& image); + + // Used for getting a 32-bit integer representing time + // (checks the size is within signed 32-bit bounds before casting it) + int GetElapsedTimeMicroseconds(int64_t start, int64_t stop); + + // Updates the encoder with the target bit rate and the frame rate. + void SetRates(int bit_rate, int frame_rate) override; + + // Return the size of the encoded frame in bytes. + size_t EncodedFrameSize() override; + + // Return the encoded frame type (key or delta). + FrameType EncodedFrameType() override; + + // Return the number of dropped frames. + int NumberDroppedFrames() override; + + // Return the number of spatial resizes. + int NumberSpatialResizes() override; + + webrtc::VideoEncoder* const encoder_; + webrtc::VideoDecoder* const decoder_; + std::unique_ptr bitrate_allocator_; + FrameReader* const frame_reader_; + FrameWriter* const frame_writer_; + PacketManipulator* const packet_manipulator_; + const TestConfig& config_; + Stats* stats_; + + std::unique_ptr encode_callback_; + std::unique_ptr decode_callback_; + + // Keep track of the last successful frame, since we need to write that + // when decoding fails. + std::unique_ptr last_successful_frame_buffer_; + // To keep track of if we have excluded the first key frame from packet loss. + bool first_key_frame_has_been_excluded_; + // To tell the decoder previous frame have been dropped due to packet loss. + bool last_frame_missing_; + // If Init() has executed successfully. + bool initialized_; + size_t encoded_frame_size_; + FrameType encoded_frame_type_; + int prev_time_stamp_; + int num_dropped_frames_; + int num_spatial_resizes_; + int last_encoder_frame_width_; + int last_encoder_frame_height_; + + // Statistics. + double bit_rate_factor_; // Multiply frame length with this to get bit rate. + int64_t encode_start_ns_; + int64_t decode_start_ns_; }; } // namespace test diff --git a/webrtc/modules/video_coding/codecs/test/videoprocessor_integrationtest.cc b/webrtc/modules/video_coding/codecs/test/videoprocessor_integrationtest.cc index 88f5b0e3f8..841303e7e4 100644 --- a/webrtc/modules/video_coding/codecs/test/videoprocessor_integrationtest.cc +++ b/webrtc/modules/video_coding/codecs/test/videoprocessor_integrationtest.cc @@ -24,8 +24,8 @@ TEST_F(VideoProcessorIntegrationTest, Process0PercentPacketLossH264) { // Bitrate and frame rate profile. RateProfile rate_profile; SetRateProfilePars(&rate_profile, 0, 500, 30, 0); - rate_profile.frame_index_rate_update[1] = kNbrFramesShort + 1; - rate_profile.num_frames = kNbrFramesShort; + rate_profile.frame_index_rate_update[1] = kNumFramesShort + 1; + rate_profile.num_frames = kNumFramesShort; // Codec/network settings. CodecConfigPars process_settings; SetCodecParameters(&process_settings, kVideoCodecH264, 0.0f, -1, 1, false, @@ -55,8 +55,8 @@ TEST_F(VideoProcessorIntegrationTest, Process0PercentPacketLossVP9) { // Bitrate and frame rate profile. RateProfile rate_profile; SetRateProfilePars(&rate_profile, 0, 500, 30, 0); - rate_profile.frame_index_rate_update[1] = kNbrFramesShort + 1; - rate_profile.num_frames = kNbrFramesShort; + rate_profile.frame_index_rate_update[1] = kNumFramesShort + 1; + rate_profile.num_frames = kNumFramesShort; // Codec/network settings. CodecConfigPars process_settings; SetCodecParameters(&process_settings, kVideoCodecVP9, 0.0f, -1, 1, false, @@ -77,8 +77,8 @@ TEST_F(VideoProcessorIntegrationTest, Process5PercentPacketLossVP9) { // Bitrate and frame rate profile. RateProfile rate_profile; SetRateProfilePars(&rate_profile, 0, 500, 30, 0); - rate_profile.frame_index_rate_update[1] = kNbrFramesShort + 1; - rate_profile.num_frames = kNbrFramesShort; + rate_profile.frame_index_rate_update[1] = kNumFramesShort + 1; + rate_profile.num_frames = kNumFramesShort; // Codec/network settings. CodecConfigPars process_settings; SetCodecParameters(&process_settings, kVideoCodecVP9, 0.05f, -1, 1, false, @@ -103,8 +103,8 @@ TEST_F(VideoProcessorIntegrationTest, ProcessNoLossChangeBitRateVP9) { SetRateProfilePars(&rate_profile, 0, 200, 30, 0); SetRateProfilePars(&rate_profile, 1, 700, 30, 100); SetRateProfilePars(&rate_profile, 2, 500, 30, 200); - rate_profile.frame_index_rate_update[3] = kNbrFramesLong + 1; - rate_profile.num_frames = kNbrFramesLong; + rate_profile.frame_index_rate_update[3] = kNumFramesLong + 1; + rate_profile.num_frames = kNumFramesLong; // Codec/network settings. CodecConfigPars process_settings; SetCodecParameters(&process_settings, kVideoCodecVP9, 0.0f, -1, 1, false, @@ -136,8 +136,8 @@ TEST_F(VideoProcessorIntegrationTest, SetRateProfilePars(&rate_profile, 0, 100, 24, 0); SetRateProfilePars(&rate_profile, 1, 100, 15, 100); SetRateProfilePars(&rate_profile, 2, 100, 10, 200); - rate_profile.frame_index_rate_update[3] = kNbrFramesLong + 1; - rate_profile.num_frames = kNbrFramesLong; + rate_profile.frame_index_rate_update[3] = kNumFramesLong + 1; + rate_profile.num_frames = kNumFramesLong; // Codec/network settings. CodecConfigPars process_settings; SetCodecParameters(&process_settings, kVideoCodecVP9, 0.0f, -1, 1, false, @@ -159,8 +159,8 @@ TEST_F(VideoProcessorIntegrationTest, ProcessNoLossDenoiserOnVP9) { // Bitrate and frame rate profile. RateProfile rate_profile; SetRateProfilePars(&rate_profile, 0, 500, 30, 0); - rate_profile.frame_index_rate_update[1] = kNbrFramesShort + 1; - rate_profile.num_frames = kNbrFramesShort; + rate_profile.frame_index_rate_update[1] = kNumFramesShort + 1; + rate_profile.num_frames = kNumFramesShort; // Codec/network settings. CodecConfigPars process_settings; SetCodecParameters(&process_settings, kVideoCodecVP9, 0.0f, -1, 1, false, @@ -184,8 +184,8 @@ TEST_F(VideoProcessorIntegrationTest, // Bitrate and frame rate profile. RateProfile rate_profile; SetRateProfilePars(&rate_profile, 0, 50, 30, 0); - rate_profile.frame_index_rate_update[1] = kNbrFramesLong + 1; - rate_profile.num_frames = kNbrFramesLong; + rate_profile.frame_index_rate_update[1] = kNumFramesLong + 1; + rate_profile.num_frames = kNumFramesLong; // Codec/network settings. CodecConfigPars process_settings; SetCodecParameters(&process_settings, kVideoCodecVP9, 0.0f, -1, 1, false, @@ -212,8 +212,8 @@ TEST_F(VideoProcessorIntegrationTest, ProcessZeroPacketLoss) { // Bitrate and frame rate profile. RateProfile rate_profile; SetRateProfilePars(&rate_profile, 0, 500, 30, 0); - rate_profile.frame_index_rate_update[1] = kNbrFramesShort + 1; - rate_profile.num_frames = kNbrFramesShort; + rate_profile.frame_index_rate_update[1] = kNumFramesShort + 1; + rate_profile.num_frames = kNumFramesShort; // Codec/network settings. CodecConfigPars process_settings; SetCodecParameters(&process_settings, kVideoCodecVP8, 0.0f, -1, 1, false, @@ -234,8 +234,8 @@ TEST_F(VideoProcessorIntegrationTest, Process5PercentPacketLoss) { // Bitrate and frame rate profile. RateProfile rate_profile; SetRateProfilePars(&rate_profile, 0, 500, 30, 0); - rate_profile.frame_index_rate_update[1] = kNbrFramesShort + 1; - rate_profile.num_frames = kNbrFramesShort; + rate_profile.frame_index_rate_update[1] = kNumFramesShort + 1; + rate_profile.num_frames = kNumFramesShort; // Codec/network settings. CodecConfigPars process_settings; SetCodecParameters(&process_settings, kVideoCodecVP8, 0.05f, -1, 1, false, @@ -256,8 +256,8 @@ TEST_F(VideoProcessorIntegrationTest, Process10PercentPacketLoss) { // Bitrate and frame rate profile. RateProfile rate_profile; SetRateProfilePars(&rate_profile, 0, 500, 30, 0); - rate_profile.frame_index_rate_update[1] = kNbrFramesShort + 1; - rate_profile.num_frames = kNbrFramesShort; + rate_profile.frame_index_rate_update[1] = kNumFramesShort + 1; + rate_profile.num_frames = kNumFramesShort; // Codec/network settings. CodecConfigPars process_settings; SetCodecParameters(&process_settings, kVideoCodecVP8, 0.1f, -1, 1, false, @@ -300,8 +300,8 @@ TEST_F(VideoProcessorIntegrationTest, MAYBE_ProcessNoLossChangeBitRateVP8) { SetRateProfilePars(&rate_profile, 0, 200, 30, 0); SetRateProfilePars(&rate_profile, 1, 800, 30, 100); SetRateProfilePars(&rate_profile, 2, 500, 30, 200); - rate_profile.frame_index_rate_update[3] = kNbrFramesLong + 1; - rate_profile.num_frames = kNbrFramesLong; + rate_profile.frame_index_rate_update[3] = kNumFramesLong + 1; + rate_profile.num_frames = kNumFramesLong; // Codec/network settings. CodecConfigPars process_settings; SetCodecParameters(&process_settings, kVideoCodecVP8, 0.0f, -1, 1, false, @@ -341,8 +341,8 @@ TEST_F(VideoProcessorIntegrationTest, SetRateProfilePars(&rate_profile, 0, 80, 24, 0); SetRateProfilePars(&rate_profile, 1, 80, 15, 100); SetRateProfilePars(&rate_profile, 2, 80, 10, 200); - rate_profile.frame_index_rate_update[3] = kNbrFramesLong + 1; - rate_profile.num_frames = kNbrFramesLong; + rate_profile.frame_index_rate_update[3] = kNumFramesLong + 1; + rate_profile.num_frames = kNumFramesLong; // Codec/network settings. CodecConfigPars process_settings; SetCodecParameters(&process_settings, kVideoCodecVP8, 0.0f, -1, 1, false, @@ -377,8 +377,8 @@ TEST_F(VideoProcessorIntegrationTest, MAYBE_ProcessNoLossTemporalLayersVP8) { RateProfile rate_profile; SetRateProfilePars(&rate_profile, 0, 200, 30, 0); SetRateProfilePars(&rate_profile, 1, 400, 30, 150); - rate_profile.frame_index_rate_update[2] = kNbrFramesLong + 1; - rate_profile.num_frames = kNbrFramesLong; + rate_profile.frame_index_rate_update[2] = kNumFramesLong + 1; + rate_profile.num_frames = kNumFramesLong; // Codec/network settings. CodecConfigPars process_settings; SetCodecParameters(&process_settings, kVideoCodecVP8, 0.0f, -1, 3, false, diff --git a/webrtc/modules/video_coding/codecs/test/videoprocessor_integrationtest.h b/webrtc/modules/video_coding/codecs/test/videoprocessor_integrationtest.h index f244bea183..54700c1b53 100644 --- a/webrtc/modules/video_coding/codecs/test/videoprocessor_integrationtest.h +++ b/webrtc/modules/video_coding/codecs/test/videoprocessor_integrationtest.h @@ -16,6 +16,7 @@ #include #include +#include "webrtc/base/checks.h" #include "webrtc/modules/video_coding/codecs/h264/include/h264.h" #include "webrtc/modules/video_coding/codecs/test/packet_manipulator.h" #include "webrtc/modules/video_coding/codecs/test/videoprocessor.h" @@ -97,9 +98,9 @@ struct RateControlMetrics { }; #if !defined(WEBRTC_IOS) -const int kNbrFramesShort = 100; // Some tests are run for shorter sequence. +const int kNumFramesShort = 100; #endif -const int kNbrFramesLong = 299; +const int kNumFramesLong = 299; // Parameters from VP8 wrapper, which control target size of key frames. const float kInitialBufferSize = 0.5f; @@ -116,52 +117,6 @@ const float kScaleKeyFrameSize = 0.5f; // happen when some significant regression or breakdown occurs. class VideoProcessorIntegrationTest : public testing::Test { protected: - std::unique_ptr encoder_; - std::unique_ptr decoder_; - std::unique_ptr frame_reader_; - std::unique_ptr frame_writer_; - test::PacketReader packet_reader_; - std::unique_ptr packet_manipulator_; - test::Stats stats_; - test::TestConfig config_; - VideoCodec codec_settings_; - std::unique_ptr processor_; - TemporalLayersFactory tl_factory_; - - // Quantities defined/updated for every encoder rate update. - // Some quantities defined per temporal layer (at most 3 layers in this test). - int num_frames_per_update_[3]; - float sum_frame_size_mismatch_[3]; - float sum_encoded_frame_size_[3]; - float encoding_bitrate_[3]; - float per_frame_bandwidth_[3]; - float bit_rate_layer_[3]; - float frame_rate_layer_[3]; - int num_frames_total_; - float sum_encoded_frame_size_total_; - float encoding_bitrate_total_; - float perc_encoding_rate_mismatch_; - int num_frames_to_hit_target_; - bool encoding_rate_within_target_; - int bit_rate_; - int frame_rate_; - int layer_; - float target_size_key_frame_initial_; - float target_size_key_frame_; - float sum_key_frame_size_mismatch_; - int num_key_frames_; - float start_bitrate_; - - // Codec and network settings. - VideoCodecType codec_type_; - float packet_loss_; - int num_temporal_layers_; - int key_frame_interval_; - bool error_concealment_on_; - bool denoising_on_; - bool frame_dropper_on_; - bool spatial_resize_on_; - VideoProcessorIntegrationTest() {} virtual ~VideoProcessorIntegrationTest() {} @@ -230,7 +185,7 @@ class VideoProcessorIntegrationTest : public testing::Test { config_.codec_settings->VP9()->keyFrameInterval = kBaseKeyFrameInterval; break; default: - assert(false); + RTC_NOTREACHED(); break; } frame_reader_.reset(new test::FrameReaderImpl( @@ -238,15 +193,15 @@ class VideoProcessorIntegrationTest : public testing::Test { config_.codec_settings->height)); frame_writer_.reset(new test::FrameWriterImpl( config_.output_filename, config_.frame_length_in_bytes)); - ASSERT_TRUE(frame_reader_->Init()); - ASSERT_TRUE(frame_writer_->Init()); + RTC_CHECK(frame_reader_->Init()); + RTC_CHECK(frame_writer_->Init()); packet_manipulator_.reset(new test::PacketManipulatorImpl( &packet_reader_, config_.networking_config, config_.verbose)); processor_.reset(new test::VideoProcessorImpl( encoder_.get(), decoder_.get(), frame_reader_.get(), frame_writer_.get(), packet_manipulator_.get(), config_, &stats_)); - ASSERT_TRUE(processor_->Init()); + RTC_CHECK(processor_->Init()); } // Reset quantities after each encoder update, update the target @@ -401,13 +356,13 @@ class VideoProcessorIntegrationTest : public testing::Test { layer_ = 2; } } else { - assert(false); // Only up to 3 layers. + RTC_NOTREACHED() << "Max 3 layers are supported."; } } // Set the bitrate and frame rate per layer, for up to 3 layers. void SetLayerRates() { - assert(num_temporal_layers_ <= 3); + RTC_DCHECK_LE(num_temporal_layers_, 3); for (int i = 0; i < num_temporal_layers_; i++) { float bit_rate_ratio = kVp8LayerRateAlloction[num_temporal_layers_ - 1][i]; @@ -452,6 +407,7 @@ class VideoProcessorIntegrationTest : public testing::Test { target_size_key_frame_initial_ = 0.5 * kInitialBufferSize * bit_rate_layer_[0]; processor_->SetRates(bit_rate_, frame_rate_); + // Process each frame, up to |num_frames|. int num_frames = rate_profile.num_frames; int update_index = 0; @@ -507,6 +463,7 @@ class VideoProcessorIntegrationTest : public testing::Test { // Release encoder and decoder to make sure they have finished processing: EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK, encoder_->Release()); EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK, decoder_->Release()); + // Close the files before we start using them for SSIM/PSNR calculations. frame_reader_->Close(); frame_writer_->Close(); @@ -616,6 +573,52 @@ class VideoProcessorIntegrationTest : public testing::Test { rc_metrics[update_index].num_spatial_resizes = num_spatial_resizes; rc_metrics[update_index].num_key_frames = num_key_frames; } + + std::unique_ptr encoder_; + std::unique_ptr decoder_; + std::unique_ptr frame_reader_; + std::unique_ptr frame_writer_; + test::PacketReader packet_reader_; + std::unique_ptr packet_manipulator_; + test::Stats stats_; + test::TestConfig config_; + VideoCodec codec_settings_; + std::unique_ptr processor_; + TemporalLayersFactory tl_factory_; + + // Quantities defined/updated for every encoder rate update. + // Some quantities defined per temporal layer (at most 3 layers in this test). + int num_frames_per_update_[3]; + float sum_frame_size_mismatch_[3]; + float sum_encoded_frame_size_[3]; + float encoding_bitrate_[3]; + float per_frame_bandwidth_[3]; + float bit_rate_layer_[3]; + float frame_rate_layer_[3]; + int num_frames_total_; + float sum_encoded_frame_size_total_; + float encoding_bitrate_total_; + float perc_encoding_rate_mismatch_; + int num_frames_to_hit_target_; + bool encoding_rate_within_target_; + int bit_rate_; + int frame_rate_; + int layer_; + float target_size_key_frame_initial_; + float target_size_key_frame_; + float sum_key_frame_size_mismatch_; + int num_key_frames_; + float start_bitrate_; + + // Codec and network settings. + VideoCodecType codec_type_; + float packet_loss_; + int num_temporal_layers_; + int key_frame_interval_; + bool error_concealment_on_; + bool denoising_on_; + bool frame_dropper_on_; + bool spatial_resize_on_; }; } // namespace test