OLD | NEW |
1 /* | 1 /* |
2 * Copyright (c) 2015 The WebRTC project authors. All Rights Reserved. | 2 * Copyright (c) 2015 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 */ |
11 | 11 |
12 #include "webrtc/modules/video_coding/codecs/h264/h264_video_toolbox_nalu.h" | 12 #include "webrtc/modules/video_coding/codecs/h264/h264_video_toolbox_nalu.h" |
13 | 13 |
14 #if defined(WEBRTC_VIDEO_TOOLBOX_SUPPORTED) | 14 #if defined(WEBRTC_VIDEO_TOOLBOX_SUPPORTED) |
15 | 15 |
16 #include <CoreFoundation/CoreFoundation.h> | 16 #include <CoreFoundation/CoreFoundation.h> |
17 #include <memory> | 17 #include <memory> |
18 #include <vector> | 18 #include <vector> |
19 | 19 |
20 #include "webrtc/base/checks.h" | 20 #include "webrtc/base/checks.h" |
21 #include "webrtc/base/logging.h" | 21 #include "webrtc/base/logging.h" |
| 22 #include "webrtc/common_video/h264/h264_common.h" |
22 | 23 |
23 namespace webrtc { | 24 namespace webrtc { |
24 | 25 |
| 26 using H264::NaluType; |
| 27 using H264::kAud; |
| 28 using H264::kSps; |
| 29 using H264::ParseNaluType; |
| 30 |
25 const char kAnnexBHeaderBytes[4] = {0, 0, 0, 1}; | 31 const char kAnnexBHeaderBytes[4] = {0, 0, 0, 1}; |
26 const size_t kAvccHeaderByteSize = sizeof(uint32_t); | 32 const size_t kAvccHeaderByteSize = sizeof(uint32_t); |
27 | 33 |
28 bool H264CMSampleBufferToAnnexBBuffer( | 34 bool H264CMSampleBufferToAnnexBBuffer( |
29 CMSampleBufferRef avcc_sample_buffer, | 35 CMSampleBufferRef avcc_sample_buffer, |
30 bool is_keyframe, | 36 bool is_keyframe, |
31 rtc::Buffer* annexb_buffer, | 37 rtc::Buffer* annexb_buffer, |
32 webrtc::RTPFragmentationHeader** out_header) { | 38 webrtc::RTPFragmentationHeader** out_header) { |
33 RTC_DCHECK(avcc_sample_buffer); | 39 RTC_DCHECK(avcc_sample_buffer); |
34 RTC_DCHECK(out_header); | 40 RTC_DCHECK(out_header); |
(...skipping 211 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
246 | 252 |
247 bool H264AnnexBBufferHasVideoFormatDescription(const uint8_t* annexb_buffer, | 253 bool H264AnnexBBufferHasVideoFormatDescription(const uint8_t* annexb_buffer, |
248 size_t annexb_buffer_size) { | 254 size_t annexb_buffer_size) { |
249 RTC_DCHECK(annexb_buffer); | 255 RTC_DCHECK(annexb_buffer); |
250 RTC_DCHECK_GT(annexb_buffer_size, 4u); | 256 RTC_DCHECK_GT(annexb_buffer_size, 4u); |
251 | 257 |
252 // The buffer we receive via RTP has 00 00 00 01 start code artifically | 258 // The buffer we receive via RTP has 00 00 00 01 start code artifically |
253 // embedded by the RTP depacketizer. Extract NALU information. | 259 // embedded by the RTP depacketizer. Extract NALU information. |
254 // TODO(tkchin): handle potential case where sps and pps are delivered | 260 // TODO(tkchin): handle potential case where sps and pps are delivered |
255 // separately. | 261 // separately. |
256 uint8_t first_nalu_type = annexb_buffer[4] & 0x1f; | 262 NaluType first_nalu_type = ParseNaluType(annexb_buffer[4]); |
257 bool is_first_nalu_type_sps = first_nalu_type == 0x7; | 263 bool is_first_nalu_type_sps = first_nalu_type == kSps; |
258 return is_first_nalu_type_sps; | 264 if (is_first_nalu_type_sps) |
| 265 return true; |
| 266 bool is_first_nalu_type_aud = first_nalu_type == kAud; |
| 267 // Start code + access unit delimiter + start code = 4 + 2 + 4 = 10. |
| 268 if (!is_first_nalu_type_aud || annexb_buffer_size <= 10u) |
| 269 return false; |
| 270 NaluType second_nalu_type = ParseNaluType(annexb_buffer[10]); |
| 271 bool is_second_nalu_type_sps = second_nalu_type == kSps; |
| 272 return is_second_nalu_type_sps; |
259 } | 273 } |
260 | 274 |
261 CMVideoFormatDescriptionRef CreateVideoFormatDescription( | 275 CMVideoFormatDescriptionRef CreateVideoFormatDescription( |
262 const uint8_t* annexb_buffer, | 276 const uint8_t* annexb_buffer, |
263 size_t annexb_buffer_size) { | 277 size_t annexb_buffer_size) { |
264 if (!H264AnnexBBufferHasVideoFormatDescription(annexb_buffer, | 278 if (!H264AnnexBBufferHasVideoFormatDescription(annexb_buffer, |
265 annexb_buffer_size)) { | 279 annexb_buffer_size)) { |
266 return nullptr; | 280 return nullptr; |
267 } | 281 } |
268 AnnexBBufferReader reader(annexb_buffer, annexb_buffer_size); | 282 AnnexBBufferReader reader(annexb_buffer, annexb_buffer_size); |
269 CMVideoFormatDescriptionRef description = nullptr; | 283 CMVideoFormatDescriptionRef description = nullptr; |
270 OSStatus status = noErr; | 284 OSStatus status = noErr; |
271 // Parse the SPS and PPS into a CMVideoFormatDescription. | 285 // Parse the SPS and PPS into a CMVideoFormatDescription. |
272 const uint8_t* param_set_ptrs[2] = {}; | 286 const uint8_t* param_set_ptrs[2] = {}; |
273 size_t param_set_sizes[2] = {}; | 287 size_t param_set_sizes[2] = {}; |
| 288 // Skip AUD. |
| 289 if (ParseNaluType(annexb_buffer[4]) == kAud) { |
| 290 if (!reader.ReadNalu(¶m_set_ptrs[0], ¶m_set_sizes[0])) { |
| 291 LOG(LS_ERROR) << "Failed to read AUD"; |
| 292 return nullptr; |
| 293 } |
| 294 } |
274 if (!reader.ReadNalu(¶m_set_ptrs[0], ¶m_set_sizes[0])) { | 295 if (!reader.ReadNalu(¶m_set_ptrs[0], ¶m_set_sizes[0])) { |
275 LOG(LS_ERROR) << "Failed to read SPS"; | 296 LOG(LS_ERROR) << "Failed to read SPS"; |
276 return nullptr; | 297 return nullptr; |
277 } | 298 } |
278 if (!reader.ReadNalu(¶m_set_ptrs[1], ¶m_set_sizes[1])) { | 299 if (!reader.ReadNalu(¶m_set_ptrs[1], ¶m_set_sizes[1])) { |
279 LOG(LS_ERROR) << "Failed to read PPS"; | 300 LOG(LS_ERROR) << "Failed to read PPS"; |
280 return nullptr; | 301 return nullptr; |
281 } | 302 } |
282 status = CMVideoFormatDescriptionCreateFromH264ParameterSets( | 303 status = CMVideoFormatDescriptionCreateFromH264ParameterSets( |
283 kCFAllocatorDefault, 2, param_set_ptrs, param_set_sizes, 4, | 304 kCFAllocatorDefault, 2, param_set_ptrs, param_set_sizes, 4, |
(...skipping 83 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
367 return true; | 388 return true; |
368 } | 389 } |
369 | 390 |
370 size_t AvccBufferWriter::BytesRemaining() const { | 391 size_t AvccBufferWriter::BytesRemaining() const { |
371 return length_ - offset_; | 392 return length_ - offset_; |
372 } | 393 } |
373 | 394 |
374 } // namespace webrtc | 395 } // namespace webrtc |
375 | 396 |
376 #endif // defined(WEBRTC_VIDEO_TOOLBOX_SUPPORTED) | 397 #endif // defined(WEBRTC_VIDEO_TOOLBOX_SUPPORTED) |
OLD | NEW |