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 270 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
281 if (lhs->pic_order_cnt != rhs->pic_order_cnt) | 281 if (lhs->pic_order_cnt != rhs->pic_order_cnt) |
282 return lhs->pic_order_cnt > rhs->pic_order_cnt; | 282 return lhs->pic_order_cnt > rhs->pic_order_cnt; |
283 // If |pic_order_cnt| is the same, fall back on using the bitstream order. | 283 // If |pic_order_cnt| is the same, fall back on using the bitstream order. |
284 // TODO(sandersd): Assign a sequence number in Decode() and use that instead. | 284 // TODO(sandersd): Assign a sequence number in Decode() and use that instead. |
285 // TODO(sandersd): Using the sequence number, ensure that frames older than | 285 // TODO(sandersd): Using the sequence number, ensure that frames older than |
286 // |kMaxReorderQueueSize| are ordered first, regardless of |pic_order_cnt|. | 286 // |kMaxReorderQueueSize| are ordered first, regardless of |pic_order_cnt|. |
287 return lhs->bitstream_id > rhs->bitstream_id; | 287 return lhs->bitstream_id > rhs->bitstream_id; |
288 } | 288 } |
289 | 289 |
290 VTVideoDecodeAccelerator::VTVideoDecodeAccelerator( | 290 VTVideoDecodeAccelerator::VTVideoDecodeAccelerator( |
291 const base::Callback<bool(void)>& make_context_current, | 291 const MakeGLContextCurrentCallback& make_context_current_cb, |
292 const base::Callback<void(uint32_t, uint32_t, scoped_refptr<gl::GLImage>)>& | 292 const BindGLImageCallback& bind_image_cb) |
293 bind_image) | 293 : make_context_current_cb_(make_context_current_cb), |
294 : make_context_current_(make_context_current), | 294 bind_image_cb_(bind_image_cb), |
295 bind_image_(bind_image), | |
296 client_(nullptr), | 295 client_(nullptr), |
297 state_(STATE_DECODING), | 296 state_(STATE_DECODING), |
298 format_(nullptr), | 297 format_(nullptr), |
299 session_(nullptr), | 298 session_(nullptr), |
300 last_sps_id_(-1), | 299 last_sps_id_(-1), |
301 last_pps_id_(-1), | 300 last_pps_id_(-1), |
302 config_changed_(false), | 301 config_changed_(false), |
303 missing_idr_logged_(false), | 302 missing_idr_logged_(false), |
304 gpu_task_runner_(base::ThreadTaskRunnerHandle::Get()), | 303 gpu_task_runner_(base::ThreadTaskRunnerHandle::Get()), |
305 decoder_thread_("VTDecoderThread"), | 304 decoder_thread_("VTDecoderThread"), |
306 weak_this_factory_(this) { | 305 weak_this_factory_(this) { |
307 DCHECK(!make_context_current_.is_null()); | |
308 callback_.decompressionOutputCallback = OutputThunk; | 306 callback_.decompressionOutputCallback = OutputThunk; |
309 callback_.decompressionOutputRefCon = this; | 307 callback_.decompressionOutputRefCon = this; |
310 weak_this_ = weak_this_factory_.GetWeakPtr(); | 308 weak_this_ = weak_this_factory_.GetWeakPtr(); |
311 } | 309 } |
312 | 310 |
313 VTVideoDecodeAccelerator::~VTVideoDecodeAccelerator() { | 311 VTVideoDecodeAccelerator::~VTVideoDecodeAccelerator() { |
314 DCHECK(gpu_thread_checker_.CalledOnValidThread()); | 312 DCHECK(gpu_thread_checker_.CalledOnValidThread()); |
315 } | 313 } |
316 | 314 |
317 bool VTVideoDecodeAccelerator::Initialize(const Config& config, | 315 bool VTVideoDecodeAccelerator::Initialize(const Config& config, |
318 Client* client) { | 316 Client* client) { |
319 DCHECK(gpu_thread_checker_.CalledOnValidThread()); | 317 DCHECK(gpu_thread_checker_.CalledOnValidThread()); |
320 | 318 |
| 319 if (make_context_current_cb_.is_null() || bind_image_cb_.is_null()) { |
| 320 NOTREACHED() << "GL callbacks are required for this VDA"; |
| 321 return false; |
| 322 } |
| 323 |
321 if (config.is_encrypted) { | 324 if (config.is_encrypted) { |
322 NOTREACHED() << "Encrypted streams are not supported for this VDA"; | 325 NOTREACHED() << "Encrypted streams are not supported for this VDA"; |
323 return false; | 326 return false; |
324 } | 327 } |
325 | 328 |
326 client_ = client; | 329 client_ = client; |
327 | 330 |
328 if (!InitializeVideoToolbox()) | 331 if (!InitializeVideoToolbox()) |
329 return false; | 332 return false; |
330 | 333 |
(...skipping 690 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1021 | 1024 |
1022 if (available_picture_ids_.empty()) | 1025 if (available_picture_ids_.empty()) |
1023 return false; | 1026 return false; |
1024 | 1027 |
1025 int32_t picture_id = available_picture_ids_.back(); | 1028 int32_t picture_id = available_picture_ids_.back(); |
1026 DCHECK(picture_info_map_.count(picture_id)); | 1029 DCHECK(picture_info_map_.count(picture_id)); |
1027 PictureInfo* picture_info = picture_info_map_.find(picture_id)->second.get(); | 1030 PictureInfo* picture_info = picture_info_map_.find(picture_id)->second.get(); |
1028 DCHECK(!picture_info->cv_image); | 1031 DCHECK(!picture_info->cv_image); |
1029 DCHECK(!picture_info->gl_image); | 1032 DCHECK(!picture_info->gl_image); |
1030 | 1033 |
1031 if (!make_context_current_.Run()) { | 1034 if (!make_context_current_cb_.Run()) { |
1032 DLOG(ERROR) << "Failed to make GL context current"; | 1035 DLOG(ERROR) << "Failed to make GL context current"; |
1033 NotifyError(PLATFORM_FAILURE, SFT_PLATFORM_ERROR); | 1036 NotifyError(PLATFORM_FAILURE, SFT_PLATFORM_ERROR); |
1034 return false; | 1037 return false; |
1035 } | 1038 } |
1036 | 1039 |
1037 IOSurfaceRef surface = CVPixelBufferGetIOSurface(frame.image.get()); | 1040 IOSurfaceRef surface = CVPixelBufferGetIOSurface(frame.image.get()); |
1038 if (gfx::GetGLImplementation() != gfx::kGLImplementationDesktopGLCoreProfile) | 1041 if (gfx::GetGLImplementation() != gfx::kGLImplementationDesktopGLCoreProfile) |
1039 glEnable(GL_TEXTURE_RECTANGLE_ARB); | 1042 glEnable(GL_TEXTURE_RECTANGLE_ARB); |
1040 gfx::ScopedTextureBinder texture_binder(GL_TEXTURE_RECTANGLE_ARB, | 1043 gfx::ScopedTextureBinder texture_binder(GL_TEXTURE_RECTANGLE_ARB, |
1041 picture_info->service_texture_id); | 1044 picture_info->service_texture_id); |
(...skipping 18 matching lines...) Expand all Loading... |
1060 | 1063 |
1061 bool allow_overlay = false; | 1064 bool allow_overlay = false; |
1062 scoped_refptr<gl::GLImageIOSurface> gl_image( | 1065 scoped_refptr<gl::GLImageIOSurface> gl_image( |
1063 new gl::GLImageIOSurface(frame.coded_size, GL_BGRA_EXT)); | 1066 new gl::GLImageIOSurface(frame.coded_size, GL_BGRA_EXT)); |
1064 if (gl_image->Initialize(surface, gfx::GenericSharedMemoryId(), | 1067 if (gl_image->Initialize(surface, gfx::GenericSharedMemoryId(), |
1065 gfx::BufferFormat::BGRA_8888)) { | 1068 gfx::BufferFormat::BGRA_8888)) { |
1066 allow_overlay = true; | 1069 allow_overlay = true; |
1067 } else { | 1070 } else { |
1068 gl_image = nullptr; | 1071 gl_image = nullptr; |
1069 } | 1072 } |
1070 bind_image_.Run(picture_info->client_texture_id, GL_TEXTURE_RECTANGLE_ARB, | 1073 if (!bind_image_cb_.Run(picture_info->client_texture_id, |
1071 gl_image); | 1074 GL_TEXTURE_RECTANGLE_ARB, gl_image)) { |
| 1075 DLOG(ERROR) << "Failed to bind image"; |
| 1076 NotifyError(PLATFORM_FAILURE, SFT_PLATFORM_ERROR); |
| 1077 return false; |
| 1078 } |
1072 | 1079 |
1073 // Assign the new image(s) to the the picture info. | 1080 // Assign the new image(s) to the the picture info. |
1074 picture_info->gl_image = gl_image; | 1081 picture_info->gl_image = gl_image; |
1075 picture_info->cv_image = frame.image; | 1082 picture_info->cv_image = frame.image; |
1076 available_picture_ids_.pop_back(); | 1083 available_picture_ids_.pop_back(); |
1077 | 1084 |
1078 // TODO(sandersd): Currently, the size got from | 1085 // TODO(sandersd): Currently, the size got from |
1079 // CMVideoFormatDescriptionGetDimensions is visible size. We pass it to | 1086 // CMVideoFormatDescriptionGetDimensions is visible size. We pass it to |
1080 // GpuVideoDecoder so that GpuVideoDecoder can use correct visible size in | 1087 // GpuVideoDecoder so that GpuVideoDecoder can use correct visible size in |
1081 // resolution changed. We should find the correct API to get the real | 1088 // resolution changed. We should find the correct API to get the real |
(...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1138 // destructing |this|. | 1145 // destructing |this|. |
1139 // TODO(sandersd): Prevent the decoder from reading buffers before discarding | 1146 // TODO(sandersd): Prevent the decoder from reading buffers before discarding |
1140 // them. | 1147 // them. |
1141 for (int32_t bitstream_id : assigned_bitstream_ids_) | 1148 for (int32_t bitstream_id : assigned_bitstream_ids_) |
1142 client_->NotifyEndOfBitstreamBuffer(bitstream_id); | 1149 client_->NotifyEndOfBitstreamBuffer(bitstream_id); |
1143 assigned_bitstream_ids_.clear(); | 1150 assigned_bitstream_ids_.clear(); |
1144 state_ = STATE_DESTROYING; | 1151 state_ = STATE_DESTROYING; |
1145 QueueFlush(TASK_DESTROY); | 1152 QueueFlush(TASK_DESTROY); |
1146 } | 1153 } |
1147 | 1154 |
1148 bool VTVideoDecodeAccelerator::CanDecodeOnIOThread() { | 1155 bool VTVideoDecodeAccelerator::TryToSetupDecodeOnSeparateThread( |
| 1156 const base::WeakPtr<Client>& decode_client, |
| 1157 const scoped_refptr<base::SingleThreadTaskRunner>& decode_task_runner) { |
1149 return false; | 1158 return false; |
1150 } | 1159 } |
1151 | 1160 |
1152 // static | 1161 // static |
1153 media::VideoDecodeAccelerator::SupportedProfiles | 1162 media::VideoDecodeAccelerator::SupportedProfiles |
1154 VTVideoDecodeAccelerator::GetSupportedProfiles() { | 1163 VTVideoDecodeAccelerator::GetSupportedProfiles() { |
1155 SupportedProfiles profiles; | 1164 SupportedProfiles profiles; |
1156 for (const auto& supported_profile : kSupportedProfiles) { | 1165 for (const auto& supported_profile : kSupportedProfiles) { |
1157 SupportedProfile profile; | 1166 SupportedProfile profile; |
1158 profile.profile = supported_profile; | 1167 profile.profile = supported_profile; |
1159 profile.min_resolution.SetSize(16, 16); | 1168 profile.min_resolution.SetSize(16, 16); |
1160 profile.max_resolution.SetSize(4096, 2160); | 1169 profile.max_resolution.SetSize(4096, 2160); |
1161 profiles.push_back(profile); | 1170 profiles.push_back(profile); |
1162 } | 1171 } |
1163 return profiles; | 1172 return profiles; |
1164 } | 1173 } |
1165 | 1174 |
1166 } // namespace content | 1175 } // namespace content |
OLD | NEW |