summaryrefslogtreecommitdiffstats
path: root/third_party/libwebrtc/modules/video_coding
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--third_party/libwebrtc/modules/video_coding/BUILD.gn3
-rw-r--r--third_party/libwebrtc/modules/video_coding/codecs/av1/dav1d_decoder.cc2
-rw-r--r--third_party/libwebrtc/modules/video_coding/codecs/av1/libaom_av1_unittest.cc3
-rw-r--r--third_party/libwebrtc/modules/video_coding/codecs/h264/h264_decoder_impl.cc6
-rw-r--r--third_party/libwebrtc/modules/video_coding/codecs/test/video_codec_test.cc34
-rw-r--r--third_party/libwebrtc/modules/video_coding/codecs/test/videocodec_test_fixture_impl.cc2
-rw-r--r--third_party/libwebrtc/modules/video_coding/fec_controller_default.cc30
-rw-r--r--third_party/libwebrtc/modules/video_coding/fec_controller_default.h11
-rw-r--r--third_party/libwebrtc/modules/video_coding/fec_controller_unittest.cc4
-rw-r--r--third_party/libwebrtc/modules/video_coding/nack_requester.cc56
-rw-r--r--third_party/libwebrtc/modules/video_coding/nack_requester.h10
-rw-r--r--third_party/libwebrtc/modules/video_coding/nack_requester_unittest.cc160
-rw-r--r--third_party/libwebrtc/modules/video_coding/utility/qp_parser.cc16
-rw-r--r--third_party/libwebrtc/modules/video_coding/utility/qp_parser.h18
14 files changed, 130 insertions, 225 deletions
diff --git a/third_party/libwebrtc/modules/video_coding/BUILD.gn b/third_party/libwebrtc/modules/video_coding/BUILD.gn
index d9e614ff81..0457b818c3 100644
--- a/third_party/libwebrtc/modules/video_coding/BUILD.gn
+++ b/third_party/libwebrtc/modules/video_coding/BUILD.gn
@@ -218,6 +218,7 @@ rtc_library("video_coding") {
"../../api:rtp_packet_info",
"../../api:scoped_refptr",
"../../api:sequence_checker",
+ "../../api/environment",
"../../api/task_queue",
"../../api/units:data_rate",
"../../api/units:data_size",
@@ -258,7 +259,6 @@ rtc_library("video_coding") {
"../../rtc_base/task_utils:repeating_task",
"../../rtc_base/third_party/base64",
"../../system_wrappers",
- "../../system_wrappers:field_trial",
"../../system_wrappers:metrics",
"../../video/config:encoder_config",
"../rtp_rtcp",
@@ -1217,6 +1217,7 @@ if (rtc_include_tests) {
"../../api:scoped_refptr",
"../../api:simulcast_test_fixture_api",
"../../api:videocodec_test_fixture_api",
+ "../../api/environment:environment_factory",
"../../api/task_queue",
"../../api/task_queue:default_task_queue_factory",
"../../api/test/video:function_video_factory",
diff --git a/third_party/libwebrtc/modules/video_coding/codecs/av1/dav1d_decoder.cc b/third_party/libwebrtc/modules/video_coding/codecs/av1/dav1d_decoder.cc
index 6a787ff935..d658e401e8 100644
--- a/third_party/libwebrtc/modules/video_coding/codecs/av1/dav1d_decoder.cc
+++ b/third_party/libwebrtc/modules/video_coding/codecs/av1/dav1d_decoder.cc
@@ -87,6 +87,8 @@ bool Dav1dDecoder::Configure(const Settings& settings) {
s.n_threads = std::max(2, settings.number_of_cores());
s.max_frame_delay = 1; // For low latency decoding.
s.all_layers = 0; // Don't output a frame for every spatial layer.
+ // Limit max frame size to avoid OOM'ing fuzzers. crbug.com/325284120.
+ s.frame_size_limit = 16384 * 16384;
s.operating_point = 31; // Decode all operating points.
return dav1d_open(&context_, &s) == 0;
diff --git a/third_party/libwebrtc/modules/video_coding/codecs/av1/libaom_av1_unittest.cc b/third_party/libwebrtc/modules/video_coding/codecs/av1/libaom_av1_unittest.cc
index 766b7660e4..d486c1d062 100644
--- a/third_party/libwebrtc/modules/video_coding/codecs/av1/libaom_av1_unittest.cc
+++ b/third_party/libwebrtc/modules/video_coding/codecs/av1/libaom_av1_unittest.cc
@@ -350,7 +350,8 @@ INSTANTIATE_TEST_SUITE_P(
SvcTestParam{"L3T1", /*num_frames_to_generate=*/3},
SvcTestParam{"L3T3", /*num_frames_to_generate=*/8},
SvcTestParam{"S2T1", /*num_frames_to_generate=*/3},
- SvcTestParam{"S3T3", /*num_frames_to_generate=*/8},
+ // TODO: bugs.webrtc.org/15715 - Re-enable once AV1 is fixed.
+ // SvcTestParam{"S3T3", /*num_frames_to_generate=*/8},
SvcTestParam{"L2T2", /*num_frames_to_generate=*/4},
SvcTestParam{"L2T2_KEY", /*num_frames_to_generate=*/4},
SvcTestParam{"L2T2_KEY_SHIFT",
diff --git a/third_party/libwebrtc/modules/video_coding/codecs/h264/h264_decoder_impl.cc b/third_party/libwebrtc/modules/video_coding/codecs/h264/h264_decoder_impl.cc
index a9e9926c4f..c6446c25ce 100644
--- a/third_party/libwebrtc/modules/video_coding/codecs/h264/h264_decoder_impl.cc
+++ b/third_party/libwebrtc/modules/video_coding/codecs/h264/h264_decoder_impl.cc
@@ -80,7 +80,11 @@ int H264DecoderImpl::AVGetBuffer2(AVCodecContext* context,
kPixelFormatsSupported.begin(), kPixelFormatsSupported.end(),
[context](AVPixelFormat format) { return context->pix_fmt == format; });
- RTC_CHECK(pixelFormatSupported != kPixelFormatsSupported.end());
+ if (pixelFormatSupported == kPixelFormatsSupported.end()) {
+ RTC_LOG(LS_ERROR) << "Unsupported pixel format: " << context->pix_fmt;
+ decoder->ReportError();
+ return -1;
+ }
// `av_frame->width` and `av_frame->height` are set by FFmpeg. These are the
// actual image's dimensions and may be different from `context->width` and
diff --git a/third_party/libwebrtc/modules/video_coding/codecs/test/video_codec_test.cc b/third_party/libwebrtc/modules/video_coding/codecs/test/video_codec_test.cc
index 60c2fcbb6e..2ab1106a59 100644
--- a/third_party/libwebrtc/modules/video_coding/codecs/test/video_codec_test.cc
+++ b/third_party/libwebrtc/modules/video_coding/codecs/test/video_codec_test.cc
@@ -178,7 +178,8 @@ std::string TestOutputPath() {
} // namespace
std::unique_ptr<VideoCodecStats> RunEncodeDecodeTest(
- std::string codec_impl,
+ std::string encoder_impl,
+ std::string decoder_impl,
const VideoInfo& video_info,
const std::map<uint32_t, EncodingSettings>& encoding_settings) {
VideoSourceSettings source_settings{
@@ -190,28 +191,34 @@ std::unique_ptr<VideoCodecStats> RunEncodeDecodeTest(
encoding_settings.begin()->second.sdp_video_format;
std::unique_ptr<VideoEncoderFactory> encoder_factory =
- CreateEncoderFactory(codec_impl);
+ CreateEncoderFactory(encoder_impl);
if (!encoder_factory
->QueryCodecSupport(sdp_video_format,
/*scalability_mode=*/absl::nullopt)
.is_supported) {
- RTC_LOG(LS_WARNING) << "No encoder for video format "
+ RTC_LOG(LS_WARNING) << "No " << encoder_impl << " encoder for video format "
<< sdp_video_format.ToString();
return nullptr;
}
std::unique_ptr<VideoDecoderFactory> decoder_factory =
- CreateDecoderFactory(codec_impl);
+ CreateDecoderFactory(decoder_impl);
if (!decoder_factory
->QueryCodecSupport(sdp_video_format,
/*reference_scaling=*/false)
.is_supported) {
+ RTC_LOG(LS_WARNING) << "No " << decoder_impl << " decoder for video format "
+ << sdp_video_format.ToString()
+ << ". Trying built-in decoder.";
+ // TODO(ssilkin): No H264 support in ffmpeg on ARM. Consider trying HW
+ // decoder.
decoder_factory = CreateDecoderFactory("builtin");
if (!decoder_factory
->QueryCodecSupport(sdp_video_format,
/*reference_scaling=*/false)
.is_supported) {
- RTC_LOG(LS_WARNING) << "No decoder for video format "
+ RTC_LOG(LS_WARNING) << "No " << decoder_impl
+ << " decoder for video format "
<< sdp_video_format.ToString();
return nullptr;
}
@@ -221,7 +228,7 @@ std::unique_ptr<VideoCodecStats> RunEncodeDecodeTest(
VideoCodecTester::EncoderSettings encoder_settings;
encoder_settings.pacing_settings.mode =
- codec_impl == "builtin" ? PacingMode::kNoPacing : PacingMode::kRealTime;
+ encoder_impl == "builtin" ? PacingMode::kNoPacing : PacingMode::kRealTime;
if (absl::GetFlag(FLAGS_dump_encoder_input)) {
encoder_settings.encoder_input_base_path = output_path + "_enc_input";
}
@@ -231,7 +238,7 @@ std::unique_ptr<VideoCodecStats> RunEncodeDecodeTest(
VideoCodecTester::DecoderSettings decoder_settings;
decoder_settings.pacing_settings.mode =
- codec_impl == "builtin" ? PacingMode::kNoPacing : PacingMode::kRealTime;
+ decoder_impl == "builtin" ? PacingMode::kNoPacing : PacingMode::kRealTime;
if (absl::GetFlag(FLAGS_dump_decoder_input)) {
decoder_settings.decoder_input_base_path = output_path + "_dec_input";
}
@@ -318,7 +325,7 @@ TEST_P(SpatialQualityTest, SpatialQuality) {
{bitrate_kbps}, framerate_fps, num_frames);
std::unique_ptr<VideoCodecStats> stats =
- RunEncodeDecodeTest(codec_impl, video_info, frames_settings);
+ RunEncodeDecodeTest(codec_impl, codec_impl, video_info, frames_settings);
VideoCodecStats::Stream stream;
if (stats != nullptr) {
@@ -348,15 +355,15 @@ INSTANTIATE_TEST_SUITE_P(
Values("builtin"),
#endif
Values(kRawVideos.at("FourPeople_1280x720_30")),
- Values(std::make_tuple(320, 180, 30, 32, 28),
- std::make_tuple(320, 180, 30, 64, 30),
- std::make_tuple(320, 180, 30, 128, 33),
+ Values(std::make_tuple(320, 180, 30, 32, 26),
+ std::make_tuple(320, 180, 30, 64, 29),
+ std::make_tuple(320, 180, 30, 128, 32),
std::make_tuple(320, 180, 30, 256, 36),
- std::make_tuple(640, 360, 30, 128, 31),
+ std::make_tuple(640, 360, 30, 128, 29),
std::make_tuple(640, 360, 30, 256, 33),
std::make_tuple(640, 360, 30, 384, 35),
std::make_tuple(640, 360, 30, 512, 36),
- std::make_tuple(1280, 720, 30, 256, 32),
+ std::make_tuple(1280, 720, 30, 256, 30),
std::make_tuple(1280, 720, 30, 512, 34),
std::make_tuple(1280, 720, 30, 1024, 37),
std::make_tuple(1280, 720, 30, 2048, 39))),
@@ -538,6 +545,7 @@ TEST(VideoCodecTest, DISABLED_EncodeDecode) {
// Sync with changes in Stream::LogMetrics (see TODOs there).
std::unique_ptr<VideoCodecStats> stats = RunEncodeDecodeTest(
CodecNameToCodecImpl(absl::GetFlag(FLAGS_encoder)),
+ CodecNameToCodecImpl(absl::GetFlag(FLAGS_decoder)),
kRawVideos.at(absl::GetFlag(FLAGS_video_name)), frames_settings);
ASSERT_NE(nullptr, stats);
diff --git a/third_party/libwebrtc/modules/video_coding/codecs/test/videocodec_test_fixture_impl.cc b/third_party/libwebrtc/modules/video_coding/codecs/test/videocodec_test_fixture_impl.cc
index eb264e5285..35355d4387 100644
--- a/third_party/libwebrtc/modules/video_coding/codecs/test/videocodec_test_fixture_impl.cc
+++ b/third_party/libwebrtc/modules/video_coding/codecs/test/videocodec_test_fixture_impl.cc
@@ -167,7 +167,7 @@ SdpVideoFormat CreateSdpVideoFormat(
H264PacketizationMode::NonInterleaved
? "1"
: "0";
- SdpVideoFormat::Parameters codec_params = {
+ CodecParameterMap codec_params = {
{cricket::kH264FmtpProfileLevelId,
*H264ProfileLevelIdToString(H264ProfileLevelId(
config.h264_codec_settings.profile, H264Level::kLevel3_1))},
diff --git a/third_party/libwebrtc/modules/video_coding/fec_controller_default.cc b/third_party/libwebrtc/modules/video_coding/fec_controller_default.cc
index f204b01c7c..d548d6580c 100644
--- a/third_party/libwebrtc/modules/video_coding/fec_controller_default.cc
+++ b/third_party/libwebrtc/modules/video_coding/fec_controller_default.cc
@@ -15,30 +15,28 @@
#include <algorithm>
#include <string>
+#include "api/environment/environment.h"
+#include "api/field_trials_view.h"
#include "modules/include/module_fec_types.h"
#include "rtc_base/logging.h"
-#include "system_wrappers/include/field_trial.h"
+#include "system_wrappers/include/clock.h"
namespace webrtc {
const float kProtectionOverheadRateThreshold = 0.5;
FecControllerDefault::FecControllerDefault(
- Clock* clock,
+ const Environment& env,
VCMProtectionCallback* protection_callback)
- : clock_(clock),
+ : env_(env),
protection_callback_(protection_callback),
loss_prot_logic_(new media_optimization::VCMLossProtectionLogic(
- clock_->TimeInMilliseconds())),
+ env_.clock().TimeInMilliseconds())),
max_payload_size_(1460),
overhead_threshold_(GetProtectionOverheadRateThreshold()) {}
-FecControllerDefault::FecControllerDefault(Clock* clock)
- : clock_(clock),
- loss_prot_logic_(new media_optimization::VCMLossProtectionLogic(
- clock_->TimeInMilliseconds())),
- max_payload_size_(1460),
- overhead_threshold_(GetProtectionOverheadRateThreshold()) {}
+FecControllerDefault::FecControllerDefault(const Environment& env)
+ : FecControllerDefault(env, nullptr) {}
FecControllerDefault::~FecControllerDefault(void) {
loss_prot_logic_->Release();
@@ -61,8 +59,8 @@ void FecControllerDefault::SetEncodingData(size_t width,
float FecControllerDefault::GetProtectionOverheadRateThreshold() {
float overhead_threshold =
- strtof(webrtc::field_trial::FindFullName(
- "WebRTC-ProtectionOverheadRateThreshold")
+ strtof(env_.field_trials()
+ .Lookup("WebRTC-ProtectionOverheadRateThreshold")
.c_str(),
nullptr);
if (overhead_threshold > 0 && overhead_threshold <= 1) {
@@ -107,7 +105,7 @@ uint32_t FecControllerDefault::UpdateFecRates(
media_optimization::FilterPacketLossMode filter_mode =
media_optimization::kMaxFilter;
uint8_t packet_loss_enc = loss_prot_logic_->FilteredLoss(
- clock_->TimeInMilliseconds(), filter_mode, fraction_lost);
+ env_.clock().TimeInMilliseconds(), filter_mode, fraction_lost);
// For now use the filtered loss for computing the robustness settings.
loss_prot_logic_->UpdateFilteredLossPr(packet_loss_enc);
if (loss_prot_logic_->SelectedType() == media_optimization::kNone) {
@@ -191,11 +189,11 @@ void FecControllerDefault::UpdateWithEncodedData(
const float min_packets_per_frame =
encoded_length / static_cast<float>(max_payload_size_);
if (delta_frame) {
- loss_prot_logic_->UpdatePacketsPerFrame(min_packets_per_frame,
- clock_->TimeInMilliseconds());
+ loss_prot_logic_->UpdatePacketsPerFrame(
+ min_packets_per_frame, env_.clock().TimeInMilliseconds());
} else {
loss_prot_logic_->UpdatePacketsPerFrameKey(
- min_packets_per_frame, clock_->TimeInMilliseconds());
+ min_packets_per_frame, env_.clock().TimeInMilliseconds());
}
}
if (!delta_frame && encoded_length > 0) {
diff --git a/third_party/libwebrtc/modules/video_coding/fec_controller_default.h b/third_party/libwebrtc/modules/video_coding/fec_controller_default.h
index a97dea011b..f60302b2d8 100644
--- a/third_party/libwebrtc/modules/video_coding/fec_controller_default.h
+++ b/third_party/libwebrtc/modules/video_coding/fec_controller_default.h
@@ -17,24 +17,25 @@
#include <memory>
#include <vector>
+#include "api/environment/environment.h"
#include "api/fec_controller.h"
#include "modules/video_coding/media_opt_util.h"
#include "rtc_base/synchronization/mutex.h"
#include "rtc_base/thread_annotations.h"
-#include "system_wrappers/include/clock.h"
namespace webrtc {
class FecControllerDefault : public FecController {
public:
- FecControllerDefault(Clock* clock,
+ FecControllerDefault(const Environment& env,
VCMProtectionCallback* protection_callback);
- explicit FecControllerDefault(Clock* clock);
- ~FecControllerDefault() override;
+ explicit FecControllerDefault(const Environment& env);
FecControllerDefault(const FecControllerDefault&) = delete;
FecControllerDefault& operator=(const FecControllerDefault&) = delete;
+ ~FecControllerDefault() override;
+
void SetProtectionCallback(
VCMProtectionCallback* protection_callback) override;
void SetProtectionMethod(bool enable_fec, bool enable_nack) override;
@@ -54,7 +55,7 @@ class FecControllerDefault : public FecController {
private:
enum { kBitrateAverageWinMs = 1000 };
- Clock* const clock_;
+ const Environment env_;
VCMProtectionCallback* protection_callback_;
Mutex mutex_;
std::unique_ptr<media_optimization::VCMLossProtectionLogic> loss_prot_logic_
diff --git a/third_party/libwebrtc/modules/video_coding/fec_controller_unittest.cc b/third_party/libwebrtc/modules/video_coding/fec_controller_unittest.cc
index fa3cc7a93b..c4a0a08fd1 100644
--- a/third_party/libwebrtc/modules/video_coding/fec_controller_unittest.cc
+++ b/third_party/libwebrtc/modules/video_coding/fec_controller_unittest.cc
@@ -14,6 +14,7 @@
#include <vector>
+#include "api/environment/environment_factory.h"
#include "modules/include/module_fec_types.h"
#include "modules/video_coding/fec_controller_default.h"
#include "system_wrappers/include/clock.h"
@@ -50,7 +51,8 @@ class ProtectionBitrateCalculatorTest : public ::testing::Test {
// Note: simulated clock starts at 1 seconds, since parts of webrtc use 0 as
// a special case (e.g. frame rate in media optimization).
ProtectionBitrateCalculatorTest()
- : clock_(1000), fec_controller_(&clock_, &protection_callback_) {}
+ : clock_(1000),
+ fec_controller_(CreateEnvironment(&clock_), &protection_callback_) {}
SimulatedClock clock_;
ProtectionCallback protection_callback_;
diff --git a/third_party/libwebrtc/modules/video_coding/nack_requester.cc b/third_party/libwebrtc/modules/video_coding/nack_requester.cc
index 008420f4da..b3e928d05e 100644
--- a/third_party/libwebrtc/modules/video_coding/nack_requester.cc
+++ b/third_party/libwebrtc/modules/video_coding/nack_requester.cc
@@ -141,13 +141,12 @@ void NackRequester::ProcessNacks() {
}
}
-int NackRequester::OnReceivedPacket(uint16_t seq_num, bool is_keyframe) {
+int NackRequester::OnReceivedPacket(uint16_t seq_num) {
RTC_DCHECK_RUN_ON(worker_thread_);
- return OnReceivedPacket(seq_num, is_keyframe, false);
+ return OnReceivedPacket(seq_num, false);
}
int NackRequester::OnReceivedPacket(uint16_t seq_num,
- bool is_keyframe,
bool is_recovered) {
RTC_DCHECK_RUN_ON(worker_thread_);
// TODO(philipel): When the packet includes information whether it is
@@ -158,8 +157,6 @@ int NackRequester::OnReceivedPacket(uint16_t seq_num,
if (!initialized_) {
newest_seq_num_ = seq_num;
- if (is_keyframe)
- keyframe_list_.insert(seq_num);
initialized_ = true;
return 0;
}
@@ -182,15 +179,6 @@ int NackRequester::OnReceivedPacket(uint16_t seq_num,
return nacks_sent_for_packet;
}
- // Keep track of new keyframes.
- if (is_keyframe)
- keyframe_list_.insert(seq_num);
-
- // And remove old ones so we don't accumulate keyframes.
- auto it = keyframe_list_.lower_bound(seq_num - kMaxPacketAge);
- if (it != keyframe_list_.begin())
- keyframe_list_.erase(keyframe_list_.begin(), it);
-
if (is_recovered) {
recovered_list_.insert(seq_num);
@@ -225,8 +213,6 @@ void NackRequester::ClearUpTo(uint16_t seq_num) {
// thread.
RTC_DCHECK_RUN_ON(worker_thread_);
nack_list_.erase(nack_list_.begin(), nack_list_.lower_bound(seq_num));
- keyframe_list_.erase(keyframe_list_.begin(),
- keyframe_list_.lower_bound(seq_num));
recovered_list_.erase(recovered_list_.begin(),
recovered_list_.lower_bound(seq_num));
}
@@ -236,25 +222,6 @@ void NackRequester::UpdateRtt(int64_t rtt_ms) {
rtt_ = TimeDelta::Millis(rtt_ms);
}
-bool NackRequester::RemovePacketsUntilKeyFrame() {
- // Called on worker_thread_.
- while (!keyframe_list_.empty()) {
- auto it = nack_list_.lower_bound(*keyframe_list_.begin());
-
- if (it != nack_list_.begin()) {
- // We have found a keyframe that actually is newer than at least one
- // packet in the nack list.
- nack_list_.erase(nack_list_.begin(), it);
- return true;
- }
-
- // If this keyframe is so old it does not remove any packets from the list,
- // remove it from the list of keyframes and try the next keyframe.
- keyframe_list_.erase(keyframe_list_.begin());
- }
- return false;
-}
-
void NackRequester::AddPacketsToNack(uint16_t seq_num_start,
uint16_t seq_num_end) {
// Called on worker_thread_.
@@ -262,22 +229,13 @@ void NackRequester::AddPacketsToNack(uint16_t seq_num_start,
auto it = nack_list_.lower_bound(seq_num_end - kMaxPacketAge);
nack_list_.erase(nack_list_.begin(), it);
- // If the nack list is too large, remove packets from the nack list until
- // the latest first packet of a keyframe. If the list is still too large,
- // clear it and request a keyframe.
uint16_t num_new_nacks = ForwardDiff(seq_num_start, seq_num_end);
if (nack_list_.size() + num_new_nacks > kMaxNackPackets) {
- while (RemovePacketsUntilKeyFrame() &&
- nack_list_.size() + num_new_nacks > kMaxNackPackets) {
- }
-
- if (nack_list_.size() + num_new_nacks > kMaxNackPackets) {
- nack_list_.clear();
- RTC_LOG(LS_WARNING) << "NACK list full, clearing NACK"
- " list and requesting keyframe.";
- keyframe_request_sender_->RequestKeyFrame();
- return;
- }
+ nack_list_.clear();
+ RTC_LOG(LS_WARNING) << "NACK list full, clearing NACK"
+ " list and requesting keyframe.";
+ keyframe_request_sender_->RequestKeyFrame();
+ return;
}
for (uint16_t seq_num = seq_num_start; seq_num != seq_num_end; ++seq_num) {
diff --git a/third_party/libwebrtc/modules/video_coding/nack_requester.h b/third_party/libwebrtc/modules/video_coding/nack_requester.h
index c860787dcf..b5ef30f01b 100644
--- a/third_party/libwebrtc/modules/video_coding/nack_requester.h
+++ b/third_party/libwebrtc/modules/video_coding/nack_requester.h
@@ -78,8 +78,8 @@ class NackRequester final : public NackRequesterBase {
void ProcessNacks() override;
- int OnReceivedPacket(uint16_t seq_num, bool is_keyframe);
- int OnReceivedPacket(uint16_t seq_num, bool is_keyframe, bool is_recovered);
+ int OnReceivedPacket(uint16_t seq_num);
+ int OnReceivedPacket(uint16_t seq_num, bool is_recovered);
void ClearUpTo(uint16_t seq_num);
void UpdateRtt(int64_t rtt_ms);
@@ -108,10 +108,6 @@ class NackRequester final : public NackRequesterBase {
void AddPacketsToNack(uint16_t seq_num_start, uint16_t seq_num_end)
RTC_EXCLUSIVE_LOCKS_REQUIRED(worker_thread_);
- // Removes packets from the nack list until the next keyframe. Returns true
- // if packets were removed.
- bool RemovePacketsUntilKeyFrame()
- RTC_EXCLUSIVE_LOCKS_REQUIRED(worker_thread_);
std::vector<uint16_t> GetNackBatch(NackFilterOptions options)
RTC_EXCLUSIVE_LOCKS_REQUIRED(worker_thread_);
@@ -134,8 +130,6 @@ class NackRequester final : public NackRequesterBase {
// synchronized access.
std::map<uint16_t, NackInfo, DescendingSeqNumComp<uint16_t>> nack_list_
RTC_GUARDED_BY(worker_thread_);
- std::set<uint16_t, DescendingSeqNumComp<uint16_t>> keyframe_list_
- RTC_GUARDED_BY(worker_thread_);
std::set<uint16_t, DescendingSeqNumComp<uint16_t>> recovered_list_
RTC_GUARDED_BY(worker_thread_);
video_coding::Histogram reordering_histogram_ RTC_GUARDED_BY(worker_thread_);
diff --git a/third_party/libwebrtc/modules/video_coding/nack_requester_unittest.cc b/third_party/libwebrtc/modules/video_coding/nack_requester_unittest.cc
index 6f11cb6e91..2f24df2aef 100644
--- a/third_party/libwebrtc/modules/video_coding/nack_requester_unittest.cc
+++ b/third_party/libwebrtc/modules/video_coding/nack_requester_unittest.cc
@@ -102,90 +102,25 @@ class TestNackRequester : public ::testing::Test,
TEST_F(TestNackRequester, NackOnePacket) {
NackRequester& nack_module = CreateNackModule();
- nack_module.OnReceivedPacket(1, false, false);
- nack_module.OnReceivedPacket(3, false, false);
+ nack_module.OnReceivedPacket(1);
+ nack_module.OnReceivedPacket(3);
ASSERT_EQ(1u, sent_nacks_.size());
EXPECT_EQ(2, sent_nacks_[0]);
}
TEST_F(TestNackRequester, WrappingSeqNum) {
NackRequester& nack_module = CreateNackModule();
- nack_module.OnReceivedPacket(0xfffe, false, false);
- nack_module.OnReceivedPacket(1, false, false);
+ nack_module.OnReceivedPacket(0xfffe);
+ nack_module.OnReceivedPacket(1);
ASSERT_EQ(2u, sent_nacks_.size());
EXPECT_EQ(0xffff, sent_nacks_[0]);
EXPECT_EQ(0, sent_nacks_[1]);
}
-TEST_F(TestNackRequester, WrappingSeqNumClearToKeyframe) {
- NackRequester& nack_module = CreateNackModule(TimeDelta::Millis(10));
- nack_module.OnReceivedPacket(0xfffe, false, false);
- nack_module.OnReceivedPacket(1, false, false);
- ASSERT_EQ(2u, sent_nacks_.size());
- EXPECT_EQ(0xffff, sent_nacks_[0]);
- EXPECT_EQ(0, sent_nacks_[1]);
-
- sent_nacks_.clear();
- nack_module.OnReceivedPacket(2, true, false);
- ASSERT_EQ(0u, sent_nacks_.size());
-
- nack_module.OnReceivedPacket(501, true, false);
- ASSERT_EQ(498u, sent_nacks_.size());
- for (int seq_num = 3; seq_num < 501; ++seq_num)
- EXPECT_EQ(seq_num, sent_nacks_[seq_num - 3]);
-
- sent_nacks_.clear();
- nack_module.OnReceivedPacket(1001, false, false);
- EXPECT_EQ(499u, sent_nacks_.size());
- for (int seq_num = 502; seq_num < 1001; ++seq_num)
- EXPECT_EQ(seq_num, sent_nacks_[seq_num - 502]);
-
- sent_nacks_.clear();
- clock_->AdvanceTimeMilliseconds(100);
- ASSERT_TRUE(WaitForSendNack());
- ASSERT_EQ(999u, sent_nacks_.size());
- EXPECT_EQ(0xffff, sent_nacks_[0]);
- EXPECT_EQ(0, sent_nacks_[1]);
- for (int seq_num = 3; seq_num < 501; ++seq_num)
- EXPECT_EQ(seq_num, sent_nacks_[seq_num - 1]);
- for (int seq_num = 502; seq_num < 1001; ++seq_num)
- EXPECT_EQ(seq_num, sent_nacks_[seq_num - 2]);
-
- // Adding packet 1004 will cause the nack list to reach it's max limit.
- // It will then clear all nacks up to the next keyframe (seq num 2),
- // thus removing 0xffff and 0 from the nack list.
- sent_nacks_.clear();
- nack_module.OnReceivedPacket(1004, false, false);
- ASSERT_EQ(2u, sent_nacks_.size());
- EXPECT_EQ(1002, sent_nacks_[0]);
- EXPECT_EQ(1003, sent_nacks_[1]);
-
- sent_nacks_.clear();
- clock_->AdvanceTimeMilliseconds(100);
- ASSERT_TRUE(WaitForSendNack());
- ASSERT_EQ(999u, sent_nacks_.size());
- for (int seq_num = 3; seq_num < 501; ++seq_num)
- EXPECT_EQ(seq_num, sent_nacks_[seq_num - 3]);
- for (int seq_num = 502; seq_num < 1001; ++seq_num)
- EXPECT_EQ(seq_num, sent_nacks_[seq_num - 4]);
-
- // Adding packet 1007 will cause the nack module to overflow again, thus
- // clearing everything up to 501 which is the next keyframe.
- nack_module.OnReceivedPacket(1007, false, false);
- sent_nacks_.clear();
- clock_->AdvanceTimeMilliseconds(100);
- ASSERT_TRUE(WaitForSendNack());
- ASSERT_EQ(503u, sent_nacks_.size());
- for (int seq_num = 502; seq_num < 1001; ++seq_num)
- EXPECT_EQ(seq_num, sent_nacks_[seq_num - 502]);
- EXPECT_EQ(1005, sent_nacks_[501]);
- EXPECT_EQ(1006, sent_nacks_[502]);
-}
-
TEST_F(TestNackRequester, ResendNack) {
NackRequester& nack_module = CreateNackModule(TimeDelta::Millis(1));
- nack_module.OnReceivedPacket(1, false, false);
- nack_module.OnReceivedPacket(3, false, false);
+ nack_module.OnReceivedPacket(1);
+ nack_module.OnReceivedPacket(3);
size_t expected_nacks_sent = 1;
ASSERT_EQ(expected_nacks_sent, sent_nacks_.size());
EXPECT_EQ(2, sent_nacks_[0]);
@@ -225,8 +160,8 @@ TEST_F(TestNackRequester, ResendNack) {
TEST_F(TestNackRequester, ResendPacketMaxRetries) {
NackRequester& nack_module = CreateNackModule(TimeDelta::Millis(1));
- nack_module.OnReceivedPacket(1, false, false);
- nack_module.OnReceivedPacket(3, false, false);
+ nack_module.OnReceivedPacket(1);
+ nack_module.OnReceivedPacket(3);
ASSERT_EQ(1u, sent_nacks_.size());
EXPECT_EQ(2, sent_nacks_[0]);
@@ -246,37 +181,22 @@ TEST_F(TestNackRequester, ResendPacketMaxRetries) {
TEST_F(TestNackRequester, TooLargeNackList) {
NackRequester& nack_module = CreateNackModule();
- nack_module.OnReceivedPacket(0, false, false);
- nack_module.OnReceivedPacket(1001, false, false);
+ nack_module.OnReceivedPacket(0);
+ nack_module.OnReceivedPacket(1001);
EXPECT_EQ(1000u, sent_nacks_.size());
EXPECT_EQ(0, keyframes_requested_);
- nack_module.OnReceivedPacket(1003, false, false);
+ nack_module.OnReceivedPacket(1003);
EXPECT_EQ(1000u, sent_nacks_.size());
EXPECT_EQ(1, keyframes_requested_);
- nack_module.OnReceivedPacket(1004, false, false);
- EXPECT_EQ(1000u, sent_nacks_.size());
- EXPECT_EQ(1, keyframes_requested_);
-}
-
-TEST_F(TestNackRequester, TooLargeNackListWithKeyFrame) {
- NackRequester& nack_module = CreateNackModule();
- nack_module.OnReceivedPacket(0, false, false);
- nack_module.OnReceivedPacket(1, true, false);
- nack_module.OnReceivedPacket(1001, false, false);
- EXPECT_EQ(999u, sent_nacks_.size());
- EXPECT_EQ(0, keyframes_requested_);
- nack_module.OnReceivedPacket(1003, false, false);
- EXPECT_EQ(1000u, sent_nacks_.size());
- EXPECT_EQ(0, keyframes_requested_);
- nack_module.OnReceivedPacket(1005, false, false);
+ nack_module.OnReceivedPacket(1004);
EXPECT_EQ(1000u, sent_nacks_.size());
EXPECT_EQ(1, keyframes_requested_);
}
TEST_F(TestNackRequester, ClearUpTo) {
NackRequester& nack_module = CreateNackModule(TimeDelta::Millis(1));
- nack_module.OnReceivedPacket(0, false, false);
- nack_module.OnReceivedPacket(100, false, false);
+ nack_module.OnReceivedPacket(0);
+ nack_module.OnReceivedPacket(100);
EXPECT_EQ(99u, sent_nacks_.size());
sent_nacks_.clear();
@@ -289,8 +209,8 @@ TEST_F(TestNackRequester, ClearUpTo) {
TEST_F(TestNackRequester, ClearUpToWrap) {
NackRequester& nack_module = CreateNackModule();
- nack_module.OnReceivedPacket(0xfff0, false, false);
- nack_module.OnReceivedPacket(0xf, false, false);
+ nack_module.OnReceivedPacket(0xfff0);
+ nack_module.OnReceivedPacket(0xf);
EXPECT_EQ(30u, sent_nacks_.size());
sent_nacks_.clear();
@@ -303,13 +223,13 @@ TEST_F(TestNackRequester, ClearUpToWrap) {
TEST_F(TestNackRequester, PacketNackCount) {
NackRequester& nack_module = CreateNackModule(TimeDelta::Millis(1));
- EXPECT_EQ(0, nack_module.OnReceivedPacket(0, false, false));
- EXPECT_EQ(0, nack_module.OnReceivedPacket(2, false, false));
- EXPECT_EQ(1, nack_module.OnReceivedPacket(1, false, false));
+ EXPECT_EQ(0, nack_module.OnReceivedPacket(0));
+ EXPECT_EQ(0, nack_module.OnReceivedPacket(2));
+ EXPECT_EQ(1, nack_module.OnReceivedPacket(1));
sent_nacks_.clear();
nack_module.UpdateRtt(100);
- EXPECT_EQ(0, nack_module.OnReceivedPacket(5, false, false));
+ EXPECT_EQ(0, nack_module.OnReceivedPacket(5));
clock_->AdvanceTimeMilliseconds(100);
WaitForSendNack();
EXPECT_EQ(4u, sent_nacks_.size());
@@ -319,40 +239,24 @@ TEST_F(TestNackRequester, PacketNackCount) {
EXPECT_EQ(6u, sent_nacks_.size());
- EXPECT_EQ(3, nack_module.OnReceivedPacket(3, false, false));
- EXPECT_EQ(3, nack_module.OnReceivedPacket(4, false, false));
- EXPECT_EQ(0, nack_module.OnReceivedPacket(4, false, false));
-}
-
-TEST_F(TestNackRequester, NackListFullAndNoOverlapWithKeyframes) {
- NackRequester& nack_module = CreateNackModule();
- const int kMaxNackPackets = 1000;
- const unsigned int kFirstGap = kMaxNackPackets - 20;
- const unsigned int kSecondGap = 200;
- uint16_t seq_num = 0;
- nack_module.OnReceivedPacket(seq_num++, true, false);
- seq_num += kFirstGap;
- nack_module.OnReceivedPacket(seq_num++, true, false);
- EXPECT_EQ(kFirstGap, sent_nacks_.size());
- sent_nacks_.clear();
- seq_num += kSecondGap;
- nack_module.OnReceivedPacket(seq_num, true, false);
- EXPECT_EQ(kSecondGap, sent_nacks_.size());
+ EXPECT_EQ(3, nack_module.OnReceivedPacket(3));
+ EXPECT_EQ(3, nack_module.OnReceivedPacket(4));
+ EXPECT_EQ(0, nack_module.OnReceivedPacket(4));
}
TEST_F(TestNackRequester, HandleFecRecoveredPacket) {
NackRequester& nack_module = CreateNackModule();
- nack_module.OnReceivedPacket(1, false, false);
- nack_module.OnReceivedPacket(4, false, true);
+ nack_module.OnReceivedPacket(1);
+ nack_module.OnReceivedPacket(4, /*is_recovered=*/true);
EXPECT_EQ(0u, sent_nacks_.size());
- nack_module.OnReceivedPacket(5, false, false);
+ nack_module.OnReceivedPacket(5);
EXPECT_EQ(2u, sent_nacks_.size());
}
TEST_F(TestNackRequester, SendNackWithoutDelay) {
NackRequester& nack_module = CreateNackModule();
- nack_module.OnReceivedPacket(0, false, false);
- nack_module.OnReceivedPacket(100, false, false);
+ nack_module.OnReceivedPacket(0);
+ nack_module.OnReceivedPacket(100);
EXPECT_EQ(99u, sent_nacks_.size());
}
@@ -389,14 +293,14 @@ class TestNackRequesterWithFieldTrial : public ::testing::Test,
};
TEST_F(TestNackRequesterWithFieldTrial, SendNackWithDelay) {
- nack_module_.OnReceivedPacket(0, false, false);
- nack_module_.OnReceivedPacket(100, false, false);
+ nack_module_.OnReceivedPacket(0);
+ nack_module_.OnReceivedPacket(100);
EXPECT_EQ(0u, sent_nacks_.size());
clock_->AdvanceTimeMilliseconds(10);
- nack_module_.OnReceivedPacket(106, false, false);
+ nack_module_.OnReceivedPacket(106);
EXPECT_EQ(99u, sent_nacks_.size());
clock_->AdvanceTimeMilliseconds(10);
- nack_module_.OnReceivedPacket(109, false, false);
+ nack_module_.OnReceivedPacket(109);
EXPECT_EQ(104u, sent_nacks_.size());
}
} // namespace webrtc
diff --git a/third_party/libwebrtc/modules/video_coding/utility/qp_parser.cc b/third_party/libwebrtc/modules/video_coding/utility/qp_parser.cc
index 3b9aaa377e..a531b54a7e 100644
--- a/third_party/libwebrtc/modules/video_coding/utility/qp_parser.cc
+++ b/third_party/libwebrtc/modules/video_coding/utility/qp_parser.cc
@@ -37,7 +37,10 @@ absl::optional<uint32_t> QpParser::Parse(VideoCodecType codec_type,
} else if (codec_type == kVideoCodecH264) {
return h264_parsers_[spatial_idx].Parse(frame_data, frame_size);
} else if (codec_type == kVideoCodecH265) {
- // TODO(bugs.webrtc.org/13485)
+ // H.265 bitstream parser is conditionally built.
+#ifdef RTC_ENABLE_H265
+ return h265_parsers_[spatial_idx].Parse(frame_data, frame_size);
+#endif
}
return absl::nullopt;
@@ -52,4 +55,15 @@ absl::optional<uint32_t> QpParser::H264QpParser::Parse(
return bitstream_parser_.GetLastSliceQp();
}
+#ifdef RTC_ENABLE_H265
+absl::optional<uint32_t> QpParser::H265QpParser::Parse(
+ const uint8_t* frame_data,
+ size_t frame_size) {
+ MutexLock lock(&mutex_);
+ bitstream_parser_.ParseBitstream(
+ rtc::ArrayView<const uint8_t>(frame_data, frame_size));
+ return bitstream_parser_.GetLastSliceQp();
+}
+#endif
+
} // namespace webrtc
diff --git a/third_party/libwebrtc/modules/video_coding/utility/qp_parser.h b/third_party/libwebrtc/modules/video_coding/utility/qp_parser.h
index f132ff9337..210fe02bc3 100644
--- a/third_party/libwebrtc/modules/video_coding/utility/qp_parser.h
+++ b/third_party/libwebrtc/modules/video_coding/utility/qp_parser.h
@@ -15,6 +15,9 @@
#include "api/video/video_codec_constants.h"
#include "api/video/video_codec_type.h"
#include "common_video/h264/h264_bitstream_parser.h"
+#ifdef RTC_ENABLE_H265
+#include "common_video/h265/h265_bitstream_parser.h"
+#endif
#include "rtc_base/synchronization/mutex.h"
namespace webrtc {
@@ -38,6 +41,21 @@ class QpParser {
};
H264QpParser h264_parsers_[kMaxSimulcastStreams];
+
+#ifdef RTC_ENABLE_H265
+ // A thread safe wrapper for H.265 bitstream parser.
+ class H265QpParser {
+ public:
+ absl::optional<uint32_t> Parse(const uint8_t* frame_data,
+ size_t frame_size);
+
+ private:
+ Mutex mutex_;
+ H265BitstreamParser bitstream_parser_ RTC_GUARDED_BY(mutex_);
+ };
+
+ H265QpParser h265_parsers_[kMaxSimulcastStreams];
+#endif
};
} // namespace webrtc