OLD | NEW |
---|---|
(Empty) | |
1 /* | |
2 * Copyright (c) 2016 The WebRTC project authors. All Rights Reserved. | |
3 * | |
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 | |
6 * tree. An additional intellectual property rights grant can be found | |
7 * in the file PATENTS. All contributing project authors may | |
8 * be found in the AUTHORS file in the root of the source tree. | |
9 */ | |
10 | |
11 #include "webrtc/modules/rtp_rtcp/source/h264/h264_common.h" | |
12 | |
13 namespace webrtc { | |
14 | |
15 const size_t H264Common::kNaluHeaderSize = 4; | |
16 const size_t H264Common::kNaluHeaderAndTypeSize = kNaluHeaderSize + 1; | |
17 const uint8_t kNaluTypeMask = 0x1F; | |
18 | |
19 std::vector<size_t> H264Common::FindNaluStartOffsets(const uint8_t* buffer, | |
20 size_t buffer_size) { | |
21 // This is sorta like Boyer-Moore, but with only the first optimization step: | |
22 // given a 4-byte sequence we're looking at, if the 4th byte isn't 1 or 0, | |
23 // skip ahead to the next 4-byte sequence. 0s and 1s are relatively rare, so | |
24 // this will skip the majority of reads/checks. | |
25 RTC_CHECK_GE(buffer_size, kNaluHeaderSize); | |
26 std::vector<size_t> sequences; | |
27 const uint8_t* end = buffer + buffer_size - 4; | |
28 for (const uint8_t* head = buffer; head < end;) { | |
29 if (head[3] > 1) { | |
30 head += 4; | |
31 } else if (head[3] == 1 && head[2] == 0 && head[1] == 0 && head[0] == 0) { | |
32 sequences.push_back(static_cast<size_t>(head - buffer)); | |
33 head += 4; | |
34 } else { | |
35 head++; | |
36 } | |
37 } | |
38 | |
39 return sequences; | |
40 } | |
41 | |
42 H264Common::NaluType webrtc::H264Common::ParseNaluType(uint8_t data) { | |
43 return static_cast<NaluType>(data & kNaluTypeMask); | |
44 } | |
45 | |
46 std::unique_ptr<rtc::ByteBufferWriter> webrtc::H264Common::ParseRbsp( | |
47 const uint8_t* data, | |
48 size_t length) { | |
49 // First, parse out rbsp, which is basically the source buffer minus emulation | |
50 // bytes (the last byte of a 0x00 0x00 0x03 sequence). RBSP is defined in | |
51 // section 7.3.1 of the H.264 standard. | |
52 std::unique_ptr<rtc::ByteBufferWriter> rbsp_buffer( | |
53 new rtc::ByteBufferWriter()); | |
54 const char* sps_bytes = reinterpret_cast<const char*>(data); | |
55 for (size_t i = 0; i < length;) { | |
56 // Be careful about over/underflow here. byte_length_ - 3 can underflow, and | |
57 // i + 3 can overflow, but byte_length_ - i can't, because i < byte_length_ | |
58 // above, and that expression will produce the number of bytes left in | |
59 // the stream including the byte at i. | |
60 if (length - i >= 3 && data[i] == 0 && data[i + 1] == 0 && | |
61 data[i + 2] == 3) { | |
62 // Two rbsp bytes + the emulation byte. | |
63 rbsp_buffer->WriteBytes(sps_bytes + i, 2); | |
64 i += 3; | |
65 } else { | |
66 // Single rbsp byte. | |
67 rbsp_buffer->WriteBytes(sps_bytes + i, 1); | |
68 i++; | |
69 } | |
70 } | |
71 return rbsp_buffer; | |
72 } | |
73 | |
74 // Writes bytes into RBSP, adding emulation (0x03) bytes where necessary. Also | |
75 // removes trailing empty bytes. | |
76 void webrtc::H264Common::WriteRbsp(const uint8_t* bytes, | |
77 size_t length, | |
78 rtc::ByteBufferWriter* destination) { | |
79 // Walk length backwards to remove any empty bytes at the end. | |
noahric
2016/05/18 01:35:06
I don't remember if that's generally correct. It w
sprang_webrtc
2016/05/20 16:11:00
Changed things around so this isn't necessary anym
| |
80 while (length > 0 && bytes[length - 1] == 0) | |
noahric
2016/05/18 01:35:06
Man, webrtc engineers and hating on braces for sin
sprang_webrtc
2016/05/20 16:11:00
I've been slapping in the back of the head by Pete
noahric
2016/05/26 18:56:52
I'd slap him back for you, except geography interv
| |
81 --length; | |
82 | |
83 bool last_byte_was_null = false; | |
84 for (size_t i = 0; i < length; ++i) { | |
85 uint8_t byte = bytes[i]; | |
86 destination->WriteUInt8(byte); | |
87 if (byte == 0) { | |
88 if (last_byte_was_null) { | |
89 destination->WriteUInt8(0x03u); | |
90 last_byte_was_null = false; | |
91 } else { | |
92 last_byte_was_null = true; | |
93 } | |
94 } else { | |
95 last_byte_was_null = false; | |
96 } | |
97 } | |
98 } | |
99 | |
100 } // namespace webrtc | |
OLD | NEW |