Skip to content

Commit 59c7b22

Browse files
Emil VardarWebRTC LUCI CQ
authored andcommitted
Log received frames QP value.
spatial_layers_qp holds the QP values for all the spatial layers. However, receiver only sees one of the spatial layers at a given time. It is of interest to know the shown spatial layers QP. This could also be used to indicate if upper layers are frequently dropped or not. Bug: None Change-Id: I462ea11e3447f8ffd11f4a6f2ccbf361102c762f Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/358863 Reviewed-by: Ilya Nikolaevskiy <[email protected]> Reviewed-by: Mirko Bonadei <[email protected]> Commit-Queue: Emil Vardar (xWF) <[email protected]> Cr-Commit-Position: refs/heads/main@{#42759}
1 parent 5352352 commit 59c7b22

11 files changed

+100
-6
lines changed

api/test/video_quality_analyzer_interface.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -72,6 +72,8 @@ class VideoQualityAnalyzerInterface
7272
// Decode time provided by decoder itself. If decoder doesn’t produce such
7373
// information can be omitted.
7474
absl::optional<int32_t> decode_time_ms = absl::nullopt;
75+
// Decoder quantizer value.
76+
absl::optional<uint8_t> qp = absl::nullopt;
7577
};
7678

7779
~VideoQualityAnalyzerInterface() override = default;

test/pc/e2e/analyzer/video/default_video_quality_analyzer.cc

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -476,7 +476,7 @@ void DefaultVideoQualityAnalyzer::OnFrameDecoded(
476476
used_decoder.switched_on_at = now;
477477
used_decoder.switched_from_at = now;
478478
it->second.OnFrameDecoded(peer_index, now, frame.width(), frame.height(),
479-
used_decoder);
479+
used_decoder, stats.qp);
480480

