• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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