| 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 "media/gpu/vt_video_decode_accelerator_mac.h" | 5 #include "media/gpu/vt_video_decode_accelerator_mac.h" |
| 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 #include <stddef.h> | 10 #include <stddef.h> |
| 11 | 11 |
| 12 #include <algorithm> | 12 #include <algorithm> |
| 13 #include <memory> | 13 #include <memory> |
| 14 | 14 |
| 15 #include "base/atomic_sequence_num.h" |
| 15 #include "base/bind.h" | 16 #include "base/bind.h" |
| 16 #include "base/logging.h" | 17 #include "base/logging.h" |
| 17 #include "base/mac/mac_logging.h" | 18 #include "base/mac/mac_logging.h" |
| 18 #include "base/macros.h" | 19 #include "base/macros.h" |
| 19 #include "base/memory/ptr_util.h" | 20 #include "base/memory/ptr_util.h" |
| 20 #include "base/metrics/histogram_macros.h" | 21 #include "base/metrics/histogram_macros.h" |
| 22 #include "base/strings/stringprintf.h" |
| 21 #include "base/sys_byteorder.h" | 23 #include "base/sys_byteorder.h" |
| 22 #include "base/sys_info.h" | 24 #include "base/sys_info.h" |
| 23 #include "base/threading/thread_task_runner_handle.h" | 25 #include "base/threading/thread_task_runner_handle.h" |
| 26 #include "base/trace_event/memory_dump_manager.h" |
| 24 #include "base/version.h" | 27 #include "base/version.h" |
| 25 #include "media/base/limits.h" | 28 #include "media/base/limits.h" |
| 26 #include "media/gpu/shared_memory_region.h" | 29 #include "media/gpu/shared_memory_region.h" |
| 27 #include "ui/gfx/geometry/rect.h" | 30 #include "ui/gfx/geometry/rect.h" |
| 28 #include "ui/gl/gl_context.h" | 31 #include "ui/gl/gl_context.h" |
| 29 #include "ui/gl/gl_image_io_surface.h" | 32 #include "ui/gl/gl_image_io_surface.h" |
| 30 #include "ui/gl/gl_implementation.h" | 33 #include "ui/gl/gl_implementation.h" |
| 31 #include "ui/gl/scoped_binders.h" | 34 #include "ui/gl/scoped_binders.h" |
| 32 | 35 |
| 33 #define NOTIFY_STATUS(name, status, session_failure) \ | 36 #define NOTIFY_STATUS(name, status, session_failure) \ |
| 34 do { \ | 37 do { \ |
| 35 OSSTATUS_DLOG(ERROR, status) << name; \ | 38 OSSTATUS_DLOG(ERROR, status) << name; \ |
| 36 NotifyError(PLATFORM_FAILURE, session_failure); \ | 39 NotifyError(PLATFORM_FAILURE, session_failure); \ |
| 37 } while (0) | 40 } while (0) |
| 38 | 41 |
| 39 namespace media { | 42 namespace media { |
| 40 | 43 |
| 41 namespace { | 44 namespace { |
| 42 | 45 |
| 46 // A sequence of ids for memory tracing. |
| 47 base::StaticAtomicSequenceNumber g_memory_dump_ids; |
| 48 |
| 49 // A sequence of shared memory ids for CVPixelBufferRefs. |
| 50 base::StaticAtomicSequenceNumber g_cv_pixel_buffer_ids; |
| 51 |
| 43 // Only H.264 with 4:2:0 chroma sampling is supported. | 52 // Only H.264 with 4:2:0 chroma sampling is supported. |
| 44 const VideoCodecProfile kSupportedProfiles[] = { | 53 const VideoCodecProfile kSupportedProfiles[] = { |
| 45 H264PROFILE_BASELINE, H264PROFILE_EXTENDED, H264PROFILE_MAIN, | 54 H264PROFILE_BASELINE, H264PROFILE_EXTENDED, H264PROFILE_MAIN, |
| 46 H264PROFILE_HIGH, | 55 H264PROFILE_HIGH, |
| 47 | 56 |
| 48 // TODO(hubbe): Re-enable this once software fallback is working. | 57 // TODO(hubbe): Re-enable this once software fallback is working. |
| 49 // http://crbug.com/605790 | 58 // http://crbug.com/605790 |
| 50 // H264PROFILE_HIGH10PROFILE, | 59 // H264PROFILE_HIGH10PROFILE, |
| 51 | 60 |
| 52 // TODO(sandersd): Find and test media with these profiles before enabling. | 61 // TODO(sandersd): Find and test media with these profiles before enabling. |
| (...skipping 236 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 289 const MakeGLContextCurrentCallback& make_context_current_cb, | 298 const MakeGLContextCurrentCallback& make_context_current_cb, |
| 290 const BindGLImageCallback& bind_image_cb) | 299 const BindGLImageCallback& bind_image_cb) |
| 291 : make_context_current_cb_(make_context_current_cb), | 300 : make_context_current_cb_(make_context_current_cb), |
| 292 bind_image_cb_(bind_image_cb), | 301 bind_image_cb_(bind_image_cb), |
| 293 gpu_task_runner_(base::ThreadTaskRunnerHandle::Get()), | 302 gpu_task_runner_(base::ThreadTaskRunnerHandle::Get()), |
| 294 decoder_thread_("VTDecoderThread"), | 303 decoder_thread_("VTDecoderThread"), |
| 295 weak_this_factory_(this) { | 304 weak_this_factory_(this) { |
| 296 callback_.decompressionOutputCallback = OutputThunk; | 305 callback_.decompressionOutputCallback = OutputThunk; |
| 297 callback_.decompressionOutputRefCon = this; | 306 callback_.decompressionOutputRefCon = this; |
| 298 weak_this_ = weak_this_factory_.GetWeakPtr(); | 307 weak_this_ = weak_this_factory_.GetWeakPtr(); |
| 308 |
| 309 memory_dump_id_ = g_memory_dump_ids.GetNext(); |
| 310 base::trace_event::MemoryDumpManager::GetInstance()->RegisterDumpProvider( |
| 311 this, "VTVideoDecodeAccelerator", gpu_task_runner_); |
| 299 } | 312 } |
| 300 | 313 |
| 301 VTVideoDecodeAccelerator::~VTVideoDecodeAccelerator() { | 314 VTVideoDecodeAccelerator::~VTVideoDecodeAccelerator() { |
| 302 DVLOG(1) << __func__; | 315 DVLOG(1) << __func__; |
| 303 DCHECK(gpu_task_runner_->BelongsToCurrentThread()); | 316 DCHECK(gpu_task_runner_->BelongsToCurrentThread()); |
| 317 |
| 318 base::trace_event::MemoryDumpManager::GetInstance()->UnregisterDumpProvider( |
| 319 this); |
| 320 } |
| 321 |
| 322 bool VTVideoDecodeAccelerator::OnMemoryDump( |
| 323 const base::trace_event::MemoryDumpArgs& args, |
| 324 base::trace_event::ProcessMemoryDump* pmd) { |
| 325 for (const auto& it : picture_info_map_) { |
| 326 int32_t picture_id = it.first; |
| 327 PictureInfo* picture_info = it.second.get(); |
| 328 if (picture_info->gl_image) { |
| 329 std::string dump_name = |
| 330 base::StringPrintf("media/vt_video_decode_accelerator_%d/picture_%d", |
| 331 memory_dump_id_, picture_id); |
| 332 picture_info->gl_image->OnMemoryDump(pmd, 0, dump_name); |
| 333 } |
| 334 } |
| 335 return true; |
| 304 } | 336 } |
| 305 | 337 |
| 306 bool VTVideoDecodeAccelerator::Initialize(const Config& config, | 338 bool VTVideoDecodeAccelerator::Initialize(const Config& config, |
| 307 Client* client) { | 339 Client* client) { |
| 308 DVLOG(1) << __func__; | 340 DVLOG(1) << __func__; |
| 309 DCHECK(gpu_task_runner_->BelongsToCurrentThread()); | 341 DCHECK(gpu_task_runner_->BelongsToCurrentThread()); |
| 310 | 342 |
| 311 if (make_context_current_cb_.is_null() || bind_image_cb_.is_null()) { | 343 if (make_context_current_cb_.is_null() || bind_image_cb_.is_null()) { |
| 312 NOTREACHED() << "GL callbacks are required for this VDA"; | 344 NOTREACHED() << "GL callbacks are required for this VDA"; |
| 313 return false; | 345 return false; |
| (...skipping 769 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1083 | 1115 |
| 1084 if (!make_context_current_cb_.Run()) { | 1116 if (!make_context_current_cb_.Run()) { |
| 1085 DLOG(ERROR) << "Failed to make GL context current"; | 1117 DLOG(ERROR) << "Failed to make GL context current"; |
| 1086 NotifyError(PLATFORM_FAILURE, SFT_PLATFORM_ERROR); | 1118 NotifyError(PLATFORM_FAILURE, SFT_PLATFORM_ERROR); |
| 1087 return false; | 1119 return false; |
| 1088 } | 1120 } |
| 1089 | 1121 |
| 1090 scoped_refptr<gl::GLImageIOSurface> gl_image( | 1122 scoped_refptr<gl::GLImageIOSurface> gl_image( |
| 1091 new gl::GLImageIOSurface(frame.image_size, GL_BGRA_EXT)); | 1123 new gl::GLImageIOSurface(frame.image_size, GL_BGRA_EXT)); |
| 1092 if (!gl_image->InitializeWithCVPixelBuffer( | 1124 if (!gl_image->InitializeWithCVPixelBuffer( |
| 1093 frame.image.get(), gfx::GenericSharedMemoryId(), | 1125 frame.image.get(), |
| 1126 gfx::GenericSharedMemoryId(g_cv_pixel_buffer_ids.GetNext()), |
| 1094 gfx::BufferFormat::YUV_420_BIPLANAR)) { | 1127 gfx::BufferFormat::YUV_420_BIPLANAR)) { |
| 1095 NOTIFY_STATUS("Failed to initialize GLImageIOSurface", PLATFORM_FAILURE, | 1128 NOTIFY_STATUS("Failed to initialize GLImageIOSurface", PLATFORM_FAILURE, |
| 1096 SFT_PLATFORM_ERROR); | 1129 SFT_PLATFORM_ERROR); |
| 1097 } | 1130 } |
| 1098 | 1131 |
| 1099 if (!bind_image_cb_.Run(picture_info->client_texture_id, | 1132 if (!bind_image_cb_.Run(picture_info->client_texture_id, |
| 1100 GL_TEXTURE_RECTANGLE_ARB, gl_image, false)) { | 1133 GL_TEXTURE_RECTANGLE_ARB, gl_image, false)) { |
| 1101 DLOG(ERROR) << "Failed to bind image"; | 1134 DLOG(ERROR) << "Failed to bind image"; |
| 1102 NotifyError(PLATFORM_FAILURE, SFT_PLATFORM_ERROR); | 1135 NotifyError(PLATFORM_FAILURE, SFT_PLATFORM_ERROR); |
| 1103 return false; | 1136 return false; |
| (...skipping 89 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1193 SupportedProfile profile; | 1226 SupportedProfile profile; |
| 1194 profile.profile = supported_profile; | 1227 profile.profile = supported_profile; |
| 1195 profile.min_resolution.SetSize(16, 16); | 1228 profile.min_resolution.SetSize(16, 16); |
| 1196 profile.max_resolution.SetSize(4096, 2160); | 1229 profile.max_resolution.SetSize(4096, 2160); |
| 1197 profiles.push_back(profile); | 1230 profiles.push_back(profile); |
| 1198 } | 1231 } |
| 1199 return profiles; | 1232 return profiles; |
| 1200 } | 1233 } |
| 1201 | 1234 |
| 1202 } // namespace media | 1235 } // namespace media |
| OLD | NEW |