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