Chromium Code Reviews| 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 <algorithm> | 5 #include <algorithm> |
| 6 | 6 |
| 7 #include <CoreVideo/CoreVideo.h> | 7 #include <CoreVideo/CoreVideo.h> |
| 8 #include <OpenGL/CGLIOSurface.h> | 8 #include <OpenGL/CGLIOSurface.h> |
| 9 #include <OpenGL/gl.h> | 9 #include <OpenGL/gl.h> |
| 10 | 10 |
| (...skipping 14 matching lines...) Expand all Loading... | |
| 25 using content_common_gpu_media::StubPathMap; | 25 using content_common_gpu_media::StubPathMap; |
| 26 | 26 |
| 27 #define NOTIFY_STATUS(name, status) \ | 27 #define NOTIFY_STATUS(name, status) \ |
| 28 do { \ | 28 do { \ |
| 29 OSSTATUS_DLOG(ERROR, status) << name; \ | 29 OSSTATUS_DLOG(ERROR, status) << name; \ |
| 30 NotifyError(PLATFORM_FAILURE); \ | 30 NotifyError(PLATFORM_FAILURE); \ |
| 31 } while (0) | 31 } while (0) |
| 32 | 32 |
| 33 namespace content { | 33 namespace content { |
| 34 | 34 |
| 35 // Track VideoToolbox loaded to make sure that loading is attempted once and | |
|
DaleCurtis
2014/12/04 01:57:31
Seems instead you should be using a LazyInstance::
sandersd (OOO until July 31)
2014/12/04 02:05:48
That seems rather complicated for this use case, s
| |
| 36 // only once, regardless of the --no-sandbox flag. | |
| 37 static bool vt_init_attempted = false; | |
| 38 static bool vt_init_successful = false; | |
| 39 | |
| 35 // Size to use for NALU length headers in AVC format (can be 1, 2, or 4). | 40 // Size to use for NALU length headers in AVC format (can be 1, 2, or 4). |
| 36 static const int kNALUHeaderLength = 4; | 41 static const int kNALUHeaderLength = 4; |
| 37 | 42 |
| 38 // We request 5 picture buffers from the client, each of which has a texture ID | 43 // We request 5 picture buffers from the client, each of which has a texture ID |
| 39 // that we can bind decoded frames to. We need enough to satisfy preroll, and | 44 // that we can bind decoded frames to. We need enough to satisfy preroll, and |
| 40 // enough to avoid unnecessary stalling, but no more than that. The resource | 45 // enough to avoid unnecessary stalling, but no more than that. The resource |
| 41 // requirements are low, as we don't need the textures to be backed by storage. | 46 // requirements are low, as we don't need the textures to be backed by storage. |
| 42 static const int kNumPictureBuffers = media::limits::kMaxVideoFrames + 1; | 47 static const int kNumPictureBuffers = media::limits::kMaxVideoFrames + 1; |
| 43 | 48 |
| 44 // Maximum number of frames to queue for reordering before we stop asking for | 49 // Maximum number of frames to queue for reordering before we stop asking for |
| (...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 79 // VideoToolbox normally loads the hardware-specific libraries lazily, so we | 84 // VideoToolbox normally loads the hardware-specific libraries lazily, so we |
| 80 // must actually create a decompression session. | 85 // must actually create a decompression session. |
| 81 // | 86 // |
| 82 // If creating a decompression session fails, hardware decoding will be disabled | 87 // If creating a decompression session fails, hardware decoding will be disabled |
| 83 // (Initialize() will always return false). If it succeeds but a required | 88 // (Initialize() will always return false). If it succeeds but a required |
| 84 // library is not loaded yet (I have not experienced this, but the details are | 89 // library is not loaded yet (I have not experienced this, but the details are |
| 85 // not documented), then VideoToolbox will fall back on software decoding | 90 // not documented), then VideoToolbox will fall back on software decoding |
| 86 // internally. If that happens, the likely solution is to expand the scope of | 91 // internally. If that happens, the likely solution is to expand the scope of |
| 87 // this initialization. | 92 // this initialization. |
| 88 void InitializeVideoToolbox() { | 93 void InitializeVideoToolbox() { |
| 94 vt_init_attempted = true; | |
| 95 | |
| 89 if (base::CommandLine::ForCurrentProcess()->HasSwitch( | 96 if (base::CommandLine::ForCurrentProcess()->HasSwitch( |
| 90 switches::kDisableAcceleratedVideoDecode)) { | 97 switches::kDisableAcceleratedVideoDecode)) { |
| 91 return; | 98 return; |
| 92 } | 99 } |
| 93 | 100 |
| 94 if (!IsVtInitialized()) { | 101 if (!IsVtInitialized()) { |
| 95 // CoreVideo is also required, but the loader stops after the first path is | 102 // CoreVideo is also required, but the loader stops after the first path is |
| 96 // loaded. Instead we rely on the transitive dependency from VideoToolbox to | 103 // loaded. Instead we rely on the transitive dependency from VideoToolbox to |
| 97 // CoreVideo. | 104 // CoreVideo. |
| 98 // TODO(sandersd): Fallback to PrivateFrameworks to support OS X < 10.8. | 105 // TODO(sandersd): Fallback to PrivateFrameworks to support OS X < 10.8. |
| (...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 152 decoder_config, // video_decoder_specification | 159 decoder_config, // video_decoder_specification |
| 153 image_config, // destination_image_buffer_attributes | 160 image_config, // destination_image_buffer_attributes |
| 154 &callback, // output_callback | 161 &callback, // output_callback |
| 155 session.InitializeInto()); | 162 session.InitializeInto()); |
| 156 if (status) { | 163 if (status) { |
| 157 OSSTATUS_LOG(ERROR, status) << "Failed to create VTDecompressionSession " | 164 OSSTATUS_LOG(ERROR, status) << "Failed to create VTDecompressionSession " |
| 158 << "while initializing VideoToolbox"; | 165 << "while initializing VideoToolbox"; |
| 159 content_common_gpu_media::UninitializeVt(); | 166 content_common_gpu_media::UninitializeVt(); |
| 160 return; | 167 return; |
| 161 } | 168 } |
| 169 | |
| 170 vt_init_successful = true; | |
| 162 } | 171 } |
| 163 | 172 |
| 164 // Route decoded frame callbacks back into the VTVideoDecodeAccelerator. | 173 // Route decoded frame callbacks back into the VTVideoDecodeAccelerator. |
| 165 static void OutputThunk( | 174 static void OutputThunk( |
| 166 void* decompression_output_refcon, | 175 void* decompression_output_refcon, |
| 167 void* source_frame_refcon, | 176 void* source_frame_refcon, |
| 168 OSStatus status, | 177 OSStatus status, |
| 169 VTDecodeInfoFlags info_flags, | 178 VTDecodeInfoFlags info_flags, |
| 170 CVImageBufferRef image_buffer, | 179 CVImageBufferRef image_buffer, |
| 171 CMTime presentation_time_stamp, | 180 CMTime presentation_time_stamp, |
| (...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 222 | 231 |
| 223 VTVideoDecodeAccelerator::~VTVideoDecodeAccelerator() { | 232 VTVideoDecodeAccelerator::~VTVideoDecodeAccelerator() { |
| 224 } | 233 } |
| 225 | 234 |
| 226 bool VTVideoDecodeAccelerator::Initialize( | 235 bool VTVideoDecodeAccelerator::Initialize( |
| 227 media::VideoCodecProfile profile, | 236 media::VideoCodecProfile profile, |
| 228 Client* client) { | 237 Client* client) { |
| 229 DCHECK(gpu_thread_checker_.CalledOnValidThread()); | 238 DCHECK(gpu_thread_checker_.CalledOnValidThread()); |
| 230 client_ = client; | 239 client_ = client; |
| 231 | 240 |
| 232 if (!IsVtInitialized()) | 241 if (!vt_init_attempted) |
| 242 InitializeVideoToolbox(); | |
| 243 | |
| 244 if (!vt_init_successful) | |
| 233 return false; | 245 return false; |
| 234 | 246 |
| 235 // Only H.264 is supported. | 247 // Only H.264 is supported. |
| 236 if (profile < media::H264PROFILE_MIN || profile > media::H264PROFILE_MAX) | 248 if (profile < media::H264PROFILE_MIN || profile > media::H264PROFILE_MAX) |
| 237 return false; | 249 return false; |
| 238 | 250 |
| 239 // Spawn a thread to handle parsing and calling VideoToolbox. | 251 // Spawn a thread to handle parsing and calling VideoToolbox. |
| 240 if (!decoder_thread_.Start()) | 252 if (!decoder_thread_.Start()) |
| 241 return false; | 253 return false; |
| 242 | 254 |
| (...skipping 224 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 467 if (config_changed) { | 479 if (config_changed) { |
| 468 if (last_sps_.size() == 0 || last_pps_.size() == 0) { | 480 if (last_sps_.size() == 0 || last_pps_.size() == 0) { |
| 469 DLOG(ERROR) << "Invalid configuration data"; | 481 DLOG(ERROR) << "Invalid configuration data"; |
| 470 NotifyError(INVALID_ARGUMENT); | 482 NotifyError(INVALID_ARGUMENT); |
| 471 return; | 483 return; |
| 472 } | 484 } |
| 473 if (!ConfigureDecoder()) | 485 if (!ConfigureDecoder()) |
| 474 return; | 486 return; |
| 475 } | 487 } |
| 476 | 488 |
| 477 // If there are no non-configuration units, drop the bitstream buffer by | 489 // If there are no image slices, drop the bitstream buffer by returning an |
| 478 // returning an empty frame. | 490 // empty frame. |
| 479 if (!data_size) { | 491 if (!data_size) { |
| 480 if (!FinishDelayedFrames()) | 492 if (!FinishDelayedFrames()) |
| 481 return; | 493 return; |
| 482 gpu_task_runner_->PostTask(FROM_HERE, base::Bind( | 494 gpu_task_runner_->PostTask(FROM_HERE, base::Bind( |
| 483 &VTVideoDecodeAccelerator::DecodeDone, weak_this_, frame)); | 495 &VTVideoDecodeAccelerator::DecodeDone, weak_this_, frame)); |
| 484 return; | 496 return; |
| 485 } | 497 } |
| 486 | 498 |
| 487 // If the session is not configured by this point, fail. | 499 // If the session is not configured by this point, fail. |
| 488 if (!session_) { | 500 if (!session_) { |
| (...skipping 398 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 887 assigned_bitstream_ids_.clear(); | 899 assigned_bitstream_ids_.clear(); |
| 888 state_ = STATE_DESTROYING; | 900 state_ = STATE_DESTROYING; |
| 889 QueueFlush(TASK_DESTROY); | 901 QueueFlush(TASK_DESTROY); |
| 890 } | 902 } |
| 891 | 903 |
| 892 bool VTVideoDecodeAccelerator::CanDecodeOnIOThread() { | 904 bool VTVideoDecodeAccelerator::CanDecodeOnIOThread() { |
| 893 return false; | 905 return false; |
| 894 } | 906 } |
| 895 | 907 |
| 896 } // namespace content | 908 } // namespace content |
| OLD | NEW |