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