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 #include <stddef.h> | 10 #include <stddef.h> |
(...skipping 265 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
276 if (lhs->pic_order_cnt != rhs->pic_order_cnt) | 276 if (lhs->pic_order_cnt != rhs->pic_order_cnt) |
277 return lhs->pic_order_cnt > rhs->pic_order_cnt; | 277 return lhs->pic_order_cnt > rhs->pic_order_cnt; |
278 // If |pic_order_cnt| is the same, fall back on using the bitstream order. | 278 // If |pic_order_cnt| is the same, fall back on using the bitstream order. |
279 // TODO(sandersd): Assign a sequence number in Decode() and use that instead. | 279 // TODO(sandersd): Assign a sequence number in Decode() and use that instead. |
280 // TODO(sandersd): Using the sequence number, ensure that frames older than | 280 // TODO(sandersd): Using the sequence number, ensure that frames older than |
281 // |kMaxReorderQueueSize| are ordered first, regardless of |pic_order_cnt|. | 281 // |kMaxReorderQueueSize| are ordered first, regardless of |pic_order_cnt|. |
282 return lhs->bitstream_id > rhs->bitstream_id; | 282 return lhs->bitstream_id > rhs->bitstream_id; |
283 } | 283 } |
284 | 284 |
285 VTVideoDecodeAccelerator::VTVideoDecodeAccelerator( | 285 VTVideoDecodeAccelerator::VTVideoDecodeAccelerator( |
286 const MakeGLContextCurrentCallback& make_context_current_cb, | 286 const MakeContextCurrentCallback& make_context_current, |
287 const BindGLImageCallback& bind_image_cb) | 287 const BindImageCallback& bind_image) |
288 : make_context_current_cb_(make_context_current_cb), | 288 : make_context_current_(make_context_current), |
289 bind_image_cb_(bind_image_cb), | 289 bind_image_(bind_image), |
290 client_(nullptr), | 290 client_(nullptr), |
291 state_(STATE_DECODING), | 291 state_(STATE_DECODING), |
292 format_(nullptr), | 292 format_(nullptr), |
293 session_(nullptr), | 293 session_(nullptr), |
294 last_sps_id_(-1), | 294 last_sps_id_(-1), |
295 last_pps_id_(-1), | 295 last_pps_id_(-1), |
296 config_changed_(false), | 296 config_changed_(false), |
297 missing_idr_logged_(false), | 297 missing_idr_logged_(false), |
298 gpu_task_runner_(base::ThreadTaskRunnerHandle::Get()), | 298 gpu_task_runner_(base::ThreadTaskRunnerHandle::Get()), |
299 decoder_thread_("VTDecoderThread"), | 299 decoder_thread_("VTDecoderThread"), |
300 weak_this_factory_(this) { | 300 weak_this_factory_(this) { |
| 301 DCHECK(!make_context_current_.is_null()); |
301 callback_.decompressionOutputCallback = OutputThunk; | 302 callback_.decompressionOutputCallback = OutputThunk; |
302 callback_.decompressionOutputRefCon = this; | 303 callback_.decompressionOutputRefCon = this; |
303 weak_this_ = weak_this_factory_.GetWeakPtr(); | 304 weak_this_ = weak_this_factory_.GetWeakPtr(); |
304 } | 305 } |
305 | 306 |
306 VTVideoDecodeAccelerator::~VTVideoDecodeAccelerator() { | 307 VTVideoDecodeAccelerator::~VTVideoDecodeAccelerator() { |
307 DCHECK(gpu_thread_checker_.CalledOnValidThread()); | 308 DCHECK(gpu_thread_checker_.CalledOnValidThread()); |
308 } | 309 } |
309 | 310 |
310 bool VTVideoDecodeAccelerator::Initialize(const Config& config, | 311 bool VTVideoDecodeAccelerator::Initialize(const Config& config, |
311 Client* client) { | 312 Client* client) { |
312 DCHECK(gpu_thread_checker_.CalledOnValidThread()); | 313 DCHECK(gpu_thread_checker_.CalledOnValidThread()); |
313 | 314 |
314 if (make_context_current_cb_.is_null() || bind_image_cb_.is_null()) { | |
315 NOTREACHED() << "GL callbacks are required for this VDA"; | |
316 return false; | |
317 } | |
318 | |
319 if (config.is_encrypted) { | 315 if (config.is_encrypted) { |
320 NOTREACHED() << "Encrypted streams are not supported for this VDA"; | 316 NOTREACHED() << "Encrypted streams are not supported for this VDA"; |
321 return false; | 317 return false; |
322 } | 318 } |
323 | 319 |
324 client_ = client; | 320 client_ = client; |
325 | 321 |
326 if (!InitializeVideoToolbox()) | 322 if (!InitializeVideoToolbox()) |
327 return false; | 323 return false; |
328 | 324 |
(...skipping 690 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1019 | 1015 |
1020 if (available_picture_ids_.empty()) | 1016 if (available_picture_ids_.empty()) |
1021 return false; | 1017 return false; |
1022 | 1018 |
1023 int32_t picture_id = available_picture_ids_.back(); | 1019 int32_t picture_id = available_picture_ids_.back(); |
1024 DCHECK(picture_info_map_.count(picture_id)); | 1020 DCHECK(picture_info_map_.count(picture_id)); |
1025 PictureInfo* picture_info = picture_info_map_.find(picture_id)->second.get(); | 1021 PictureInfo* picture_info = picture_info_map_.find(picture_id)->second.get(); |
1026 DCHECK(!picture_info->cv_image); | 1022 DCHECK(!picture_info->cv_image); |
1027 DCHECK(!picture_info->gl_image); | 1023 DCHECK(!picture_info->gl_image); |
1028 | 1024 |
1029 if (!make_context_current_cb_.Run()) { | 1025 if (!make_context_current_.Run()) { |
1030 DLOG(ERROR) << "Failed to make GL context current"; | 1026 DLOG(ERROR) << "Failed to make GL context current"; |
1031 NotifyError(PLATFORM_FAILURE, SFT_PLATFORM_ERROR); | 1027 NotifyError(PLATFORM_FAILURE, SFT_PLATFORM_ERROR); |
1032 return false; | 1028 return false; |
1033 } | 1029 } |
1034 | 1030 |
1035 IOSurfaceRef io_surface = CVPixelBufferGetIOSurface(frame.image.get()); | 1031 IOSurfaceRef io_surface = CVPixelBufferGetIOSurface(frame.image.get()); |
1036 | 1032 |
1037 scoped_refptr<gl::GLImageIOSurface> gl_image( | 1033 scoped_refptr<gl::GLImageIOSurface> gl_image( |
1038 new gl::GLImageIOSurface(frame.coded_size, GL_BGRA_EXT)); | 1034 new gl::GLImageIOSurface(frame.coded_size, GL_BGRA_EXT)); |
1039 if (!gl_image->Initialize(io_surface, gfx::GenericSharedMemoryId(), | 1035 if (!gl_image->Initialize(io_surface, gfx::GenericSharedMemoryId(), |
1040 gfx::BufferFormat::YUV_420_BIPLANAR)) { | 1036 gfx::BufferFormat::YUV_420_BIPLANAR)) { |
1041 NOTIFY_STATUS("Failed to initialize GLImageIOSurface", PLATFORM_FAILURE, | 1037 NOTIFY_STATUS("Failed to initialize GLImageIOSurface", PLATFORM_FAILURE, |
1042 SFT_PLATFORM_ERROR); | 1038 SFT_PLATFORM_ERROR); |
1043 return false; | 1039 return false; |
1044 } | 1040 } |
1045 | 1041 |
1046 // Mark that the image is not bound for sampling. 4:2:0 images need to | 1042 // Mark that the image is not bound for sampling. 4:2:0 images need to |
1047 // undergo a separate copy to be displayed. | 1043 // undergo a separate copy to be displayed. |
1048 if (!bind_image_cb_.Run(picture_info->client_texture_id, | 1044 bind_image_.Run(picture_info->client_texture_id, GL_TEXTURE_RECTANGLE_ARB, |
1049 GL_TEXTURE_RECTANGLE_ARB, gl_image, false)) { | 1045 gl_image, false); |
1050 DLOG(ERROR) << "Failed to bind image"; | |
1051 NotifyError(PLATFORM_FAILURE, SFT_PLATFORM_ERROR); | |
1052 return false; | |
1053 } | |
1054 | 1046 |
1055 // Assign the new image(s) to the the picture info. | 1047 // Assign the new image(s) to the the picture info. |
1056 picture_info->gl_image = gl_image; | 1048 picture_info->gl_image = gl_image; |
1057 picture_info->cv_image = frame.image; | 1049 picture_info->cv_image = frame.image; |
1058 available_picture_ids_.pop_back(); | 1050 available_picture_ids_.pop_back(); |
1059 | 1051 |
1060 // TODO(sandersd): Currently, the size got from | 1052 // TODO(sandersd): Currently, the size got from |
1061 // CMVideoFormatDescriptionGetDimensions is visible size. We pass it to | 1053 // CMVideoFormatDescriptionGetDimensions is visible size. We pass it to |
1062 // GpuVideoDecoder so that GpuVideoDecoder can use correct visible size in | 1054 // GpuVideoDecoder so that GpuVideoDecoder can use correct visible size in |
1063 // resolution changed. We should find the correct API to get the real | 1055 // resolution changed. We should find the correct API to get the real |
(...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1119 // destructing |this|. | 1111 // destructing |this|. |
1120 // TODO(sandersd): Prevent the decoder from reading buffers before discarding | 1112 // TODO(sandersd): Prevent the decoder from reading buffers before discarding |
1121 // them. | 1113 // them. |
1122 for (int32_t bitstream_id : assigned_bitstream_ids_) | 1114 for (int32_t bitstream_id : assigned_bitstream_ids_) |
1123 client_->NotifyEndOfBitstreamBuffer(bitstream_id); | 1115 client_->NotifyEndOfBitstreamBuffer(bitstream_id); |
1124 assigned_bitstream_ids_.clear(); | 1116 assigned_bitstream_ids_.clear(); |
1125 state_ = STATE_DESTROYING; | 1117 state_ = STATE_DESTROYING; |
1126 QueueFlush(TASK_DESTROY); | 1118 QueueFlush(TASK_DESTROY); |
1127 } | 1119 } |
1128 | 1120 |
1129 bool VTVideoDecodeAccelerator::TryToSetupDecodeOnSeparateThread( | 1121 bool VTVideoDecodeAccelerator::CanDecodeOnIOThread() { |
1130 const base::WeakPtr<Client>& decode_client, | |
1131 const scoped_refptr<base::SingleThreadTaskRunner>& decode_task_runner) { | |
1132 return false; | 1122 return false; |
1133 } | 1123 } |
1134 | 1124 |
1135 // static | 1125 // static |
1136 media::VideoDecodeAccelerator::SupportedProfiles | 1126 media::VideoDecodeAccelerator::SupportedProfiles |
1137 VTVideoDecodeAccelerator::GetSupportedProfiles() { | 1127 VTVideoDecodeAccelerator::GetSupportedProfiles() { |
1138 SupportedProfiles profiles; | 1128 SupportedProfiles profiles; |
1139 for (const auto& supported_profile : kSupportedProfiles) { | 1129 for (const auto& supported_profile : kSupportedProfiles) { |
1140 SupportedProfile profile; | 1130 SupportedProfile profile; |
1141 profile.profile = supported_profile; | 1131 profile.profile = supported_profile; |
1142 profile.min_resolution.SetSize(16, 16); | 1132 profile.min_resolution.SetSize(16, 16); |
1143 profile.max_resolution.SetSize(4096, 2160); | 1133 profile.max_resolution.SetSize(4096, 2160); |
1144 profiles.push_back(profile); | 1134 profiles.push_back(profile); |
1145 } | 1135 } |
1146 return profiles; | 1136 return profiles; |
1147 } | 1137 } |
1148 | 1138 |
1149 } // namespace content | 1139 } // namespace content |
OLD | NEW |