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