Home | History | Annotate | Download | only in source
      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 
     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 
     29 RtpPacketizerGeneric::~RtpPacketizerGeneric() {
     30 }
     31 
     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 
     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 
     77 ProtectionType RtpPacketizerGeneric::GetProtectionType() {
     78   return kProtectedPacket;
     79 }
     80 
     81 StorageType RtpPacketizerGeneric::GetStorageType(
     82     uint32_t retransmission_settings) {
     83   return kAllowRetransmission;
     84 }
     85 
     86 std::string RtpPacketizerGeneric::ToString() {
     87   return "RtpPacketizerGeneric";
     88 }
     89 
     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