// Copyright 2014 The Chromium Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. #include "media/cast/net/rtp/rtp_packet_builder.h" #include "base/big_endian.h" #include "base/logging.h" namespace media { namespace cast { const uint32 kCastRtpHeaderLength = 7; const uint32 kGenericRtpHeaderLength = 12; static const uint8 kRtpMarkerBitMask = 0x80; RtpPacketBuilder::RtpPacketBuilder() : is_key_(false), frame_id_(0), packet_id_(0), max_packet_id_(0), reference_frame_id_(0), timestamp_(0), sequence_number_(0), marker_(false), payload_type_(0), ssrc_(0) {} void RtpPacketBuilder::SetKeyFrame(bool is_key) { is_key_ = is_key; } void RtpPacketBuilder::SetFrameIds(uint32 frame_id, uint32 reference_frame_id) { frame_id_ = frame_id; reference_frame_id_ = reference_frame_id; } void RtpPacketBuilder::SetPacketId(uint16 packet_id) { packet_id_ = packet_id; } void RtpPacketBuilder::SetMaxPacketId(uint16 max_packet_id) { max_packet_id_ = max_packet_id; } void RtpPacketBuilder::SetTimestamp(uint32 timestamp) { timestamp_ = timestamp; } void RtpPacketBuilder::SetSequenceNumber(uint16 sequence_number) { sequence_number_ = sequence_number; } void RtpPacketBuilder::SetMarkerBit(bool marker) { marker_ = marker; } void RtpPacketBuilder::SetPayloadType(int payload_type) { payload_type_ = payload_type; } void RtpPacketBuilder::SetSsrc(uint32 ssrc) { ssrc_ = ssrc; } void RtpPacketBuilder::BuildHeader(uint8* data, uint32 data_length) { BuildCommonHeader(data, data_length); BuildCastHeader(data + kGenericRtpHeaderLength, data_length - kGenericRtpHeaderLength); } void RtpPacketBuilder::BuildCastHeader(uint8* data, uint32 data_length) { // Build header. DCHECK_LE(kCastRtpHeaderLength, data_length); // Set the first 7 bytes to 0. memset(data, 0, kCastRtpHeaderLength); base::BigEndianWriter big_endian_writer(reinterpret_cast(data), 56); const bool includes_specific_frame_reference = (is_key_ && (reference_frame_id_ != frame_id_)) || (!is_key_ && (reference_frame_id_ != (frame_id_ - 1))); big_endian_writer.WriteU8((is_key_ ? 0x80 : 0) | (includes_specific_frame_reference ? 0x40 : 0)); big_endian_writer.WriteU8(frame_id_); big_endian_writer.WriteU16(packet_id_); big_endian_writer.WriteU16(max_packet_id_); if (includes_specific_frame_reference) { big_endian_writer.WriteU8(reference_frame_id_); } } void RtpPacketBuilder::BuildCommonHeader(uint8* data, uint32 data_length) { DCHECK_LE(kGenericRtpHeaderLength, data_length); base::BigEndianWriter big_endian_writer(reinterpret_cast(data), 96); big_endian_writer.WriteU8(0x80); big_endian_writer.WriteU8(payload_type_ | (marker_ ? kRtpMarkerBitMask : 0)); big_endian_writer.WriteU16(sequence_number_); big_endian_writer.WriteU32(timestamp_); big_endian_writer.WriteU32(ssrc_); } } // namespace cast } // namespace media