1b5e6bfc76a32a588da2400636688d34a71a2f47dpbos@webrtc.org/* 2b5e6bfc76a32a588da2400636688d34a71a2f47dpbos@webrtc.org * Copyright (c) 2014 The WebRTC project authors. All Rights Reserved. 3b5e6bfc76a32a588da2400636688d34a71a2f47dpbos@webrtc.org * 4b5e6bfc76a32a588da2400636688d34a71a2f47dpbos@webrtc.org * Use of this source code is governed by a BSD-style license 5b5e6bfc76a32a588da2400636688d34a71a2f47dpbos@webrtc.org * that can be found in the LICENSE file in the root of the source 6b5e6bfc76a32a588da2400636688d34a71a2f47dpbos@webrtc.org * tree. An additional intellectual property rights grant can be found 7b5e6bfc76a32a588da2400636688d34a71a2f47dpbos@webrtc.org * in the file PATENTS. All contributing project authors may 8b5e6bfc76a32a588da2400636688d34a71a2f47dpbos@webrtc.org * be found in the AUTHORS file in the root of the source tree. 9b5e6bfc76a32a588da2400636688d34a71a2f47dpbos@webrtc.org */ 10b5e6bfc76a32a588da2400636688d34a71a2f47dpbos@webrtc.org 11b5e6bfc76a32a588da2400636688d34a71a2f47dpbos@webrtc.org#include <string> 12b5e6bfc76a32a588da2400636688d34a71a2f47dpbos@webrtc.org 137ada923a94de3cd95142b3052996f9b38e134f39pbos#include "webrtc/base/logging.h" 14ff761fba8274d93bd73e76c8b8a1f2d0776dd840Henrik Kjellander#include "webrtc/modules/include/module_common_types.h" 15b5e6bfc76a32a588da2400636688d34a71a2f47dpbos@webrtc.org#include "webrtc/modules/rtp_rtcp/source/rtp_format_video_generic.h" 16b5e6bfc76a32a588da2400636688d34a71a2f47dpbos@webrtc.org 17b5e6bfc76a32a588da2400636688d34a71a2f47dpbos@webrtc.orgnamespace webrtc { 18b5e6bfc76a32a588da2400636688d34a71a2f47dpbos@webrtc.org 19b5e6bfc76a32a588da2400636688d34a71a2f47dpbos@webrtc.orgstatic const size_t kGenericHeaderLength = 1; 20b5e6bfc76a32a588da2400636688d34a71a2f47dpbos@webrtc.org 21b5e6bfc76a32a588da2400636688d34a71a2f47dpbos@webrtc.orgRtpPacketizerGeneric::RtpPacketizerGeneric(FrameType frame_type, 22b5e6bfc76a32a588da2400636688d34a71a2f47dpbos@webrtc.org size_t max_payload_len) 23b5e6bfc76a32a588da2400636688d34a71a2f47dpbos@webrtc.org : payload_data_(NULL), 24b5e6bfc76a32a588da2400636688d34a71a2f47dpbos@webrtc.org payload_size_(0), 25b5e6bfc76a32a588da2400636688d34a71a2f47dpbos@webrtc.org max_payload_len_(max_payload_len - kGenericHeaderLength), 26b5e6bfc76a32a588da2400636688d34a71a2f47dpbos@webrtc.org frame_type_(frame_type) { 27b5e6bfc76a32a588da2400636688d34a71a2f47dpbos@webrtc.org} 28b5e6bfc76a32a588da2400636688d34a71a2f47dpbos@webrtc.org 29b5e6bfc76a32a588da2400636688d34a71a2f47dpbos@webrtc.orgRtpPacketizerGeneric::~RtpPacketizerGeneric() { 30b5e6bfc76a32a588da2400636688d34a71a2f47dpbos@webrtc.org} 31b5e6bfc76a32a588da2400636688d34a71a2f47dpbos@webrtc.org 32b5e6bfc76a32a588da2400636688d34a71a2f47dpbos@webrtc.orgvoid RtpPacketizerGeneric::SetPayloadData( 33b5e6bfc76a32a588da2400636688d34a71a2f47dpbos@webrtc.org const uint8_t* payload_data, 34b5e6bfc76a32a588da2400636688d34a71a2f47dpbos@webrtc.org size_t payload_size, 35b5e6bfc76a32a588da2400636688d34a71a2f47dpbos@webrtc.org const RTPFragmentationHeader* fragmentation) { 36b5e6bfc76a32a588da2400636688d34a71a2f47dpbos@webrtc.org payload_data_ = payload_data; 37b5e6bfc76a32a588da2400636688d34a71a2f47dpbos@webrtc.org payload_size_ = payload_size; 38b5e6bfc76a32a588da2400636688d34a71a2f47dpbos@webrtc.org 39b5e6bfc76a32a588da2400636688d34a71a2f47dpbos@webrtc.org // Fragment packets more evenly by splitting the payload up evenly. 404591fbd09f9cb6e83433c49a12dd8524c2806502pkasting@chromium.org size_t num_packets = 41b5e6bfc76a32a588da2400636688d34a71a2f47dpbos@webrtc.org (payload_size_ + max_payload_len_ - 1) / max_payload_len_; 42b5e6bfc76a32a588da2400636688d34a71a2f47dpbos@webrtc.org payload_length_ = (payload_size_ + num_packets - 1) / num_packets; 43b5e6bfc76a32a588da2400636688d34a71a2f47dpbos@webrtc.org assert(payload_length_ <= max_payload_len_); 44b5e6bfc76a32a588da2400636688d34a71a2f47dpbos@webrtc.org 45b5e6bfc76a32a588da2400636688d34a71a2f47dpbos@webrtc.org generic_header_ = RtpFormatVideoGeneric::kFirstPacketBit; 46b5e6bfc76a32a588da2400636688d34a71a2f47dpbos@webrtc.org} 47b5e6bfc76a32a588da2400636688d34a71a2f47dpbos@webrtc.org 48b5e6bfc76a32a588da2400636688d34a71a2f47dpbos@webrtc.orgbool RtpPacketizerGeneric::NextPacket(uint8_t* buffer, 49b5e6bfc76a32a588da2400636688d34a71a2f47dpbos@webrtc.org size_t* bytes_to_send, 50b5e6bfc76a32a588da2400636688d34a71a2f47dpbos@webrtc.org bool* last_packet) { 51b5e6bfc76a32a588da2400636688d34a71a2f47dpbos@webrtc.org if (payload_size_ < payload_length_) { 52b5e6bfc76a32a588da2400636688d34a71a2f47dpbos@webrtc.org payload_length_ = payload_size_; 53b5e6bfc76a32a588da2400636688d34a71a2f47dpbos@webrtc.org } 54b5e6bfc76a32a588da2400636688d34a71a2f47dpbos@webrtc.org 55b5e6bfc76a32a588da2400636688d34a71a2f47dpbos@webrtc.org payload_size_ -= payload_length_; 56b5e6bfc76a32a588da2400636688d34a71a2f47dpbos@webrtc.org *bytes_to_send = payload_length_ + kGenericHeaderLength; 57b5e6bfc76a32a588da2400636688d34a71a2f47dpbos@webrtc.org assert(payload_length_ <= max_payload_len_); 58b5e6bfc76a32a588da2400636688d34a71a2f47dpbos@webrtc.org 59b5e6bfc76a32a588da2400636688d34a71a2f47dpbos@webrtc.org uint8_t* out_ptr = buffer; 60b5e6bfc76a32a588da2400636688d34a71a2f47dpbos@webrtc.org // Put generic header in packet 61b5e6bfc76a32a588da2400636688d34a71a2f47dpbos@webrtc.org if (frame_type_ == kVideoFrameKey) { 62b5e6bfc76a32a588da2400636688d34a71a2f47dpbos@webrtc.org generic_header_ |= RtpFormatVideoGeneric::kKeyFrameBit; 63b5e6bfc76a32a588da2400636688d34a71a2f47dpbos@webrtc.org } 64b5e6bfc76a32a588da2400636688d34a71a2f47dpbos@webrtc.org *out_ptr++ = generic_header_; 65b5e6bfc76a32a588da2400636688d34a71a2f47dpbos@webrtc.org // Remove first-packet bit, following packets are intermediate 66b5e6bfc76a32a588da2400636688d34a71a2f47dpbos@webrtc.org generic_header_ &= ~RtpFormatVideoGeneric::kFirstPacketBit; 67b5e6bfc76a32a588da2400636688d34a71a2f47dpbos@webrtc.org 68b5e6bfc76a32a588da2400636688d34a71a2f47dpbos@webrtc.org // Put payload in packet 69b5e6bfc76a32a588da2400636688d34a71a2f47dpbos@webrtc.org memcpy(out_ptr, payload_data_, payload_length_); 70b5e6bfc76a32a588da2400636688d34a71a2f47dpbos@webrtc.org payload_data_ += payload_length_; 71b5e6bfc76a32a588da2400636688d34a71a2f47dpbos@webrtc.org 72b5e6bfc76a32a588da2400636688d34a71a2f47dpbos@webrtc.org *last_packet = payload_size_ <= 0; 73b5e6bfc76a32a588da2400636688d34a71a2f47dpbos@webrtc.org 74b5e6bfc76a32a588da2400636688d34a71a2f47dpbos@webrtc.org return true; 75b5e6bfc76a32a588da2400636688d34a71a2f47dpbos@webrtc.org} 76b5e6bfc76a32a588da2400636688d34a71a2f47dpbos@webrtc.org 77b5e6bfc76a32a588da2400636688d34a71a2f47dpbos@webrtc.orgProtectionType RtpPacketizerGeneric::GetProtectionType() { 78b5e6bfc76a32a588da2400636688d34a71a2f47dpbos@webrtc.org return kProtectedPacket; 79b5e6bfc76a32a588da2400636688d34a71a2f47dpbos@webrtc.org} 80b5e6bfc76a32a588da2400636688d34a71a2f47dpbos@webrtc.org 81b5e6bfc76a32a588da2400636688d34a71a2f47dpbos@webrtc.orgStorageType RtpPacketizerGeneric::GetStorageType( 82b5e6bfc76a32a588da2400636688d34a71a2f47dpbos@webrtc.org uint32_t retransmission_settings) { 83b5e6bfc76a32a588da2400636688d34a71a2f47dpbos@webrtc.org return kAllowRetransmission; 84b5e6bfc76a32a588da2400636688d34a71a2f47dpbos@webrtc.org} 85b5e6bfc76a32a588da2400636688d34a71a2f47dpbos@webrtc.org 86b5e6bfc76a32a588da2400636688d34a71a2f47dpbos@webrtc.orgstd::string RtpPacketizerGeneric::ToString() { 87b5e6bfc76a32a588da2400636688d34a71a2f47dpbos@webrtc.org return "RtpPacketizerGeneric"; 88b5e6bfc76a32a588da2400636688d34a71a2f47dpbos@webrtc.org} 89b5e6bfc76a32a588da2400636688d34a71a2f47dpbos@webrtc.org 90730d2707713c4240070af17e56edd10d039bafd2pbos@webrtc.orgbool RtpDepacketizerGeneric::Parse(ParsedPayload* parsed_payload, 91b5e6bfc76a32a588da2400636688d34a71a2f47dpbos@webrtc.org const uint8_t* payload_data, 92b5e6bfc76a32a588da2400636688d34a71a2f47dpbos@webrtc.org size_t payload_data_length) { 93730d2707713c4240070af17e56edd10d039bafd2pbos@webrtc.org assert(parsed_payload != NULL); 947ada923a94de3cd95142b3052996f9b38e134f39pbos if (payload_data_length == 0) { 957ada923a94de3cd95142b3052996f9b38e134f39pbos LOG(LS_ERROR) << "Empty payload."; 967ada923a94de3cd95142b3052996f9b38e134f39pbos return false; 977ada923a94de3cd95142b3052996f9b38e134f39pbos } 98730d2707713c4240070af17e56edd10d039bafd2pbos@webrtc.org 99b5e6bfc76a32a588da2400636688d34a71a2f47dpbos@webrtc.org uint8_t generic_header = *payload_data++; 100b5e6bfc76a32a588da2400636688d34a71a2f47dpbos@webrtc.org --payload_data_length; 101b5e6bfc76a32a588da2400636688d34a71a2f47dpbos@webrtc.org 102d42a3adf429ad27779bea1789f53b76e52388583pbos@webrtc.org parsed_payload->frame_type = 103b5e6bfc76a32a588da2400636688d34a71a2f47dpbos@webrtc.org ((generic_header & RtpFormatVideoGeneric::kKeyFrameBit) != 0) 104b5e6bfc76a32a588da2400636688d34a71a2f47dpbos@webrtc.org ? kVideoFrameKey 105b5e6bfc76a32a588da2400636688d34a71a2f47dpbos@webrtc.org : kVideoFrameDelta; 106d42a3adf429ad27779bea1789f53b76e52388583pbos@webrtc.org parsed_payload->type.Video.isFirstPacket = 107b5e6bfc76a32a588da2400636688d34a71a2f47dpbos@webrtc.org (generic_header & RtpFormatVideoGeneric::kFirstPacketBit) != 0; 108d42a3adf429ad27779bea1789f53b76e52388583pbos@webrtc.org parsed_payload->type.Video.codec = kRtpVideoGeneric; 109d42a3adf429ad27779bea1789f53b76e52388583pbos@webrtc.org parsed_payload->type.Video.width = 0; 110d42a3adf429ad27779bea1789f53b76e52388583pbos@webrtc.org parsed_payload->type.Video.height = 0; 111b5e6bfc76a32a588da2400636688d34a71a2f47dpbos@webrtc.org 112730d2707713c4240070af17e56edd10d039bafd2pbos@webrtc.org parsed_payload->payload = payload_data; 113730d2707713c4240070af17e56edd10d039bafd2pbos@webrtc.org parsed_payload->payload_length = payload_data_length; 114b5e6bfc76a32a588da2400636688d34a71a2f47dpbos@webrtc.org return true; 115b5e6bfc76a32a588da2400636688d34a71a2f47dpbos@webrtc.org} 116b5e6bfc76a32a588da2400636688d34a71a2f47dpbos@webrtc.org} // namespace webrtc 117