Get rid of packet loss related stuff from videoprocessor.

This feature is not needed in video codec testing framework. In WebRTC
video codecs never deal with packet loss. Packet loss is handled by
jitter buffer which prevents passing of incomplete frames to decoder.

Bug: webrtc:8768
Change-Id: I211cf51d913bec6a1f935e30691661d428ebd3b6
Reviewed-on: https://webrtc-review.googlesource.com/40740
Commit-Queue: Sergey Silkin <ssilkin@webrtc.org>
Reviewed-by: Stefan Holmer <stefan@webrtc.org>
Reviewed-by: Rasmus Brandt <brandtr@webrtc.org>
Reviewed-by: Åsa Persson <asapersson@webrtc.org>
Cr-Commit-Position: refs/heads/master@{#21722}
This commit is contained in:
Sergey Silkin 2018-01-22 15:49:55 +01:00 committed by Commit Bot
parent e93de5ff70
commit 1723cf9fa2
17 changed files with 13 additions and 687 deletions

View file

@ -480,9 +480,6 @@ if (rtc_include_tests) {
rtc_source_set("video_codecs_test_framework") { rtc_source_set("video_codecs_test_framework") {
testonly = true testonly = true
sources = [ sources = [
"codecs/test/mock/mock_packet_manipulator.h",
"codecs/test/packet_manipulator.cc",
"codecs/test/packet_manipulator.h",
"codecs/test/stats.cc", "codecs/test/stats.cc",
"codecs/test/stats.h", "codecs/test/stats.h",
"codecs/test/test_config.cc", "codecs/test/test_config.cc",
@ -629,7 +626,6 @@ if (rtc_include_tests) {
testonly = true testonly = true
sources = [ sources = [
"codecs/test/packet_manipulator_unittest.cc",
"codecs/test/stats_unittest.cc", "codecs/test/stats_unittest.cc",
"codecs/test/test_config_unittest.cc", "codecs/test/test_config_unittest.cc",
"codecs/test/videoprocessor_unittest.cc", "codecs/test/videoprocessor_unittest.cc",

View file

@ -1,32 +0,0 @@
/*
* Copyright (c) 2011 The WebRTC project authors. All Rights Reserved.
*
* Use of this source code is governed by a BSD-style license
* that can be found in the LICENSE file in the root of the source
* tree. An additional intellectual property rights grant can be found
* in the file PATENTS. All contributing project authors may
* be found in the AUTHORS file in the root of the source tree.
*/
#ifndef MODULES_VIDEO_CODING_CODECS_TEST_MOCK_MOCK_PACKET_MANIPULATOR_H_
#define MODULES_VIDEO_CODING_CODECS_TEST_MOCK_MOCK_PACKET_MANIPULATOR_H_
#include <string>
#include "modules/video_coding/codecs/test/packet_manipulator.h"
#include "test/gmock.h"
#include "typedefs.h" // NOLINT(build/include)
#include "common_video/include/video_frame.h"
namespace webrtc {
namespace test {
class MockPacketManipulator : public PacketManipulator {
public:
MOCK_METHOD1(ManipulatePackets, int(webrtc::EncodedImage* encoded_image));
};
} // namespace test
} // namespace webrtc
#endif // MODULES_VIDEO_CODING_CODECS_TEST_MOCK_MOCK_PACKET_MANIPULATOR_H_

View file

@ -1,95 +0,0 @@
/*
* Copyright (c) 2012 The WebRTC project authors. All Rights Reserved.
*
* Use of this source code is governed by a BSD-style license
* that can be found in the LICENSE file in the root of the source
* tree. An additional intellectual property rights grant can be found
* in the file PATENTS. All contributing project authors may
* be found in the AUTHORS file in the root of the source tree.
*/
#include "modules/video_coding/codecs/test/packet_manipulator.h"
#include <stdio.h>
#include "rtc_base/checks.h"
#include "rtc_base/format_macros.h"
namespace webrtc {
namespace test {
PacketManipulatorImpl::PacketManipulatorImpl(PacketReader* packet_reader,
const NetworkingConfig& config,
bool verbose)
: packet_reader_(packet_reader),
config_(config),
verbose_(verbose),
active_burst_packets_(0),
random_seed_(1) {
RTC_DCHECK(packet_reader);
}
int PacketManipulatorImpl::ManipulatePackets(
webrtc::EncodedImage* encoded_image) {
int nbr_packets_dropped = 0;
// There's no need to build a copy of the image data since viewing an
// EncodedImage object, setting the length to a new lower value represents
// that everything is dropped after that position in the byte array.
// EncodedImage._size is the allocated bytes.
// EncodedImage._length is how many that are filled with data.
int new_length = 0;
packet_reader_->InitializeReading(encoded_image->_buffer,
encoded_image->_length,
config_.packet_size_in_bytes);
uint8_t* packet = nullptr;
int nbr_bytes_to_read;
// keep track of if we've lost any packets, since then we shall loose
// the remains of the current frame:
bool packet_loss_has_occurred = false;
while ((nbr_bytes_to_read = packet_reader_->NextPacket(&packet)) > 0) {
// Check if we're currently in a packet loss burst that is not completed:
if (active_burst_packets_ > 0) {
active_burst_packets_--;
nbr_packets_dropped++;
} else if (RandomUniform() < config_.packet_loss_probability ||
packet_loss_has_occurred) {
packet_loss_has_occurred = true;
nbr_packets_dropped++;
if (config_.packet_loss_mode == kBurst) {
// Initiate a new burst
active_burst_packets_ = config_.packet_loss_burst_length - 1;
}
} else {
new_length += nbr_bytes_to_read;
}
}
encoded_image->_length = new_length;
if (nbr_packets_dropped > 0) {
// Must set completeFrame to false to inform the decoder about this:
encoded_image->_completeFrame = false;
if (verbose_) {
printf("Dropped %d packets for frame %d (frame length: %" PRIuS ")\n",
nbr_packets_dropped, encoded_image->_timeStamp,
encoded_image->_length);
}
}
return nbr_packets_dropped;
}
void PacketManipulatorImpl::InitializeRandomSeed(unsigned int seed) {
random_seed_ = seed;
}
inline double PacketManipulatorImpl::RandomUniform() {
// Use the previous result as new seed before each rand() call. Doing this
// it doesn't matter if other threads are calling rand() since we'll always
// get the same behavior as long as we're using a fixed initial seed.
critsect_.Enter();
srand(random_seed_);
random_seed_ = rand(); // NOLINT (rand_r instead of rand)
critsect_.Leave();
return (random_seed_ + 1.0) / (RAND_MAX + 1.0);
}
} // namespace test
} // namespace webrtc

View file

@ -1,112 +0,0 @@
/*
* Copyright (c) 2012 The WebRTC project authors. All Rights Reserved.
*
* Use of this source code is governed by a BSD-style license
* that can be found in the LICENSE file in the root of the source
* tree. An additional intellectual property rights grant can be found
* in the file PATENTS. All contributing project authors may
* be found in the AUTHORS file in the root of the source tree.
*/
#ifndef MODULES_VIDEO_CODING_CODECS_TEST_PACKET_MANIPULATOR_H_
#define MODULES_VIDEO_CODING_CODECS_TEST_PACKET_MANIPULATOR_H_
#include <stdlib.h>
#include "modules/video_coding/include/video_codec_interface.h"
#include "rtc_base/criticalsection.h"
#include "test/testsupport/packet_reader.h"
namespace webrtc {
namespace test {
// Which mode the packet loss shall be performed according to.
enum PacketLossMode {
// Drops packets with a configured probability independently for each packet
kUniform,
// Drops packets similar to uniform but when a packet is being dropped, the
// number of lost packets in a row is equal to the configured burst length.
kBurst
};
// Contains configurations related to networking and simulation of
// scenarios caused by network interference.
struct NetworkingConfig {
NetworkingConfig()
: packet_size_in_bytes(1500),
max_payload_size_in_bytes(1440),
packet_loss_mode(kUniform),
packet_loss_probability(0.0),
packet_loss_burst_length(1) {}
// Packet size in bytes. Default: 1500 bytes.
size_t packet_size_in_bytes;
// Encoder specific setting of maximum size in bytes of each payload.
// Default: 1440 bytes.
size_t max_payload_size_in_bytes;
// Packet loss mode. Two different packet loss models are supported:
// uniform or burst. This setting has no effect unless
// packet_loss_probability is >0.
// Default: uniform.
PacketLossMode packet_loss_mode;
// Packet loss probability. A value between 0.0 and 1.0 that defines the
// probability of a packet being lost. 0.1 means 10% and so on.
// Default: 0 (no loss).
double packet_loss_probability;
// Packet loss burst length. Defines how many packets will be lost in a burst
// when a packet has been decided to be lost. Must be >=1. Default: 1.
int packet_loss_burst_length;
};
// Class for simulating packet loss on the encoded frame data.
// When a packet loss has occurred in a frame, the remaining data in that
// frame is lost (even if burst length is only a single packet).
// TODO(kjellander): Support discarding only individual packets in the frame
// when CL 172001 has been submitted. This also requires a correct
// fragmentation header to be passed to the decoder.
//
// To get a repeatable packet drop pattern, re-initialize the random seed
// using InitializeRandomSeed before each test run.
class PacketManipulator {
public:
virtual ~PacketManipulator() {}
// Manipulates the data of the encoded_image to simulate parts being lost
// during transport.
// If packets are dropped from frame data, the completedFrame field will be
// set to false.
// Returns the number of packets being dropped.
virtual int ManipulatePackets(webrtc::EncodedImage* encoded_image) = 0;
};
class PacketManipulatorImpl : public PacketManipulator {
public:
PacketManipulatorImpl(PacketReader* packet_reader,
const NetworkingConfig& config,
bool verbose);
~PacketManipulatorImpl() = default;
int ManipulatePackets(webrtc::EncodedImage* encoded_image) override;
virtual void InitializeRandomSeed(unsigned int seed);
protected:
// Returns a uniformly distributed random value between 0.0 and 1.0
virtual double RandomUniform();
private:
PacketReader* const packet_reader_;
const NetworkingConfig& config_;
const bool verbose_;
// Used to simulate a burst over several frames.
int active_burst_packets_;
rtc::CriticalSection critsect_;
unsigned int random_seed_;
};
} // namespace test
} // namespace webrtc
#endif // MODULES_VIDEO_CODING_CODECS_TEST_PACKET_MANIPULATOR_H_

View file

@ -1,96 +0,0 @@
/*
* Copyright (c) 2012 The WebRTC project authors. All Rights Reserved.
*
* Use of this source code is governed by a BSD-style license
* that can be found in the LICENSE file in the root of the source
* tree. An additional intellectual property rights grant can be found
* in the file PATENTS. All contributing project authors may
* be found in the AUTHORS file in the root of the source tree.
*/
#include "modules/video_coding/codecs/test/packet_manipulator.h"
#include <queue>
#include "modules/video_coding/include/video_codec_interface.h"
#include "test/gtest.h"
#include "test/testsupport/unittest_utils.h"
#include "typedefs.h" // NOLINT(build/include)
namespace webrtc {
namespace test {
const double kNeverDropProbability = 0.0;
const double kAlwaysDropProbability = 1.0;
const int kBurstLength = 1;
class PacketManipulatorTest : public PacketRelatedTest {
protected:
PacketReader packet_reader_;
EncodedImage image_;
NetworkingConfig drop_config_;
NetworkingConfig no_drop_config_;
PacketManipulatorTest() {
image_._buffer = packet_data_;
image_._length = kPacketDataLength;
image_._size = kPacketDataLength;
drop_config_.packet_size_in_bytes = kPacketSizeInBytes;
drop_config_.packet_loss_probability = kAlwaysDropProbability;
drop_config_.packet_loss_burst_length = kBurstLength;
drop_config_.packet_loss_mode = kUniform;
no_drop_config_.packet_size_in_bytes = kPacketSizeInBytes;
no_drop_config_.packet_loss_probability = kNeverDropProbability;
no_drop_config_.packet_loss_burst_length = kBurstLength;
no_drop_config_.packet_loss_mode = kUniform;
}
virtual ~PacketManipulatorTest() {}
void SetUp() { PacketRelatedTest::SetUp(); }
void TearDown() { PacketRelatedTest::TearDown(); }
void VerifyPacketLoss(int expected_nbr_packets_dropped,
int actual_nbr_packets_dropped,
size_t expected_packet_data_length,
uint8_t* expected_packet_data,
const EncodedImage& actual_image) {
EXPECT_EQ(expected_nbr_packets_dropped, actual_nbr_packets_dropped);
EXPECT_EQ(expected_packet_data_length, image_._length);
EXPECT_EQ(0, memcmp(expected_packet_data, actual_image._buffer,
expected_packet_data_length));
}
};
TEST_F(PacketManipulatorTest, Constructor) {
PacketManipulatorImpl manipulator(&packet_reader_, no_drop_config_, false);
}
TEST_F(PacketManipulatorTest, DropNone) {
PacketManipulatorImpl manipulator(&packet_reader_, no_drop_config_, false);
int nbr_packets_dropped = manipulator.ManipulatePackets(&image_);
VerifyPacketLoss(0, nbr_packets_dropped, kPacketDataLength, packet_data_,
image_);
}
TEST_F(PacketManipulatorTest, UniformDropNoneSmallFrame) {
size_t data_length = 400; // smaller than the packet size
image_._length = data_length;
PacketManipulatorImpl manipulator(&packet_reader_, no_drop_config_, false);
int nbr_packets_dropped = manipulator.ManipulatePackets(&image_);
VerifyPacketLoss(0, nbr_packets_dropped, data_length, packet_data_, image_);
}
TEST_F(PacketManipulatorTest, UniformDropAll) {
PacketManipulatorImpl manipulator(&packet_reader_, drop_config_, false);
int nbr_packets_dropped = manipulator.ManipulatePackets(&image_);
VerifyPacketLoss(kPacketDataNumberOfPackets, nbr_packets_dropped, 0,
packet_data_, image_);
}
} // namespace test
} // namespace webrtc

View file

@ -57,11 +57,6 @@ struct FrameStatistic {
// Quantization. // Quantization.
int qp = -1; int qp = -1;
// How many packets were discarded of the encoded frame data (if any).
size_t packets_dropped = 0;
size_t total_packets = 0;
size_t manipulated_length = 0;
// Quality. // Quality.
float psnr = 0.0; float psnr = 0.0;
float ssim = 0.0; float ssim = 0.0;

View file

@ -16,21 +16,11 @@
#include "common_types.h" // NOLINT(build/include) #include "common_types.h" // NOLINT(build/include)
#include "modules/video_coding/codecs/h264/include/h264_globals.h" #include "modules/video_coding/codecs/h264/include/h264_globals.h"
#include "modules/video_coding/codecs/test/packet_manipulator.h" #include "modules/video_coding/include/video_codec_interface.h"
namespace webrtc { namespace webrtc {
namespace test { namespace test {
// Defines which frame types shall be excluded from packet loss and when.
enum ExcludeFrameTypes {
// Will exclude the first keyframe in the video sequence from packet loss.
// Following keyframes will be targeted for packet loss.
kExcludeOnlyFirstKeyFrame,
// Exclude all keyframes from packet loss, no matter where in the video
// sequence they occur.
kExcludeAllKeyFrames
};
// Test configuration for a test run. // Test configuration for a test run.
struct TestConfig { struct TestConfig {
class EncodedFrameChecker { class EncodedFrameChecker {
@ -73,12 +63,8 @@ struct TestConfig {
// Number of frames to process. // Number of frames to process.
size_t num_frames = 0; size_t num_frames = 0;
// Configurations related to networking. // Bitstream constraints.
NetworkingConfig networking_config; size_t max_payload_size_bytes = 1440;
// Decides how the packet loss simulations shall exclude certain frames from
// packet loss.
ExcludeFrameTypes exclude_frame_types = kExcludeOnlyFirstKeyFrame;
// Force the encoder and decoder to use a single core for processing. // Force the encoder and decoder to use a single core for processing.
// Using a single core is necessary to get a deterministic behavior for the // Using a single core is necessary to get a deterministic behavior for the

View file

@ -97,7 +97,6 @@ void ExtractBufferWithSize(const VideoFrame& image,
VideoProcessor::VideoProcessor(webrtc::VideoEncoder* encoder, VideoProcessor::VideoProcessor(webrtc::VideoEncoder* encoder,
webrtc::VideoDecoder* decoder, webrtc::VideoDecoder* decoder,
FrameReader* analysis_frame_reader, FrameReader* analysis_frame_reader,
PacketManipulator* packet_manipulator,
const TestConfig& config, const TestConfig& config,
Stats* stats, Stats* stats,
IvfFileWriter* encoded_frame_writer, IvfFileWriter* encoded_frame_writer,
@ -108,7 +107,6 @@ VideoProcessor::VideoProcessor(webrtc::VideoEncoder* encoder,
bitrate_allocator_(CreateBitrateAllocator(&config_)), bitrate_allocator_(CreateBitrateAllocator(&config_)),
encode_callback_(this), encode_callback_(this),
decode_callback_(this), decode_callback_(this),
packet_manipulator_(packet_manipulator),
analysis_frame_reader_(analysis_frame_reader), analysis_frame_reader_(analysis_frame_reader),
encoded_frame_writer_(encoded_frame_writer), encoded_frame_writer_(encoded_frame_writer),
decoded_frame_writer_(decoded_frame_writer), decoded_frame_writer_(decoded_frame_writer),
@ -117,12 +115,10 @@ VideoProcessor::VideoProcessor(webrtc::VideoEncoder* encoder,
last_decoded_frame_num_(0), last_decoded_frame_num_(0),
num_encoded_frames_(0), num_encoded_frames_(0),
num_decoded_frames_(0), num_decoded_frames_(0),
first_key_frame_has_been_excluded_(false),
last_decoded_frame_buffer_(analysis_frame_reader->FrameLength()), last_decoded_frame_buffer_(analysis_frame_reader->FrameLength()),
stats_(stats) { stats_(stats) {
RTC_DCHECK(encoder); RTC_DCHECK(encoder);
RTC_DCHECK(decoder); RTC_DCHECK(decoder);
RTC_DCHECK(packet_manipulator);
RTC_DCHECK(analysis_frame_reader); RTC_DCHECK(analysis_frame_reader);
RTC_DCHECK(stats); RTC_DCHECK(stats);
@ -133,10 +129,9 @@ VideoProcessor::VideoProcessor(webrtc::VideoEncoder* encoder,
WEBRTC_VIDEO_CODEC_OK); WEBRTC_VIDEO_CODEC_OK);
// Initialize the encoder and decoder. // Initialize the encoder and decoder.
RTC_CHECK_EQ( RTC_CHECK_EQ(encoder_->InitEncode(&config_.codec_settings,
encoder_->InitEncode(&config_.codec_settings,
static_cast<int>(config_.NumberOfCores()), static_cast<int>(config_.NumberOfCores()),
config_.networking_config.max_payload_size_in_bytes), config_.max_payload_size_bytes),
WEBRTC_VIDEO_CODEC_OK); WEBRTC_VIDEO_CODEC_OK);
RTC_CHECK_EQ(decoder_->InitDecode(&config_.codec_settings, RTC_CHECK_EQ(decoder_->InitDecode(&config_.codec_settings,
static_cast<int>(config_.NumberOfCores())), static_cast<int>(config_.NumberOfCores())),
@ -218,13 +213,6 @@ void VideoProcessor::FrameEncoded(webrtc::VideoCodecType codec,
RTC_CHECK_GT(frame_number, last_encoded_frame_num_); RTC_CHECK_GT(frame_number, last_encoded_frame_num_);
} }
// Check for dropped frames.
bool last_frame_missing = false;
if (frame_number > 0) {
const FrameStatistic* last_encoded_frame_stat =
stats_->GetFrame(last_encoded_frame_num_);
last_frame_missing = (last_encoded_frame_stat->manipulated_length == 0);
}
last_encoded_frame_num_ = frame_number; last_encoded_frame_num_ = frame_number;
// Update frame statistics. // Update frame statistics.
@ -237,32 +225,13 @@ void VideoProcessor::FrameEncoded(webrtc::VideoCodecType codec,
frame_stat->qp = encoded_image.qp_; frame_stat->qp = encoded_image.qp_;
frame_stat->target_bitrate_kbps = frame_stat->target_bitrate_kbps =
bitrate_allocation_.GetSpatialLayerSum(0) / 1000; bitrate_allocation_.GetSpatialLayerSum(0) / 1000;
frame_stat->total_packets =
encoded_image._length / config_.networking_config.packet_size_in_bytes +
1;
frame_stat->max_nalu_size_bytes = GetMaxNaluSizeBytes(encoded_image, config_); frame_stat->max_nalu_size_bytes = GetMaxNaluSizeBytes(encoded_image, config_);
// Make a raw copy of |encoded_image| to feed to the decoder.
size_t copied_buffer_size = encoded_image._length +
EncodedImage::GetBufferPaddingBytes(codec);
std::unique_ptr<uint8_t[]> copied_buffer(new uint8_t[copied_buffer_size]);
memcpy(copied_buffer.get(), encoded_image._buffer, encoded_image._length);
EncodedImage copied_image = encoded_image;
copied_image._size = copied_buffer_size;
copied_image._buffer = copied_buffer.get();
// Simulate packet loss.
if (!ExcludeFrame(copied_image)) {
frame_stat->packets_dropped =
packet_manipulator_->ManipulatePackets(&copied_image);
}
frame_stat->manipulated_length = copied_image._length;
// For the highest measurement accuracy of the decode time, the start/stop // For the highest measurement accuracy of the decode time, the start/stop
// time recordings should wrap the Decode call as tightly as possible. // time recordings should wrap the Decode call as tightly as possible.
frame_stat->decode_start_ns = rtc::TimeNanos(); frame_stat->decode_start_ns = rtc::TimeNanos();
frame_stat->decode_return_code = frame_stat->decode_return_code =
decoder_->Decode(copied_image, last_frame_missing, nullptr); decoder_->Decode(encoded_image, false, nullptr);
if (encoded_frame_writer_) { if (encoded_frame_writer_) {
RTC_CHECK(encoded_frame_writer_->WriteFrame(encoded_image, codec)); RTC_CHECK(encoded_frame_writer_->WriteFrame(encoded_image, codec));
@ -337,27 +306,5 @@ void VideoProcessor::WriteDecodedFrameToFile(rtc::Buffer* buffer) {
RTC_CHECK(decoded_frame_writer_->WriteFrame(buffer->data())); RTC_CHECK(decoded_frame_writer_->WriteFrame(buffer->data()));
} }
bool VideoProcessor::ExcludeFrame(const EncodedImage& encoded_image) {
RTC_DCHECK_CALLED_SEQUENTIALLY(&sequence_checker_);
if (encoded_image._frameType != kVideoFrameKey) {
return false;
}
bool exclude_frame = false;
switch (config_.exclude_frame_types) {
case kExcludeOnlyFirstKeyFrame:
if (!first_key_frame_has_been_excluded_) {
first_key_frame_has_been_excluded_ = true;
exclude_frame = true;
}
break;
case kExcludeAllKeyFrames:
exclude_frame = true;
break;
default:
RTC_NOTREACHED();
}
return exclude_frame;
}
} // namespace test } // namespace test
} // namespace webrtc } // namespace webrtc

View file

@ -19,7 +19,6 @@
#include "api/video/video_frame.h" #include "api/video/video_frame.h"
#include "common_video/libyuv/include/webrtc_libyuv.h" #include "common_video/libyuv/include/webrtc_libyuv.h"
#include "modules/video_coding/codecs/h264/include/h264_globals.h" #include "modules/video_coding/codecs/h264/include/h264_globals.h"
#include "modules/video_coding/codecs/test/packet_manipulator.h"
#include "modules/video_coding/codecs/test/stats.h" #include "modules/video_coding/codecs/test/stats.h"
#include "modules/video_coding/codecs/test/test_config.h" #include "modules/video_coding/codecs/test/test_config.h"
#include "modules/video_coding/include/video_codec_interface.h" #include "modules/video_coding/include/video_codec_interface.h"
@ -46,23 +45,12 @@ namespace test {
// The class processes a frame at the time for the configured input file. // The class processes a frame at the time for the configured input file.
// It maintains state of where in the source input file the processing is at. // It maintains state of where in the source input file the processing is at.
// //
// Regarding packet loss: Note that keyframes are excluded (first or all
// depending on the ExcludeFrameTypes setting). This is because if key frames
// would be altered, all the following delta frames would be pretty much
// worthless. VP8 has an error-resilience feature that makes it able to handle
// packet loss in key non-first keyframes, which is why only the first is
// excluded by default.
// Packet loss in such important frames is handled on a higher level in the
// Video Engine, where signaling would request a retransmit of the lost packets,
// since they're so important.
//
// Note this class is not thread safe and is meant for simple testing purposes. // Note this class is not thread safe and is meant for simple testing purposes.
class VideoProcessor { class VideoProcessor {
public: public:
VideoProcessor(webrtc::VideoEncoder* encoder, VideoProcessor(webrtc::VideoEncoder* encoder,
webrtc::VideoDecoder* decoder, webrtc::VideoDecoder* decoder,
FrameReader* analysis_frame_reader, FrameReader* analysis_frame_reader,
PacketManipulator* packet_manipulator,
const TestConfig& config, const TestConfig& config,
Stats* stats, Stats* stats,
IvfFileWriter* encoded_frame_writer, IvfFileWriter* encoded_frame_writer,
@ -177,7 +165,6 @@ class VideoProcessor {
void FrameDecoded(const webrtc::VideoFrame& image); void FrameDecoded(const webrtc::VideoFrame& image);
void WriteDecodedFrameToFile(rtc::Buffer* buffer); void WriteDecodedFrameToFile(rtc::Buffer* buffer);
bool ExcludeFrame(const EncodedImage& encoded_image);
TestConfig config_ RTC_GUARDED_BY(sequence_checker_); TestConfig config_ RTC_GUARDED_BY(sequence_checker_);
@ -190,9 +177,6 @@ class VideoProcessor {
VideoProcessorEncodeCompleteCallback encode_callback_; VideoProcessorEncodeCompleteCallback encode_callback_;
VideoProcessorDecodeCompleteCallback decode_callback_; VideoProcessorDecodeCompleteCallback decode_callback_;
// Fake network.
PacketManipulator* const packet_manipulator_;
// Input frames. Used as reference at frame quality evaluation. // Input frames. Used as reference at frame quality evaluation.
// Async codecs might queue frames. To handle that we keep input frame // Async codecs might queue frames. To handle that we keep input frame
// and release it after corresponding coded frame is decoded and quality // and release it after corresponding coded frame is decoded and quality
@ -218,9 +202,6 @@ class VideoProcessor {
size_t num_encoded_frames_ RTC_GUARDED_BY(sequence_checker_); size_t num_encoded_frames_ RTC_GUARDED_BY(sequence_checker_);
size_t num_decoded_frames_ RTC_GUARDED_BY(sequence_checker_); size_t num_decoded_frames_ RTC_GUARDED_BY(sequence_checker_);
// Keep track of if we have excluded the first key frame from packet loss.
bool first_key_frame_has_been_excluded_ RTC_GUARDED_BY(sequence_checker_);
// Keep track of the last successfully decoded frame, since we write that // Keep track of the last successfully decoded frame, since we write that
// frame to disk when decoding fails. // frame to disk when decoding fails.
rtc::Buffer last_decoded_frame_buffer_ RTC_GUARDED_BY(sequence_checker_); rtc::Buffer last_decoded_frame_buffer_ RTC_GUARDED_BY(sequence_checker_);

View file

@ -489,15 +489,12 @@ void VideoProcessorIntegrationTest::SetUpAndInitObjects(
} }
cpu_process_time_.reset(new CpuProcessTime(config_)); cpu_process_time_.reset(new CpuProcessTime(config_));
packet_manipulator_.reset(new PacketManipulatorImpl(
&packet_reader_, config_.networking_config, false));
rtc::Event sync_event(false, false); rtc::Event sync_event(false, false);
task_queue->PostTask([this, &sync_event]() { task_queue->PostTask([this, &sync_event]() {
processor_ = rtc::MakeUnique<VideoProcessor>( processor_ = rtc::MakeUnique<VideoProcessor>(
encoder_.get(), decoder_.get(), analysis_frame_reader_.get(), encoder_.get(), decoder_.get(), analysis_frame_reader_.get(), config_,
packet_manipulator_.get(), config_, &stats_, &stats_, encoded_frame_writer_.get(), decoded_frame_writer_.get());
encoded_frame_writer_.get(), decoded_frame_writer_.get());
sync_event.Set(); sync_event.Set();
}); });
sync_event.Wait(rtc::Event::kForever); sync_event.Wait(rtc::Event::kForever);

View file

@ -21,7 +21,6 @@
#include "common_video/h264/h264_common.h" #include "common_video/h264/h264_common.h"
#include "media/engine/webrtcvideodecoderfactory.h" #include "media/engine/webrtcvideodecoderfactory.h"
#include "media/engine/webrtcvideoencoderfactory.h" #include "media/engine/webrtcvideoencoderfactory.h"
#include "modules/video_coding/codecs/test/packet_manipulator.h"
#include "modules/video_coding/codecs/test/stats.h" #include "modules/video_coding/codecs/test/stats.h"
#include "modules/video_coding/codecs/test/test_config.h" #include "modules/video_coding/codecs/test/test_config.h"
#include "modules/video_coding/codecs/test/videoprocessor.h" #include "modules/video_coding/codecs/test/videoprocessor.h"
@ -29,7 +28,6 @@
#include "test/gtest.h" #include "test/gtest.h"
#include "test/testsupport/frame_reader.h" #include "test/testsupport/frame_reader.h"
#include "test/testsupport/frame_writer.h" #include "test/testsupport/frame_writer.h"
#include "test/testsupport/packet_reader.h"
namespace webrtc { namespace webrtc {
namespace test { namespace test {
@ -145,8 +143,6 @@ class VideoProcessorIntegrationTest : public testing::Test {
std::unique_ptr<FrameWriter> analysis_frame_writer_; std::unique_ptr<FrameWriter> analysis_frame_writer_;
std::unique_ptr<IvfFileWriter> encoded_frame_writer_; std::unique_ptr<IvfFileWriter> encoded_frame_writer_;
std::unique_ptr<FrameWriter> decoded_frame_writer_; std::unique_ptr<FrameWriter> decoded_frame_writer_;
PacketReader packet_reader_;
std::unique_ptr<PacketManipulator> packet_manipulator_;
Stats stats_; Stats stats_;
std::unique_ptr<VideoProcessor> processor_; std::unique_ptr<VideoProcessor> processor_;
std::unique_ptr<CpuProcessTime> cpu_process_time_; std::unique_ptr<CpuProcessTime> cpu_process_time_;

View file

@ -40,7 +40,6 @@ class VideoProcessorIntegrationTestOpenH264
config_.output_filename = config_.output_filename =
TempFilename(OutputPath(), "videoprocessor_integrationtest_libvpx"); TempFilename(OutputPath(), "videoprocessor_integrationtest_libvpx");
config_.num_frames = kNumFrames; config_.num_frames = kNumFrames;
config_.networking_config.packet_loss_probability = 0.0;
// Only allow encoder/decoder to use single core, for predictability. // Only allow encoder/decoder to use single core, for predictability.
config_.use_single_core = true; config_.use_single_core = true;
config_.hw_encoder = false; config_.hw_encoder = false;
@ -70,7 +69,7 @@ TEST_F(VideoProcessorIntegrationTestOpenH264, ConstantHighBitrate) {
TEST_F(VideoProcessorIntegrationTestOpenH264, SingleNalUnit) { TEST_F(VideoProcessorIntegrationTestOpenH264, SingleNalUnit) {
config_.h264_codec_settings.packetization_mode = config_.h264_codec_settings.packetization_mode =
H264PacketizationMode::SingleNalUnit; H264PacketizationMode::SingleNalUnit;
config_.networking_config.max_payload_size_in_bytes = 500; config_.max_payload_size_bytes = 500;
config_.SetCodecSettings(kVideoCodecH264, 1, false, false, true, false, config_.SetCodecSettings(kVideoCodecH264, 1, false, false, true, false,
kResilienceOn, kCifWidth, kCifHeight); kResilienceOn, kCifWidth, kCifHeight);
@ -81,8 +80,7 @@ TEST_F(VideoProcessorIntegrationTestOpenH264, SingleNalUnit) {
std::vector<QualityThresholds> quality_thresholds = {{37, 35, 0.93, 0.91}}; std::vector<QualityThresholds> quality_thresholds = {{37, 35, 0.93, 0.91}};
BitstreamThresholds bs_thresholds = { BitstreamThresholds bs_thresholds = {config_.max_payload_size_bytes};
config_.networking_config.max_payload_size_in_bytes};
ProcessFramesAndMaybeVerify(rate_profiles, &rc_thresholds, ProcessFramesAndMaybeVerify(rate_profiles, &rc_thresholds,
&quality_thresholds, &bs_thresholds, &quality_thresholds, &bs_thresholds,

View file

@ -12,7 +12,6 @@
#include "api/video/i420_buffer.h" #include "api/video/i420_buffer.h"
#include "common_types.h" // NOLINT(build/include) #include "common_types.h" // NOLINT(build/include)
#include "modules/video_coding/codecs/test/mock/mock_packet_manipulator.h"
#include "modules/video_coding/codecs/test/videoprocessor.h" #include "modules/video_coding/codecs/test/videoprocessor.h"
#include "modules/video_coding/include/mock/mock_video_codec_interface.h" #include "modules/video_coding/include/mock/mock_video_codec_interface.h"
#include "modules/video_coding/include/video_coding.h" #include "modules/video_coding/include/video_coding.h"
@ -20,7 +19,6 @@
#include "test/gmock.h" #include "test/gmock.h"
#include "test/gtest.h" #include "test/gtest.h"
#include "test/testsupport/mock/mock_frame_reader.h" #include "test/testsupport/mock/mock_frame_reader.h"
#include "test/testsupport/packet_reader.h"
#include "test/testsupport/unittest_utils.h" #include "test/testsupport/unittest_utils.h"
#include "test/video_codec_settings.h" #include "test/video_codec_settings.h"
#include "typedefs.h" // NOLINT(build/include) #include "typedefs.h" // NOLINT(build/include)
@ -53,8 +51,7 @@ class VideoProcessorTest : public testing::Test {
EXPECT_CALL(frame_reader_mock_, FrameLength()) EXPECT_CALL(frame_reader_mock_, FrameLength())
.WillRepeatedly(Return(kFrameSize)); .WillRepeatedly(Return(kFrameSize));
video_processor_ = rtc::MakeUnique<VideoProcessor>( video_processor_ = rtc::MakeUnique<VideoProcessor>(
&encoder_mock_, &decoder_mock_, &frame_reader_mock_, &encoder_mock_, &decoder_mock_, &frame_reader_mock_, config_, &stats_,
&packet_manipulator_mock_, config_, &stats_,
nullptr /* encoded_frame_writer */, nullptr /* decoded_frame_writer */); nullptr /* encoded_frame_writer */, nullptr /* decoded_frame_writer */);
} }
@ -77,7 +74,6 @@ class VideoProcessorTest : public testing::Test {
MockVideoEncoder encoder_mock_; MockVideoEncoder encoder_mock_;
MockVideoDecoder decoder_mock_; MockVideoDecoder decoder_mock_;
MockFrameReader frame_reader_mock_; MockFrameReader frame_reader_mock_;
MockPacketManipulator packet_manipulator_mock_;
Stats stats_; Stats stats_;
std::unique_ptr<VideoProcessor> video_processor_; std::unique_ptr<VideoProcessor> video_processor_;
}; };

View file

@ -169,8 +169,6 @@ rtc_source_set("test_support") {
sources = [ sources = [
"gmock.h", "gmock.h",
"gtest.h", "gtest.h",
"testsupport/packet_reader.cc",
"testsupport/packet_reader.h",
"testsupport/unittest_utils.h", "testsupport/unittest_utils.h",
] ]
@ -346,7 +344,6 @@ if (rtc_include_tests) {
"single_threaded_task_queue_unittest.cc", "single_threaded_task_queue_unittest.cc",
"testsupport/always_passing_unittest.cc", "testsupport/always_passing_unittest.cc",
"testsupport/metrics/video_metrics_unittest.cc", "testsupport/metrics/video_metrics_unittest.cc",
"testsupport/packet_reader_unittest.cc",
"testsupport/perf_test_unittest.cc", "testsupport/perf_test_unittest.cc",
"testsupport/test_artifacts_unittest.cc", "testsupport/test_artifacts_unittest.cc",
"testsupport/y4m_frame_writer_unittest.cc", "testsupport/y4m_frame_writer_unittest.cc",

View file

@ -1,49 +0,0 @@
/*
* Copyright (c) 2011 The WebRTC project authors. All Rights Reserved.
*
* Use of this source code is governed by a BSD-style license
* that can be found in the LICENSE file in the root of the source
* tree. An additional intellectual property rights grant can be found
* in the file PATENTS. All contributing project authors may
* be found in the AUTHORS file in the root of the source tree.
*/
#include "test/testsupport/packet_reader.h"
#include <assert.h>
#include <stdio.h>
#include <algorithm>
namespace webrtc {
namespace test {
PacketReader::PacketReader()
: initialized_(false) {}
PacketReader::~PacketReader() {}
void PacketReader::InitializeReading(uint8_t* data,
size_t data_length_in_bytes,
size_t packet_size_in_bytes) {
assert(data);
assert(packet_size_in_bytes > 0);
data_ = data;
data_length_ = data_length_in_bytes;
packet_size_ = packet_size_in_bytes;
currentIndex_ = 0;
initialized_ = true;
}
int PacketReader::NextPacket(uint8_t** packet_pointer) {
if (!initialized_) {
fprintf(stderr, "Attempting to use uninitialized PacketReader!\n");
return -1;
}
*packet_pointer = data_ + currentIndex_;
size_t old_index = currentIndex_;
currentIndex_ = std::min(currentIndex_ + packet_size_, data_length_);
return static_cast<int>(currentIndex_ - old_index);
}
} // namespace test
} // namespace webrtc

View file

@ -1,54 +0,0 @@
/*
* Copyright (c) 2011 The WebRTC project authors. All Rights Reserved.
*
* Use of this source code is governed by a BSD-style license
* that can be found in the LICENSE file in the root of the source
* tree. An additional intellectual property rights grant can be found
* in the file PATENTS. All contributing project authors may
* be found in the AUTHORS file in the root of the source tree.
*/
#ifndef TEST_TESTSUPPORT_PACKET_READER_H_
#define TEST_TESTSUPPORT_PACKET_READER_H_
#include <cstddef>
#include "typedefs.h" // NOLINT(build/include)
namespace webrtc {
namespace test {
// Reads chunks of data to simulate network packets from a byte array.
class PacketReader {
public:
PacketReader();
virtual ~PacketReader();
// Inizializes a new reading operation. Must be done before invoking the
// NextPacket method.
// * data_length_in_bytes is the length of the data byte array.
// 0 length will result in no packets are read.
// * packet_size_in_bytes is the number of bytes to read in each NextPacket
// method call. Must be > 0
virtual void InitializeReading(uint8_t* data, size_t data_length_in_bytes,
size_t packet_size_in_bytes);
// Moves the supplied pointer to the beginning of the next packet.
// Returns:
// * The size of the packet ready to read (lower than the packet size for
// the last packet)
// * 0 if there are no more packets to read
// * -1 if InitializeReading has not been called (also prints to stderr).
virtual int NextPacket(uint8_t** packet_pointer);
private:
uint8_t* data_;
size_t data_length_;
size_t packet_size_;
size_t currentIndex_;
bool initialized_;
};
} // namespace test
} // namespace webrtc
#endif // TEST_TESTSUPPORT_PACKET_READER_H_

View file

@ -1,125 +0,0 @@
/*
* Copyright (c) 2012 The WebRTC project authors. All Rights Reserved.
*
* Use of this source code is governed by a BSD-style license
* that can be found in the LICENSE file in the root of the source
* tree. An additional intellectual property rights grant can be found
* in the file PATENTS. All contributing project authors may
* be found in the AUTHORS file in the root of the source tree.
*/
#include "test/testsupport/packet_reader.h"
#include "test/gtest.h"
#include "test/testsupport/unittest_utils.h"
namespace webrtc {
namespace test {
class PacketReaderTest: public PacketRelatedTest {
protected:
PacketReaderTest() {}
virtual ~PacketReaderTest() {}
void SetUp() {
reader_ = new PacketReader();
}
void TearDown() {
delete reader_;
}
void VerifyPacketData(size_t expected_length,
int actual_length,
uint8_t* original_data_pointer,
uint8_t* new_data_pointer) {
EXPECT_EQ(static_cast<int>(expected_length), actual_length);
EXPECT_EQ(*original_data_pointer, *new_data_pointer);
EXPECT_EQ(0, memcmp(original_data_pointer, new_data_pointer,
actual_length));
}
PacketReader* reader_;
};
// Test lack of initialization
TEST_F(PacketReaderTest, Uninitialized) {
uint8_t* data_pointer = NULL;
EXPECT_EQ(-1, reader_->NextPacket(&data_pointer));
EXPECT_EQ(NULL, data_pointer);
}
TEST_F(PacketReaderTest, InitializeZeroLengthArgument) {
reader_->InitializeReading(packet_data_, 0, kPacketSizeInBytes);
ASSERT_EQ(0, reader_->NextPacket(&packet_data_pointer_));
}
// Test with something smaller than one packet
TEST_F(PacketReaderTest, NormalSmallData) {
const int kDataLengthInBytes = 1499;
uint8_t data[kDataLengthInBytes];
uint8_t* data_pointer = data;
memset(data, 1, kDataLengthInBytes);
reader_->InitializeReading(data, kDataLengthInBytes, kPacketSizeInBytes);
int length_to_read = reader_->NextPacket(&data_pointer);
VerifyPacketData(kDataLengthInBytes, length_to_read, data, data_pointer);
EXPECT_EQ(0, data_pointer - data); // pointer hasn't moved
// Reading another one shall result in 0 bytes:
length_to_read = reader_->NextPacket(&data_pointer);
EXPECT_EQ(0, length_to_read);
EXPECT_EQ(kDataLengthInBytes, data_pointer - data);
}
// Test with data length that exactly matches one packet
TEST_F(PacketReaderTest, NormalOnePacketData) {
uint8_t data[kPacketSizeInBytes];
uint8_t* data_pointer = data;
memset(data, 1, kPacketSizeInBytes);
reader_->InitializeReading(data, kPacketSizeInBytes, kPacketSizeInBytes);
int length_to_read = reader_->NextPacket(&data_pointer);
VerifyPacketData(kPacketSizeInBytes, length_to_read, data, data_pointer);
EXPECT_EQ(0, data_pointer - data); // pointer hasn't moved
// Reading another one shall result in 0 bytes:
length_to_read = reader_->NextPacket(&data_pointer);
EXPECT_EQ(0, length_to_read);
EXPECT_EQ(kPacketSizeInBytes, static_cast<size_t>(data_pointer - data));
}
// Test with data length that will result in 3 packets
TEST_F(PacketReaderTest, NormalLargeData) {
reader_->InitializeReading(packet_data_, kPacketDataLength,
kPacketSizeInBytes);
int length_to_read = reader_->NextPacket(&packet_data_pointer_);
VerifyPacketData(kPacketSizeInBytes, length_to_read,
packet1_, packet_data_pointer_);
length_to_read = reader_->NextPacket(&packet_data_pointer_);
VerifyPacketData(kPacketSizeInBytes, length_to_read,
packet2_, packet_data_pointer_);
length_to_read = reader_->NextPacket(&packet_data_pointer_);
VerifyPacketData(1u, length_to_read,
packet3_, packet_data_pointer_);
// Reading another one shall result in 0 bytes:
length_to_read = reader_->NextPacket(&packet_data_pointer_);
EXPECT_EQ(0, length_to_read);
EXPECT_EQ(kPacketDataLength,
static_cast<size_t>(packet_data_pointer_ - packet_data_));
}
// Test with empty data.
TEST_F(PacketReaderTest, EmptyData) {
const int kDataLengthInBytes = 0;
// But don't really try to allocate a zero-length array...
uint8_t data[kPacketSizeInBytes];
uint8_t* data_pointer = data;
reader_->InitializeReading(data, kDataLengthInBytes, kPacketSizeInBytes);
EXPECT_EQ(kDataLengthInBytes, reader_->NextPacket(&data_pointer));
// Do it again to make sure nothing changes
EXPECT_EQ(kDataLengthInBytes, reader_->NextPacket(&data_pointer));
}
} // namespace test
} // namespace webrtc