• 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/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