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 <CoreVideo/CoreVideo.h> | 5 #include <CoreVideo/CoreVideo.h> |
6 #include <OpenGL/CGLIOSurface.h> | 6 #include <OpenGL/CGLIOSurface.h> |
7 #include <OpenGL/gl.h> | 7 #include <OpenGL/gl.h> |
8 | 8 |
9 #include "base/bind.h" | 9 #include "base/bind.h" |
10 #include "base/command_line.h" | 10 #include "base/command_line.h" |
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
61 int32_t bitstream_id) | 61 int32_t bitstream_id) |
62 : action(action), | 62 : action(action), |
63 bitstream_id(bitstream_id) { | 63 bitstream_id(bitstream_id) { |
64 } | 64 } |
65 | 65 |
66 VTVideoDecodeAccelerator::PendingAction::~PendingAction() { | 66 VTVideoDecodeAccelerator::PendingAction::~PendingAction() { |
67 } | 67 } |
68 | 68 |
69 VTVideoDecodeAccelerator::VTVideoDecodeAccelerator(CGLContextObj cgl_context) | 69 VTVideoDecodeAccelerator::VTVideoDecodeAccelerator(CGLContextObj cgl_context) |
70 : cgl_context_(cgl_context), | 70 : cgl_context_(cgl_context), |
71 client_(NULL), | 71 client_(nullptr), |
72 format_(NULL), | 72 format_(nullptr), |
73 session_(NULL), | 73 session_(nullptr), |
74 gpu_task_runner_(base::ThreadTaskRunnerHandle::Get()), | 74 gpu_task_runner_(base::ThreadTaskRunnerHandle::Get()), |
75 weak_this_factory_(this), | 75 weak_this_factory_(this), |
76 decoder_thread_("VTDecoderThread") { | 76 decoder_thread_("VTDecoderThread") { |
77 callback_.decompressionOutputCallback = OutputThunk; | 77 callback_.decompressionOutputCallback = OutputThunk; |
78 callback_.decompressionOutputRefCon = this; | 78 callback_.decompressionOutputRefCon = this; |
79 } | 79 } |
80 | 80 |
81 VTVideoDecodeAccelerator::~VTVideoDecodeAccelerator() { | 81 VTVideoDecodeAccelerator::~VTVideoDecodeAccelerator() { |
82 } | 82 } |
83 | 83 |
(...skipping 162 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
246 if (!session_) | 246 if (!session_) |
247 ConfigureDecoder(config_nalu_data_ptrs, config_nalu_data_sizes); | 247 ConfigureDecoder(config_nalu_data_ptrs, config_nalu_data_sizes); |
248 | 248 |
249 // If there are no non-configuration units, immediately return an empty | 249 // If there are no non-configuration units, immediately return an empty |
250 // (ie. dropped) frame. It is an error to create a MemoryBlock with zero | 250 // (ie. dropped) frame. It is an error to create a MemoryBlock with zero |
251 // size. | 251 // size. |
252 if (!data_size) { | 252 if (!data_size) { |
253 gpu_task_runner_->PostTask(FROM_HERE, base::Bind( | 253 gpu_task_runner_->PostTask(FROM_HERE, base::Bind( |
254 &VTVideoDecodeAccelerator::OutputTask, | 254 &VTVideoDecodeAccelerator::OutputTask, |
255 weak_this_factory_.GetWeakPtr(), | 255 weak_this_factory_.GetWeakPtr(), |
256 DecodedFrame(bitstream.id(), NULL))); | 256 DecodedFrame(bitstream.id(), nullptr))); |
257 return; | 257 return; |
258 } | 258 } |
259 | 259 |
260 // 3. Allocate a memory-backed CMBlockBuffer for the translated data. | 260 // 3. Allocate a memory-backed CMBlockBuffer for the translated data. |
261 base::ScopedCFTypeRef<CMBlockBufferRef> data; | 261 base::ScopedCFTypeRef<CMBlockBufferRef> data; |
262 CHECK(!CMBlockBufferCreateWithMemoryBlock( | 262 CHECK(!CMBlockBufferCreateWithMemoryBlock( |
263 kCFAllocatorDefault, | 263 kCFAllocatorDefault, |
264 NULL, // &memory_block | 264 nullptr, // &memory_block |
265 data_size, // block_length | 265 data_size, // block_length |
266 kCFAllocatorDefault, // block_allocator | 266 kCFAllocatorDefault, // block_allocator |
267 NULL, // &custom_block_source | 267 nullptr, // &custom_block_source |
268 0, // offset_to_data | 268 0, // offset_to_data |
269 data_size, // data_length | 269 data_size, // data_length |
270 0, // flags | 270 0, // flags |
271 data.InitializeInto())); | 271 data.InitializeInto())); |
272 | 272 |
273 // 4. Copy NALU data, inserting length headers. | 273 // 4. Copy NALU data, inserting length headers. |
274 size_t offset = 0; | 274 size_t offset = 0; |
275 for (size_t i = 0; i < nalus.size(); i++) { | 275 for (size_t i = 0; i < nalus.size(); i++) { |
276 media::H264NALU& nalu = nalus[i]; | 276 media::H264NALU& nalu = nalus[i]; |
277 uint32_t header = base::HostToNet32(static_cast<uint32_t>(nalu.size)); | 277 uint32_t header = base::HostToNet32(static_cast<uint32_t>(nalu.size)); |
278 CHECK(!CMBlockBufferReplaceDataBytes( | 278 CHECK(!CMBlockBufferReplaceDataBytes( |
279 &header, data, offset, kNALUHeaderLength)); | 279 &header, data, offset, kNALUHeaderLength)); |
280 offset += kNALUHeaderLength; | 280 offset += kNALUHeaderLength; |
281 CHECK(!CMBlockBufferReplaceDataBytes(nalu.data, data, offset, nalu.size)); | 281 CHECK(!CMBlockBufferReplaceDataBytes(nalu.data, data, offset, nalu.size)); |
282 offset += nalu.size; | 282 offset += nalu.size; |
283 } | 283 } |
284 | 284 |
285 // 5. Package the data for VideoToolbox and request decoding. | 285 // 5. Package the data for VideoToolbox and request decoding. |
286 base::ScopedCFTypeRef<CMSampleBufferRef> frame; | 286 base::ScopedCFTypeRef<CMSampleBufferRef> frame; |
287 CHECK(!CMSampleBufferCreate( | 287 CHECK(!CMSampleBufferCreate( |
288 kCFAllocatorDefault, | 288 kCFAllocatorDefault, |
289 data, // data_buffer | 289 data, // data_buffer |
290 true, // data_ready | 290 true, // data_ready |
291 NULL, // make_data_ready_callback | 291 nullptr, // make_data_ready_callback |
292 NULL, // make_data_ready_refcon | 292 nullptr, // make_data_ready_refcon |
293 format_, // format_description | 293 format_, // format_description |
294 1, // num_samples | 294 1, // num_samples |
295 0, // num_sample_timing_entries | 295 0, // num_sample_timing_entries |
296 NULL, // &sample_timing_array | 296 nullptr, // &sample_timing_array |
297 0, // num_sample_size_entries | 297 0, // num_sample_size_entries |
298 NULL, // &sample_size_array | 298 nullptr, // &sample_size_array |
299 frame.InitializeInto())); | 299 frame.InitializeInto())); |
300 | 300 |
301 // Asynchronous Decompression allows for parallel submission of frames | 301 // Asynchronous Decompression allows for parallel submission of frames |
302 // (without it, DecodeFrame() does not return until the frame has been | 302 // (without it, DecodeFrame() does not return until the frame has been |
303 // decoded). We don't enable Temporal Processing so that frames are always | 303 // decoded). We don't enable Temporal Processing so that frames are always |
304 // returned in decode order; this makes it easier to avoid deadlock. | 304 // returned in decode order; this makes it easier to avoid deadlock. |
305 VTDecodeFrameFlags decode_flags = | 305 VTDecodeFrameFlags decode_flags = |
306 kVTDecodeFrame_EnableAsynchronousDecompression; | 306 kVTDecodeFrame_EnableAsynchronousDecompression; |
307 | 307 |
308 intptr_t bitstream_id = bitstream.id(); | 308 intptr_t bitstream_id = bitstream.id(); |
309 CHECK(!VTDecompressionSessionDecodeFrame( | 309 CHECK(!VTDecompressionSessionDecodeFrame( |
310 session_, | 310 session_, |
311 frame, // sample_buffer | 311 frame, // sample_buffer |
312 decode_flags, // decode_flags | 312 decode_flags, // decode_flags |
313 reinterpret_cast<void*>(bitstream_id), // source_frame_refcon | 313 reinterpret_cast<void*>(bitstream_id), // source_frame_refcon |
314 NULL)); // &info_flags_out | 314 nullptr)); // &info_flags_out |
315 } | 315 } |
316 | 316 |
317 // This method may be called on any VideoToolbox thread. | 317 // This method may be called on any VideoToolbox thread. |
318 // TODO(sandersd): Proper error reporting instead of CHECKs. | 318 // TODO(sandersd): Proper error reporting instead of CHECKs. |
319 void VTVideoDecodeAccelerator::Output( | 319 void VTVideoDecodeAccelerator::Output( |
320 int32_t bitstream_id, | 320 int32_t bitstream_id, |
321 OSStatus status, | 321 OSStatus status, |
322 CVImageBufferRef image_buffer) { | 322 CVImageBufferRef image_buffer) { |
323 CHECK(!status); | 323 CHECK(!status); |
324 CHECK_EQ(CFGetTypeID(image_buffer), CVPixelBufferGetTypeID()); | 324 CHECK_EQ(CFGetTypeID(image_buffer), CVPixelBufferGetTypeID()); |
(...skipping 221 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
546 pending_bitstream_ids_.pop(); | 546 pending_bitstream_ids_.pop(); |
547 } | 547 } |
548 QueueAction(ACTION_DESTROY); | 548 QueueAction(ACTION_DESTROY); |
549 } | 549 } |
550 | 550 |
551 bool VTVideoDecodeAccelerator::CanDecodeOnIOThread() { | 551 bool VTVideoDecodeAccelerator::CanDecodeOnIOThread() { |
552 return false; | 552 return false; |
553 } | 553 } |
554 | 554 |
555 } // namespace content | 555 } // namespace content |
OLD | NEW |