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 <dlfcn.h> | 5 #include <dlfcn.h> |
| 6 #include <errno.h> | 6 #include <errno.h> |
| 7 #include <fcntl.h> | 7 #include <fcntl.h> |
| 8 #include <libdrm/drm_fourcc.h> | 8 #include <libdrm/drm_fourcc.h> |
| 9 #include <linux/videodev2.h> | 9 #include <linux/videodev2.h> |
| 10 #include <poll.h> | 10 #include <poll.h> |
| (...skipping 352 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 363 attrs[5] = DRM_FORMAT_NV12; | 363 attrs[5] = DRM_FORMAT_NV12; |
| 364 for (size_t i = 0; i < output_buffer_map_.size(); ++i) { | 364 for (size_t i = 0; i < output_buffer_map_.size(); ++i) { |
| 365 DCHECK(buffers[i].size() == frame_buffer_size_); | 365 DCHECK(buffers[i].size() == frame_buffer_size_); |
| 366 OutputRecord& output_record = output_buffer_map_[i]; | 366 OutputRecord& output_record = output_buffer_map_[i]; |
| 367 attrs[7] = output_record.fds[0]; | 367 attrs[7] = output_record.fds[0]; |
| 368 attrs[9] = 0; | 368 attrs[9] = 0; |
| 369 attrs[11] = frame_buffer_size_.width(); | 369 attrs[11] = frame_buffer_size_.width(); |
| 370 attrs[13] = output_record.fds[1]; | 370 attrs[13] = output_record.fds[1]; |
| 371 attrs[15] = 0; | 371 attrs[15] = 0; |
| 372 attrs[17] = frame_buffer_size_.width(); | 372 attrs[17] = frame_buffer_size_.width(); |
| 373 EGLImageKHR egl_image = eglCreateImageKHR( | 373 EGLImageKHR egl_image = device_->CreateEGLImage( |
| 374 egl_display_, EGL_NO_CONTEXT, EGL_LINUX_DMA_BUF_EXT, NULL, attrs); | 374 egl_display_, attrs, buffers[i].texture_id(), i); |
| 375 if (egl_image == EGL_NO_IMAGE_KHR) { | 375 if (egl_image == EGL_NO_IMAGE_KHR) { |
| 376 DLOG(ERROR) << "AssignPictureBuffers(): could not create EGLImageKHR"; | 376 DLOG(ERROR) << "AssignPictureBuffers(): could not create EGLImageKHR"; |
|
Ami GONE FROM CHROMIUM
2014/02/07 09:09:30
already logged in the Device method; unnecessary
| |
| 377 NOTIFY_ERROR(PLATFORM_FAILURE); | 377 NOTIFY_ERROR(PLATFORM_FAILURE); |
| 378 return; | 378 return; |
| 379 } | 379 } |
| 380 | 380 |
| 381 glBindTexture(GL_TEXTURE_EXTERNAL_OES, buffers[i].texture_id()); | |
| 382 glEGLImageTargetTexture2DOES(GL_TEXTURE_EXTERNAL_OES, egl_image); | |
|
Pawel Osciak
2014/02/10 06:36:17
I would like to understand the big picture here pl
shivdasp
2014/02/10 13:31:17
The decoder's output buffers are created when REQB
Pawel Osciak
2014/02/12 09:15:13
By decoder do you mean V4L2VDA class?
shivdasp
2014/02/12 10:11:55
No I meant the decoder entity within the library.
Pawel Osciak
2014/02/13 10:42:54
So the YUV buffers are tied to the textures someho
shivdasp
2014/02/14 03:06:45
We send texture_id to eglCreateImageKHR and bind i
Pawel Osciak
2014/02/14 07:36:10
Wait, where do you send texture_id to eglCreateIma
shivdasp
2014/02/14 09:18:58
The texture_id is sent in eglCreateImageKHR parame
| |
| 383 picture_buffers_ref->picture_buffers.push_back( | 381 picture_buffers_ref->picture_buffers.push_back( |
| 384 PictureBufferArrayRef::PictureBufferRef(egl_image, buffers[i].id())); | 382 PictureBufferArrayRef::PictureBufferRef(egl_image, buffers[i].id())); |
| 385 } | 383 } |
| 386 decoder_thread_.message_loop()->PostTask( | 384 decoder_thread_.message_loop()->PostTask( |
| 387 FROM_HERE, | 385 FROM_HERE, |
| 388 base::Bind(&V4L2VideoDecodeAccelerator::AssignPictureBuffersTask, | 386 base::Bind(&V4L2VideoDecodeAccelerator::AssignPictureBuffersTask, |
| 389 base::Unretained(this), | 387 base::Unretained(this), |
| 390 base::Passed(&picture_buffers_ref))); | 388 base::Passed(&picture_buffers_ref))); |
| 391 } | 389 } |
| 392 | 390 |
| (...skipping 1240 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1633 } | 1631 } |
| 1634 } | 1632 } |
| 1635 | 1633 |
| 1636 bool V4L2VideoDecodeAccelerator::GetFormatInfo(struct v4l2_format* format, | 1634 bool V4L2VideoDecodeAccelerator::GetFormatInfo(struct v4l2_format* format, |
| 1637 bool* again) { | 1635 bool* again) { |
| 1638 DCHECK_EQ(decoder_thread_.message_loop(), base::MessageLoop::current()); | 1636 DCHECK_EQ(decoder_thread_.message_loop(), base::MessageLoop::current()); |
| 1639 | 1637 |
| 1640 *again = false; | 1638 *again = false; |
| 1641 memset(format, 0, sizeof(*format)); | 1639 memset(format, 0, sizeof(*format)); |
| 1642 format->type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE; | 1640 format->type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE; |
| 1643 if (HANDLE_EINTR(device_->Ioctl(VIDIOC_G_FMT, format)) != 0) { | 1641 |
| 1642 if (HANDLE_EINTR(device_->Ioctl(VIDIOC_G_FMT, format) != 0)) { | |
|
Ami GONE FROM CHROMIUM
2014/02/07 09:09:30
This is a bug!
| |
| 1644 if (errno == EINVAL) { | 1643 if (errno == EINVAL) { |
| 1645 // EINVAL means we haven't seen sufficient stream to decode the format. | 1644 // EINVAL means we haven't seen sufficient stream to decode the format. |
| 1646 *again = true; | 1645 *again = true; |
| 1647 return true; | 1646 return true; |
| 1648 } else { | 1647 } else { |
| 1649 DPLOG(ERROR) << "DecodeBufferInitial(): ioctl() failed: VIDIOC_G_FMT"; | 1648 DPLOG(ERROR) << "DecodeBufferInitial(): ioctl() failed: VIDIOC_G_FMT"; |
| 1650 NOTIFY_ERROR(PLATFORM_FAILURE); | 1649 NOTIFY_ERROR(PLATFORM_FAILURE); |
| 1651 return false; | 1650 return false; |
| 1652 } | 1651 } |
| 1653 } | 1652 } |
| 1654 | 1653 |
| 1654 // Since the underlying library at the moment is not updated this hack | |
|
Ami GONE FROM CHROMIUM
2014/02/07 09:09:30
This comment is opaque to me.
Also, if something i
Pawel Osciak
2014/02/10 06:36:17
Could this hack be moved into the library itself t
shivdasp
2014/02/10 13:31:17
Apologies. This code was not meant to be here. Wil
| |
| 1655 LOG(ERROR) << "Hardcoding the values here "; | |
| 1656 format->fmt.pix_mp.num_planes = 2; | |
| 1657 format->fmt.pix_mp.pixelformat = V4L2_PIX_FMT_NV12M; | |
| 1658 | |
| 1655 return true; | 1659 return true; |
| 1656 } | 1660 } |
| 1657 | 1661 |
| 1658 bool V4L2VideoDecodeAccelerator::CreateBuffersForFormat( | 1662 bool V4L2VideoDecodeAccelerator::CreateBuffersForFormat( |
| 1659 const struct v4l2_format& format) { | 1663 const struct v4l2_format& format) { |
| 1660 DCHECK_EQ(decoder_thread_.message_loop(), base::MessageLoop::current()); | 1664 DCHECK_EQ(decoder_thread_.message_loop(), base::MessageLoop::current()); |
| 1661 CHECK_EQ(format.fmt.pix_mp.num_planes, 2); | 1665 CHECK_EQ(format.fmt.pix_mp.num_planes, 2); |
| 1662 frame_buffer_size_.SetSize( | 1666 frame_buffer_size_.SetSize( |
| 1663 format.fmt.pix_mp.width, format.fmt.pix_mp.height); | 1667 format.fmt.pix_mp.width, format.fmt.pix_mp.height); |
| 1664 output_buffer_pixelformat_ = format.fmt.pix_mp.pixelformat; | 1668 output_buffer_pixelformat_ = format.fmt.pix_mp.pixelformat; |
| (...skipping 113 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1778 | 1782 |
| 1779 DVLOG(3) << "CreateOutputBuffers(): ProvidePictureBuffers(): " | 1783 DVLOG(3) << "CreateOutputBuffers(): ProvidePictureBuffers(): " |
| 1780 << "buffer_count=" << output_buffer_map_.size() | 1784 << "buffer_count=" << output_buffer_map_.size() |
| 1781 << ", width=" << frame_buffer_size_.width() | 1785 << ", width=" << frame_buffer_size_.width() |
| 1782 << ", height=" << frame_buffer_size_.height(); | 1786 << ", height=" << frame_buffer_size_.height(); |
| 1783 child_message_loop_proxy_->PostTask(FROM_HERE, | 1787 child_message_loop_proxy_->PostTask(FROM_HERE, |
| 1784 base::Bind(&Client::ProvidePictureBuffers, | 1788 base::Bind(&Client::ProvidePictureBuffers, |
| 1785 client_, | 1789 client_, |
| 1786 output_buffer_map_.size(), | 1790 output_buffer_map_.size(), |
| 1787 frame_buffer_size_, | 1791 frame_buffer_size_, |
| 1788 GL_TEXTURE_EXTERNAL_OES)); | 1792 device_->GetTextureTarget())); |
| 1789 | 1793 |
| 1790 return true; | 1794 return true; |
| 1791 } | 1795 } |
| 1792 | 1796 |
| 1793 void V4L2VideoDecodeAccelerator::DestroyInputBuffers() { | 1797 void V4L2VideoDecodeAccelerator::DestroyInputBuffers() { |
| 1794 DVLOG(3) << "DestroyInputBuffers()"; | 1798 DVLOG(3) << "DestroyInputBuffers()"; |
| 1795 DCHECK(child_message_loop_proxy_->BelongsToCurrentThread()); | 1799 DCHECK(child_message_loop_proxy_->BelongsToCurrentThread()); |
| 1796 DCHECK(!input_streamon_); | 1800 DCHECK(!input_streamon_); |
| 1797 | 1801 |
| 1798 for (size_t i = 0; i < input_buffer_map_.size(); ++i) { | 1802 for (size_t i = 0; i < input_buffer_map_.size(); ++i) { |
| (...skipping 119 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1918 | 1922 |
| 1919 void V4L2VideoDecodeAccelerator::PictureCleared() { | 1923 void V4L2VideoDecodeAccelerator::PictureCleared() { |
| 1920 DVLOG(3) << "PictureCleared(). clearing count=" << picture_clearing_count_; | 1924 DVLOG(3) << "PictureCleared(). clearing count=" << picture_clearing_count_; |
| 1921 DCHECK_EQ(decoder_thread_.message_loop(), base::MessageLoop::current()); | 1925 DCHECK_EQ(decoder_thread_.message_loop(), base::MessageLoop::current()); |
| 1922 DCHECK_GT(picture_clearing_count_, 0); | 1926 DCHECK_GT(picture_clearing_count_, 0); |
| 1923 picture_clearing_count_--; | 1927 picture_clearing_count_--; |
| 1924 SendPictureReady(); | 1928 SendPictureReady(); |
| 1925 } | 1929 } |
| 1926 | 1930 |
| 1927 } // namespace content | 1931 } // namespace content |
| OLD | NEW |