1b5e6bfc76a32a588da2400636688d34a71a2f47dpbos@webrtc.org/*
2b5e6bfc76a32a588da2400636688d34a71a2f47dpbos@webrtc.org *  Copyright (c) 2014 The WebRTC project authors. All Rights Reserved.
3b5e6bfc76a32a588da2400636688d34a71a2f47dpbos@webrtc.org *
4b5e6bfc76a32a588da2400636688d34a71a2f47dpbos@webrtc.org *  Use of this source code is governed by a BSD-style license
5b5e6bfc76a32a588da2400636688d34a71a2f47dpbos@webrtc.org *  that can be found in the LICENSE file in the root of the source
6b5e6bfc76a32a588da2400636688d34a71a2f47dpbos@webrtc.org *  tree. An additional intellectual property rights grant can be found
7b5e6bfc76a32a588da2400636688d34a71a2f47dpbos@webrtc.org *  in the file PATENTS.  All contributing project authors may
8b5e6bfc76a32a588da2400636688d34a71a2f47dpbos@webrtc.org *  be found in the AUTHORS file in the root of the source tree.
9b5e6bfc76a32a588da2400636688d34a71a2f47dpbos@webrtc.org */
10b5e6bfc76a32a588da2400636688d34a71a2f47dpbos@webrtc.org
11b5e6bfc76a32a588da2400636688d34a71a2f47dpbos@webrtc.org#include <string>
12b5e6bfc76a32a588da2400636688d34a71a2f47dpbos@webrtc.org
137ada923a94de3cd95142b3052996f9b38e134f39pbos#include "webrtc/base/logging.h"
14ff761fba8274d93bd73e76c8b8a1f2d0776dd840Henrik Kjellander#include "webrtc/modules/include/module_common_types.h"
15b5e6bfc76a32a588da2400636688d34a71a2f47dpbos@webrtc.org#include "webrtc/modules/rtp_rtcp/source/rtp_format_video_generic.h"
16b5e6bfc76a32a588da2400636688d34a71a2f47dpbos@webrtc.org
17b5e6bfc76a32a588da2400636688d34a71a2f47dpbos@webrtc.orgnamespace webrtc {
18b5e6bfc76a32a588da2400636688d34a71a2f47dpbos@webrtc.org
19b5e6bfc76a32a588da2400636688d34a71a2f47dpbos@webrtc.orgstatic const size_t kGenericHeaderLength = 1;
20b5e6bfc76a32a588da2400636688d34a71a2f47dpbos@webrtc.org
21b5e6bfc76a32a588da2400636688d34a71a2f47dpbos@webrtc.orgRtpPacketizerGeneric::RtpPacketizerGeneric(FrameType frame_type,
22b5e6bfc76a32a588da2400636688d34a71a2f47dpbos@webrtc.org                                           size_t max_payload_len)
23b5e6bfc76a32a588da2400636688d34a71a2f47dpbos@webrtc.org    : payload_data_(NULL),
24b5e6bfc76a32a588da2400636688d34a71a2f47dpbos@webrtc.org      payload_size_(0),
25b5e6bfc76a32a588da2400636688d34a71a2f47dpbos@webrtc.org      max_payload_len_(max_payload_len - kGenericHeaderLength),
26b5e6bfc76a32a588da2400636688d34a71a2f47dpbos@webrtc.org      frame_type_(frame_type) {
27b5e6bfc76a32a588da2400636688d34a71a2f47dpbos@webrtc.org}
28b5e6bfc76a32a588da2400636688d34a71a2f47dpbos@webrtc.org
29b5e6bfc76a32a588da2400636688d34a71a2f47dpbos@webrtc.orgRtpPacketizerGeneric::~RtpPacketizerGeneric() {
30b5e6bfc76a32a588da2400636688d34a71a2f47dpbos@webrtc.org}
31b5e6bfc76a32a588da2400636688d34a71a2f47dpbos@webrtc.org
32b5e6bfc76a32a588da2400636688d34a71a2f47dpbos@webrtc.orgvoid RtpPacketizerGeneric::SetPayloadData(
33b5e6bfc76a32a588da2400636688d34a71a2f47dpbos@webrtc.org    const uint8_t* payload_data,
34b5e6bfc76a32a588da2400636688d34a71a2f47dpbos@webrtc.org    size_t payload_size,
35b5e6bfc76a32a588da2400636688d34a71a2f47dpbos@webrtc.org    const RTPFragmentationHeader* fragmentation) {
36b5e6bfc76a32a588da2400636688d34a71a2f47dpbos@webrtc.org  payload_data_ = payload_data;
37b5e6bfc76a32a588da2400636688d34a71a2f47dpbos@webrtc.org  payload_size_ = payload_size;
38b5e6bfc76a32a588da2400636688d34a71a2f47dpbos@webrtc.org
39b5e6bfc76a32a588da2400636688d34a71a2f47dpbos@webrtc.org  // Fragment packets more evenly by splitting the payload up evenly.
404591fbd09f9cb6e83433c49a12dd8524c2806502pkasting@chromium.org  size_t num_packets =
41b5e6bfc76a32a588da2400636688d34a71a2f47dpbos@webrtc.org      (payload_size_ + max_payload_len_ - 1) / max_payload_len_;
42b5e6bfc76a32a588da2400636688d34a71a2f47dpbos@webrtc.org  payload_length_ = (payload_size_ + num_packets - 1) / num_packets;
43b5e6bfc76a32a588da2400636688d34a71a2f47dpbos@webrtc.org  assert(payload_length_ <= max_payload_len_);
44b5e6bfc76a32a588da2400636688d34a71a2f47dpbos@webrtc.org
45b5e6bfc76a32a588da2400636688d34a71a2f47dpbos@webrtc.org  generic_header_ = RtpFormatVideoGeneric::kFirstPacketBit;
46b5e6bfc76a32a588da2400636688d34a71a2f47dpbos@webrtc.org}
47b5e6bfc76a32a588da2400636688d34a71a2f47dpbos@webrtc.org
48b5e6bfc76a32a588da2400636688d34a71a2f47dpbos@webrtc.orgbool RtpPacketizerGeneric::NextPacket(uint8_t* buffer,
49b5e6bfc76a32a588da2400636688d34a71a2f47dpbos@webrtc.org                                      size_t* bytes_to_send,
50b5e6bfc76a32a588da2400636688d34a71a2f47dpbos@webrtc.org                                      bool* last_packet) {
51b5e6bfc76a32a588da2400636688d34a71a2f47dpbos@webrtc.org  if (payload_size_ < payload_length_) {
52b5e6bfc76a32a588da2400636688d34a71a2f47dpbos@webrtc.org    payload_length_ = payload_size_;
53b5e6bfc76a32a588da2400636688d34a71a2f47dpbos@webrtc.org  }
54b5e6bfc76a32a588da2400636688d34a71a2f47dpbos@webrtc.org
55b5e6bfc76a32a588da2400636688d34a71a2f47dpbos@webrtc.org  payload_size_ -= payload_length_;
56b5e6bfc76a32a588da2400636688d34a71a2f47dpbos@webrtc.org  *bytes_to_send = payload_length_ + kGenericHeaderLength;
57b5e6bfc76a32a588da2400636688d34a71a2f47dpbos@webrtc.org  assert(payload_length_ <= max_payload_len_);
58b5e6bfc76a32a588da2400636688d34a71a2f47dpbos@webrtc.org
59b5e6bfc76a32a588da2400636688d34a71a2f47dpbos@webrtc.org  uint8_t* out_ptr = buffer;
60b5e6bfc76a32a588da2400636688d34a71a2f47dpbos@webrtc.org  // Put generic header in packet
61b5e6bfc76a32a588da2400636688d34a71a2f47dpbos@webrtc.org  if (frame_type_ == kVideoFrameKey) {
62b5e6bfc76a32a588da2400636688d34a71a2f47dpbos@webrtc.org    generic_header_ |= RtpFormatVideoGeneric::kKeyFrameBit;
63b5e6bfc76a32a588da2400636688d34a71a2f47dpbos@webrtc.org  }
64b5e6bfc76a32a588da2400636688d34a71a2f47dpbos@webrtc.org  *out_ptr++ = generic_header_;
65b5e6bfc76a32a588da2400636688d34a71a2f47dpbos@webrtc.org  // Remove first-packet bit, following packets are intermediate
66b5e6bfc76a32a588da2400636688d34a71a2f47dpbos@webrtc.org  generic_header_ &= ~RtpFormatVideoGeneric::kFirstPacketBit;
67b5e6bfc76a32a588da2400636688d34a71a2f47dpbos@webrtc.org
68b5e6bfc76a32a588da2400636688d34a71a2f47dpbos@webrtc.org  // Put payload in packet
69b5e6bfc76a32a588da2400636688d34a71a2f47dpbos@webrtc.org  memcpy(out_ptr, payload_data_, payload_length_);
70b5e6bfc76a32a588da2400636688d34a71a2f47dpbos@webrtc.org  payload_data_ += payload_length_;
71b5e6bfc76a32a588da2400636688d34a71a2f47dpbos@webrtc.org
72b5e6bfc76a32a588da2400636688d34a71a2f47dpbos@webrtc.org  *last_packet = payload_size_ <= 0;
73b5e6bfc76a32a588da2400636688d34a71a2f47dpbos@webrtc.org
74b5e6bfc76a32a588da2400636688d34a71a2f47dpbos@webrtc.org  return true;
75b5e6bfc76a32a588da2400636688d34a71a2f47dpbos@webrtc.org}
76b5e6bfc76a32a588da2400636688d34a71a2f47dpbos@webrtc.org
77b5e6bfc76a32a588da2400636688d34a71a2f47dpbos@webrtc.orgProtectionType RtpPacketizerGeneric::GetProtectionType() {
78b5e6bfc76a32a588da2400636688d34a71a2f47dpbos@webrtc.org  return kProtectedPacket;
79b5e6bfc76a32a588da2400636688d34a71a2f47dpbos@webrtc.org}
80b5e6bfc76a32a588da2400636688d34a71a2f47dpbos@webrtc.org
81b5e6bfc76a32a588da2400636688d34a71a2f47dpbos@webrtc.orgStorageType RtpPacketizerGeneric::GetStorageType(
82b5e6bfc76a32a588da2400636688d34a71a2f47dpbos@webrtc.org    uint32_t retransmission_settings) {
83b5e6bfc76a32a588da2400636688d34a71a2f47dpbos@webrtc.org  return kAllowRetransmission;
84b5e6bfc76a32a588da2400636688d34a71a2f47dpbos@webrtc.org}
85b5e6bfc76a32a588da2400636688d34a71a2f47dpbos@webrtc.org
86b5e6bfc76a32a588da2400636688d34a71a2f47dpbos@webrtc.orgstd::string RtpPacketizerGeneric::ToString() {
87b5e6bfc76a32a588da2400636688d34a71a2f47dpbos@webrtc.org  return "RtpPacketizerGeneric";
88b5e6bfc76a32a588da2400636688d34a71a2f47dpbos@webrtc.org}
89b5e6bfc76a32a588da2400636688d34a71a2f47dpbos@webrtc.org
90730d2707713c4240070af17e56edd10d039bafd2pbos@webrtc.orgbool RtpDepacketizerGeneric::Parse(ParsedPayload* parsed_payload,
91b5e6bfc76a32a588da2400636688d34a71a2f47dpbos@webrtc.org                                   const uint8_t* payload_data,
92b5e6bfc76a32a588da2400636688d34a71a2f47dpbos@webrtc.org                                   size_t payload_data_length) {
93730d2707713c4240070af17e56edd10d039bafd2pbos@webrtc.org  assert(parsed_payload != NULL);
947ada923a94de3cd95142b3052996f9b38e134f39pbos  if (payload_data_length == 0) {
957ada923a94de3cd95142b3052996f9b38e134f39pbos    LOG(LS_ERROR) << "Empty payload.";
967ada923a94de3cd95142b3052996f9b38e134f39pbos    return false;
977ada923a94de3cd95142b3052996f9b38e134f39pbos  }
98730d2707713c4240070af17e56edd10d039bafd2pbos@webrtc.org
99b5e6bfc76a32a588da2400636688d34a71a2f47dpbos@webrtc.org  uint8_t generic_header = *payload_data++;
100b5e6bfc76a32a588da2400636688d34a71a2f47dpbos@webrtc.org  --payload_data_length;
101b5e6bfc76a32a588da2400636688d34a71a2f47dpbos@webrtc.org
102d42a3adf429ad27779bea1789f53b76e52388583pbos@webrtc.org  parsed_payload->frame_type =
103b5e6bfc76a32a588da2400636688d34a71a2f47dpbos@webrtc.org      ((generic_header & RtpFormatVideoGeneric::kKeyFrameBit) != 0)
104b5e6bfc76a32a588da2400636688d34a71a2f47dpbos@webrtc.org          ? kVideoFrameKey
105b5e6bfc76a32a588da2400636688d34a71a2f47dpbos@webrtc.org          : kVideoFrameDelta;
106d42a3adf429ad27779bea1789f53b76e52388583pbos@webrtc.org  parsed_payload->type.Video.isFirstPacket =
107b5e6bfc76a32a588da2400636688d34a71a2f47dpbos@webrtc.org      (generic_header & RtpFormatVideoGeneric::kFirstPacketBit) != 0;
108d42a3adf429ad27779bea1789f53b76e52388583pbos@webrtc.org  parsed_payload->type.Video.codec = kRtpVideoGeneric;
109d42a3adf429ad27779bea1789f53b76e52388583pbos@webrtc.org  parsed_payload->type.Video.width = 0;
110d42a3adf429ad27779bea1789f53b76e52388583pbos@webrtc.org  parsed_payload->type.Video.height = 0;
111b5e6bfc76a32a588da2400636688d34a71a2f47dpbos@webrtc.org
112730d2707713c4240070af17e56edd10d039bafd2pbos@webrtc.org  parsed_payload->payload = payload_data;
113730d2707713c4240070af17e56edd10d039bafd2pbos@webrtc.org  parsed_payload->payload_length = payload_data_length;
114b5e6bfc76a32a588da2400636688d34a71a2f47dpbos@webrtc.org  return true;
115b5e6bfc76a32a588da2400636688d34a71a2f47dpbos@webrtc.org}
116b5e6bfc76a32a588da2400636688d34a71a2f47dpbos@webrtc.org}  // namespace webrtc
117