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

Side by Side Diff: webrtc/modules/video_coding/video_packet_buffer_unittest.cc

Issue 2926083002: Only create H264 frames if there are no gaps in the packet sequence number. (Closed)
Patch Set: Feedback Created 3 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 /* 1 /*
2 * Copyright (c) 2016 The WebRTC project authors. All Rights Reserved. 2 * Copyright (c) 2016 The WebRTC project authors. All Rights Reserved.
3 * 3 *
4 * Use of this source code is governed by a BSD-style license 4 * Use of this source code is governed by a BSD-style license
5 * that can be found in the LICENSE file in the root of the source 5 * that can be found in the LICENSE file in the root of the source
6 * tree. An additional intellectual property rights grant can be found 6 * tree. An additional intellectual property rights grant can be found
7 * in the file PATENTS. All contributing project authors may 7 * in the file PATENTS. All contributing project authors may
8 * be found in the AUTHORS file in the root of the source tree. 8 * be found in the AUTHORS file in the root of the source tree.
9 */ 9 */
10 10
11 #include <cstring> 11 #include <cstring>
12 #include <map> 12 #include <map>
13 #include <set> 13 #include <set>
14 #include <utility> 14 #include <utility>
15 15
16 #include "webrtc/base/random.h" 16 #include "webrtc/base/random.h"
17 #include "webrtc/common_video/h264/h264_common.h"
17 #include "webrtc/modules/video_coding/frame_object.h" 18 #include "webrtc/modules/video_coding/frame_object.h"
18 #include "webrtc/modules/video_coding/packet_buffer.h" 19 #include "webrtc/modules/video_coding/packet_buffer.h"
19 #include "webrtc/system_wrappers/include/clock.h" 20 #include "webrtc/system_wrappers/include/clock.h"
20 #include "webrtc/test/gtest.h" 21 #include "webrtc/test/gtest.h"
21 22
22 namespace webrtc { 23 namespace webrtc {
23 namespace video_coding { 24 namespace video_coding {
24 25
25 class TestPacketBuffer : public ::testing::Test, 26 class TestPacketBuffer : public ::testing::Test,
26 public OnReceivedFrameCallback { 27 public OnReceivedFrameCallback {
27 protected: 28 protected:
28 TestPacketBuffer() 29 TestPacketBuffer()
29 : rand_(0x7732213), 30 : rand_(0x7732213),
30 clock_(new SimulatedClock(0)), 31 clock_(new SimulatedClock(0)),
31 packet_buffer_( 32 packet_buffer_(
32 PacketBuffer::Create(clock_.get(), kStartSize, kMaxSize, this)) {} 33 PacketBuffer::Create(clock_.get(), kStartSize, kMaxSize, this)) {}
33 34
34 uint16_t Rand() { return rand_.Rand<uint16_t>(); } 35 uint16_t Rand() { return rand_.Rand<uint16_t>(); }
35 36
36 void OnReceivedFrame(std::unique_ptr<RtpFrameObject> frame) override { 37 void OnReceivedFrame(std::unique_ptr<RtpFrameObject> frame) override {
37 uint16_t first_seq_num = frame->first_seq_num(); 38 uint16_t first_seq_num = frame->first_seq_num();
38 if (frames_from_callback_.find(first_seq_num) != 39 if (frames_from_callback_.find(first_seq_num) !=
39 frames_from_callback_.end()) { 40 frames_from_callback_.end()) {
40 ADD_FAILURE() << "Already received frame with first sequence number " 41 ADD_FAILURE() << "Already received frame with first sequence number "
41 << first_seq_num << "."; 42 << first_seq_num << ".";
42 return; 43 return;
43 } 44 }
45
44 frames_from_callback_.insert( 46 frames_from_callback_.insert(
45 std::make_pair(frame->first_seq_num(), std::move(frame))); 47 std::make_pair(frame->first_seq_num(), std::move(frame)));
46 } 48 }
47 49
48 enum IsKeyFrame { kKeyFrame, kDeltaFrame }; 50 enum IsKeyFrame { kKeyFrame, kDeltaFrame };
49 enum IsFirst { kFirst, kNotFirst }; 51 enum IsFirst { kFirst, kNotFirst };
50 enum IsLast { kLast, kNotLast }; 52 enum IsLast { kLast, kNotLast };
51 53
52 bool Insert(uint16_t seq_num, // packet sequence number 54 bool Insert(uint16_t seq_num, // packet sequence number
53 IsKeyFrame keyframe, // is keyframe 55 IsKeyFrame keyframe, // is keyframe
54 IsFirst first, // is first packet of frame 56 IsFirst first, // is first packet of frame
55 IsLast last, // is last packet of frame 57 IsLast last, // is last packet of frame
56 int data_size = 0, // size of data 58 int data_size = 0, // size of data
57 uint8_t* data = nullptr) { // data pointer 59 uint8_t* data = nullptr) { // data pointer
58 VCMPacket packet; 60 VCMPacket packet;
59 packet.codec = kVideoCodecGeneric; 61 packet.codec = kVideoCodecGeneric;
60 packet.seqNum = seq_num; 62 packet.seqNum = seq_num;
61 packet.frameType = 63 packet.frameType =
62 keyframe == kKeyFrame ? kVideoFrameKey : kVideoFrameDelta; 64 keyframe == kKeyFrame ? kVideoFrameKey : kVideoFrameDelta;
63 packet.is_first_packet_in_frame = first == kFirst; 65 packet.is_first_packet_in_frame = first == kFirst;
64 packet.markerBit = last == kLast; 66 packet.markerBit = last == kLast;
65 packet.sizeBytes = data_size; 67 packet.sizeBytes = data_size;
66 packet.dataPtr = data; 68 packet.dataPtr = data;
67 69
68 return packet_buffer_->InsertPacket(&packet); 70 return packet_buffer_->InsertPacket(&packet);
69 } 71 }
70 72
73 bool InsertH264(uint16_t seq_num, // packet sequence number
74 IsKeyFrame keyframe, // is keyframe
75 IsFirst first, // is first packet of frame
76 IsLast last, // is last packet of frame
77 uint32_t timestamp, // rtp timestamp
78 int data_size = 0, // size of data
79 uint8_t* data = nullptr) { // data pointer
80 VCMPacket packet;
81 packet.codec = kVideoCodecH264;
82 packet.seqNum = seq_num;
83 packet.timestamp = timestamp;
84 packet.video_header.codecHeader.H264.nalus[0].type = H264::NaluType::kIdr;
85 packet.video_header.codecHeader.H264.nalus_length = keyframe == kKeyFrame;
86 packet.is_first_packet_in_frame = first == kFirst;
87 packet.markerBit = last == kLast;
88 packet.sizeBytes = data_size;
89 packet.dataPtr = data;
90
91 return packet_buffer_->InsertPacket(&packet);
92 }
93
71 void CheckFrame(uint16_t first_seq_num) { 94 void CheckFrame(uint16_t first_seq_num) {
72 auto frame_it = frames_from_callback_.find(first_seq_num); 95 auto frame_it = frames_from_callback_.find(first_seq_num);
73 ASSERT_FALSE(frame_it == frames_from_callback_.end()) 96 ASSERT_FALSE(frame_it == frames_from_callback_.end())
74 << "Could not find frame with first sequence number " << first_seq_num 97 << "Could not find frame with first sequence number " << first_seq_num
75 << "."; 98 << ".";
76 } 99 }
77 100
78 const int kStartSize = 16; 101 const int kStartSize = 16;
79 const int kMaxSize = 64; 102 const int kMaxSize = 64;
80 103
(...skipping 278 matching lines...) Expand 10 before | Expand all | Expand 10 after
359 uint16_t seq_num = Rand(); 382 uint16_t seq_num = Rand();
360 uint8_t data_data[] = "some plain old data"; 383 uint8_t data_data[] = "some plain old data";
361 uint8_t* data = new uint8_t[sizeof(data_data)]; 384 uint8_t* data = new uint8_t[sizeof(data_data)];
362 memcpy(data, data_data, sizeof(data_data)); 385 memcpy(data, data_data, sizeof(data_data));
363 386
364 // EncodedImage::kBufferPaddingBytesH264 is unknown at compile time. 387 // EncodedImage::kBufferPaddingBytesH264 is unknown at compile time.
365 std::unique_ptr<uint8_t[]> result( 388 std::unique_ptr<uint8_t[]> result(
366 new uint8_t[sizeof(data_data) + EncodedImage::kBufferPaddingBytesH264]); 389 new uint8_t[sizeof(data_data) + EncodedImage::kBufferPaddingBytesH264]);
367 390
368 VCMPacket packet; 391 VCMPacket packet;
392 packet.video_header.codecHeader.H264.nalus_length = 1;
393 packet.video_header.codecHeader.H264.nalus[0].type = H264::NaluType::kIdr;
369 packet.seqNum = seq_num; 394 packet.seqNum = seq_num;
370 packet.codec = kVideoCodecH264; 395 packet.codec = kVideoCodecH264;
371 packet.insertStartCode = true; 396 packet.insertStartCode = true;
372 packet.video_header.codecHeader.H264.packetization_type = kH264SingleNalu; 397 packet.video_header.codecHeader.H264.packetization_type = kH264SingleNalu;
373 packet.dataPtr = data; 398 packet.dataPtr = data;
374 packet.sizeBytes = sizeof(data_data); 399 packet.sizeBytes = sizeof(data_data);
375 packet.is_first_packet_in_frame = true; 400 packet.is_first_packet_in_frame = true;
376 packet.markerBit = true; 401 packet.markerBit = true;
377 packet_buffer_->InsertPacket(&packet); 402 packet_buffer_->InsertPacket(&packet);
378 403
(...skipping 92 matching lines...) Expand 10 before | Expand all | Expand 10 after
471 496
472 TEST_F(TestPacketBuffer, ContinuousSeqNumDoubleMarkerBit) { 497 TEST_F(TestPacketBuffer, ContinuousSeqNumDoubleMarkerBit) {
473 Insert(2, kKeyFrame, kNotFirst, kNotLast); 498 Insert(2, kKeyFrame, kNotFirst, kNotLast);
474 Insert(1, kKeyFrame, kFirst, kLast); 499 Insert(1, kKeyFrame, kFirst, kLast);
475 frames_from_callback_.clear(); 500 frames_from_callback_.clear();
476 Insert(3, kKeyFrame, kNotFirst, kLast); 501 Insert(3, kKeyFrame, kNotFirst, kLast);
477 502
478 EXPECT_EQ(0UL, frames_from_callback_.size()); 503 EXPECT_EQ(0UL, frames_from_callback_.size());
479 } 504 }
480 505
481 TEST_F(TestPacketBuffer, OneH264FrameFillBuffer) {
482 VCMPacket packet;
483 packet.seqNum = 0;
484 packet.codec = kVideoCodecH264;
485 packet.dataPtr = nullptr;
486 packet.sizeBytes = 0;
487 packet.is_first_packet_in_frame = true;
488 packet.markerBit = false;
489 packet_buffer_->InsertPacket(&packet);
490
491 packet.is_first_packet_in_frame = false;
492 for (int i = 1; i < kStartSize - 1; ++i) {
493 packet.seqNum = i;
494 packet_buffer_->InsertPacket(&packet);
495 }
496
497 packet.seqNum = kStartSize - 1;
498 packet.markerBit = true;
499 packet_buffer_->InsertPacket(&packet);
500
501 EXPECT_EQ(1UL, frames_from_callback_.size());
502 CheckFrame(0);
503 }
504
505 TEST_F(TestPacketBuffer, OneH264FrameMaxSeqNum) {
506 VCMPacket packet;
507 packet.seqNum = 65534;
508 packet.codec = kVideoCodecH264;
509 packet.dataPtr = nullptr;
510 packet.sizeBytes = 0;
511 packet.is_first_packet_in_frame = true;
512 packet.markerBit = false;
513 packet_buffer_->InsertPacket(&packet);
514
515 packet.is_first_packet_in_frame = false;
516 packet.seqNum = 65535;
517 packet.markerBit = true;
518 packet_buffer_->InsertPacket(&packet);
519
520 EXPECT_EQ(1UL, frames_from_callback_.size());
521 CheckFrame(65534);
522 }
523
524 TEST_F(TestPacketBuffer, PacketTimestamps) { 506 TEST_F(TestPacketBuffer, PacketTimestamps) {
525 rtc::Optional<int64_t> packet_ms; 507 rtc::Optional<int64_t> packet_ms;
526 rtc::Optional<int64_t> packet_keyframe_ms; 508 rtc::Optional<int64_t> packet_keyframe_ms;
527 509
528 packet_ms = packet_buffer_->LastReceivedPacketMs(); 510 packet_ms = packet_buffer_->LastReceivedPacketMs();
529 packet_keyframe_ms = packet_buffer_->LastReceivedKeyframePacketMs(); 511 packet_keyframe_ms = packet_buffer_->LastReceivedKeyframePacketMs();
530 EXPECT_FALSE(packet_ms); 512 EXPECT_FALSE(packet_ms);
531 EXPECT_FALSE(packet_keyframe_ms); 513 EXPECT_FALSE(packet_keyframe_ms);
532 514
533 int64_t keyframe_ms = clock_->TimeInMilliseconds(); 515 int64_t keyframe_ms = clock_->TimeInMilliseconds();
(...skipping 15 matching lines...) Expand all
549 EXPECT_EQ(delta_ms, *packet_ms); 531 EXPECT_EQ(delta_ms, *packet_ms);
550 EXPECT_EQ(keyframe_ms, *packet_keyframe_ms); 532 EXPECT_EQ(keyframe_ms, *packet_keyframe_ms);
551 533
552 packet_buffer_->Clear(); 534 packet_buffer_->Clear();
553 packet_ms = packet_buffer_->LastReceivedPacketMs(); 535 packet_ms = packet_buffer_->LastReceivedPacketMs();
554 packet_keyframe_ms = packet_buffer_->LastReceivedKeyframePacketMs(); 536 packet_keyframe_ms = packet_buffer_->LastReceivedKeyframePacketMs();
555 EXPECT_FALSE(packet_ms); 537 EXPECT_FALSE(packet_ms);
556 EXPECT_FALSE(packet_keyframe_ms); 538 EXPECT_FALSE(packet_keyframe_ms);
557 } 539 }
558 540
541 TEST_F(TestPacketBuffer, OneFrameFillBufferH264) {
542 InsertH264(0, kKeyFrame, kFirst, kNotLast, 1000);
543 for (int i = 1; i < kStartSize - 1; ++i)
544 InsertH264(i, kKeyFrame, kNotFirst, kNotLast, 1000);
545 InsertH264(kStartSize - 1, kKeyFrame, kNotFirst, kLast, 1000);
546
547 EXPECT_EQ(1UL, frames_from_callback_.size());
548 CheckFrame(0);
549 }
550
551 TEST_F(TestPacketBuffer, OneFrameMaxSeqNumH264) {
552 InsertH264(65534, kKeyFrame, kFirst, kNotLast, 1000);
553 InsertH264(65535, kKeyFrame, kNotFirst, kLast, 1000);
554
555 EXPECT_EQ(1UL, frames_from_callback_.size());
556 CheckFrame(65534);
557 }
558
559 TEST_F(TestPacketBuffer, ClearMissingPacketsOnKeyframeH264) {
560 InsertH264(0, kKeyFrame, kFirst, kLast, 1000);
561 InsertH264(2, kKeyFrame, kFirst, kLast, 3000);
562 InsertH264(3, kDeltaFrame, kFirst, kNotLast, 4000);
563 InsertH264(4, kDeltaFrame, kNotFirst, kLast, 4000);
564
565 ASSERT_EQ(3UL, frames_from_callback_.size());
566
567 InsertH264(kStartSize + 1, kKeyFrame, kFirst, kLast, 18000);
568
569 ASSERT_EQ(4UL, frames_from_callback_.size());
570 CheckFrame(0);
571 CheckFrame(2);
572 CheckFrame(3);
573 CheckFrame(kStartSize + 1);
574 }
575
576 TEST_F(TestPacketBuffer, FindFramesOnPaddingH264) {
577 InsertH264(0, kKeyFrame, kFirst, kLast, 1000);
578 InsertH264(2, kDeltaFrame, kFirst, kLast, 1000);
579
580 ASSERT_EQ(1UL, frames_from_callback_.size());
581 packet_buffer_->PaddingReceived(1);
582 ASSERT_EQ(2UL, frames_from_callback_.size());
583 CheckFrame(0);
584 CheckFrame(2);
585 }
586
559 } // namespace video_coding 587 } // namespace video_coding
560 } // namespace webrtc 588 } // namespace webrtc
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698