| 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 <sys/eventfd.h> | 10 #include <sys/eventfd.h> |
| (...skipping 304 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 315 decoder_thread_.message_loop()->PostTask(FROM_HERE, base::Bind( | 315 decoder_thread_.message_loop()->PostTask(FROM_HERE, base::Bind( |
| 316 &V4L2VideoDecodeAccelerator::DecodeTask, base::Unretained(this), | 316 &V4L2VideoDecodeAccelerator::DecodeTask, base::Unretained(this), |
| 317 bitstream_buffer)); | 317 bitstream_buffer)); |
| 318 } | 318 } |
| 319 | 319 |
| 320 void V4L2VideoDecodeAccelerator::AssignPictureBuffers( | 320 void V4L2VideoDecodeAccelerator::AssignPictureBuffers( |
| 321 const std::vector<media::PictureBuffer>& buffers) { | 321 const std::vector<media::PictureBuffer>& buffers) { |
| 322 DVLOG(3) << "AssignPictureBuffers(): buffer_count=" << buffers.size(); | 322 DVLOG(3) << "AssignPictureBuffers(): buffer_count=" << buffers.size(); |
| 323 DCHECK(child_task_runner_->BelongsToCurrentThread()); | 323 DCHECK(child_task_runner_->BelongsToCurrentThread()); |
| 324 | 324 |
| 325 if (buffers.size() != output_buffer_map_.size()) { | 325 const uint32_t req_buffer_count = |
| 326 output_dpb_size_ + kDpbOutputBufferExtraCount; |
| 327 |
| 328 if (buffers.size() < req_buffer_count) { |
| 326 LOG(ERROR) << "AssignPictureBuffers(): Failed to provide requested picture" | 329 LOG(ERROR) << "AssignPictureBuffers(): Failed to provide requested picture" |
| 327 " buffers. (Got " << buffers.size() | 330 " buffers. (Got " << buffers.size() |
| 328 << ", requested " << output_buffer_map_.size() << ")"; | 331 << ", requested " << req_buffer_count << ")"; |
| 329 NOTIFY_ERROR(INVALID_ARGUMENT); | 332 NOTIFY_ERROR(INVALID_ARGUMENT); |
| 330 return; | 333 return; |
| 331 } | 334 } |
| 332 | 335 |
| 333 if (!make_context_current_.Run()) { | 336 if (!make_context_current_.Run()) { |
| 334 LOG(ERROR) << "AssignPictureBuffers(): could not make context current"; | 337 LOG(ERROR) << "AssignPictureBuffers(): could not make context current"; |
| 335 NOTIFY_ERROR(PLATFORM_FAILURE); | 338 NOTIFY_ERROR(PLATFORM_FAILURE); |
| 336 return; | 339 return; |
| 337 } | 340 } |
| 338 | 341 |
| 339 gfx::ScopedTextureBinder bind_restore(GL_TEXTURE_EXTERNAL_OES, 0); | 342 gfx::ScopedTextureBinder bind_restore(GL_TEXTURE_EXTERNAL_OES, 0); |
| 340 | 343 |
| 341 // It's safe to manipulate all the buffer state here, because the decoder | 344 // It's safe to manipulate all the buffer state here, because the decoder |
| 342 // thread is waiting on pictures_assigned_. | 345 // thread is waiting on pictures_assigned_. |
| 346 |
| 347 // Allocate the output buffers. |
| 348 struct v4l2_requestbuffers reqbufs; |
| 349 memset(&reqbufs, 0, sizeof(reqbufs)); |
| 350 reqbufs.count = buffers.size(); |
| 351 reqbufs.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE; |
| 352 reqbufs.memory = V4L2_MEMORY_MMAP; |
| 353 IOCTL_OR_ERROR_RETURN(VIDIOC_REQBUFS, &reqbufs); |
| 354 |
| 355 if (reqbufs.count != buffers.size()) { |
| 356 DLOG(ERROR) << "Could not allocate enough output buffers"; |
| 357 NOTIFY_ERROR(PLATFORM_FAILURE); |
| 358 return; |
| 359 } |
| 360 |
| 361 output_buffer_map_.resize(buffers.size()); |
| 362 |
| 343 DCHECK(free_output_buffers_.empty()); | 363 DCHECK(free_output_buffers_.empty()); |
| 344 for (size_t i = 0; i < output_buffer_map_.size(); ++i) { | 364 for (size_t i = 0; i < output_buffer_map_.size(); ++i) { |
| 345 DCHECK(buffers[i].size() == coded_size_); | 365 DCHECK(buffers[i].size() == coded_size_); |
| 346 | 366 |
| 347 OutputRecord& output_record = output_buffer_map_[i]; | 367 OutputRecord& output_record = output_buffer_map_[i]; |
| 348 DCHECK(!output_record.at_device); | 368 DCHECK(!output_record.at_device); |
| 349 DCHECK(!output_record.at_client); | 369 DCHECK(!output_record.at_client); |
| 350 DCHECK_EQ(output_record.egl_image, EGL_NO_IMAGE_KHR); | 370 DCHECK_EQ(output_record.egl_image, EGL_NO_IMAGE_KHR); |
| 351 DCHECK_EQ(output_record.egl_sync, EGL_NO_SYNC_KHR); | 371 DCHECK_EQ(output_record.egl_sync, EGL_NO_SYNC_KHR); |
| 352 DCHECK_EQ(output_record.picture_id, -1); | 372 DCHECK_EQ(output_record.picture_id, -1); |
| (...skipping 1501 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1854 | 1874 |
| 1855 // Number of output buffers we need. | 1875 // Number of output buffers we need. |
| 1856 struct v4l2_control ctrl; | 1876 struct v4l2_control ctrl; |
| 1857 memset(&ctrl, 0, sizeof(ctrl)); | 1877 memset(&ctrl, 0, sizeof(ctrl)); |
| 1858 ctrl.id = V4L2_CID_MIN_BUFFERS_FOR_CAPTURE; | 1878 ctrl.id = V4L2_CID_MIN_BUFFERS_FOR_CAPTURE; |
| 1859 IOCTL_OR_ERROR_RETURN_FALSE(VIDIOC_G_CTRL, &ctrl); | 1879 IOCTL_OR_ERROR_RETURN_FALSE(VIDIOC_G_CTRL, &ctrl); |
| 1860 output_dpb_size_ = ctrl.value; | 1880 output_dpb_size_ = ctrl.value; |
| 1861 | 1881 |
| 1862 // Output format setup in Initialize(). | 1882 // Output format setup in Initialize(). |
| 1863 | 1883 |
| 1864 // Allocate the output buffers. | 1884 const uint32_t buffer_count = output_dpb_size_ + kDpbOutputBufferExtraCount; |
| 1865 struct v4l2_requestbuffers reqbufs; | |
| 1866 memset(&reqbufs, 0, sizeof(reqbufs)); | |
| 1867 reqbufs.count = output_dpb_size_ + kDpbOutputBufferExtraCount; | |
| 1868 reqbufs.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE; | |
| 1869 reqbufs.memory = V4L2_MEMORY_MMAP; | |
| 1870 IOCTL_OR_ERROR_RETURN_FALSE(VIDIOC_REQBUFS, &reqbufs); | |
| 1871 | |
| 1872 output_buffer_map_.resize(reqbufs.count); | |
| 1873 | |
| 1874 DVLOG(3) << "CreateOutputBuffers(): ProvidePictureBuffers(): " | 1885 DVLOG(3) << "CreateOutputBuffers(): ProvidePictureBuffers(): " |
| 1875 << "buffer_count=" << output_buffer_map_.size() | 1886 << "buffer_count=" << buffer_count |
| 1876 << ", coded_size=" << coded_size_.ToString(); | 1887 << ", coded_size=" << coded_size_.ToString(); |
| 1877 child_task_runner_->PostTask( | 1888 child_task_runner_->PostTask( |
| 1878 FROM_HERE, base::Bind(&Client::ProvidePictureBuffers, client_, | 1889 FROM_HERE, base::Bind(&Client::ProvidePictureBuffers, client_, |
| 1879 output_buffer_map_.size(), coded_size_, | 1890 buffer_count, coded_size_, |
| 1880 device_->GetTextureTarget())); | 1891 device_->GetTextureTarget())); |
| 1881 | 1892 |
| 1882 // Wait for the client to call AssignPictureBuffers() on the Child thread. | 1893 // Wait for the client to call AssignPictureBuffers() on the Child thread. |
| 1883 // We do this, because if we continue decoding without finishing buffer | 1894 // We do this, because if we continue decoding without finishing buffer |
| 1884 // allocation, we may end up Resetting before AssignPictureBuffers arrives, | 1895 // allocation, we may end up Resetting before AssignPictureBuffers arrives, |
| 1885 // resulting in unnecessary complications and subtle bugs. | 1896 // resulting in unnecessary complications and subtle bugs. |
| 1886 // For example, if the client calls Decode(Input1), Reset(), Decode(Input2) | 1897 // For example, if the client calls Decode(Input1), Reset(), Decode(Input2) |
| 1887 // in a sequence, and Decode(Input1) results in us getting here and exiting | 1898 // in a sequence, and Decode(Input1) results in us getting here and exiting |
| 1888 // without waiting, we might end up running Reset{,Done}Task() before | 1899 // without waiting, we might end up running Reset{,Done}Task() before |
| 1889 // AssignPictureBuffers is scheduled, thus cleaning up and pushing buffers | 1900 // AssignPictureBuffers is scheduled, thus cleaning up and pushing buffers |
| (...skipping 138 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2028 | 2039 |
| 2029 void V4L2VideoDecodeAccelerator::PictureCleared() { | 2040 void V4L2VideoDecodeAccelerator::PictureCleared() { |
| 2030 DVLOG(3) << "PictureCleared(). clearing count=" << picture_clearing_count_; | 2041 DVLOG(3) << "PictureCleared(). clearing count=" << picture_clearing_count_; |
| 2031 DCHECK_EQ(decoder_thread_.message_loop(), base::MessageLoop::current()); | 2042 DCHECK_EQ(decoder_thread_.message_loop(), base::MessageLoop::current()); |
| 2032 DCHECK_GT(picture_clearing_count_, 0); | 2043 DCHECK_GT(picture_clearing_count_, 0); |
| 2033 picture_clearing_count_--; | 2044 picture_clearing_count_--; |
| 2034 SendPictureReady(); | 2045 SendPictureReady(); |
| 2035 } | 2046 } |
| 2036 | 2047 |
| 2037 } // namespace content | 2048 } // namespace content |
| OLD | NEW |