1 /* 2 * Copyright (c) 2014 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 <string> 12 13 #include "webrtc/base/logging.h" 14 #include "webrtc/modules/include/module_common_types.h" 15 #include "webrtc/modules/rtp_rtcp/source/rtp_format_video_generic.h" 16 17 namespace webrtc { 18 19 static const size_t kGenericHeaderLength = 1; 20 21 RtpPacketizerGeneric::RtpPacketizerGeneric(FrameType frame_type, 22 size_t max_payload_len) 23 : payload_data_(NULL), 24 payload_size_(0), 25 max_payload_len_(max_payload_len - kGenericHeaderLength), 26 frame_type_(frame_type) { 27 } 28 29 RtpPacketizerGeneric::~RtpPacketizerGeneric() { 30 } 31 32 void RtpPacketizerGeneric::SetPayloadData( 33 const uint8_t* payload_data, 34 size_t payload_size, 35 const RTPFragmentationHeader* fragmentation) { 36 payload_data_ = payload_data; 37 payload_size_ = payload_size; 38 39 // Fragment packets more evenly by splitting the payload up evenly. 40 size_t num_packets = 41 (payload_size_ + max_payload_len_ - 1) / max_payload_len_; 42 payload_length_ = (payload_size_ + num_packets - 1) / num_packets; 43 assert(payload_length_ <= max_payload_len_); 44 45 generic_header_ = RtpFormatVideoGeneric::kFirstPacketBit; 46 } 47 48 bool RtpPacketizerGeneric::NextPacket(uint8_t* buffer, 49 size_t* bytes_to_send, 50 bool* last_packet) { 51 if (payload_size_ < payload_length_) { 52 payload_length_ = payload_size_; 53 } 54 55 payload_size_ -= payload_length_; 56 *bytes_to_send = payload_length_ + kGenericHeaderLength; 57 assert(payload_length_ <= max_payload_len_); 58 59 uint8_t* out_ptr = buffer; 60 // Put generic header in packet 61 if (frame_type_ == kVideoFrameKey) { 62 generic_header_ |= RtpFormatVideoGeneric::kKeyFrameBit; 63 } 64 *out_ptr++ = generic_header_; 65 // Remove first-packet bit, following packets are intermediate 66 generic_header_ &= ~RtpFormatVideoGeneric::kFirstPacketBit; 67 68 // Put payload in packet 69 memcpy(out_ptr, payload_data_, payload_length_); 70 payload_data_ += payload_length_; 71 72 *last_packet = payload_size_ <= 0; 73 74 return true; 75 } 76 77 ProtectionType RtpPacketizerGeneric::GetProtectionType() { 78 return kProtectedPacket; 79 } 80 81 StorageType RtpPacketizerGeneric::GetStorageType( 82 uint32_t retransmission_settings) { 83 return kAllowRetransmission; 84 } 85 86 std::string RtpPacketizerGeneric::ToString() { 87 return "RtpPacketizerGeneric"; 88 } 89 90 bool RtpDepacketizerGeneric::Parse(ParsedPayload* parsed_payload, 91 const uint8_t* payload_data, 92 size_t payload_data_length) { 93 assert(parsed_payload != NULL); 94 if (payload_data_length == 0) { 95 LOG(LS_ERROR) << "Empty payload."; 96 return false; 97 } 98 99 uint8_t generic_header = *payload_data++; 100 --payload_data_length; 101 102 parsed_payload->frame_type = 103 ((generic_header & RtpFormatVideoGeneric::kKeyFrameBit) != 0) 104 ? kVideoFrameKey 105 : kVideoFrameDelta; 106 parsed_payload->type.Video.isFirstPacket = 107 (generic_header & RtpFormatVideoGeneric::kFirstPacketBit) != 0; 108 parsed_payload->type.Video.codec = kRtpVideoGeneric; 109 parsed_payload->type.Video.width = 0; 110 parsed_payload->type.Video.height = 0; 111 112 parsed_payload->payload = payload_data; 113 parsed_payload->payload_length = payload_data_length; 114 return true; 115 } 116 } // namespace webrtc 117