|  | /* | 
|  | *  Copyright (c) 2013 The WebRTC project authors. All Rights Reserved. | 
|  | * | 
|  | *  Use of this source code is governed by a BSD-style license | 
|  | *  that can be found in the LICENSE file in the root of the source | 
|  | *  tree. An additional intellectual property rights grant can be found | 
|  | *  in the file PATENTS.  All contributing project authors may | 
|  | *  be found in the AUTHORS file in the root of the source tree. | 
|  | */ | 
|  |  | 
|  | #include "webrtc/modules/video_coding/test/stream_generator.h" | 
|  |  | 
|  | #include <string.h> | 
|  |  | 
|  | #include <list> | 
|  |  | 
|  | #include "testing/gtest/include/gtest/gtest.h" | 
|  | #include "webrtc/modules/video_coding/packet.h" | 
|  | #include "webrtc/modules/video_coding/test/test_util.h" | 
|  | #include "webrtc/system_wrappers/include/clock.h" | 
|  |  | 
|  | namespace webrtc { | 
|  |  | 
|  | StreamGenerator::StreamGenerator(uint16_t start_seq_num, int64_t current_time) | 
|  | : packets_(), sequence_number_(start_seq_num), start_time_(current_time) {} | 
|  |  | 
|  | void StreamGenerator::Init(uint16_t start_seq_num, int64_t current_time) { | 
|  | packets_.clear(); | 
|  | sequence_number_ = start_seq_num; | 
|  | start_time_ = current_time; | 
|  | memset(packet_buffer_, 0, sizeof(packet_buffer_)); | 
|  | } | 
|  |  | 
|  | void StreamGenerator::GenerateFrame(FrameType type, | 
|  | int num_media_packets, | 
|  | int num_empty_packets, | 
|  | int64_t time_ms) { | 
|  | uint32_t timestamp = 90 * (time_ms - start_time_); | 
|  | for (int i = 0; i < num_media_packets; ++i) { | 
|  | const int packet_size = | 
|  | (kFrameSize + num_media_packets / 2) / num_media_packets; | 
|  | bool marker_bit = (i == num_media_packets - 1); | 
|  | packets_.push_back(GeneratePacket(sequence_number_, timestamp, packet_size, | 
|  | (i == 0), marker_bit, type)); | 
|  | ++sequence_number_; | 
|  | } | 
|  | for (int i = 0; i < num_empty_packets; ++i) { | 
|  | packets_.push_back(GeneratePacket(sequence_number_, timestamp, 0, false, | 
|  | false, kEmptyFrame)); | 
|  | ++sequence_number_; | 
|  | } | 
|  | } | 
|  |  | 
|  | VCMPacket StreamGenerator::GeneratePacket(uint16_t sequence_number, | 
|  | uint32_t timestamp, | 
|  | unsigned int size, | 
|  | bool first_packet, | 
|  | bool marker_bit, | 
|  | FrameType type) { | 
|  | EXPECT_LT(size, kMaxPacketSize); | 
|  | VCMPacket packet; | 
|  | packet.seqNum = sequence_number; | 
|  | packet.timestamp = timestamp; | 
|  | packet.frameType = type; | 
|  | packet.isFirstPacket = first_packet; | 
|  | packet.markerBit = marker_bit; | 
|  | packet.sizeBytes = size; | 
|  | packet.dataPtr = packet_buffer_; | 
|  | if (packet.isFirstPacket) | 
|  | packet.completeNALU = kNaluStart; | 
|  | else if (packet.markerBit) | 
|  | packet.completeNALU = kNaluEnd; | 
|  | else | 
|  | packet.completeNALU = kNaluIncomplete; | 
|  | return packet; | 
|  | } | 
|  |  | 
|  | bool StreamGenerator::PopPacket(VCMPacket* packet, int index) { | 
|  | std::list<VCMPacket>::iterator it = GetPacketIterator(index); | 
|  | if (it == packets_.end()) | 
|  | return false; | 
|  | if (packet) | 
|  | *packet = (*it); | 
|  | packets_.erase(it); | 
|  | return true; | 
|  | } | 
|  |  | 
|  | bool StreamGenerator::GetPacket(VCMPacket* packet, int index) { | 
|  | std::list<VCMPacket>::iterator it = GetPacketIterator(index); | 
|  | if (it == packets_.end()) | 
|  | return false; | 
|  | if (packet) | 
|  | *packet = (*it); | 
|  | return true; | 
|  | } | 
|  |  | 
|  | bool StreamGenerator::NextPacket(VCMPacket* packet) { | 
|  | if (packets_.empty()) | 
|  | return false; | 
|  | if (packet != NULL) | 
|  | *packet = packets_.front(); | 
|  | packets_.pop_front(); | 
|  | return true; | 
|  | } | 
|  |  | 
|  | void StreamGenerator::DropLastPacket() { | 
|  | packets_.pop_back(); | 
|  | } | 
|  |  | 
|  | uint16_t StreamGenerator::NextSequenceNumber() const { | 
|  | if (packets_.empty()) | 
|  | return sequence_number_; | 
|  | return packets_.front().seqNum; | 
|  | } | 
|  |  | 
|  | int StreamGenerator::PacketsRemaining() const { | 
|  | return packets_.size(); | 
|  | } | 
|  |  | 
|  | std::list<VCMPacket>::iterator StreamGenerator::GetPacketIterator(int index) { | 
|  | std::list<VCMPacket>::iterator it = packets_.begin(); | 
|  | for (int i = 0; i < index; ++i) { | 
|  | ++it; | 
|  | if (it == packets_.end()) | 
|  | break; | 
|  | } | 
|  | return it; | 
|  | } | 
|  |  | 
|  | }  // namespace webrtc |