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