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
RtpPacketizerGeneric(FrameType frame_type,size_t max_payload_len)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
~RtpPacketizerGeneric()29 RtpPacketizerGeneric::~RtpPacketizerGeneric() {
30 }
31
SetPayloadData(const uint8_t * payload_data,size_t payload_size,const RTPFragmentationHeader * fragmentation)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
NextPacket(uint8_t * buffer,size_t * bytes_to_send,bool * last_packet)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
GetProtectionType()77 ProtectionType RtpPacketizerGeneric::GetProtectionType() {
78 return kProtectedPacket;
79 }
80
GetStorageType(uint32_t retransmission_settings)81 StorageType RtpPacketizerGeneric::GetStorageType(
82 uint32_t retransmission_settings) {
83 return kAllowRetransmission;
84 }
85
ToString()86 std::string RtpPacketizerGeneric::ToString() {
87 return "RtpPacketizerGeneric";
88 }
89
Parse(ParsedPayload * parsed_payload,const uint8_t * payload_data,size_t payload_data_length)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