481481
if (options_.report_infra_metrics) {
482482
analyzer_stats_.on_frame_decoded_processing_time_ms.AddSample(
@@ -1258,6 +1258,9 @@ void DefaultVideoQualityAnalyzer::ReportResults(
12581258
ImprovementDirection::kSmallerIsBetter,
12591259
std::move(qp_metadata));
12601260
}
1261+
metrics_logger_->LogMetric(
1262+
"rendered_frame_qp", test_case_name, stats.rendered_frame_qp,
1263+
Unit::kUnitless, ImprovementDirection::kSmallerIsBetter, metric_metadata);
12611264
metrics_logger_->LogSingleValueMetric(
12621265
"actual_encode_bitrate", test_case_name,
12631266
static_cast<double>(stats.total_encoded_images_payload) /

test/pc/e2e/analyzer/video/default_video_quality_analyzer_frame_in_flight.cc

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -135,11 +135,13 @@ void FrameInFlight::OnFrameDecoded(size_t peer,
135135
webrtc::Timestamp time,
136136
int width,
137137
int height,
138-
const StreamCodecInfo& used_decoder) {
138+
const StreamCodecInfo& used_decoder,
139+
const absl::optional<uint8_t> qp) {
139140
receiver_stats_[peer].decode_end_time = time;
140141
receiver_stats_[peer].used_decoder = used_decoder;
141142
receiver_stats_[peer].decoded_frame_width = width;
142143
receiver_stats_[peer].decoded_frame_height = height;
144+
receiver_stats_[peer].decoded_frame_qp = qp;
143145
}
144146

145147
void FrameInFlight::OnDecoderError(size_t peer,
@@ -204,6 +206,7 @@ FrameStats FrameInFlight::GetStatsForPeer(size_t peer) const {
204206
receiver_stats->time_between_rendered_frames;
205207
stats.decoded_frame_width = receiver_stats->decoded_frame_width;
206208
stats.decoded_frame_height = receiver_stats->decoded_frame_height;
209+
stats.decoded_frame_qp = receiver_stats->decoded_frame_qp;
207210
stats.used_decoder = receiver_stats->used_decoder;
208211
stats.pre_decoded_frame_type = receiver_stats->frame_type;
209212
stats.pre_decoded_image_size = receiver_stats->encoded_image_size;

test/pc/e2e/analyzer/video/default_video_quality_analyzer_frame_in_flight.h

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,8 @@ struct ReceiverFrameStats {
4646
absl::optional<int> decoded_frame_width = absl::nullopt;
4747
absl::optional<int> decoded_frame_height = absl::nullopt;
4848

49+
absl::optional<uint8_t> decoded_frame_qp = absl::nullopt;
50+
4951
// Can be not set if frame was dropped in the network.
5052
absl::optional<StreamCodecInfo> used_decoder = absl::nullopt;
5153

@@ -113,7 +115,9 @@ class FrameInFlight {
113115
Timestamp time,
114116
int width,
115117
int height,
116-
const StreamCodecInfo& used_decoder);
118+
const StreamCodecInfo& used_decoder,
119+
const absl::optional<uint8_t> qp);
120+
117121
void OnDecoderError(size_t peer, const StreamCodecInfo& used_decoder);
118122

119123
bool HasDecodeEndTime(size_t peer) const;

test/pc/e2e/analyzer/video/default_video_quality_analyzer_frames_comparator.cc

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -552,6 +552,14 @@ void DefaultVideoQualityAnalyzerFramesComparator::ProcessComparison(
552552
StatsSample(*comparison.frame_stats.decoded_frame_width *
553553
*comparison.frame_stats.decoded_frame_height,
554554
frame_stats.decode_end_time, metadata));
555+
// TODO(webrtc:357636606): Add a check that the rendered QP is among the
556+
// encoded spatial layer's QP. Can only do that if there are 1 and only 1
557+
// QP value per spatial layer.
558+
if (frame_stats.decoded_frame_qp.has_value()) {
559+
stats->rendered_frame_qp.AddSample(
560+
StatsSample(static_cast<double>(*frame_stats.decoded_frame_qp),
561+
frame_stats.decode_end_time, metadata));
562+
}
555563
}
556564

557565
if (frame_stats.prev_frame_rendered_time.has_value() &&

test/pc/e2e/analyzer/video/default_video_quality_analyzer_frames_comparator_test.cc

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -401,6 +401,7 @@ TEST(DefaultVideoQualityAnalyzerFramesComparatorTest,
401401
ExpectEmpty(stats.resolution_of_decoded_frame);
402402
ExpectEmpty(stats.target_encode_bitrate);
403403
EXPECT_THAT(stats.spatial_layers_qp, IsEmpty());
404+
ExpectEmpty(stats.rendered_frame_qp);
404405
ExpectEmpty(stats.recv_key_frame_size_bytes);
405406
ExpectEmpty(stats.recv_delta_frame_size_bytes);
406407
EXPECT_EQ(stats.total_encoded_images_payload, 0);
@@ -461,6 +462,7 @@ TEST(DefaultVideoQualityAnalyzerFramesComparatorTest,
461462
ExpectEmpty(stats.resolution_of_decoded_frame);
462463
ExpectEmpty(stats.target_encode_bitrate);
463464
EXPECT_THAT(stats.spatial_layers_qp, IsEmpty());
465+
ExpectEmpty(stats.rendered_frame_qp);
464466
ExpectEmpty(stats.recv_key_frame_size_bytes);
465467
ExpectEmpty(stats.recv_delta_frame_size_bytes);
466468
EXPECT_EQ(stats.total_encoded_images_payload, 0);
@@ -536,6 +538,7 @@ TEST(DefaultVideoQualityAnalyzerFramesComparatorTest,
536538
EXPECT_THAT(stats.spatial_layers_qp, SizeIs(1));
537539
ExpectSizeAndAllElementsAre(stats.spatial_layers_qp[0], /*size=*/2,
538540
/*value=*/5.0);
541+
ExpectEmpty(stats.rendered_frame_qp);
539542
ExpectEmpty(stats.recv_key_frame_size_bytes);
540543
ExpectEmpty(stats.recv_delta_frame_size_bytes);
541544
EXPECT_EQ(stats.total_encoded_images_payload, 1000);
@@ -612,6 +615,7 @@ TEST(DefaultVideoQualityAnalyzerFramesComparatorTest,
612615
EXPECT_THAT(stats.spatial_layers_qp, SizeIs(1));
613616
ExpectSizeAndAllElementsAre(stats.spatial_layers_qp[0], /*size=*/2,
614617
/*value=*/5.0);
618+
ExpectEmpty(stats.rendered_frame_qp);
615619
ExpectEmpty(stats.recv_key_frame_size_bytes);
616620
ExpectEmpty(stats.recv_delta_frame_size_bytes);
617621
EXPECT_EQ(stats.total_encoded_images_payload, 1000);
@@ -694,6 +698,7 @@ TEST(DefaultVideoQualityAnalyzerFramesComparatorTest,
694698
EXPECT_THAT(stats.spatial_layers_qp, SizeIs(1));
695699
ExpectSizeAndAllElementsAre(stats.spatial_layers_qp[0], /*size=*/2,
696700
/*value=*/5.0);
701+
ExpectEmpty(stats.rendered_frame_qp);
697702
ExpectSizeAndAllElementsAre(stats.recv_key_frame_size_bytes, /*size=*/1,
698703
/*value=*/500.0);
699704
ExpectEmpty(stats.recv_delta_frame_size_bytes);
@@ -749,6 +754,7 @@ TEST(DefaultVideoQualityAnalyzerFramesComparatorTest,
749754
frame_stats.decode_end_time = captured_time + TimeDelta::Millis(50);
750755
frame_stats.decoded_frame_width = 200;
751756
frame_stats.decoded_frame_height = 100;
757+
frame_stats.decoded_frame_qp = 10;
752758

753759
frame_stats.used_decoder =
754760
Vp8CodecForOneFrame(frame_id, frame_stats.decode_end_time);
@@ -784,6 +790,8 @@ TEST(DefaultVideoQualityAnalyzerFramesComparatorTest,
784790
EXPECT_THAT(stats.spatial_layers_qp, SizeIs(1));
785791
ExpectSizeAndAllElementsAre(stats.spatial_layers_qp[0], /*size=*/2,
786792
/*value=*/5.0);
793+
ExpectSizeAndAllElementsAre(stats.rendered_frame_qp, /*size=*/1,
794+
/*value=*/10.0);
787795
ExpectSizeAndAllElementsAre(stats.recv_key_frame_size_bytes, /*size=*/1,
788796
/*value=*/500.0);
789797
ExpectEmpty(stats.recv_delta_frame_size_bytes);
@@ -840,6 +848,7 @@ TEST(DefaultVideoQualityAnalyzerFramesComparatorTest,
840848
frame_stats.decoder_failed = true;
841849
frame_stats.used_decoder =
842850
Vp8CodecForOneFrame(frame_id, frame_stats.decode_end_time);
851+
frame_stats.decoded_frame_qp = 10;
843852

844853
comparator.Start(/*max_threads_count=*/1);
845854
comparator.EnsureStatsForStream(stream, sender, /*peers_count=*/2,
@@ -872,6 +881,7 @@ TEST(DefaultVideoQualityAnalyzerFramesComparatorTest,
872881
EXPECT_THAT(stats.spatial_layers_qp, SizeIs(1));
873882
ExpectSizeAndAllElementsAre(stats.spatial_layers_qp[0], /*size=*/2,
874883
/*value=*/5.0);
884+
ExpectEmpty(stats.rendered_frame_qp);
875885
ExpectSizeAndAllElementsAre(stats.recv_key_frame_size_bytes, /*size=*/1,
876886
/*value=*/500.0);
877887
ExpectEmpty(stats.recv_delta_frame_size_bytes);
@@ -936,6 +946,7 @@ TEST(DefaultVideoQualityAnalyzerFramesComparatorTest,
936946
ExpectEmpty(stats.resolution_of_decoded_frame);
937947
ExpectEmpty(stats.target_encode_bitrate);
938948
EXPECT_THAT(stats.spatial_layers_qp, IsEmpty());
949+
ExpectEmpty(stats.rendered_frame_qp);
939950
ExpectEmpty(stats.recv_key_frame_size_bytes);
940951
ExpectEmpty(stats.recv_delta_frame_size_bytes);
941952
EXPECT_EQ(stats.total_encoded_images_payload, 0);
@@ -996,6 +1007,7 @@ TEST(DefaultVideoQualityAnalyzerFramesComparatorTest,
9961007
ExpectEmpty(stats.resolution_of_decoded_frame);
9971008
ExpectEmpty(stats.target_encode_bitrate);
9981009
EXPECT_THAT(stats.spatial_layers_qp, IsEmpty());
1010+
ExpectEmpty(stats.rendered_frame_qp);
9991011
ExpectEmpty(stats.recv_key_frame_size_bytes);
10001012
ExpectEmpty(stats.recv_delta_frame_size_bytes);
10011013
EXPECT_EQ(stats.total_encoded_images_payload, 0);
@@ -1071,6 +1083,7 @@ TEST(DefaultVideoQualityAnalyzerFramesComparatorTest,
10711083
EXPECT_THAT(stats.spatial_layers_qp, SizeIs(1));
10721084
ExpectSizeAndAllElementsAre(stats.spatial_layers_qp[0], /*size=*/2,
10731085
/*value=*/5.0);
1086+
ExpectEmpty(stats.rendered_frame_qp);
10741087
ExpectEmpty(stats.recv_key_frame_size_bytes);
10751088
ExpectEmpty(stats.recv_delta_frame_size_bytes);
10761089
EXPECT_EQ(stats.total_encoded_images_payload, 1000);
@@ -1147,6 +1160,7 @@ TEST(DefaultVideoQualityAnalyzerFramesComparatorTest,
11471160
EXPECT_THAT(stats.spatial_layers_qp, SizeIs(1));
11481161
ExpectSizeAndAllElementsAre(stats.spatial_layers_qp[0], /*size=*/2,
11491162
/*value=*/5.0);
1163+
ExpectEmpty(stats.rendered_frame_qp);
11501164
ExpectEmpty(stats.recv_key_frame_size_bytes);
11511165
ExpectEmpty(stats.recv_delta_frame_size_bytes);
11521166
EXPECT_EQ(stats.total_encoded_images_payload, 1000);
@@ -1235,6 +1249,7 @@ TEST(DefaultVideoQualityAnalyzerFramesComparatorTest,
12351249
EXPECT_EQ(stats.encoders,
12361250
std::vector<StreamCodecInfo>{*frame_stats.used_encoder});
12371251
EXPECT_THAT(stats.decoders, IsEmpty());
1252+
ExpectEmpty(stats.rendered_frame_qp);
12381253
}
12391254

12401255
TEST(DefaultVideoQualityAnalyzerFramesComparatorTest,
@@ -1280,6 +1295,7 @@ TEST(DefaultVideoQualityAnalyzerFramesComparatorTest,
12801295
Vp8CodecForOneFrame(frame_id, frame_stats.decode_end_time);
12811296
frame_stats.decoded_frame_width = 200;
12821297
frame_stats.decoded_frame_height = 100;
1298+
frame_stats.decoded_frame_qp = 10;
12831299

12841300
comparator.Start(/*max_threads_count=*/1);
12851301
comparator.EnsureStatsForStream(stream, sender, /*peers_count=*/2,
@@ -1311,6 +1327,7 @@ TEST(DefaultVideoQualityAnalyzerFramesComparatorTest,
13111327
EXPECT_THAT(stats.spatial_layers_qp, SizeIs(1));
13121328
ExpectSizeAndAllElementsAre(stats.spatial_layers_qp[0], /*size=*/2,
13131329
/*value=*/5.0);
1330+
ExpectEmpty(stats.rendered_frame_qp);
13141331
ExpectEmpty(stats.recv_key_frame_size_bytes);
13151332
ExpectEmpty(stats.recv_delta_frame_size_bytes);
13161333
EXPECT_EQ(stats.total_encoded_images_payload, 1000);
@@ -1366,6 +1383,7 @@ TEST(DefaultVideoQualityAnalyzerFramesComparatorTest,
13661383
frame_stats.decoder_failed = true;
13671384
frame_stats.used_decoder =
13681385
Vp8CodecForOneFrame(frame_id, frame_stats.decode_end_time);
1386+
frame_stats.decoded_frame_qp = 10;
13691387

13701388
comparator.Start(/*max_threads_count=*/1);
13711389
comparator.EnsureStatsForStream(stream, sender, /*peers_count=*/2,
@@ -1398,6 +1416,7 @@ TEST(DefaultVideoQualityAnalyzerFramesComparatorTest,
13981416
EXPECT_THAT(stats.spatial_layers_qp, SizeIs(1));
13991417
ExpectSizeAndAllElementsAre(stats.spatial_layers_qp[0], /*size=*/2,
14001418
/*value=*/5.0);
1419+
ExpectEmpty(stats.rendered_frame_qp);
14011420
ExpectSizeAndAllElementsAre(stats.recv_key_frame_size_bytes, /*size=*/1,
14021421
/*value=*/500.0);
14031422
ExpectEmpty(stats.recv_delta_frame_size_bytes);
@@ -1460,6 +1479,7 @@ TEST(DefaultVideoQualityAnalyzerFramesComparatorTest,
14601479
Vp8CodecForOneFrame(frame_id, frame_stats.decode_end_time);
14611480
frame_stats.decoded_frame_width = 200;
14621481
frame_stats.decoded_frame_height = 100;
1482+
frame_stats.decoded_frame_qp = 10;
14631483
// Frame rendered
14641484
frame_stats.rendered_time = captured_time + TimeDelta::Millis(60);
14651485

@@ -1494,6 +1514,8 @@ TEST(DefaultVideoQualityAnalyzerFramesComparatorTest,
14941514
EXPECT_THAT(stats.spatial_layers_qp, SizeIs(1));
14951515
ExpectSizeAndAllElementsAre(stats.spatial_layers_qp[0], /*size=*/2,
14961516
/*value=*/5.0);
1517+
ExpectSizeAndAllElementsAre(stats.rendered_frame_qp, /*size=*/1,
1518+
/*value=*/10.0);
14971519
ExpectSizeAndAllElementsAre(stats.recv_key_frame_size_bytes, /*size=*/1,
14981520
/*value=*/500.0);
14991521
ExpectEmpty(stats.recv_delta_frame_size_bytes);
@@ -1555,6 +1577,7 @@ TEST(DefaultVideoQualityAnalyzerFramesComparatorTest, AllStatsHaveMetadataSet) {
15551577
frame_stats.rendered_time = captured_time + TimeDelta::Millis(60);
15561578
frame_stats.decoded_frame_width = 200;
15571579
frame_stats.decoded_frame_height = 100;
1580+
frame_stats.decoded_frame_qp = 10;
15581581

15591582
comparator.Start(/*max_threads_count=*/1);
15601583
comparator.EnsureStatsForStream(stream, sender, /*peers_count=*/2,
@@ -1580,6 +1603,7 @@ TEST(DefaultVideoQualityAnalyzerFramesComparatorTest, AllStatsHaveMetadataSet) {
15801603
AssertFirstMetadataHasField(stats.target_encode_bitrate, "frame_id", "1");
15811604
AssertFirstMetadataHasField(stats.spatial_layers_qp[0], "frame_id", "1");
15821605
AssertFirstMetadataHasField(stats.recv_key_frame_size_bytes, "frame_id", "1");
1606+
AssertFirstMetadataHasField(stats.rendered_frame_qp, "frame_id", "1");
15831607

15841608
ExpectEmpty(stats.recv_delta_frame_size_bytes);
15851609
}

test/pc/e2e/analyzer/video/default_video_quality_analyzer_internal_shared_objects.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -72,6 +72,11 @@ struct FrameStats {
7272
// Sender side qp values per spatial layer. In case when spatial layer is not
7373
// set for `webrtc::EncodedImage`, 0 is used as default.
7474
std::map<int, SamplesStatsCounter> spatial_layers_qp;
75+
// Receive side qp value. Receiver only renders one spatial layer for a given
76+
// time index. The QP value here corresponds to one of the encoded spatial
77+
// layer's QP given in `spatial_layers_qp`, i.e. to the one that corresponds
78+
// to the rendered frame.
79+
absl::optional<uint8_t> decoded_frame_qp = absl::nullopt;
7580

7681
absl::optional<int> decoded_frame_width = absl::nullopt;
7782
absl::optional<int> decoded_frame_height = absl::nullopt;

test/pc/e2e/analyzer/video/default_video_quality_analyzer_metric_names_test.cc

Lines changed: 18 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -280,6 +280,11 @@ TEST(DefaultVideoQualityAnalyzerMetricNamesTest, MetricNamesForP2PAreCorrect) {
280280
.name = "qp_sl0",
281281
.unit = Unit::kUnitless,
282282
.improvement_direction = ImprovementDirection::kSmallerIsBetter},
283+
MetricValidationInfo{
284+
.test_case = "test_case/alice_video",
285+
.name = "rendered_frame_qp",
286+
.unit = Unit::kUnitless,
287+
.improvement_direction = ImprovementDirection::kSmallerIsBetter},
283288
MetricValidationInfo{
284289
.test_case = "test_case/alice_video",
285290
.name = "actual_encode_bitrate",
@@ -454,6 +459,11 @@ TEST(DefaultVideoQualityAnalyzerMetricNamesTest,
454459
.name = "qp_sl0",
455460
.unit = Unit::kUnitless,
456461
.improvement_direction = ImprovementDirection::kSmallerIsBetter},
462+
MetricValidationInfo{
463+
.test_case = "test_case/alice_video_alice_bob",
464+
.name = "rendered_frame_qp",
465+
.unit = Unit::kUnitless,
466+
.improvement_direction = ImprovementDirection::kSmallerIsBetter},
457467
MetricValidationInfo{
458468
.test_case = "test_case/alice_video_alice_bob",
459469
.name = "actual_encode_bitrate",
@@ -596,6 +606,11 @@ TEST(DefaultVideoQualityAnalyzerMetricNamesTest,
596606
.name = "qp_sl0",
597607
.unit = Unit::kUnitless,
598608
.improvement_direction = ImprovementDirection::kSmallerIsBetter},
609+
MetricValidationInfo{
610+
.test_case = "test_case/alice_video_alice_charlie",
611+
.name = "rendered_frame_qp",
612+
.unit = Unit::kUnitless,
613+
.improvement_direction = ImprovementDirection::kSmallerIsBetter},
599614
MetricValidationInfo{
600615
.test_case = "test_case/alice_video_alice_charlie",
601616
.name = "actual_encode_bitrate",
@@ -669,10 +684,10 @@ TEST(DefaultVideoQualityAnalyzerMetricNamesTest,
669684

670685
std::vector<std::string> metrics =
671686
ToTestCases(metrics_logger.GetCollectedMetrics());
672-
EXPECT_THAT(metrics, SizeIs(57));
673-
EXPECT_THAT(metrics, Contains("test_case/alice_video_alice_bob").Times(28));
687+
EXPECT_THAT(metrics, SizeIs(59));
688+
EXPECT_THAT(metrics, Contains("test_case/alice_video_alice_bob").Times(29));
674689
EXPECT_THAT(metrics,
675-
Contains("test_case/alice_video_alice_charlie").Times(28));
690+
Contains("test_case/alice_video_alice_charlie").Times(29));
676691
EXPECT_THAT(metrics, Contains("test_case").Times(1));
677692
}
678693

test/pc/e2e/analyzer/video/default_video_quality_analyzer_shared_objects.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -151,6 +151,11 @@ struct StreamStats {
151151
// Sender side qp values per spatial layer. In case when spatial layer is not
152152
// set for `webrtc::EncodedImage`, 0 is used as default.
153153
std::map<int, SamplesStatsCounter> spatial_layers_qp;
154+
// QP values of the rendered frames. In SVC or simulcast coding scenarios, the
155+
// receiver will only render one of the spatial layers at a time. Hence, this
156+
// value corresponds to the rendered frames' QP values, which should ideally
157+
// correspond to one of the QP values in `spatial_layers_qp`.
158+
SamplesStatsCounter rendered_frame_qp;
154159

155160
int64_t total_encoded_images_payload = 0;
156161
// Counters on which phase how many frames were dropped.

test/pc/e2e/analyzer/video/quality_analyzing_video_decoder.cc

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -239,6 +239,7 @@ void QualityAnalyzingVideoDecoder::OnFrameDecoded(
239239
VideoQualityAnalyzerInterface::DecoderStats stats;
240240
stats.decoder_name = codec_name;
241241
stats.decode_time_ms = decode_time_ms;
242+
stats.qp = qp;
242243
analyzer_->OnFrameDecoded(peer_name_, *frame, stats);
243244
}
244245

0 commit comments

Comments
 (0)