OLD | NEW |
---|---|
1 /* | 1 /* |
2 * Copyright (c) 2014 The WebRTC project authors. All Rights Reserved. | 2 * Copyright (c) 2014 The WebRTC project authors. All Rights Reserved. |
3 * | 3 * |
4 * Use of this source code is governed by a BSD-style license | 4 * Use of this source code is governed by a BSD-style license |
5 * that can be found in the LICENSE file in the root of the source | 5 * that can be found in the LICENSE file in the root of the source |
6 * tree. An additional intellectual property rights grant can be found | 6 * tree. An additional intellectual property rights grant can be found |
7 * in the file PATENTS. All contributing project authors may | 7 * in the file PATENTS. All contributing project authors may |
8 * be found in the AUTHORS file in the root of the source tree. | 8 * be found in the AUTHORS file in the root of the source tree. |
9 */ | 9 */ |
10 | 10 |
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
45 size_t payload_data_length) { | 45 size_t payload_data_length) { |
46 parsed_payload->type.Video.width = 0; | 46 parsed_payload->type.Video.width = 0; |
47 parsed_payload->type.Video.height = 0; | 47 parsed_payload->type.Video.height = 0; |
48 parsed_payload->type.Video.codec = kRtpVideoH264; | 48 parsed_payload->type.Video.codec = kRtpVideoH264; |
49 parsed_payload->type.Video.isFirstPacket = true; | 49 parsed_payload->type.Video.isFirstPacket = true; |
50 RTPVideoHeaderH264* h264_header = | 50 RTPVideoHeaderH264* h264_header = |
51 &parsed_payload->type.Video.codecHeader.H264; | 51 &parsed_payload->type.Video.codecHeader.H264; |
52 | 52 |
53 const uint8_t* nalu_start = payload_data + kNalHeaderSize; | 53 const uint8_t* nalu_start = payload_data + kNalHeaderSize; |
54 size_t nalu_length = payload_data_length - kNalHeaderSize; | 54 size_t nalu_length = payload_data_length - kNalHeaderSize; |
55 uint8_t nal_type = payload_data[0] & kTypeMask; | 55 uint8_t nal_type = payload_data[0] & kTypeMask; |
stefan-webrtc
2015/06/30 13:08:06
Seems like you would want to fix this as well
pbos-webrtc
2015/06/30 13:11:33
Covered by size != 0 check in ::Parse.
| |
56 if (nal_type == kStapA) { | 56 if (nal_type == kStapA) { |
57 // Skip the StapA header (StapA nal type + length). | 57 // Skip the StapA header (StapA nal type + length). |
58 nal_type = payload_data[kStapAHeaderSize] & kTypeMask; | 58 nal_type = payload_data[kStapAHeaderSize] & kTypeMask; |
stefan-webrtc
2015/06/30 13:13:18
Is this also safe?
pbos-webrtc
2015/06/30 13:16:37
No, merging in changes from another CL which fit h
| |
59 nalu_start += kStapAHeaderSize; | 59 nalu_start += kStapAHeaderSize; |
60 nalu_length -= kStapAHeaderSize; | 60 nalu_length -= kStapAHeaderSize; |
61 h264_header->packetization_type = kH264StapA; | 61 h264_header->packetization_type = kH264StapA; |
62 } else { | 62 } else { |
63 h264_header->packetization_type = kH264SingleNalu; | 63 h264_header->packetization_type = kH264SingleNalu; |
64 } | 64 } |
65 h264_header->nalu_type = nal_type; | 65 h264_header->nalu_type = nal_type; |
66 | 66 |
67 // We can read resolution out of sps packets. | 67 // We can read resolution out of sps packets. |
68 if (nal_type == kSps) { | 68 if (nal_type == kSps) { |
69 H264SpsParser parser(nalu_start, nalu_length); | 69 H264SpsParser parser(nalu_start, nalu_length); |
70 if (parser.Parse()) { | 70 if (parser.Parse()) { |
71 parsed_payload->type.Video.width = parser.width(); | 71 parsed_payload->type.Video.width = parser.width(); |
72 parsed_payload->type.Video.height = parser.height(); | 72 parsed_payload->type.Video.height = parser.height(); |
73 } | 73 } |
74 } | 74 } |
75 switch (nal_type) { | 75 switch (nal_type) { |
76 case kSps: | 76 case kSps: |
77 case kPps: | 77 case kPps: |
78 case kIdr: | 78 case kIdr: |
79 parsed_payload->frame_type = kVideoFrameKey; | 79 parsed_payload->frame_type = kVideoFrameKey; |
80 break; | 80 break; |
81 default: | 81 default: |
82 parsed_payload->frame_type = kVideoFrameDelta; | 82 parsed_payload->frame_type = kVideoFrameDelta; |
83 break; | 83 break; |
84 } | 84 } |
85 } | 85 } |
86 | 86 |
87 void ParseFuaNalu(RtpDepacketizer::ParsedPayload* parsed_payload, | 87 bool ParseFuaNalu(RtpDepacketizer::ParsedPayload* parsed_payload, |
88 const uint8_t* payload_data, | 88 const uint8_t* payload_data, |
89 size_t payload_data_length, | 89 size_t payload_data_length, |
90 size_t* offset) { | 90 size_t* offset) { |
91 if (payload_data_length < kFuAHeaderSize) { | |
92 LOG(LS_ERROR) << "FU-A NAL units truncated."; | |
93 return false; | |
94 } | |
91 uint8_t fnri = payload_data[0] & (kFBit | kNriMask); | 95 uint8_t fnri = payload_data[0] & (kFBit | kNriMask); |
92 uint8_t original_nal_type = payload_data[1] & kTypeMask; | 96 uint8_t original_nal_type = payload_data[1] & kTypeMask; |
93 bool first_fragment = (payload_data[1] & kSBit) > 0; | 97 bool first_fragment = (payload_data[1] & kSBit) > 0; |
94 | 98 |
95 uint8_t original_nal_header = fnri | original_nal_type; | 99 uint8_t original_nal_header = fnri | original_nal_type; |
96 if (first_fragment) { | 100 if (first_fragment) { |
97 *offset = kNalHeaderSize; | 101 *offset = kNalHeaderSize; |
98 uint8_t* payload = const_cast<uint8_t*>(payload_data + *offset); | 102 uint8_t* payload = const_cast<uint8_t*>(payload_data + *offset); |
99 payload[0] = original_nal_header; | 103 payload[0] = original_nal_header; |
100 } else { | 104 } else { |
101 *offset = kFuAHeaderSize; | 105 *offset = kFuAHeaderSize; |
102 } | 106 } |
103 | 107 |
104 if (original_nal_type == kIdr) { | 108 if (original_nal_type == kIdr) { |
105 parsed_payload->frame_type = kVideoFrameKey; | 109 parsed_payload->frame_type = kVideoFrameKey; |
106 } else { | 110 } else { |
107 parsed_payload->frame_type = kVideoFrameDelta; | 111 parsed_payload->frame_type = kVideoFrameDelta; |
108 } | 112 } |
109 parsed_payload->type.Video.width = 0; | 113 parsed_payload->type.Video.width = 0; |
110 parsed_payload->type.Video.height = 0; | 114 parsed_payload->type.Video.height = 0; |
111 parsed_payload->type.Video.codec = kRtpVideoH264; | 115 parsed_payload->type.Video.codec = kRtpVideoH264; |
112 parsed_payload->type.Video.isFirstPacket = first_fragment; | 116 parsed_payload->type.Video.isFirstPacket = first_fragment; |
113 RTPVideoHeaderH264* h264_header = | 117 RTPVideoHeaderH264* h264_header = |
114 &parsed_payload->type.Video.codecHeader.H264; | 118 &parsed_payload->type.Video.codecHeader.H264; |
115 h264_header->packetization_type = kH264FuA; | 119 h264_header->packetization_type = kH264FuA; |
116 h264_header->nalu_type = original_nal_type; | 120 h264_header->nalu_type = original_nal_type; |
121 return true; | |
117 } | 122 } |
118 } // namespace | 123 } // namespace |
119 | 124 |
120 RtpPacketizerH264::RtpPacketizerH264(FrameType frame_type, | 125 RtpPacketizerH264::RtpPacketizerH264(FrameType frame_type, |
121 size_t max_payload_len) | 126 size_t max_payload_len) |
122 : payload_data_(NULL), | 127 : payload_data_(NULL), |
123 payload_size_(0), | 128 payload_size_(0), |
124 max_payload_len_(max_payload_len), | 129 max_payload_len_(max_payload_len), |
125 frame_type_(frame_type) { | 130 frame_type_(frame_type) { |
126 } | 131 } |
(...skipping 192 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
319 assert(parsed_payload != NULL); | 324 assert(parsed_payload != NULL); |
320 if (payload_data_length == 0) { | 325 if (payload_data_length == 0) { |
321 LOG(LS_ERROR) << "Empty payload."; | 326 LOG(LS_ERROR) << "Empty payload."; |
322 return false; | 327 return false; |
323 } | 328 } |
324 | 329 |
325 uint8_t nal_type = payload_data[0] & kTypeMask; | 330 uint8_t nal_type = payload_data[0] & kTypeMask; |
326 size_t offset = 0; | 331 size_t offset = 0; |
327 if (nal_type == kFuA) { | 332 if (nal_type == kFuA) { |
328 // Fragmented NAL units (FU-A). | 333 // Fragmented NAL units (FU-A). |
329 ParseFuaNalu(parsed_payload, payload_data, payload_data_length, &offset); | 334 if (!ParseFuaNalu( |
335 parsed_payload, payload_data, payload_data_length, &offset)) { | |
336 return false; | |
337 } | |
330 } else { | 338 } else { |
331 // We handle STAP-A and single NALU's the same way here. The jitter buffer | 339 // We handle STAP-A and single NALU's the same way here. The jitter buffer |
332 // will depacketize the STAP-A into NAL units later. | 340 // will depacketize the STAP-A into NAL units later. |
333 ParseSingleNalu(parsed_payload, payload_data, payload_data_length); | 341 ParseSingleNalu(parsed_payload, payload_data, payload_data_length); |
334 } | 342 } |
335 | 343 |
336 parsed_payload->payload = payload_data + offset; | 344 parsed_payload->payload = payload_data + offset; |
337 parsed_payload->payload_length = payload_data_length - offset; | 345 parsed_payload->payload_length = payload_data_length - offset; |
338 return true; | 346 return true; |
339 } | 347 } |
340 } // namespace webrtc | 348 } // namespace webrtc |
OLD | NEW |