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