Ignore title parameter for navigator.registerProtocolHandler
[chromium-blink-merge.git] / media / cast / rtp_receiver / rtp_parser / rtp_parser.cc
blobd75696a861ef00891a6a8cc64e91ee04f1b78cda
1 // Copyright 2013 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 #include "media/cast/rtp_receiver/rtp_parser/rtp_parser.h"
7 #include "base/big_endian.h"
8 #include "base/logging.h"
9 #include "media/cast/cast_defines.h"
10 #include "media/cast/rtp_receiver/rtp_receiver.h"
12 namespace media {
13 namespace cast {
15 static const size_t kRtpHeaderLength = 12;
16 static const size_t kCastHeaderLength = 7;
17 static const uint8 kRtpExtensionBitMask = 0x10;
18 static const uint8 kRtpMarkerBitMask = 0x80;
19 static const uint8 kCastKeyFrameBitMask = 0x80;
20 static const uint8 kCastReferenceFrameIdBitMask = 0x40;
22 RtpParser::RtpParser(uint32 expected_sender_ssrc, uint8 expected_payload_type)
23 : expected_sender_ssrc_(expected_sender_ssrc),
24 expected_payload_type_(expected_payload_type) {}
26 RtpParser::~RtpParser() {}
28 bool RtpParser::ParsePacket(const uint8* packet,
29 size_t length,
30 RtpCastHeader* header,
31 const uint8** payload_data,
32 size_t* payload_size) {
33 DCHECK(packet);
34 DCHECK(header);
35 DCHECK(payload_data);
36 DCHECK(payload_size);
38 if (length < (kRtpHeaderLength + kCastHeaderLength))
39 return false;
41 base::BigEndianReader reader(reinterpret_cast<const char*>(packet), length);
43 // Parse the RTP header. See
44 // http://en.wikipedia.org/wiki/Real-time_Transport_Protocol for an
45 // explanation of the standard RTP packet header.
46 uint8 bits;
47 if (!reader.ReadU8(&bits))
48 return false;
49 const uint8 version = bits >> 6;
50 if (version != 2)
51 return false;
52 if (bits & kRtpExtensionBitMask)
53 return false; // We lack the implementation to skip over an extension.
54 if (!reader.ReadU8(&bits))
55 return false;
56 header->marker = !!(bits & kRtpMarkerBitMask);
57 header->payload_type = bits & ~kRtpMarkerBitMask;
58 if (header->payload_type != expected_payload_type_)
59 return false; // Punt: Unexpected payload type.
60 if (!reader.ReadU16(&header->sequence_number) ||
61 !reader.ReadU32(&header->rtp_timestamp) ||
62 !reader.ReadU32(&header->sender_ssrc)) {
63 return false;
65 if (header->sender_ssrc != expected_sender_ssrc_)
66 return false; // Punt: Sender's SSRC does not match the expected one.
68 // Parse the Cast header. Note that, from the RTP protocol's perspective, the
69 // Cast header is part of the payload (and not meant to be an extension
70 // header).
71 if (!reader.ReadU8(&bits))
72 return false;
73 header->is_key_frame = !!(bits & kCastKeyFrameBitMask);
74 const bool includes_specific_frame_reference =
75 !!(bits & kCastReferenceFrameIdBitMask);
76 uint8 truncated_frame_id;
77 if (!reader.ReadU8(&truncated_frame_id) ||
78 !reader.ReadU16(&header->packet_id) ||
79 !reader.ReadU16(&header->max_packet_id)) {
80 return false;
82 // Sanity-check: Do the packet ID values make sense w.r.t. each other?
83 if (header->max_packet_id < header->packet_id)
84 return false;
85 uint8 truncated_reference_frame_id;
86 if (!includes_specific_frame_reference) {
87 // By default, a key frame only references itself; and non-key frames
88 // reference their direct predecessor.
89 truncated_reference_frame_id = truncated_frame_id;
90 if (!header->is_key_frame)
91 --truncated_reference_frame_id;
92 } else if (!reader.ReadU8(&truncated_reference_frame_id)) {
93 return false;
96 // Only the lower 8 bits of the |frame_id| were serialized, so do some magic
97 // to restore the upper 24 bits.
99 // Note: The call to |frame_id_wrap_helper_| has side effects, so we must not
100 // call it until we know the entire deserialization will succeed.
101 header->frame_id =
102 frame_id_wrap_helper_.MapTo32bitsFrameId(truncated_frame_id);
103 // When the upper 24 bits are restored to |reference_frame_id|, make sure
104 // |reference_frame_id| will be strictly less than or equal to |frame_id|.
105 if (truncated_reference_frame_id <= truncated_frame_id)
106 header->reference_frame_id = header->frame_id & 0xffffff00;
107 else
108 header->reference_frame_id = (header->frame_id & 0xffffff00) - 0x00000100;
109 header->reference_frame_id |= truncated_reference_frame_id;
111 // All remaining data in the packet is the payload.
112 *payload_data = reinterpret_cast<const uint8*>(reader.ptr());
113 *payload_size = reader.remaining();
115 return true;
118 } // namespace cast
119 } // namespace media