| OLD | NEW |
| 1 // Copyright 2014 The Chromium Authors. All rights reserved. | 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 | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "media/cast/net/rtp/rtp_parser.h" | 5 #include "media/cast/net/rtp/rtp_parser.h" |
| 6 | 6 |
| 7 #include "base/big_endian.h" | 7 #include "base/big_endian.h" |
| 8 #include "base/logging.h" | 8 #include "base/logging.h" |
| 9 #include "media/cast/cast_defines.h" | 9 #include "media/cast/cast_defines.h" |
| 10 #include "media/cast/net/rtp/rtp_defines.h" | 10 #include "media/cast/net/rtp/rtp_defines.h" |
| (...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 44 | 44 |
| 45 // Parse the RTP header. See | 45 // Parse the RTP header. See |
| 46 // http://en.wikipedia.org/wiki/Real-time_Transport_Protocol for an | 46 // http://en.wikipedia.org/wiki/Real-time_Transport_Protocol for an |
| 47 // explanation of the standard RTP packet header. | 47 // explanation of the standard RTP packet header. |
| 48 uint8 bits; | 48 uint8 bits; |
| 49 if (!reader.ReadU8(&bits)) | 49 if (!reader.ReadU8(&bits)) |
| 50 return false; | 50 return false; |
| 51 const uint8 version = bits >> 6; | 51 const uint8 version = bits >> 6; |
| 52 if (version != 2) | 52 if (version != 2) |
| 53 return false; | 53 return false; |
| 54 header->num_csrcs = bits & kRtpNumCsrcsMask; |
| 54 if (bits & kRtpExtensionBitMask) | 55 if (bits & kRtpExtensionBitMask) |
| 55 return false; // We lack the implementation to skip over an extension. | 56 return false; // We lack the implementation to skip over an extension. |
| 56 if (!reader.ReadU8(&bits)) | 57 if (!reader.ReadU8(&bits)) |
| 57 return false; | 58 return false; |
| 58 header->marker = !!(bits & kRtpMarkerBitMask); | 59 header->marker = !!(bits & kRtpMarkerBitMask); |
| 59 header->payload_type = bits & ~kRtpMarkerBitMask; | 60 header->payload_type = bits & ~kRtpMarkerBitMask; |
| 60 if (header->payload_type != expected_payload_type_) | 61 if (header->payload_type != expected_payload_type_) |
| 61 return false; // Punt: Unexpected payload type. | 62 return false; // Punt: Unexpected payload type. |
| 62 if (!reader.ReadU16(&header->sequence_number) || | 63 if (!reader.ReadU16(&header->sequence_number) || |
| 63 !reader.ReadU32(&header->rtp_timestamp) || | 64 !reader.ReadU32(&header->rtp_timestamp) || |
| 64 !reader.ReadU32(&header->sender_ssrc)) { | 65 !reader.ReadU32(&header->sender_ssrc)) { |
| 65 return false; | 66 return false; |
| 66 } | 67 } |
| 67 if (header->sender_ssrc != expected_sender_ssrc_) | 68 if (header->sender_ssrc != expected_sender_ssrc_) |
| 68 return false; // Punt: Sender's SSRC does not match the expected one. | 69 return false; // Punt: Sender's SSRC does not match the expected one. |
| 69 | 70 |
| 70 // Parse the Cast header. Note that, from the RTP protocol's perspective, the | 71 // Parse the Cast header. Note that, from the RTP protocol's perspective, the |
| 71 // Cast header is part of the payload (and not meant to be an extension | 72 // Cast header is part of the payload (and not meant to be an extension |
| 72 // header). | 73 // header). |
| 73 if (!reader.ReadU8(&bits)) | 74 if (!reader.ReadU8(&bits)) |
| 74 return false; | 75 return false; |
| 75 header->is_key_frame = !!(bits & kCastKeyFrameBitMask); | 76 header->is_key_frame = !!(bits & kCastKeyFrameBitMask); |
| 76 const bool includes_specific_frame_reference = | 77 header->is_reference = !!(bits & kCastReferenceFrameIdBitMask); |
| 77 !!(bits & kCastReferenceFrameIdBitMask); | |
| 78 uint8 truncated_frame_id; | 78 uint8 truncated_frame_id; |
| 79 if (!reader.ReadU8(&truncated_frame_id) || | 79 if (!reader.ReadU8(&truncated_frame_id) || |
| 80 !reader.ReadU16(&header->packet_id) || | 80 !reader.ReadU16(&header->packet_id) || |
| 81 !reader.ReadU16(&header->max_packet_id)) { | 81 !reader.ReadU16(&header->max_packet_id)) { |
| 82 return false; | 82 return false; |
| 83 } | 83 } |
| 84 // Sanity-check: Do the packet ID values make sense w.r.t. each other? | 84 // Sanity-check: Do the packet ID values make sense w.r.t. each other? |
| 85 if (header->max_packet_id < header->packet_id) | 85 if (header->max_packet_id < header->packet_id) |
| 86 return false; | 86 return false; |
| 87 uint8 truncated_reference_frame_id; | 87 uint8 truncated_reference_frame_id; |
| 88 if (!includes_specific_frame_reference) { | 88 if (!header->is_reference) { |
| 89 // By default, a key frame only references itself; and non-key frames | 89 // By default, a key frame only references itself; and non-key frames |
| 90 // reference their direct predecessor. | 90 // reference their direct predecessor. |
| 91 truncated_reference_frame_id = truncated_frame_id; | 91 truncated_reference_frame_id = truncated_frame_id; |
| 92 if (!header->is_key_frame) | 92 if (!header->is_key_frame) |
| 93 --truncated_reference_frame_id; | 93 --truncated_reference_frame_id; |
| 94 } else if (!reader.ReadU8(&truncated_reference_frame_id)) { | 94 } else if (!reader.ReadU8(&truncated_reference_frame_id)) { |
| 95 return false; | 95 return false; |
| 96 } | 96 } |
| 97 | 97 |
| 98 for (int i = 0; i < (bits & kCastExtensionCountmask); i++) { | 98 for (int i = 0; i < (bits & kCastExtensionCountmask); i++) { |
| 99 uint16 type_and_size; | 99 uint16 type_and_size; |
| 100 if (!reader.ReadU16(&type_and_size)) | 100 if (!reader.ReadU16(&type_and_size)) |
| 101 return false; | 101 return false; |
| 102 base::StringPiece tmp; | 102 base::StringPiece tmp; |
| 103 if (!reader.ReadPiece(&tmp, type_and_size & 0x3ff)) | 103 if (!reader.ReadPiece(&tmp, type_and_size & 0x3ff)) |
| 104 return false; | 104 return false; |
| 105 base::BigEndianReader chunk(tmp.data(), tmp.size()); | 105 base::BigEndianReader chunk(tmp.data(), tmp.size()); |
| 106 switch (type_and_size >> 10) { | 106 switch (type_and_size >> 10) { |
| 107 case kCastRtpExtensionAdaptiveLatency: | 107 case kCastRtpExtensionAdaptiveLatency: |
| 108 if (!chunk.ReadU16(&header->new_playout_delay_ms)) | 108 if (!chunk.ReadU16(&header->new_playout_delay_ms)) |
| 109 return false; | 109 return false; |
| 110 | |
| 111 } | 110 } |
| 112 } | 111 } |
| 113 | 112 |
| 114 // Only the lower 8 bits of the |frame_id| were serialized, so do some magic | 113 // Only the lower 8 bits of the |frame_id| were serialized, so do some magic |
| 115 // to restore the upper 24 bits. | 114 // to restore the upper 24 bits. |
| 116 // | 115 // |
| 117 // Note: The call to |frame_id_wrap_helper_| has side effects, so we must not | 116 // Note: The call to |frame_id_wrap_helper_| has side effects, so we must not |
| 118 // call it until we know the entire deserialization will succeed. | 117 // call it until we know the entire deserialization will succeed. |
| 119 header->frame_id = | 118 header->frame_id = |
| 120 frame_id_wrap_helper_.MapTo32bitsFrameId(truncated_frame_id); | 119 frame_id_wrap_helper_.MapTo32bitsFrameId(truncated_frame_id); |
| 121 // When the upper 24 bits are restored to |reference_frame_id|, make sure | 120 // When the upper 24 bits are restored to |reference_frame_id|, make sure |
| 122 // |reference_frame_id| will be strictly less than or equal to |frame_id|. | 121 // |reference_frame_id| will be strictly less than or equal to |frame_id|. |
| 123 if (truncated_reference_frame_id <= truncated_frame_id) | 122 if (truncated_reference_frame_id <= truncated_frame_id) |
| 124 header->reference_frame_id = header->frame_id & 0xffffff00; | 123 header->reference_frame_id = header->frame_id & 0xffffff00; |
| 125 else | 124 else |
| 126 header->reference_frame_id = (header->frame_id & 0xffffff00) - 0x00000100; | 125 header->reference_frame_id = (header->frame_id & 0xffffff00) - 0x00000100; |
| 127 header->reference_frame_id |= truncated_reference_frame_id; | 126 header->reference_frame_id |= truncated_reference_frame_id; |
| 128 | 127 |
| 129 // All remaining data in the packet is the payload. | 128 // All remaining data in the packet is the payload. |
| 130 *payload_data = reinterpret_cast<const uint8*>(reader.ptr()); | 129 *payload_data = reinterpret_cast<const uint8*>(reader.ptr()); |
| 131 *payload_size = reader.remaining(); | 130 *payload_size = reader.remaining(); |
| 132 | 131 |
| 133 return true; | 132 return true; |
| 134 } | 133 } |
| 135 | 134 |
| 136 } // namespace cast | 135 } // namespace cast |
| 137 } // namespace media | 136 } // namespace media |
| OLD | NEW |