1/*
2 *  Copyright (c) 2012 The WebRTC project authors. All Rights Reserved.
3 *
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
6 *  tree. An additional intellectual property rights grant can be found
7 *  in the file PATENTS.  All contributing project authors may
8 *  be found in the AUTHORS file in the root of the source tree.
9 */
10
11#include <string.h>
12
13#include "testing/gtest/include/gtest/gtest.h"
14#include "webrtc/modules/interface/module_common_types.h"
15#include "webrtc/modules/video_coding/main/source/packet.h"
16#include "webrtc/modules/video_coding/main/source/session_info.h"
17
18namespace webrtc {
19
20class TestSessionInfo : public ::testing::Test {
21 protected:
22  virtual void SetUp() {
23    memset(packet_buffer_, 0, sizeof(packet_buffer_));
24    memset(frame_buffer_, 0, sizeof(frame_buffer_));
25    session_.Reset();
26    packet_.Reset();
27    packet_.frameType = kVideoFrameDelta;
28    packet_.sizeBytes = packet_buffer_size();
29    packet_.dataPtr = packet_buffer_;
30    packet_.seqNum = 0;
31    packet_.timestamp = 0;
32    frame_data.rtt_ms = 0;
33    frame_data.rolling_average_packets_per_frame = -1;
34  }
35
36  void FillPacket(uint8_t start_value) {
37    for (int i = 0; i < packet_buffer_size(); ++i)
38      packet_buffer_[i] = start_value + i;
39  }
40
41  void VerifyPacket(uint8_t* start_ptr, uint8_t start_value) {
42    for (int j = 0; j < packet_buffer_size(); ++j) {
43      ASSERT_EQ(start_value + j, start_ptr[j]);
44    }
45  }
46
47  int packet_buffer_size() const {
48    return sizeof(packet_buffer_) / sizeof(packet_buffer_[0]);
49  }
50  int frame_buffer_size() const {
51    return sizeof(frame_buffer_) / sizeof(frame_buffer_[0]);
52  }
53
54  enum { kPacketBufferSize = 10 };
55
56  uint8_t packet_buffer_[kPacketBufferSize];
57  uint8_t frame_buffer_[10 * kPacketBufferSize];
58
59  VCMSessionInfo session_;
60  VCMPacket packet_;
61  FrameData frame_data;
62};
63
64class TestVP8Partitions : public TestSessionInfo {
65 protected:
66  enum { kMaxVP8Partitions = 9 };
67
68  virtual void SetUp() {
69    TestSessionInfo::SetUp();
70    vp8_header_ = &packet_header_.type.Video.codecHeader.VP8;
71    packet_header_.frameType = kVideoFrameDelta;
72    packet_header_.type.Video.codec = kRtpVideoVp8;
73    vp8_header_->InitRTPVideoHeaderVP8();
74    fragmentation_.VerifyAndAllocateFragmentationHeader(kMaxVP8Partitions);
75  }
76
77  bool VerifyPartition(int partition_id,
78                       int packets_expected,
79                       int start_value) {
80    EXPECT_EQ(static_cast<uint32_t>(packets_expected * packet_buffer_size()),
81              fragmentation_.fragmentationLength[partition_id]);
82    for (int i = 0; i < packets_expected; ++i) {
83      int packet_index = fragmentation_.fragmentationOffset[partition_id] +
84          i * packet_buffer_size();
85      if (packet_index + packet_buffer_size() > frame_buffer_size())
86        return false;
87      VerifyPacket(frame_buffer_ + packet_index, start_value + i);
88    }
89    return true;
90  }
91
92  WebRtcRTPHeader packet_header_;
93  RTPVideoHeaderVP8* vp8_header_;
94  RTPFragmentationHeader fragmentation_;
95};
96
97class TestNalUnits : public TestSessionInfo {
98 protected:
99  virtual void SetUp() {
100    TestSessionInfo::SetUp();
101    packet_.codec = kVideoCodecVP8;
102  }
103
104  bool VerifyNalu(int offset, int packets_expected, int start_value) {
105    EXPECT_GE(session_.SessionLength(),
106              packets_expected * packet_buffer_size());
107    for (int i = 0; i < packets_expected; ++i) {
108      int packet_index = (offset + i) * packet_buffer_size();
109      VerifyPacket(frame_buffer_ + packet_index, start_value + i);
110    }
111    return true;
112  }
113};
114
115class TestNackList : public TestSessionInfo {
116 protected:
117  static const size_t kMaxSeqNumListLength = 30;
118
119  virtual void SetUp() {
120    TestSessionInfo::SetUp();
121    seq_num_list_length_ = 0;
122    memset(seq_num_list_, 0, sizeof(seq_num_list_));
123  }
124
125  void BuildSeqNumList(uint16_t low,
126                       uint16_t high) {
127    size_t i = 0;
128    while (low != high + 1) {
129      EXPECT_LT(i, kMaxSeqNumListLength);
130      if (i >= kMaxSeqNumListLength) {
131        seq_num_list_length_ = kMaxSeqNumListLength;
132        return;
133      }
134      seq_num_list_[i] = low;
135      low++;
136      i++;
137    }
138    seq_num_list_length_ = i;
139  }
140
141  void VerifyAll(int value) {
142    for (int i = 0; i < seq_num_list_length_; ++i)
143      EXPECT_EQ(seq_num_list_[i], value);
144  }
145
146  int seq_num_list_[kMaxSeqNumListLength];
147  int seq_num_list_length_;
148};
149
150TEST_F(TestSessionInfo, TestSimpleAPIs) {
151  packet_.isFirstPacket = true;
152  packet_.seqNum = 0xFFFE;
153  packet_.sizeBytes = packet_buffer_size();
154  packet_.frameType = kVideoFrameKey;
155  FillPacket(0);
156  EXPECT_EQ(packet_buffer_size(),
157            session_.InsertPacket(packet_,
158            frame_buffer_,
159            kNoErrors,
160            frame_data));
161  EXPECT_FALSE(session_.HaveLastPacket());
162  EXPECT_EQ(kVideoFrameKey, session_.FrameType());
163
164  packet_.isFirstPacket = false;
165  packet_.markerBit = true;
166  packet_.seqNum += 1;
167  EXPECT_EQ(packet_buffer_size(),
168            session_.InsertPacket(packet_,
169                                  frame_buffer_,
170                                  kNoErrors,
171                                  frame_data));
172  EXPECT_TRUE(session_.HaveLastPacket());
173  EXPECT_EQ(packet_.seqNum, session_.HighSequenceNumber());
174  EXPECT_EQ(0xFFFE, session_.LowSequenceNumber());
175
176  // Insert empty packet which will be the new high sequence number.
177  // To make things more difficult we will make sure to have a wrap here.
178  packet_.isFirstPacket = false;
179  packet_.markerBit = true;
180  packet_.seqNum  = 2;
181  packet_.sizeBytes = 0;
182  packet_.frameType = kFrameEmpty;
183  EXPECT_EQ(0,
184            session_.InsertPacket(packet_,
185                                  frame_buffer_,
186                                  kNoErrors,
187                                  frame_data));
188  EXPECT_EQ(packet_.seqNum, session_.HighSequenceNumber());
189}
190
191TEST_F(TestSessionInfo, NormalOperation) {
192  packet_.seqNum = 0xFFFF;
193  packet_.isFirstPacket = true;
194  packet_.markerBit = false;
195  FillPacket(0);
196  EXPECT_EQ(session_.InsertPacket(packet_,
197                                  frame_buffer_,
198                                  kNoErrors,
199                                  frame_data),
200            packet_buffer_size());
201
202  packet_.isFirstPacket = false;
203  for (int i = 1; i < 9; ++i) {
204    packet_.seqNum += 1;
205    FillPacket(i);
206    ASSERT_EQ(session_.InsertPacket(packet_,
207                                    frame_buffer_,
208                                    kNoErrors,
209                                    frame_data),
210              packet_buffer_size());
211  }
212
213  packet_.seqNum += 1;
214  packet_.markerBit = true;
215  FillPacket(9);
216  EXPECT_EQ(session_.InsertPacket(packet_,
217                                  frame_buffer_,
218                                  kNoErrors,
219                                  frame_data),
220            packet_buffer_size());
221
222  EXPECT_EQ(10 * packet_buffer_size(), session_.SessionLength());
223  for (int i = 0; i < 10; ++i) {
224    SCOPED_TRACE("Calling VerifyPacket");
225    VerifyPacket(frame_buffer_ + i * packet_buffer_size(), i);
226  }
227}
228
229TEST_F(TestSessionInfo, ErrorsEqualDecodableState) {
230  packet_.seqNum = 0xFFFF;
231  packet_.isFirstPacket = false;
232  packet_.markerBit = false;
233  FillPacket(3);
234  EXPECT_EQ(session_.InsertPacket(packet_,
235                                  frame_buffer_,
236                                  kWithErrors,
237                                  frame_data),
238            packet_buffer_size());
239  EXPECT_TRUE(session_.decodable());
240}
241
242TEST_F(TestSessionInfo, SelectiveDecodableState) {
243  packet_.seqNum = 0xFFFF;
244  packet_.isFirstPacket = false;
245  packet_.markerBit = false;
246  FillPacket(1);
247  frame_data.rolling_average_packets_per_frame = 11;
248  frame_data.rtt_ms = 150;
249  EXPECT_EQ(session_.InsertPacket(packet_,
250                                  frame_buffer_,
251                                  kSelectiveErrors,
252                                  frame_data),
253            packet_buffer_size());
254  EXPECT_FALSE(session_.decodable());
255
256  packet_.seqNum -= 1;
257  FillPacket(0);
258  packet_.isFirstPacket = true;
259  EXPECT_EQ(session_.InsertPacket(packet_,
260                                  frame_buffer_,
261                                  kSelectiveErrors,
262                                  frame_data),
263            packet_buffer_size());
264  EXPECT_TRUE(session_.decodable());
265
266  packet_.isFirstPacket = false;
267  packet_.seqNum += 1;
268  for (int i = 2; i < 8; ++i) {
269    packet_.seqNum += 1;
270    FillPacket(i);
271    EXPECT_EQ(session_.InsertPacket(packet_,
272                                    frame_buffer_,
273                                    kSelectiveErrors,
274                                    frame_data),
275              packet_buffer_size());
276    EXPECT_TRUE(session_.decodable());
277  }
278
279  packet_.seqNum += 1;
280  FillPacket(8);
281  EXPECT_EQ(session_.InsertPacket(packet_,
282                                  frame_buffer_,
283                                  kSelectiveErrors,
284                                  frame_data),
285            packet_buffer_size());
286  EXPECT_TRUE(session_.decodable());
287}
288
289TEST_F(TestSessionInfo, OutOfBoundsPackets1PacketFrame) {
290  packet_.seqNum = 0x0001;
291  packet_.isFirstPacket = true;
292  packet_.markerBit = true;
293  FillPacket(1);
294  EXPECT_EQ(session_.InsertPacket(packet_,
295                                  frame_buffer_,
296                                  kNoErrors,
297                                  frame_data),
298            packet_buffer_size());
299
300  packet_.seqNum = 0x0004;
301  packet_.isFirstPacket = true;
302  packet_.markerBit = true;
303  FillPacket(1);
304  EXPECT_EQ(-3, session_.InsertPacket(packet_,
305                                      frame_buffer_,
306                                      kNoErrors,
307                                      frame_data));
308  packet_.seqNum = 0x0000;
309  packet_.isFirstPacket = false;
310  packet_.markerBit = false;
311  FillPacket(1);
312  EXPECT_EQ(-3, session_.InsertPacket(packet_,
313                                      frame_buffer_,
314                                      kNoErrors,
315                                      frame_data));
316}
317
318TEST_F(TestSessionInfo, SetMarkerBitOnce) {
319  packet_.seqNum = 0x0005;
320  packet_.isFirstPacket = false;
321  packet_.markerBit = true;
322  FillPacket(1);
323  EXPECT_EQ(session_.InsertPacket(packet_,
324                                  frame_buffer_,
325                                  kNoErrors,
326                                  frame_data),
327            packet_buffer_size());
328  ++packet_.seqNum;
329  packet_.isFirstPacket = true;
330  packet_.markerBit = true;
331  FillPacket(1);
332  EXPECT_EQ(-3, session_.InsertPacket(packet_,
333                                      frame_buffer_,
334                                      kNoErrors,
335                                      frame_data));
336}
337
338TEST_F(TestSessionInfo, OutOfBoundsPacketsBase) {
339  // Allow packets in the range 5-6.
340  packet_.seqNum = 0x0005;
341  packet_.isFirstPacket = true;
342  packet_.markerBit = false;
343  FillPacket(1);
344  EXPECT_EQ(packet_buffer_size(),
345            session_.InsertPacket(packet_,
346                                  frame_buffer_,
347                                  kNoErrors,
348                                  frame_data));
349  // Insert an older packet with a first packet set.
350  packet_.seqNum = 0x0004;
351  packet_.isFirstPacket = true;
352  packet_.markerBit = true;
353  FillPacket(1);
354  EXPECT_EQ(-3, session_.InsertPacket(packet_,
355                                      frame_buffer_,
356                                      kNoErrors,
357                                      frame_data));
358  packet_.seqNum = 0x0006;
359  packet_.isFirstPacket = true;
360  packet_.markerBit = true;
361  FillPacket(1);
362  EXPECT_EQ(packet_buffer_size(),
363            session_.InsertPacket(packet_,
364                                  frame_buffer_,
365                                  kNoErrors,
366                                  frame_data));
367  packet_.seqNum = 0x0008;
368  packet_.isFirstPacket = false;
369  packet_.markerBit = true;
370  FillPacket(1);
371  EXPECT_EQ(-3, session_.InsertPacket(packet_,
372                                      frame_buffer_,
373                                      kNoErrors,
374                                      frame_data));
375}
376
377TEST_F(TestSessionInfo, OutOfBoundsPacketsWrap) {
378  packet_.seqNum = 0xFFFE;
379  packet_.isFirstPacket = true;
380  packet_.markerBit = false;
381  FillPacket(1);
382  EXPECT_EQ(packet_buffer_size(),
383            session_.InsertPacket(packet_,
384                                  frame_buffer_,
385                                  kNoErrors,
386                                  frame_data));
387
388  packet_.seqNum = 0x0004;
389  packet_.isFirstPacket = false;
390  packet_.markerBit = true;
391  FillPacket(1);
392  EXPECT_EQ(packet_buffer_size(),
393            session_.InsertPacket(packet_,
394                                  frame_buffer_,
395                                  kNoErrors,
396                                  frame_data));
397  packet_.seqNum = 0x0002;
398  packet_.isFirstPacket = false;
399  packet_.markerBit = false;
400  FillPacket(1);
401  ASSERT_EQ(packet_buffer_size(),
402            session_.InsertPacket(packet_,
403                                  frame_buffer_,
404                                  kNoErrors,
405                                  frame_data));
406  packet_.seqNum = 0xFFF0;
407  packet_.isFirstPacket = false;
408  packet_.markerBit = false;
409  FillPacket(1);
410  EXPECT_EQ(-3,
411            session_.InsertPacket(packet_,
412                                  frame_buffer_,
413                                  kNoErrors,
414                                  frame_data));
415  packet_.seqNum = 0x0006;
416  packet_.isFirstPacket = false;
417  packet_.markerBit = false;
418  FillPacket(1);
419  EXPECT_EQ(-3,
420            session_.InsertPacket(packet_,
421                                  frame_buffer_,
422                                  kNoErrors,
423                                  frame_data));
424}
425
426TEST_F(TestSessionInfo, OutOfBoundsOutOfOrder) {
427  // Insert out of bound regular packets, and then the first and last packet.
428  // Verify that correct bounds are maintained.
429  packet_.seqNum = 0x0003;
430  packet_.isFirstPacket = false;
431  packet_.markerBit = false;
432  FillPacket(1);
433  EXPECT_EQ(packet_buffer_size(),
434            session_.InsertPacket(packet_,
435                                  frame_buffer_,
436                                  kNoErrors,
437                                  frame_data));
438  // Insert an older packet with a first packet set.
439  packet_.seqNum = 0x0005;
440  packet_.isFirstPacket = true;
441  packet_.markerBit = false;
442  FillPacket(1);
443  EXPECT_EQ(packet_buffer_size(),
444            session_.InsertPacket(packet_,
445                                  frame_buffer_,
446                                  kNoErrors,
447                                  frame_data));
448  packet_.seqNum = 0x0004;
449  packet_.isFirstPacket = false;
450  packet_.markerBit = false;
451  FillPacket(1);
452  EXPECT_EQ(-3, session_.InsertPacket(packet_,
453                                      frame_buffer_,
454                                      kNoErrors,
455                                      frame_data));
456  packet_.seqNum = 0x0010;
457  packet_.isFirstPacket = false;
458  packet_.markerBit = false;
459  FillPacket(1);
460  EXPECT_EQ(packet_buffer_size(),
461            session_.InsertPacket(packet_,
462                                  frame_buffer_,
463                                  kNoErrors,
464                                  frame_data));
465  packet_.seqNum = 0x0008;
466  packet_.isFirstPacket = false;
467  packet_.markerBit = true;
468  FillPacket(1);
469  EXPECT_EQ(packet_buffer_size(),
470            session_.InsertPacket(packet_,
471                                  frame_buffer_,
472                                  kNoErrors,
473                                  frame_data));
474
475  packet_.seqNum = 0x0009;
476  packet_.isFirstPacket = false;
477  packet_.markerBit = false;
478  FillPacket(1);
479  EXPECT_EQ(-3, session_.InsertPacket(packet_,
480                                      frame_buffer_,
481                                      kNoErrors,
482                                      frame_data));
483}
484
485TEST_F(TestVP8Partitions, TwoPartitionsOneLoss) {
486  // Partition 0 | Partition 1
487  // [ 0 ] [ 2 ] | [ 3 ]
488  packet_header_.type.Video.isFirstPacket = true;
489  vp8_header_->beginningOfPartition = true;
490  vp8_header_->partitionId = 0;
491  packet_header_.header.markerBit = false;
492  packet_header_.header.sequenceNumber = 0;
493  FillPacket(0);
494  VCMPacket* packet = new VCMPacket(packet_buffer_, packet_buffer_size(),
495                                    packet_header_);
496  EXPECT_EQ(session_.InsertPacket(*packet,
497                                  frame_buffer_,
498                                  kNoErrors,
499                                  frame_data),
500            packet_buffer_size());
501  delete packet;
502
503  packet_header_.type.Video.isFirstPacket = false;
504  vp8_header_->partitionId = 0;
505  vp8_header_->beginningOfPartition = false;
506  packet_header_.header.markerBit = false;
507  packet_header_.header.sequenceNumber += 2;
508  FillPacket(2);
509  packet = new VCMPacket(packet_buffer_, packet_buffer_size(), packet_header_);
510  EXPECT_EQ(session_.InsertPacket(*packet,
511                                  frame_buffer_,
512                                  kNoErrors,
513                                  frame_data),
514            packet_buffer_size());
515  delete packet;
516
517  packet_header_.type.Video.isFirstPacket = false;
518  vp8_header_->partitionId = 1;
519  vp8_header_->beginningOfPartition = true;
520  packet_header_.header.markerBit = true;
521  packet_header_.header.sequenceNumber += 1;
522  FillPacket(3);
523  packet = new VCMPacket(packet_buffer_, packet_buffer_size(), packet_header_);
524  EXPECT_EQ(session_.InsertPacket(*packet,
525                                  frame_buffer_,
526                                  kNoErrors,
527                                  frame_data),
528            packet_buffer_size());
529  delete packet;
530
531  // One packet should be removed (end of partition 0).
532  EXPECT_EQ(session_.BuildVP8FragmentationHeader(frame_buffer_,
533                                                 frame_buffer_size(),
534                                                 &fragmentation_),
535            2 * packet_buffer_size());
536  SCOPED_TRACE("Calling VerifyPartition");
537  EXPECT_TRUE(VerifyPartition(0, 1, 0));
538  SCOPED_TRACE("Calling VerifyPartition");
539  EXPECT_TRUE(VerifyPartition(1, 1, 3));
540}
541
542TEST_F(TestVP8Partitions, TwoPartitionsOneLoss2) {
543  // Partition 0 | Partition 1
544  // [ 1 ] [ 2 ] | [ 3 ] [ 5 ]
545  packet_header_.type.Video.isFirstPacket = true;
546  vp8_header_->beginningOfPartition = true;
547  vp8_header_->partitionId = 0;
548  packet_header_.header.markerBit = false;
549  packet_header_.header.sequenceNumber = 1;
550  FillPacket(1);
551  VCMPacket* packet = new VCMPacket(packet_buffer_, packet_buffer_size(),
552                                    packet_header_);
553  EXPECT_EQ(session_.InsertPacket(*packet,
554                                  frame_buffer_,
555                                  kNoErrors,
556                                  frame_data),
557            packet_buffer_size());
558  delete packet;
559
560  packet_header_.type.Video.isFirstPacket = false;
561  vp8_header_->partitionId = 0;
562  vp8_header_->beginningOfPartition = false;
563  packet_header_.header.markerBit = false;
564  packet_header_.header.sequenceNumber += 1;
565  FillPacket(2);
566  packet = new VCMPacket(packet_buffer_, packet_buffer_size(), packet_header_);
567  EXPECT_EQ(session_.InsertPacket(*packet,
568                                  frame_buffer_,
569                                  kNoErrors,
570                                  frame_data),
571            packet_buffer_size());
572  delete packet;
573
574  packet_header_.type.Video.isFirstPacket = false;
575  vp8_header_->partitionId = 1;
576  vp8_header_->beginningOfPartition = true;
577  packet_header_.header.markerBit = false;
578  packet_header_.header.sequenceNumber += 1;
579  FillPacket(3);
580  packet = new VCMPacket(packet_buffer_, packet_buffer_size(), packet_header_);
581  EXPECT_EQ(session_.InsertPacket(*packet,
582                                  frame_buffer_,
583                                  kNoErrors,
584                                  frame_data),
585            packet_buffer_size());
586  delete packet;
587
588  packet_header_.type.Video.isFirstPacket = false;
589  vp8_header_->partitionId = 1;
590  vp8_header_->beginningOfPartition = false;
591  packet_header_.header.markerBit = true;
592  packet_header_.header.sequenceNumber += 2;
593  FillPacket(5);
594  packet = new VCMPacket(packet_buffer_, packet_buffer_size(), packet_header_);
595  EXPECT_EQ(session_.InsertPacket(*packet,
596                                  frame_buffer_,
597                                  kNoErrors,
598                                  frame_data),
599            packet_buffer_size());
600  delete packet;
601
602  // One packet should be removed (end of partition 2), 3 left.
603  EXPECT_EQ(session_.BuildVP8FragmentationHeader(frame_buffer_,
604                                                 frame_buffer_size(),
605                                                 &fragmentation_),
606            3 * packet_buffer_size());
607  SCOPED_TRACE("Calling VerifyPartition");
608  EXPECT_TRUE(VerifyPartition(0, 2, 1));
609  SCOPED_TRACE("Calling VerifyPartition");
610  EXPECT_TRUE(VerifyPartition(1, 1, 3));
611}
612
613TEST_F(TestVP8Partitions, TwoPartitionsNoLossWrap) {
614  // Partition 0       | Partition 1
615  // [ fffd ] [ fffe ] | [ ffff ] [ 0 ]
616  packet_header_.type.Video.isFirstPacket = true;
617  vp8_header_->beginningOfPartition = true;
618  vp8_header_->partitionId = 0;
619  packet_header_.header.markerBit = false;
620  packet_header_.header.sequenceNumber = 0xfffd;
621  FillPacket(0);
622  VCMPacket* packet = new VCMPacket(packet_buffer_, packet_buffer_size(),
623                                    packet_header_);
624  EXPECT_EQ(session_.InsertPacket(*packet,
625                                  frame_buffer_,
626                                  kNoErrors,
627                                  frame_data),
628            packet_buffer_size());
629  delete packet;
630
631  packet_header_.type.Video.isFirstPacket = false;
632  vp8_header_->partitionId = 0;
633  vp8_header_->beginningOfPartition = false;
634  packet_header_.header.markerBit = false;
635  packet_header_.header.sequenceNumber += 1;
636  FillPacket(1);
637  packet = new VCMPacket(packet_buffer_, packet_buffer_size(), packet_header_);
638  EXPECT_EQ(session_.InsertPacket(*packet,
639                                  frame_buffer_,
640                                  kNoErrors,
641                                  frame_data),
642            packet_buffer_size());
643  delete packet;
644
645  packet_header_.type.Video.isFirstPacket = false;
646  vp8_header_->partitionId = 1;
647  vp8_header_->beginningOfPartition = true;
648  packet_header_.header.markerBit = false;
649  packet_header_.header.sequenceNumber += 1;
650  FillPacket(2);
651  packet = new VCMPacket(packet_buffer_, packet_buffer_size(), packet_header_);
652  EXPECT_EQ(session_.InsertPacket(*packet,
653                                  frame_buffer_,
654                                  kNoErrors,
655                                  frame_data),
656            packet_buffer_size());
657  delete packet;
658
659  packet_header_.type.Video.isFirstPacket = false;
660  vp8_header_->partitionId = 1;
661  vp8_header_->beginningOfPartition = false;
662  packet_header_.header.markerBit = true;
663  packet_header_.header.sequenceNumber += 1;
664  FillPacket(3);
665  packet = new VCMPacket(packet_buffer_, packet_buffer_size(), packet_header_);
666  EXPECT_EQ(session_.InsertPacket(*packet,
667                                  frame_buffer_,
668                                  kNoErrors,
669                                  frame_data),
670            packet_buffer_size());
671  delete packet;
672
673  // No packet should be removed.
674  EXPECT_EQ(session_.BuildVP8FragmentationHeader(frame_buffer_,
675                                                 frame_buffer_size(),
676                                                 &fragmentation_),
677            4 * packet_buffer_size());
678  SCOPED_TRACE("Calling VerifyPartition");
679  EXPECT_TRUE(VerifyPartition(0, 2, 0));
680  SCOPED_TRACE("Calling VerifyPartition");
681  EXPECT_TRUE(VerifyPartition(1, 2, 2));
682}
683
684TEST_F(TestVP8Partitions, TwoPartitionsLossWrap) {
685  // Partition 0       | Partition 1
686  // [ fffd ] [ fffe ] | [ ffff ] [ 1 ]
687  packet_header_.type.Video.isFirstPacket = true;
688  vp8_header_->beginningOfPartition = true;
689  vp8_header_->partitionId = 0;
690  packet_header_.header.markerBit = false;
691  packet_header_.header.sequenceNumber = 0xfffd;
692  FillPacket(0);
693  VCMPacket* packet = new VCMPacket(packet_buffer_, packet_buffer_size(),
694                                    packet_header_);
695  EXPECT_EQ(session_.InsertPacket(*packet,
696                                  frame_buffer_,
697                                  kNoErrors,
698                                  frame_data),
699            packet_buffer_size());
700  delete packet;
701
702  packet_header_.type.Video.isFirstPacket = false;
703  vp8_header_->partitionId = 0;
704  vp8_header_->beginningOfPartition = false;
705  packet_header_.header.markerBit = false;
706  packet_header_.header.sequenceNumber += 1;
707  FillPacket(1);
708  packet = new VCMPacket(packet_buffer_, packet_buffer_size(), packet_header_);
709  EXPECT_EQ(session_.InsertPacket(*packet,
710                                  frame_buffer_,
711                                  kNoErrors,
712                                  frame_data),
713            packet_buffer_size());
714  delete packet;
715
716  packet_header_.type.Video.isFirstPacket = false;
717  vp8_header_->partitionId = 1;
718  vp8_header_->beginningOfPartition = true;
719  packet_header_.header.markerBit = false;
720  packet_header_.header.sequenceNumber += 1;
721  FillPacket(2);
722  packet = new VCMPacket(packet_buffer_, packet_buffer_size(), packet_header_);
723  EXPECT_EQ(session_.InsertPacket(*packet,
724                                  frame_buffer_,
725                                  kNoErrors,
726                                  frame_data),
727            packet_buffer_size());
728  delete packet;
729
730  packet_header_.type.Video.isFirstPacket = false;
731  vp8_header_->partitionId = 1;
732  vp8_header_->beginningOfPartition = false;
733  packet_header_.header.markerBit = true;
734  packet_header_.header.sequenceNumber += 2;
735  FillPacket(3);
736  packet = new VCMPacket(packet_buffer_, packet_buffer_size(), packet_header_);
737  EXPECT_EQ(session_.InsertPacket(*packet,
738                                  frame_buffer_,
739                                  kNoErrors,
740                                  frame_data),
741            packet_buffer_size());
742  delete packet;
743
744  // One packet should be removed from the last partition
745  EXPECT_EQ(session_.BuildVP8FragmentationHeader(frame_buffer_,
746                                                 frame_buffer_size(),
747                                                 &fragmentation_),
748            3 * packet_buffer_size());
749  SCOPED_TRACE("Calling VerifyPartition");
750  EXPECT_TRUE(VerifyPartition(0, 2, 0));
751  SCOPED_TRACE("Calling VerifyPartition");
752  EXPECT_TRUE(VerifyPartition(1, 1, 2));
753}
754
755
756TEST_F(TestVP8Partitions, ThreePartitionsOneMissing) {
757  // Partition 1  |Partition 2    | Partition 3
758  // [ 1 ] [ 2 ]  |               | [ 5 ] | [ 6 ]
759  packet_header_.type.Video.isFirstPacket = true;
760  vp8_header_->beginningOfPartition = true;
761  vp8_header_->partitionId = 0;
762  packet_header_.header.markerBit = false;
763  packet_header_.header.sequenceNumber = 1;
764  FillPacket(1);
765  VCMPacket* packet = new VCMPacket(packet_buffer_, packet_buffer_size(),
766                                    packet_header_);
767  EXPECT_EQ(session_.InsertPacket(*packet,
768                                  frame_buffer_,
769                                  kNoErrors,
770                                  frame_data),
771            packet_buffer_size());
772  delete packet;
773
774  packet_header_.type.Video.isFirstPacket = false;
775  vp8_header_->partitionId = 0;
776  vp8_header_->beginningOfPartition = false;
777  packet_header_.header.markerBit = false;
778  packet_header_.header.sequenceNumber += 1;
779  FillPacket(2);
780  packet = new VCMPacket(packet_buffer_, packet_buffer_size(), packet_header_);
781  EXPECT_EQ(session_.InsertPacket(*packet,
782                                  frame_buffer_,
783                                  kNoErrors,
784                                  frame_data),
785            packet_buffer_size());
786  delete packet;
787
788  packet_header_.type.Video.isFirstPacket = false;
789  vp8_header_->partitionId = 2;
790  vp8_header_->beginningOfPartition = true;
791  packet_header_.header.markerBit = false;
792  packet_header_.header.sequenceNumber += 3;
793  FillPacket(5);
794  packet = new VCMPacket(packet_buffer_, packet_buffer_size(), packet_header_);
795  EXPECT_EQ(session_.InsertPacket(*packet,
796                                  frame_buffer_,
797                                  kNoErrors,
798                                  frame_data),
799            packet_buffer_size());
800  delete packet;
801
802  packet_header_.type.Video.isFirstPacket = false;
803  vp8_header_->partitionId = 2;
804  vp8_header_->beginningOfPartition = false;
805  packet_header_.header.markerBit = true;
806  packet_header_.header.sequenceNumber += 1;
807  FillPacket(6);
808  packet = new VCMPacket(packet_buffer_, packet_buffer_size(), packet_header_);
809  EXPECT_EQ(session_.InsertPacket(*packet,
810                                  frame_buffer_,
811                                  kNoErrors,
812                                  frame_data),
813            packet_buffer_size());
814  delete packet;
815
816  // No packet should be removed.
817  EXPECT_EQ(session_.BuildVP8FragmentationHeader(frame_buffer_,
818                                                 frame_buffer_size(),
819                                                 &fragmentation_),
820            4 * packet_buffer_size());
821  SCOPED_TRACE("Calling VerifyPartition");
822  EXPECT_TRUE(VerifyPartition(0, 2, 1));
823  SCOPED_TRACE("Calling VerifyPartition");
824  EXPECT_TRUE(VerifyPartition(2, 2, 5));
825}
826
827TEST_F(TestVP8Partitions, ThreePartitionsLossInSecond) {
828  // Partition 0  |Partition 1          | Partition 2
829  // [ 1 ] [ 2 ]  |        [ 4 ] [ 5 ]  | [ 6 ] [ 7 ]
830  packet_header_.type.Video.isFirstPacket = true;
831  vp8_header_->beginningOfPartition = true;
832  vp8_header_->partitionId = 0;
833  packet_header_.header.markerBit = false;
834  packet_header_.header.sequenceNumber = 1;
835  FillPacket(1);
836  VCMPacket* packet = new VCMPacket(packet_buffer_, packet_buffer_size(),
837                                    packet_header_);
838  EXPECT_EQ(session_.InsertPacket(*packet,
839                                  frame_buffer_,
840                                  kNoErrors,
841                                  frame_data),
842            packet_buffer_size());
843  delete packet;
844
845  packet_header_.type.Video.isFirstPacket = false;
846  vp8_header_->partitionId = 0;
847  vp8_header_->beginningOfPartition = false;
848  packet_header_.header.markerBit = false;
849  packet_header_.header.sequenceNumber += 1;
850  FillPacket(2);
851  packet = new VCMPacket(packet_buffer_, packet_buffer_size(),
852                         packet_header_);
853  EXPECT_EQ(session_.InsertPacket(*packet,
854                                  frame_buffer_,
855                                  kNoErrors,
856                                  frame_data),
857            packet_buffer_size());
858  delete packet;
859
860  packet_header_.type.Video.isFirstPacket = false;
861  vp8_header_->partitionId = 1;
862  vp8_header_->beginningOfPartition = false;
863  packet_header_.header.markerBit = false;
864  packet_header_.header.sequenceNumber += 2;
865  FillPacket(4);
866  packet = new VCMPacket(packet_buffer_, packet_buffer_size(), packet_header_);
867  EXPECT_EQ(session_.InsertPacket(*packet,
868                                  frame_buffer_,
869                                  kNoErrors,
870                                  frame_data),
871            packet_buffer_size());
872  delete packet;
873
874  packet_header_.type.Video.isFirstPacket = false;
875  vp8_header_->partitionId = 1;
876  vp8_header_->beginningOfPartition = false;
877  packet_header_.header.markerBit = false;
878  packet_header_.header.sequenceNumber += 1;
879  FillPacket(5);
880  packet = new VCMPacket(packet_buffer_, packet_buffer_size(), packet_header_);
881  EXPECT_EQ(session_.InsertPacket(*packet,
882                                  frame_buffer_,
883                                  kNoErrors,
884                                  frame_data),
885            packet_buffer_size());
886  delete packet;
887
888  packet_header_.type.Video.isFirstPacket = false;
889  vp8_header_->partitionId = 2;
890  vp8_header_->beginningOfPartition = true;
891  packet_header_.header.markerBit = false;
892  packet_header_.header.sequenceNumber += 1;
893  FillPacket(6);
894  packet = new VCMPacket(packet_buffer_, packet_buffer_size(), packet_header_);
895  EXPECT_EQ(session_.InsertPacket(*packet,
896                                  frame_buffer_,
897                                  kNoErrors,
898                                  frame_data),
899            packet_buffer_size());
900  delete packet;
901
902  packet_header_.type.Video.isFirstPacket = false;
903  vp8_header_->partitionId = 2;
904  vp8_header_->beginningOfPartition = false;
905  packet_header_.header.markerBit = true;
906  packet_header_.header.sequenceNumber += 1;
907  FillPacket(7);
908  packet = new VCMPacket(packet_buffer_, packet_buffer_size(), packet_header_);
909  EXPECT_EQ(session_.InsertPacket(*packet,
910                                  frame_buffer_,
911                                  kNoErrors,
912                                  frame_data),
913            packet_buffer_size());
914  delete packet;
915
916  // 2 partitions left. 2 packets removed from second partition
917  EXPECT_EQ(session_.BuildVP8FragmentationHeader(frame_buffer_,
918                                                 frame_buffer_size(),
919                                                 &fragmentation_),
920            4 * packet_buffer_size());
921  SCOPED_TRACE("Calling VerifyPartition");
922  EXPECT_TRUE(VerifyPartition(0, 2, 1));
923  SCOPED_TRACE("Calling VerifyPartition");
924  EXPECT_TRUE(VerifyPartition(2, 2, 6));
925}
926
927TEST_F(TestVP8Partitions, AggregationOverTwoPackets) {
928  // Partition 0   | Partition 1         | Partition 2
929  // [ 0           |           ]  [ 1 ]  | [ 2 ]
930  packet_header_.type.Video.isFirstPacket = true;
931  vp8_header_->beginningOfPartition = true;
932  vp8_header_->partitionId = 0;
933  packet_header_.header.markerBit = false;
934  packet_header_.header.sequenceNumber = 0;
935  FillPacket(0);
936  VCMPacket* packet = new VCMPacket(packet_buffer_, packet_buffer_size(),
937                                    packet_header_);
938  EXPECT_EQ(session_.InsertPacket(*packet,
939                                  frame_buffer_,
940                                  kNoErrors,
941                                  frame_data),
942            packet_buffer_size());
943  delete packet;
944
945  packet_header_.type.Video.isFirstPacket = false;
946  vp8_header_->partitionId = 1;
947  vp8_header_->beginningOfPartition = false;
948  packet_header_.header.markerBit = false;
949  packet_header_.header.sequenceNumber += 1;
950  FillPacket(1);
951  packet = new VCMPacket(packet_buffer_, packet_buffer_size(), packet_header_);
952  EXPECT_EQ(session_.InsertPacket(*packet,
953                                  frame_buffer_,
954                                  kNoErrors,
955                                  frame_data),
956            packet_buffer_size());
957  delete packet;
958
959  packet_header_.type.Video.isFirstPacket = false;
960  vp8_header_->partitionId = 2;
961  vp8_header_->beginningOfPartition = true;
962  packet_header_.header.markerBit = true;
963  packet_header_.header.sequenceNumber += 1;
964  FillPacket(2);
965  packet = new VCMPacket(packet_buffer_, packet_buffer_size(), packet_header_);
966  EXPECT_EQ(session_.InsertPacket(*packet,
967                                  frame_buffer_,
968                                  kNoErrors,
969                                  frame_data),
970            packet_buffer_size());
971  delete packet;
972
973  // No packets removed.
974  EXPECT_EQ(session_.BuildVP8FragmentationHeader(frame_buffer_,
975                                                 frame_buffer_size(),
976                                                 &fragmentation_),
977            3 * packet_buffer_size());
978  SCOPED_TRACE("Calling VerifyPartition");
979  EXPECT_TRUE(VerifyPartition(0, 2, 0));
980  // This partition is aggregated in partition 0
981  SCOPED_TRACE("Calling VerifyPartition");
982  EXPECT_TRUE(VerifyPartition(1, 0, 0));
983  SCOPED_TRACE("Calling VerifyPartition");
984  EXPECT_TRUE(VerifyPartition(2, 1, 2));
985}
986
987TEST_F(TestNalUnits, OnlyReceivedEmptyPacket) {
988  packet_.isFirstPacket = false;
989  packet_.completeNALU = kNaluComplete;
990  packet_.frameType = kFrameEmpty;
991  packet_.sizeBytes = 0;
992  packet_.seqNum = 0;
993  packet_.markerBit = false;
994  EXPECT_EQ(0, session_.InsertPacket(packet_,
995                                     frame_buffer_,
996                                     kNoErrors,
997                                     frame_data));
998
999  EXPECT_EQ(0, session_.MakeDecodable());
1000  EXPECT_EQ(0, session_.SessionLength());
1001}
1002
1003TEST_F(TestNalUnits, OneIsolatedNaluLoss) {
1004  packet_.isFirstPacket = true;
1005  packet_.completeNALU = kNaluComplete;
1006  packet_.seqNum = 0;
1007  packet_.markerBit = false;
1008  FillPacket(0);
1009  EXPECT_EQ(session_.InsertPacket(packet_,
1010                                  frame_buffer_,
1011                                  kNoErrors,
1012                                  frame_data),
1013            packet_buffer_size());
1014
1015  packet_.isFirstPacket = false;
1016  packet_.completeNALU = kNaluComplete;
1017  packet_.seqNum += 2;
1018  packet_.markerBit = true;
1019  FillPacket(2);
1020  EXPECT_EQ(session_.InsertPacket(packet_,
1021                                  frame_buffer_,
1022                                  kNoErrors,
1023                                  frame_data),
1024            packet_buffer_size());
1025
1026  EXPECT_EQ(0, session_.MakeDecodable());
1027  EXPECT_EQ(2 * packet_buffer_size(), session_.SessionLength());
1028  SCOPED_TRACE("Calling VerifyNalu");
1029  EXPECT_TRUE(VerifyNalu(0, 1, 0));
1030  SCOPED_TRACE("Calling VerifyNalu");
1031  EXPECT_TRUE(VerifyNalu(1, 1, 2));
1032}
1033
1034TEST_F(TestNalUnits, LossInMiddleOfNalu) {
1035  packet_.isFirstPacket = true;
1036  packet_.completeNALU = kNaluComplete;
1037  packet_.seqNum = 0;
1038  packet_.markerBit = false;
1039  FillPacket(0);
1040  EXPECT_EQ(session_.InsertPacket(packet_,
1041                                  frame_buffer_,
1042                                  kNoErrors,
1043                                  frame_data),
1044            packet_buffer_size());
1045
1046  packet_.isFirstPacket = false;
1047  packet_.completeNALU = kNaluEnd;
1048  packet_.seqNum += 2;
1049  packet_.markerBit = true;
1050  FillPacket(2);
1051  EXPECT_EQ(session_.InsertPacket(packet_,
1052                                  frame_buffer_,
1053                                  kNoErrors,
1054                                  frame_data),
1055            packet_buffer_size());
1056
1057  EXPECT_EQ(packet_buffer_size(), session_.MakeDecodable());
1058  EXPECT_EQ(packet_buffer_size(), session_.SessionLength());
1059  SCOPED_TRACE("Calling VerifyNalu");
1060  EXPECT_TRUE(VerifyNalu(0, 1, 0));
1061}
1062
1063TEST_F(TestNalUnits, StartAndEndOfLastNalUnitLost) {
1064  packet_.isFirstPacket = true;
1065  packet_.completeNALU = kNaluComplete;
1066  packet_.seqNum = 0;
1067  packet_.markerBit = false;
1068  FillPacket(0);
1069  EXPECT_EQ(session_.InsertPacket(packet_,
1070                                  frame_buffer_,
1071                                  kNoErrors,
1072                                  frame_data),
1073            packet_buffer_size());
1074
1075  packet_.isFirstPacket = false;
1076  packet_.completeNALU = kNaluIncomplete;
1077  packet_.seqNum += 2;
1078  packet_.markerBit = false;
1079  FillPacket(1);
1080  EXPECT_EQ(session_.InsertPacket(packet_,
1081                                  frame_buffer_,
1082                                  kNoErrors,
1083                                  frame_data),
1084            packet_buffer_size());
1085
1086  EXPECT_EQ(packet_buffer_size(), session_.MakeDecodable());
1087  EXPECT_EQ(packet_buffer_size(), session_.SessionLength());
1088  SCOPED_TRACE("Calling VerifyNalu");
1089  EXPECT_TRUE(VerifyNalu(0, 1, 0));
1090}
1091
1092TEST_F(TestNalUnits, ReorderWrapNoLoss) {
1093  packet_.seqNum = 0xFFFF;
1094  packet_.isFirstPacket = false;
1095  packet_.completeNALU = kNaluIncomplete;
1096  packet_.seqNum += 1;
1097  packet_.markerBit = false;
1098  FillPacket(1);
1099  EXPECT_EQ(session_.InsertPacket(packet_,
1100                                  frame_buffer_,
1101                                  kNoErrors,
1102                                  frame_data),
1103            packet_buffer_size());
1104
1105  packet_.isFirstPacket = true;
1106  packet_.completeNALU = kNaluComplete;
1107  packet_.seqNum -= 1;
1108  packet_.markerBit = false;
1109  FillPacket(0);
1110  EXPECT_EQ(session_.InsertPacket(packet_,
1111                                  frame_buffer_,
1112                                  kNoErrors,
1113                                  frame_data),
1114            packet_buffer_size());
1115
1116  packet_.isFirstPacket = false;
1117  packet_.completeNALU = kNaluEnd;
1118  packet_.seqNum += 2;
1119  packet_.markerBit = true;
1120  FillPacket(2);
1121  EXPECT_EQ(session_.InsertPacket(packet_,
1122                                  frame_buffer_,
1123                                  kNoErrors,
1124                                  frame_data),
1125            packet_buffer_size());
1126
1127  EXPECT_EQ(0, session_.MakeDecodable());
1128  EXPECT_EQ(3 * packet_buffer_size(), session_.SessionLength());
1129  SCOPED_TRACE("Calling VerifyNalu");
1130  EXPECT_TRUE(VerifyNalu(0, 1, 0));
1131}
1132
1133TEST_F(TestNalUnits, WrapLosses) {
1134  packet_.seqNum = 0xFFFF;
1135  packet_.isFirstPacket = false;
1136  packet_.completeNALU = kNaluIncomplete;
1137  packet_.markerBit = false;
1138  FillPacket(1);
1139  EXPECT_EQ(session_.InsertPacket(packet_,
1140                                  frame_buffer_,
1141                                  kNoErrors,
1142                                  frame_data),
1143            packet_buffer_size());
1144
1145  packet_.isFirstPacket = false;
1146  packet_.completeNALU = kNaluEnd;
1147  packet_.seqNum += 2;
1148  packet_.markerBit = true;
1149  FillPacket(2);
1150  EXPECT_EQ(session_.InsertPacket(packet_,
1151                                  frame_buffer_,
1152                                  kNoErrors,
1153                                  frame_data),
1154            packet_buffer_size());
1155
1156  EXPECT_EQ(2 * packet_buffer_size(), session_.MakeDecodable());
1157  EXPECT_EQ(0, session_.SessionLength());
1158}
1159
1160TEST_F(TestNalUnits, ReorderWrapLosses) {
1161  packet_.seqNum = 0xFFFF;
1162
1163  packet_.isFirstPacket = false;
1164  packet_.completeNALU = kNaluEnd;
1165  packet_.seqNum += 2;
1166  packet_.markerBit = true;
1167  FillPacket(2);
1168  EXPECT_EQ(session_.InsertPacket(packet_,
1169                                  frame_buffer_,
1170                                  kNoErrors,
1171                                  frame_data),
1172            packet_buffer_size());
1173
1174  packet_.seqNum -= 2;
1175  packet_.isFirstPacket = false;
1176  packet_.completeNALU = kNaluIncomplete;
1177  packet_.markerBit = false;
1178  FillPacket(1);
1179  EXPECT_EQ(session_.InsertPacket(packet_,
1180                                  frame_buffer_,
1181                                  kNoErrors,
1182                                  frame_data),
1183            packet_buffer_size());
1184
1185  EXPECT_EQ(2 * packet_buffer_size(), session_.MakeDecodable());
1186  EXPECT_EQ(0, session_.SessionLength());
1187}
1188
1189}  // namespace webrtc
1190