| 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 <dlfcn.h> | 5 #include <dlfcn.h> |
| 6 #include <errno.h> | 6 #include <errno.h> |
| 7 #include <fcntl.h> | 7 #include <fcntl.h> |
| 8 #include <linux/videodev2.h> | 8 #include <linux/videodev2.h> |
| 9 #include <poll.h> | 9 #include <poll.h> |
| 10 #include <string.h> | 10 #include <string.h> |
| (...skipping 187 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 198 DCHECK(input_buffer_map_.empty()); | 198 DCHECK(input_buffer_map_.empty()); |
| 199 DCHECK(output_buffer_map_.empty()); | 199 DCHECK(output_buffer_map_.empty()); |
| 200 } | 200 } |
| 201 | 201 |
| 202 bool V4L2VideoDecodeAccelerator::Initialize(const Config& config, | 202 bool V4L2VideoDecodeAccelerator::Initialize(const Config& config, |
| 203 Client* client) { | 203 Client* client) { |
| 204 DVLOG(3) << "Initialize()"; | 204 DVLOG(3) << "Initialize()"; |
| 205 DCHECK(child_task_runner_->BelongsToCurrentThread()); | 205 DCHECK(child_task_runner_->BelongsToCurrentThread()); |
| 206 DCHECK_EQ(decoder_state_, kUninitialized); | 206 DCHECK_EQ(decoder_state_, kUninitialized); |
| 207 | 207 |
| 208 if (get_gl_context_cb_.is_null() || make_context_current_cb_.is_null()) { | 208 if (!device_->SupportsDecodeProfileForV4L2PixelFormats( |
| 209 NOTREACHED() << "GL callbacks are required for this VDA"; | 209 config.profile, arraysize(supported_input_fourccs_), |
| 210 supported_input_fourccs_)) { |
| 211 DVLOG(1) << "Initialize(): unsupported profile=" << config.profile; |
| 210 return false; | 212 return false; |
| 211 } | 213 } |
| 212 | 214 |
| 213 if (config.is_encrypted) { | 215 if (config.is_encrypted) { |
| 214 NOTREACHED() << "Encrypted streams are not supported for this VDA"; | 216 NOTREACHED() << "Encrypted streams are not supported for this VDA"; |
| 215 return false; | 217 return false; |
| 216 } | 218 } |
| 217 | 219 |
| 218 if (!device_->SupportsDecodeProfileForV4L2PixelFormats( | 220 if (config.output_mode != Config::OutputMode::ALLOCATE) { |
| 219 config.profile, arraysize(supported_input_fourccs_), | 221 NOTREACHED() << "Only ALLOCATE OutputMode is supported by this VDA"; |
| 220 supported_input_fourccs_)) { | |
| 221 DVLOG(1) << "Initialize(): unsupported profile=" << config.profile; | |
| 222 return false; | 222 return false; |
| 223 } | 223 } |
| 224 | 224 |
| 225 if (get_gl_context_cb_.is_null() || make_context_current_cb_.is_null()) { |
| 226 NOTREACHED() << "GL callbacks are required for this VDA"; |
| 227 return false; |
| 228 } |
| 229 |
| 225 client_ptr_factory_.reset(new base::WeakPtrFactory<Client>(client)); | 230 client_ptr_factory_.reset(new base::WeakPtrFactory<Client>(client)); |
| 226 client_ = client_ptr_factory_->GetWeakPtr(); | 231 client_ = client_ptr_factory_->GetWeakPtr(); |
| 227 // If we haven't been set up to decode on separate thread via | 232 // If we haven't been set up to decode on separate thread via |
| 228 // TryToSetupDecodeOnSeparateThread(), use the main thread/client for | 233 // TryToSetupDecodeOnSeparateThread(), use the main thread/client for |
| 229 // decode tasks. | 234 // decode tasks. |
| 230 if (!decode_task_runner_) { | 235 if (!decode_task_runner_) { |
| 231 decode_task_runner_ = child_task_runner_; | 236 decode_task_runner_ = child_task_runner_; |
| 232 DCHECK(!decode_client_); | 237 DCHECK(!decode_client_); |
| 233 decode_client_ = client_; | 238 decode_client_ = client_; |
| 234 } | 239 } |
| (...skipping 133 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 368 | 373 |
| 369 OutputRecord& output_record = output_buffer_map_[i]; | 374 OutputRecord& output_record = output_buffer_map_[i]; |
| 370 DCHECK(!output_record.at_device); | 375 DCHECK(!output_record.at_device); |
| 371 DCHECK(!output_record.at_client); | 376 DCHECK(!output_record.at_client); |
| 372 DCHECK_EQ(output_record.egl_image, EGL_NO_IMAGE_KHR); | 377 DCHECK_EQ(output_record.egl_image, EGL_NO_IMAGE_KHR); |
| 373 DCHECK_EQ(output_record.egl_sync, EGL_NO_SYNC_KHR); | 378 DCHECK_EQ(output_record.egl_sync, EGL_NO_SYNC_KHR); |
| 374 DCHECK_EQ(output_record.picture_id, -1); | 379 DCHECK_EQ(output_record.picture_id, -1); |
| 375 DCHECK_EQ(output_record.cleared, false); | 380 DCHECK_EQ(output_record.cleared, false); |
| 376 DCHECK_LE(1u, buffers[i].texture_ids().size()); | 381 DCHECK_LE(1u, buffers[i].texture_ids().size()); |
| 377 | 382 |
| 378 EGLImageKHR egl_image = device_->CreateEGLImage( | 383 std::vector<base::ScopedFD> dmabuf_fds; |
| 379 egl_display_, gl_context->GetHandle(), buffers[i].texture_ids()[0], | 384 dmabuf_fds = device_->GetDmabufsForV4L2Buffer( |
| 380 coded_size_, i, output_format_fourcc_, output_planes_count_); | 385 i, output_planes_count_, V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE); |
| 386 if (dmabuf_fds.empty()) { |
| 387 NOTIFY_ERROR(PLATFORM_FAILURE); |
| 388 return; |
| 389 } |
| 390 |
| 391 EGLImageKHR egl_image = device_->CreateEGLImage(egl_display_, |
| 392 gl_context->GetHandle(), |
| 393 buffers[i].texture_ids()[0], |
| 394 coded_size_, |
| 395 i, |
| 396 output_format_fourcc_, |
| 397 dmabuf_fds); |
| 381 if (egl_image == EGL_NO_IMAGE_KHR) { | 398 if (egl_image == EGL_NO_IMAGE_KHR) { |
| 382 LOG(ERROR) << "AssignPictureBuffers(): could not create EGLImageKHR"; | 399 LOG(ERROR) << "AssignPictureBuffers(): could not create EGLImageKHR"; |
| 383 // Ownership of EGLImages allocated in previous iterations of this loop | 400 // Ownership of EGLImages allocated in previous iterations of this loop |
| 384 // has been transferred to output_buffer_map_. After we error-out here | 401 // has been transferred to output_buffer_map_. After we error-out here |
| 385 // the destructor will handle their cleanup. | 402 // the destructor will handle their cleanup. |
| 386 NOTIFY_ERROR(PLATFORM_FAILURE); | 403 NOTIFY_ERROR(PLATFORM_FAILURE); |
| 387 return; | 404 return; |
| 388 } | 405 } |
| 389 | 406 |
| 390 output_record.egl_image = egl_image; | 407 output_record.egl_image = egl_image; |
| (...skipping 73 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 464 } | 481 } |
| 465 | 482 |
| 466 bool V4L2VideoDecodeAccelerator::TryToSetupDecodeOnSeparateThread( | 483 bool V4L2VideoDecodeAccelerator::TryToSetupDecodeOnSeparateThread( |
| 467 const base::WeakPtr<Client>& decode_client, | 484 const base::WeakPtr<Client>& decode_client, |
| 468 const scoped_refptr<base::SingleThreadTaskRunner>& decode_task_runner) { | 485 const scoped_refptr<base::SingleThreadTaskRunner>& decode_task_runner) { |
| 469 decode_client_ = decode_client_; | 486 decode_client_ = decode_client_; |
| 470 decode_task_runner_ = decode_task_runner; | 487 decode_task_runner_ = decode_task_runner; |
| 471 return true; | 488 return true; |
| 472 } | 489 } |
| 473 | 490 |
| 491 media::VideoPixelFormat V4L2VideoDecodeAccelerator::GetOutputFormat() const { |
| 492 return V4L2Device::V4L2PixFmtToVideoPixelFormat(output_format_fourcc_); |
| 493 } |
| 494 |
| 474 // static | 495 // static |
| 475 media::VideoDecodeAccelerator::SupportedProfiles | 496 media::VideoDecodeAccelerator::SupportedProfiles |
| 476 V4L2VideoDecodeAccelerator::GetSupportedProfiles() { | 497 V4L2VideoDecodeAccelerator::GetSupportedProfiles() { |
| 477 scoped_refptr<V4L2Device> device = V4L2Device::Create(V4L2Device::kDecoder); | 498 scoped_refptr<V4L2Device> device = V4L2Device::Create(V4L2Device::kDecoder); |
| 478 if (!device) | 499 if (!device) |
| 479 return SupportedProfiles(); | 500 return SupportedProfiles(); |
| 480 | 501 |
| 481 return device->GetSupportedDecodeProfiles(arraysize(supported_input_fourccs_), | 502 return device->GetSupportedDecodeProfiles(arraysize(supported_input_fourccs_), |
| 482 supported_input_fourccs_); | 503 supported_input_fourccs_); |
| 483 } | 504 } |
| (...skipping 1559 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2043 | 2064 |
| 2044 void V4L2VideoDecodeAccelerator::PictureCleared() { | 2065 void V4L2VideoDecodeAccelerator::PictureCleared() { |
| 2045 DVLOG(3) << "PictureCleared(). clearing count=" << picture_clearing_count_; | 2066 DVLOG(3) << "PictureCleared(). clearing count=" << picture_clearing_count_; |
| 2046 DCHECK_EQ(decoder_thread_.message_loop(), base::MessageLoop::current()); | 2067 DCHECK_EQ(decoder_thread_.message_loop(), base::MessageLoop::current()); |
| 2047 DCHECK_GT(picture_clearing_count_, 0); | 2068 DCHECK_GT(picture_clearing_count_, 0); |
| 2048 picture_clearing_count_--; | 2069 picture_clearing_count_--; |
| 2049 SendPictureReady(); | 2070 SendPictureReady(); |
| 2050 } | 2071 } |
| 2051 | 2072 |
| 2052 } // namespace content | 2073 } // namespace content |
| OLD | NEW |