Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(477)

Side by Side Diff: webrtc/modules/video_coding/codecs/h264/h264_video_toolbox_nalu.cc

Issue 1335923002: Add RTC_ prefix to (D)CHECKs and related macros. (Closed) Base URL: https://chromium.googlesource.com/external/webrtc.git@master
Patch Set: Rebase. Created 5 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
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 */
(...skipping 11 matching lines...) Expand all
22 namespace webrtc { 22 namespace webrtc {
23 23
24 const char kAnnexBHeaderBytes[4] = {0, 0, 0, 1}; 24 const char kAnnexBHeaderBytes[4] = {0, 0, 0, 1};
25 const size_t kAvccHeaderByteSize = sizeof(uint32_t); 25 const size_t kAvccHeaderByteSize = sizeof(uint32_t);
26 26
27 bool H264CMSampleBufferToAnnexBBuffer( 27 bool H264CMSampleBufferToAnnexBBuffer(
28 CMSampleBufferRef avcc_sample_buffer, 28 CMSampleBufferRef avcc_sample_buffer,
29 bool is_keyframe, 29 bool is_keyframe,
30 rtc::Buffer* annexb_buffer, 30 rtc::Buffer* annexb_buffer,
31 webrtc::RTPFragmentationHeader** out_header) { 31 webrtc::RTPFragmentationHeader** out_header) {
32 DCHECK(avcc_sample_buffer); 32 RTC_DCHECK(avcc_sample_buffer);
33 DCHECK(out_header); 33 RTC_DCHECK(out_header);
34 *out_header = nullptr; 34 *out_header = nullptr;
35 35
36 // Get format description from the sample buffer. 36 // Get format description from the sample buffer.
37 CMVideoFormatDescriptionRef description = 37 CMVideoFormatDescriptionRef description =
38 CMSampleBufferGetFormatDescription(avcc_sample_buffer); 38 CMSampleBufferGetFormatDescription(avcc_sample_buffer);
39 if (description == nullptr) { 39 if (description == nullptr) {
40 LOG(LS_ERROR) << "Failed to get sample buffer's description."; 40 LOG(LS_ERROR) << "Failed to get sample buffer's description.";
41 return false; 41 return false;
42 } 42 }
43 43
44 // Get parameter set information. 44 // Get parameter set information.
45 int nalu_header_size = 0; 45 int nalu_header_size = 0;
46 size_t param_set_count = 0; 46 size_t param_set_count = 0;
47 OSStatus status = CMVideoFormatDescriptionGetH264ParameterSetAtIndex( 47 OSStatus status = CMVideoFormatDescriptionGetH264ParameterSetAtIndex(
48 description, 0, nullptr, nullptr, &param_set_count, &nalu_header_size); 48 description, 0, nullptr, nullptr, &param_set_count, &nalu_header_size);
49 if (status != noErr) { 49 if (status != noErr) {
50 LOG(LS_ERROR) << "Failed to get parameter set."; 50 LOG(LS_ERROR) << "Failed to get parameter set.";
51 return false; 51 return false;
52 } 52 }
53 // TODO(tkchin): handle other potential sizes. 53 // TODO(tkchin): handle other potential sizes.
54 DCHECK_EQ(nalu_header_size, 4); 54 RTC_DCHECK_EQ(nalu_header_size, 4);
55 DCHECK_EQ(param_set_count, 2u); 55 RTC_DCHECK_EQ(param_set_count, 2u);
56 56
57 // Truncate any previous data in the buffer without changing its capacity. 57 // Truncate any previous data in the buffer without changing its capacity.
58 annexb_buffer->SetSize(0); 58 annexb_buffer->SetSize(0);
59 59
60 size_t nalu_offset = 0; 60 size_t nalu_offset = 0;
61 std::vector<size_t> frag_offsets; 61 std::vector<size_t> frag_offsets;
62 std::vector<size_t> frag_lengths; 62 std::vector<size_t> frag_lengths;
63 63
64 // Place all parameter sets at the front of buffer. 64 // Place all parameter sets at the front of buffer.
65 if (is_keyframe) { 65 if (is_keyframe) {
(...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after
115 if (status != noErr) { 115 if (status != noErr) {
116 LOG(LS_ERROR) << "Failed to get block buffer data."; 116 LOG(LS_ERROR) << "Failed to get block buffer data.";
117 CFRelease(contiguous_buffer); 117 CFRelease(contiguous_buffer);
118 return false; 118 return false;
119 } 119 }
120 size_t bytes_remaining = block_buffer_size; 120 size_t bytes_remaining = block_buffer_size;
121 while (bytes_remaining > 0) { 121 while (bytes_remaining > 0) {
122 // The size type here must match |nalu_header_size|, we expect 4 bytes. 122 // The size type here must match |nalu_header_size|, we expect 4 bytes.
123 // Read the length of the next packet of data. Must convert from big endian 123 // Read the length of the next packet of data. Must convert from big endian
124 // to host endian. 124 // to host endian.
125 DCHECK_GE(bytes_remaining, (size_t)nalu_header_size); 125 RTC_DCHECK_GE(bytes_remaining, (size_t)nalu_header_size);
126 uint32_t* uint32_data_ptr = reinterpret_cast<uint32*>(data_ptr); 126 uint32_t* uint32_data_ptr = reinterpret_cast<uint32*>(data_ptr);
127 uint32_t packet_size = CFSwapInt32BigToHost(*uint32_data_ptr); 127 uint32_t packet_size = CFSwapInt32BigToHost(*uint32_data_ptr);
128 // Update buffer. 128 // Update buffer.
129 annexb_buffer->AppendData(kAnnexBHeaderBytes, sizeof(kAnnexBHeaderBytes)); 129 annexb_buffer->AppendData(kAnnexBHeaderBytes, sizeof(kAnnexBHeaderBytes));
130 annexb_buffer->AppendData(data_ptr + nalu_header_size, packet_size); 130 annexb_buffer->AppendData(data_ptr + nalu_header_size, packet_size);
131 // Update fragmentation. 131 // Update fragmentation.
132 frag_offsets.push_back(nalu_offset + sizeof(kAnnexBHeaderBytes)); 132 frag_offsets.push_back(nalu_offset + sizeof(kAnnexBHeaderBytes));
133 frag_lengths.push_back(packet_size); 133 frag_lengths.push_back(packet_size);
134 nalu_offset += sizeof(kAnnexBHeaderBytes) + packet_size; 134 nalu_offset += sizeof(kAnnexBHeaderBytes) + packet_size;
135 135
136 size_t bytes_written = packet_size + nalu_header_size; 136 size_t bytes_written = packet_size + nalu_header_size;
137 bytes_remaining -= bytes_written; 137 bytes_remaining -= bytes_written;
138 data_ptr += bytes_written; 138 data_ptr += bytes_written;
139 } 139 }
140 DCHECK_EQ(bytes_remaining, (size_t)0); 140 RTC_DCHECK_EQ(bytes_remaining, (size_t)0);
141 141
142 rtc::scoped_ptr<webrtc::RTPFragmentationHeader> header; 142 rtc::scoped_ptr<webrtc::RTPFragmentationHeader> header;
143 header.reset(new webrtc::RTPFragmentationHeader()); 143 header.reset(new webrtc::RTPFragmentationHeader());
144 header->VerifyAndAllocateFragmentationHeader(frag_offsets.size()); 144 header->VerifyAndAllocateFragmentationHeader(frag_offsets.size());
145 DCHECK_EQ(frag_lengths.size(), frag_offsets.size()); 145 RTC_DCHECK_EQ(frag_lengths.size(), frag_offsets.size());
146 for (size_t i = 0; i < frag_offsets.size(); ++i) { 146 for (size_t i = 0; i < frag_offsets.size(); ++i) {
147 header->fragmentationOffset[i] = frag_offsets[i]; 147 header->fragmentationOffset[i] = frag_offsets[i];
148 header->fragmentationLength[i] = frag_lengths[i]; 148 header->fragmentationLength[i] = frag_lengths[i];
149 header->fragmentationPlType[i] = 0; 149 header->fragmentationPlType[i] = 0;
150 header->fragmentationTimeDiff[i] = 0; 150 header->fragmentationTimeDiff[i] = 0;
151 } 151 }
152 *out_header = header.release(); 152 *out_header = header.release();
153 CFRelease(contiguous_buffer); 153 CFRelease(contiguous_buffer);
154 return true; 154 return true;
155 } 155 }
156 156
157 bool H264AnnexBBufferToCMSampleBuffer( 157 bool H264AnnexBBufferToCMSampleBuffer(
158 const uint8_t* annexb_buffer, 158 const uint8_t* annexb_buffer,
159 size_t annexb_buffer_size, 159 size_t annexb_buffer_size,
160 CMVideoFormatDescriptionRef video_format, 160 CMVideoFormatDescriptionRef video_format,
161 CMSampleBufferRef* out_sample_buffer) { 161 CMSampleBufferRef* out_sample_buffer) {
162 DCHECK(annexb_buffer); 162 RTC_DCHECK(annexb_buffer);
163 DCHECK(out_sample_buffer); 163 RTC_DCHECK(out_sample_buffer);
164 *out_sample_buffer = nullptr; 164 *out_sample_buffer = nullptr;
165 165
166 // The buffer we receive via RTP has 00 00 00 01 start code artifically 166 // The buffer we receive via RTP has 00 00 00 01 start code artifically
167 // embedded by the RTP depacketizer. Extract NALU information. 167 // embedded by the RTP depacketizer. Extract NALU information.
168 // TODO(tkchin): handle potential case where sps and pps are delivered 168 // TODO(tkchin): handle potential case where sps and pps are delivered
169 // separately. 169 // separately.
170 uint8_t first_nalu_type = annexb_buffer[4] & 0x1f; 170 uint8_t first_nalu_type = annexb_buffer[4] & 0x1f;
171 bool is_first_nalu_type_sps = first_nalu_type == 0x7; 171 bool is_first_nalu_type_sps = first_nalu_type == 0x7;
172 172
173 AnnexBBufferReader reader(annexb_buffer, annexb_buffer_size); 173 AnnexBBufferReader reader(annexb_buffer, annexb_buffer_size);
(...skipping 12 matching lines...) Expand all
186 return false; 186 return false;
187 } 187 }
188 status = CMVideoFormatDescriptionCreateFromH264ParameterSets( 188 status = CMVideoFormatDescriptionCreateFromH264ParameterSets(
189 kCFAllocatorDefault, 2, param_set_ptrs, param_set_sizes, 4, 189 kCFAllocatorDefault, 2, param_set_ptrs, param_set_sizes, 4,
190 &description); 190 &description);
191 if (status != noErr) { 191 if (status != noErr) {
192 LOG(LS_ERROR) << "Failed to create video format description."; 192 LOG(LS_ERROR) << "Failed to create video format description.";
193 return false; 193 return false;
194 } 194 }
195 } else { 195 } else {
196 DCHECK(video_format); 196 RTC_DCHECK(video_format);
197 description = video_format; 197 description = video_format;
198 // We don't need to retain, but it makes logic easier since we are creating 198 // We don't need to retain, but it makes logic easier since we are creating
199 // in the other block. 199 // in the other block.
200 CFRetain(description); 200 CFRetain(description);
201 } 201 }
202 202
203 // Allocate memory as a block buffer. 203 // Allocate memory as a block buffer.
204 // TODO(tkchin): figure out how to use a pool. 204 // TODO(tkchin): figure out how to use a pool.
205 CMBlockBufferRef block_buffer = nullptr; 205 CMBlockBufferRef block_buffer = nullptr;
206 status = CMBlockBufferCreateWithMemoryBlock( 206 status = CMBlockBufferCreateWithMemoryBlock(
(...skipping 27 matching lines...) Expand all
234 size_t block_buffer_size = 0; 234 size_t block_buffer_size = 0;
235 char* data_ptr = nullptr; 235 char* data_ptr = nullptr;
236 status = CMBlockBufferGetDataPointer(contiguous_buffer, 0, nullptr, 236 status = CMBlockBufferGetDataPointer(contiguous_buffer, 0, nullptr,
237 &block_buffer_size, &data_ptr); 237 &block_buffer_size, &data_ptr);
238 if (status != kCMBlockBufferNoErr) { 238 if (status != kCMBlockBufferNoErr) {
239 LOG(LS_ERROR) << "Failed to get block buffer data pointer."; 239 LOG(LS_ERROR) << "Failed to get block buffer data pointer.";
240 CFRelease(description); 240 CFRelease(description);
241 CFRelease(contiguous_buffer); 241 CFRelease(contiguous_buffer);
242 return false; 242 return false;
243 } 243 }
244 DCHECK(block_buffer_size == reader.BytesRemaining()); 244 RTC_DCHECK(block_buffer_size == reader.BytesRemaining());
245 245
246 // Write Avcc NALUs into block buffer memory. 246 // Write Avcc NALUs into block buffer memory.
247 AvccBufferWriter writer(reinterpret_cast<uint8_t*>(data_ptr), 247 AvccBufferWriter writer(reinterpret_cast<uint8_t*>(data_ptr),
248 block_buffer_size); 248 block_buffer_size);
249 while (reader.BytesRemaining() > 0) { 249 while (reader.BytesRemaining() > 0) {
250 const uint8_t* nalu_data_ptr = nullptr; 250 const uint8_t* nalu_data_ptr = nullptr;
251 size_t nalu_data_size = 0; 251 size_t nalu_data_size = 0;
252 if (reader.ReadNalu(&nalu_data_ptr, &nalu_data_size)) { 252 if (reader.ReadNalu(&nalu_data_ptr, &nalu_data_size)) {
253 writer.WriteNalu(nalu_data_ptr, nalu_data_size); 253 writer.WriteNalu(nalu_data_ptr, nalu_data_size);
254 } 254 }
(...skipping 10 matching lines...) Expand all
265 return false; 265 return false;
266 } 266 }
267 CFRelease(description); 267 CFRelease(description);
268 CFRelease(contiguous_buffer); 268 CFRelease(contiguous_buffer);
269 return true; 269 return true;
270 } 270 }
271 271
272 AnnexBBufferReader::AnnexBBufferReader(const uint8_t* annexb_buffer, 272 AnnexBBufferReader::AnnexBBufferReader(const uint8_t* annexb_buffer,
273 size_t length) 273 size_t length)
274 : start_(annexb_buffer), offset_(0), next_offset_(0), length_(length) { 274 : start_(annexb_buffer), offset_(0), next_offset_(0), length_(length) {
275 DCHECK(annexb_buffer); 275 RTC_DCHECK(annexb_buffer);
276 offset_ = FindNextNaluHeader(start_, length_, 0); 276 offset_ = FindNextNaluHeader(start_, length_, 0);
277 next_offset_ = 277 next_offset_ =
278 FindNextNaluHeader(start_, length_, offset_ + sizeof(kAnnexBHeaderBytes)); 278 FindNextNaluHeader(start_, length_, offset_ + sizeof(kAnnexBHeaderBytes));
279 } 279 }
280 280
281 bool AnnexBBufferReader::ReadNalu(const uint8_t** out_nalu, 281 bool AnnexBBufferReader::ReadNalu(const uint8_t** out_nalu,
282 size_t* out_length) { 282 size_t* out_length) {
283 DCHECK(out_nalu); 283 RTC_DCHECK(out_nalu);
284 DCHECK(out_length); 284 RTC_DCHECK(out_length);
285 *out_nalu = nullptr; 285 *out_nalu = nullptr;
286 *out_length = 0; 286 *out_length = 0;
287 287
288 size_t data_offset = offset_ + sizeof(kAnnexBHeaderBytes); 288 size_t data_offset = offset_ + sizeof(kAnnexBHeaderBytes);
289 if (data_offset > length_) { 289 if (data_offset > length_) {
290 return false; 290 return false;
291 } 291 }
292 *out_nalu = start_ + data_offset; 292 *out_nalu = start_ + data_offset;
293 *out_length = next_offset_ - data_offset; 293 *out_length = next_offset_ - data_offset;
294 offset_ = next_offset_; 294 offset_ = next_offset_;
295 next_offset_ = 295 next_offset_ =
296 FindNextNaluHeader(start_, length_, offset_ + sizeof(kAnnexBHeaderBytes)); 296 FindNextNaluHeader(start_, length_, offset_ + sizeof(kAnnexBHeaderBytes));
297 return true; 297 return true;
298 } 298 }
299 299
300 size_t AnnexBBufferReader::BytesRemaining() const { 300 size_t AnnexBBufferReader::BytesRemaining() const {
301 return length_ - offset_; 301 return length_ - offset_;
302 } 302 }
303 303
304 size_t AnnexBBufferReader::FindNextNaluHeader(const uint8_t* start, 304 size_t AnnexBBufferReader::FindNextNaluHeader(const uint8_t* start,
305 size_t length, 305 size_t length,
306 size_t offset) const { 306 size_t offset) const {
307 DCHECK(start); 307 RTC_DCHECK(start);
308 if (offset + sizeof(kAnnexBHeaderBytes) > length) { 308 if (offset + sizeof(kAnnexBHeaderBytes) > length) {
309 return length; 309 return length;
310 } 310 }
311 // NALUs are separated by an 00 00 00 01 header. Scan the byte stream 311 // NALUs are separated by an 00 00 00 01 header. Scan the byte stream
312 // starting from the offset for the next such sequence. 312 // starting from the offset for the next such sequence.
313 const uint8_t* current = start + offset; 313 const uint8_t* current = start + offset;
314 // The loop reads sizeof(kAnnexBHeaderBytes) at a time, so stop when there 314 // The loop reads sizeof(kAnnexBHeaderBytes) at a time, so stop when there
315 // aren't enough bytes remaining. 315 // aren't enough bytes remaining.
316 const uint8_t* const end = start + length - sizeof(kAnnexBHeaderBytes); 316 const uint8_t* const end = start + length - sizeof(kAnnexBHeaderBytes);
317 while (current < end) { 317 while (current < end) {
318 if (current[3] > 1) { 318 if (current[3] > 1) {
319 current += 4; 319 current += 4;
320 } else if (current[3] == 1 && current[2] == 0 && current[1] == 0 && 320 } else if (current[3] == 1 && current[2] == 0 && current[1] == 0 &&
321 current[0] == 0) { 321 current[0] == 0) {
322 return current - start; 322 return current - start;
323 } else { 323 } else {
324 ++current; 324 ++current;
325 } 325 }
326 } 326 }
327 return length; 327 return length;
328 } 328 }
329 329
330 AvccBufferWriter::AvccBufferWriter(uint8_t* const avcc_buffer, size_t length) 330 AvccBufferWriter::AvccBufferWriter(uint8_t* const avcc_buffer, size_t length)
331 : start_(avcc_buffer), offset_(0), length_(length) { 331 : start_(avcc_buffer), offset_(0), length_(length) {
332 DCHECK(avcc_buffer); 332 RTC_DCHECK(avcc_buffer);
333 } 333 }
334 334
335 bool AvccBufferWriter::WriteNalu(const uint8_t* data, size_t data_size) { 335 bool AvccBufferWriter::WriteNalu(const uint8_t* data, size_t data_size) {
336 // Check if we can write this length of data. 336 // Check if we can write this length of data.
337 if (data_size + kAvccHeaderByteSize > BytesRemaining()) { 337 if (data_size + kAvccHeaderByteSize > BytesRemaining()) {
338 return false; 338 return false;
339 } 339 }
340 // Write length header, which needs to be big endian. 340 // Write length header, which needs to be big endian.
341 uint32_t big_endian_length = CFSwapInt32HostToBig(data_size); 341 uint32_t big_endian_length = CFSwapInt32HostToBig(data_size);
342 memcpy(start_ + offset_, &big_endian_length, sizeof(big_endian_length)); 342 memcpy(start_ + offset_, &big_endian_length, sizeof(big_endian_length));
343 offset_ += sizeof(big_endian_length); 343 offset_ += sizeof(big_endian_length);
344 // Write data. 344 // Write data.
345 memcpy(start_ + offset_, data, data_size); 345 memcpy(start_ + offset_, data, data_size);
346 offset_ += data_size; 346 offset_ += data_size;
347 return true; 347 return true;
348 } 348 }
349 349
350 size_t AvccBufferWriter::BytesRemaining() const { 350 size_t AvccBufferWriter::BytesRemaining() const {
351 return length_ - offset_; 351 return length_ - offset_;
352 } 352 }
353 353
354 } // namespace webrtc 354 } // namespace webrtc
355 355
356 #endif // defined(WEBRTC_VIDEO_TOOLBOX_SUPPORTED) 356 #endif // defined(WEBRTC_VIDEO_TOOLBOX_SUPPORTED)
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698