1 /*
2  *  Copyright (c) 2013 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 "webrtc/modules/video_coding/test/stream_generator.h"
12 
13 #include <string.h>
14 
15 #include <list>
16 
17 #include "testing/gtest/include/gtest/gtest.h"
18 #include "webrtc/modules/video_coding/packet.h"
19 #include "webrtc/modules/video_coding/test/test_util.h"
20 #include "webrtc/system_wrappers/include/clock.h"
21 
22 namespace webrtc {
23 
StreamGenerator(uint16_t start_seq_num,int64_t current_time)24 StreamGenerator::StreamGenerator(uint16_t start_seq_num, int64_t current_time)
25     : packets_(), sequence_number_(start_seq_num), start_time_(current_time) {}
26 
Init(uint16_t start_seq_num,int64_t current_time)27 void StreamGenerator::Init(uint16_t start_seq_num, int64_t current_time) {
28   packets_.clear();
29   sequence_number_ = start_seq_num;
30   start_time_ = current_time;
31   memset(packet_buffer_, 0, sizeof(packet_buffer_));
32 }
33 
GenerateFrame(FrameType type,int num_media_packets,int num_empty_packets,int64_t time_ms)34 void StreamGenerator::GenerateFrame(FrameType type,
35                                     int num_media_packets,
36                                     int num_empty_packets,
37                                     int64_t time_ms) {
38   uint32_t timestamp = 90 * (time_ms - start_time_);
39   for (int i = 0; i < num_media_packets; ++i) {
40     const int packet_size =
41         (kFrameSize + num_media_packets / 2) / num_media_packets;
42     bool marker_bit = (i == num_media_packets - 1);
43     packets_.push_back(GeneratePacket(sequence_number_, timestamp, packet_size,
44                                       (i == 0), marker_bit, type));
45     ++sequence_number_;
46   }
47   for (int i = 0; i < num_empty_packets; ++i) {
48     packets_.push_back(GeneratePacket(sequence_number_, timestamp, 0, false,
49                                       false, kEmptyFrame));
50     ++sequence_number_;
51   }
52 }
53 
GeneratePacket(uint16_t sequence_number,uint32_t timestamp,unsigned int size,bool first_packet,bool marker_bit,FrameType type)54 VCMPacket StreamGenerator::GeneratePacket(uint16_t sequence_number,
55                                           uint32_t timestamp,
56                                           unsigned int size,
57                                           bool first_packet,
58                                           bool marker_bit,
59                                           FrameType type) {
60   EXPECT_LT(size, kMaxPacketSize);
61   VCMPacket packet;
62   packet.seqNum = sequence_number;
63   packet.timestamp = timestamp;
64   packet.frameType = type;
65   packet.isFirstPacket = first_packet;
66   packet.markerBit = marker_bit;
67   packet.sizeBytes = size;
68   packet.dataPtr = packet_buffer_;
69   if (packet.isFirstPacket)
70     packet.completeNALU = kNaluStart;
71   else if (packet.markerBit)
72     packet.completeNALU = kNaluEnd;
73   else
74     packet.completeNALU = kNaluIncomplete;
75   return packet;
76 }
77 
PopPacket(VCMPacket * packet,int index)78 bool StreamGenerator::PopPacket(VCMPacket* packet, int index) {
79   std::list<VCMPacket>::iterator it = GetPacketIterator(index);
80   if (it == packets_.end())
81     return false;
82   if (packet)
83     *packet = (*it);
84   packets_.erase(it);
85   return true;
86 }
87 
GetPacket(VCMPacket * packet,int index)88 bool StreamGenerator::GetPacket(VCMPacket* packet, int index) {
89   std::list<VCMPacket>::iterator it = GetPacketIterator(index);
90   if (it == packets_.end())
91     return false;
92   if (packet)
93     *packet = (*it);
94   return true;
95 }
96 
NextPacket(VCMPacket * packet)97 bool StreamGenerator::NextPacket(VCMPacket* packet) {
98   if (packets_.empty())
99     return false;
100   if (packet != NULL)
101     *packet = packets_.front();
102   packets_.pop_front();
103   return true;
104 }
105 
DropLastPacket()106 void StreamGenerator::DropLastPacket() {
107   packets_.pop_back();
108 }
109 
NextSequenceNumber() const110 uint16_t StreamGenerator::NextSequenceNumber() const {
111   if (packets_.empty())
112     return sequence_number_;
113   return packets_.front().seqNum;
114 }
115 
PacketsRemaining() const116 int StreamGenerator::PacketsRemaining() const {
117   return packets_.size();
118 }
119 
GetPacketIterator(int index)120 std::list<VCMPacket>::iterator StreamGenerator::GetPacketIterator(int index) {
121   std::list<VCMPacket>::iterator it = packets_.begin();
122   for (int i = 0; i < index; ++i) {
123     ++it;
124     if (it == packets_.end())
125       break;
126   }
127   return it;
128 }
129 
130 }  // namespace webrtc
131