OLD | NEW |
1 // Copyright 2015 The Chromium Authors. All rights reserved. | 1 // Copyright 2015 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 <errno.h> | 5 #include <errno.h> |
6 #include <fcntl.h> | 6 #include <fcntl.h> |
7 #include <linux/videodev2.h> | 7 #include <linux/videodev2.h> |
8 #include <poll.h> | 8 #include <poll.h> |
9 #include <string.h> | 9 #include <string.h> |
10 #include <sys/eventfd.h> | 10 #include <sys/eventfd.h> |
(...skipping 378 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
389 device_(device), | 389 device_(device), |
390 decoder_thread_("V4L2SliceVideoDecodeAcceleratorThread"), | 390 decoder_thread_("V4L2SliceVideoDecodeAcceleratorThread"), |
391 device_poll_thread_("V4L2SliceVideoDecodeAcceleratorDevicePollThread"), | 391 device_poll_thread_("V4L2SliceVideoDecodeAcceleratorDevicePollThread"), |
392 input_streamon_(false), | 392 input_streamon_(false), |
393 input_buffer_queued_count_(0), | 393 input_buffer_queued_count_(0), |
394 output_streamon_(false), | 394 output_streamon_(false), |
395 output_buffer_queued_count_(0), | 395 output_buffer_queued_count_(0), |
396 video_profile_(media::VIDEO_CODEC_PROFILE_UNKNOWN), | 396 video_profile_(media::VIDEO_CODEC_PROFILE_UNKNOWN), |
397 output_format_fourcc_(0), | 397 output_format_fourcc_(0), |
398 state_(kUninitialized), | 398 state_(kUninitialized), |
399 output_mode_(Config::OutputMode::ALLOCATE), | |
400 decoder_flushing_(false), | 399 decoder_flushing_(false), |
401 decoder_resetting_(false), | 400 decoder_resetting_(false), |
402 surface_set_change_pending_(false), | 401 surface_set_change_pending_(false), |
403 picture_clearing_count_(0), | 402 picture_clearing_count_(0), |
404 egl_display_(egl_display), | 403 egl_display_(egl_display), |
405 get_gl_context_cb_(get_gl_context_cb), | 404 get_gl_context_cb_(get_gl_context_cb), |
406 make_context_current_cb_(make_context_current_cb), | 405 make_context_current_cb_(make_context_current_cb), |
407 weak_this_factory_(this) { | 406 weak_this_factory_(this) { |
408 weak_this_ = weak_this_factory_.GetWeakPtr(); | 407 weak_this_ = weak_this_factory_.GetWeakPtr(); |
409 } | 408 } |
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
450 NOTREACHED() << "Encrypted streams are not supported for this VDA"; | 449 NOTREACHED() << "Encrypted streams are not supported for this VDA"; |
451 return false; | 450 return false; |
452 } | 451 } |
453 | 452 |
454 if (config.output_mode != Config::OutputMode::ALLOCATE && | 453 if (config.output_mode != Config::OutputMode::ALLOCATE && |
455 config.output_mode != Config::OutputMode::IMPORT) { | 454 config.output_mode != Config::OutputMode::IMPORT) { |
456 NOTREACHED() << "Only ALLOCATE and IMPORT OutputModes are supported"; | 455 NOTREACHED() << "Only ALLOCATE and IMPORT OutputModes are supported"; |
457 return false; | 456 return false; |
458 } | 457 } |
459 | 458 |
| 459 if (config.flush_mode != Config::FlushMode::KEEP_OUTPUT_BUFFERS && |
| 460 config.flush_mode != Config::FlushMode::RETURN_OUTPUT_BUFFERS) { |
| 461 NOTIMPLEMENTED() << "Unsupported Config::FlushMode"; |
| 462 return false; |
| 463 } |
| 464 |
460 client_ptr_factory_.reset( | 465 client_ptr_factory_.reset( |
461 new base::WeakPtrFactory<VideoDecodeAccelerator::Client>(client)); | 466 new base::WeakPtrFactory<VideoDecodeAccelerator::Client>(client)); |
462 client_ = client_ptr_factory_->GetWeakPtr(); | 467 client_ = client_ptr_factory_->GetWeakPtr(); |
463 // If we haven't been set up to decode on separate thread via | 468 // If we haven't been set up to decode on separate thread via |
464 // TryToSetupDecodeOnSeparateThread(), use the main thread/client for | 469 // TryToSetupDecodeOnSeparateThread(), use the main thread/client for |
465 // decode tasks. | 470 // decode tasks. |
466 if (!decode_task_runner_) { | 471 if (!decode_task_runner_) { |
467 decode_task_runner_ = child_task_runner_; | 472 decode_task_runner_ = child_task_runner_; |
468 DCHECK(!decode_client_); | 473 DCHECK(!decode_client_); |
469 decode_client_ = client_; | 474 decode_client_ = client_; |
(...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
521 if (!SetupFormats()) | 526 if (!SetupFormats()) |
522 return false; | 527 return false; |
523 | 528 |
524 if (!decoder_thread_.Start()) { | 529 if (!decoder_thread_.Start()) { |
525 DLOG(ERROR) << "Initialize(): device thread failed to start"; | 530 DLOG(ERROR) << "Initialize(): device thread failed to start"; |
526 return false; | 531 return false; |
527 } | 532 } |
528 decoder_thread_task_runner_ = decoder_thread_.task_runner(); | 533 decoder_thread_task_runner_ = decoder_thread_.task_runner(); |
529 | 534 |
530 state_ = kInitialized; | 535 state_ = kInitialized; |
531 output_mode_ = config.output_mode; | 536 config_ = config; |
532 | 537 |
533 // InitializeTask will NOTIFY_ERROR on failure. | 538 // InitializeTask will NOTIFY_ERROR on failure. |
534 decoder_thread_task_runner_->PostTask( | 539 decoder_thread_task_runner_->PostTask( |
535 FROM_HERE, base::Bind(&V4L2SliceVideoDecodeAccelerator::InitializeTask, | 540 FROM_HERE, base::Bind(&V4L2SliceVideoDecodeAccelerator::InitializeTask, |
536 base::Unretained(this))); | 541 base::Unretained(this))); |
537 | 542 |
538 DVLOGF(1) << "V4L2SliceVideoDecodeAccelerator initialized"; | 543 DVLOGF(1) << "V4L2SliceVideoDecodeAccelerator initialized"; |
539 return true; | 544 return true; |
540 } | 545 } |
541 | 546 |
(...skipping 380 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
922 input_buffer_queued_count_--; | 927 input_buffer_queued_count_--; |
923 DVLOGF(4) << "Dequeued input=" << dqbuf.index | 928 DVLOGF(4) << "Dequeued input=" << dqbuf.index |
924 << " count: " << input_buffer_queued_count_; | 929 << " count: " << input_buffer_queued_count_; |
925 } | 930 } |
926 | 931 |
927 while (output_buffer_queued_count_ > 0) { | 932 while (output_buffer_queued_count_ > 0) { |
928 DCHECK(output_streamon_); | 933 DCHECK(output_streamon_); |
929 memset(&dqbuf, 0, sizeof(dqbuf)); | 934 memset(&dqbuf, 0, sizeof(dqbuf)); |
930 memset(&planes, 0, sizeof(planes)); | 935 memset(&planes, 0, sizeof(planes)); |
931 dqbuf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE; | 936 dqbuf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE; |
932 dqbuf.memory = | 937 dqbuf.memory = (config_.output_mode == Config::OutputMode::ALLOCATE |
933 (output_mode_ == Config::OutputMode::ALLOCATE ? V4L2_MEMORY_MMAP | 938 ? V4L2_MEMORY_MMAP |
934 : V4L2_MEMORY_DMABUF); | 939 : V4L2_MEMORY_DMABUF); |
935 dqbuf.m.planes = planes; | 940 dqbuf.m.planes = planes; |
936 dqbuf.length = output_planes_count_; | 941 dqbuf.length = output_planes_count_; |
937 if (device_->Ioctl(VIDIOC_DQBUF, &dqbuf) != 0) { | 942 if (device_->Ioctl(VIDIOC_DQBUF, &dqbuf) != 0) { |
938 if (errno == EAGAIN) { | 943 if (errno == EAGAIN) { |
939 // EAGAIN if we're just out of buffers to dequeue. | 944 // EAGAIN if we're just out of buffers to dequeue. |
940 break; | 945 break; |
941 } | 946 } |
942 PLOG(ERROR) << "ioctl() failed: VIDIOC_DQBUF"; | 947 PLOG(ERROR) << "ioctl() failed: VIDIOC_DQBUF"; |
943 NOTIFY_ERROR(PLATFORM_FAILURE); | 948 NOTIFY_ERROR(PLATFORM_FAILURE); |
944 return; | 949 return; |
(...skipping 153 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1098 } | 1103 } |
1099 output_record.egl_sync = EGL_NO_SYNC_KHR; | 1104 output_record.egl_sync = EGL_NO_SYNC_KHR; |
1100 } | 1105 } |
1101 | 1106 |
1102 struct v4l2_buffer qbuf; | 1107 struct v4l2_buffer qbuf; |
1103 struct v4l2_plane qbuf_planes[VIDEO_MAX_PLANES]; | 1108 struct v4l2_plane qbuf_planes[VIDEO_MAX_PLANES]; |
1104 memset(&qbuf, 0, sizeof(qbuf)); | 1109 memset(&qbuf, 0, sizeof(qbuf)); |
1105 memset(qbuf_planes, 0, sizeof(qbuf_planes)); | 1110 memset(qbuf_planes, 0, sizeof(qbuf_planes)); |
1106 qbuf.index = index; | 1111 qbuf.index = index; |
1107 qbuf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE; | 1112 qbuf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE; |
1108 if (output_mode_ == Config::OutputMode::ALLOCATE) { | 1113 if (config_.output_mode == Config::OutputMode::ALLOCATE) { |
1109 qbuf.memory = V4L2_MEMORY_MMAP; | 1114 qbuf.memory = V4L2_MEMORY_MMAP; |
1110 } else { | 1115 } else { |
1111 qbuf.memory = V4L2_MEMORY_DMABUF; | 1116 qbuf.memory = V4L2_MEMORY_DMABUF; |
1112 DCHECK_EQ(output_planes_count_, output_record.dmabuf_fds.size()); | 1117 DCHECK_EQ(output_planes_count_, output_record.dmabuf_fds.size()); |
1113 for (size_t i = 0; i < output_record.dmabuf_fds.size(); ++i) { | 1118 for (size_t i = 0; i < output_record.dmabuf_fds.size(); ++i) { |
1114 DCHECK(output_record.dmabuf_fds[i].is_valid()); | 1119 DCHECK(output_record.dmabuf_fds[i].is_valid()); |
1115 qbuf_planes[i].m.fd = output_record.dmabuf_fds[i].get(); | 1120 qbuf_planes[i].m.fd = output_record.dmabuf_fds[i].get(); |
1116 } | 1121 } |
1117 } | 1122 } |
1118 qbuf.m.planes = qbuf_planes; | 1123 qbuf.m.planes = qbuf_planes; |
(...skipping 377 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1496 << ", requested " << req_buffer_count << ")"; | 1501 << ", requested " << req_buffer_count << ")"; |
1497 NOTIFY_ERROR(INVALID_ARGUMENT); | 1502 NOTIFY_ERROR(INVALID_ARGUMENT); |
1498 return; | 1503 return; |
1499 } | 1504 } |
1500 | 1505 |
1501 // Allocate the output buffers. | 1506 // Allocate the output buffers. |
1502 struct v4l2_requestbuffers reqbufs; | 1507 struct v4l2_requestbuffers reqbufs; |
1503 memset(&reqbufs, 0, sizeof(reqbufs)); | 1508 memset(&reqbufs, 0, sizeof(reqbufs)); |
1504 reqbufs.count = buffers.size(); | 1509 reqbufs.count = buffers.size(); |
1505 reqbufs.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE; | 1510 reqbufs.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE; |
1506 reqbufs.memory = | 1511 reqbufs.memory = (config_.output_mode == Config::OutputMode::ALLOCATE |
1507 (output_mode_ == Config::OutputMode::ALLOCATE ? V4L2_MEMORY_MMAP | 1512 ? V4L2_MEMORY_MMAP |
1508 : V4L2_MEMORY_DMABUF); | 1513 : V4L2_MEMORY_DMABUF); |
1509 IOCTL_OR_ERROR_RETURN(VIDIOC_REQBUFS, &reqbufs); | 1514 IOCTL_OR_ERROR_RETURN(VIDIOC_REQBUFS, &reqbufs); |
1510 | 1515 |
1511 if (reqbufs.count != buffers.size()) { | 1516 if (reqbufs.count != buffers.size()) { |
1512 DLOG(ERROR) << "Could not allocate enough output buffers"; | 1517 DLOG(ERROR) << "Could not allocate enough output buffers"; |
1513 NOTIFY_ERROR(PLATFORM_FAILURE); | 1518 NOTIFY_ERROR(PLATFORM_FAILURE); |
1514 return; | 1519 return; |
1515 } | 1520 } |
1516 | 1521 |
1517 DCHECK(free_output_buffers_.empty()); | 1522 DCHECK(free_output_buffers_.empty()); |
1518 DCHECK(output_buffer_map_.empty()); | 1523 DCHECK(output_buffer_map_.empty()); |
1519 output_buffer_map_.resize(buffers.size()); | 1524 output_buffer_map_.resize(buffers.size()); |
1520 for (size_t i = 0; i < output_buffer_map_.size(); ++i) { | 1525 for (size_t i = 0; i < output_buffer_map_.size(); ++i) { |
1521 DCHECK(buffers[i].size() == coded_size_); | 1526 DCHECK(buffers[i].size() == coded_size_); |
1522 DCHECK_EQ(1u, buffers[i].texture_ids().size()); | 1527 DCHECK_EQ(1u, buffers[i].texture_ids().size()); |
1523 | 1528 |
1524 OutputRecord& output_record = output_buffer_map_[i]; | 1529 OutputRecord& output_record = output_buffer_map_[i]; |
1525 DCHECK(!output_record.at_device); | 1530 DCHECK(!output_record.at_device); |
1526 DCHECK(!output_record.at_client); | 1531 DCHECK(!output_record.at_client); |
1527 DCHECK_EQ(output_record.egl_image, EGL_NO_IMAGE_KHR); | 1532 DCHECK_EQ(output_record.egl_image, EGL_NO_IMAGE_KHR); |
1528 DCHECK_EQ(output_record.egl_sync, EGL_NO_SYNC_KHR); | 1533 DCHECK_EQ(output_record.egl_sync, EGL_NO_SYNC_KHR); |
1529 DCHECK_EQ(output_record.picture_id, -1); | 1534 DCHECK_EQ(output_record.picture_id, -1); |
1530 DCHECK(output_record.dmabuf_fds.empty()); | 1535 DCHECK(output_record.dmabuf_fds.empty()); |
1531 DCHECK_EQ(output_record.cleared, false); | 1536 DCHECK_EQ(output_record.cleared, false); |
1532 | 1537 |
1533 output_record.picture_id = buffers[i].id(); | 1538 output_record.picture_id = buffers[i].id(); |
1534 output_record.texture_id = buffers[i].texture_ids()[0]; | 1539 output_record.texture_id = buffers[i].texture_ids()[0]; |
1535 // This will remain true until ImportBufferForPicture is called, either by | 1540 // This will remain true until ImportBufferForPicture is called, either by |
1536 // the client, or by ourselves, if we are allocating. | 1541 // the client, or by ourselves, if we are allocating. |
1537 output_record.at_client = true; | 1542 output_record.at_client = true; |
1538 if (output_mode_ == Config::OutputMode::ALLOCATE) { | 1543 if (config_.output_mode == Config::OutputMode::ALLOCATE) { |
1539 std::vector<base::ScopedFD> dmabuf_fds = | 1544 std::vector<base::ScopedFD> dmabuf_fds = |
1540 std::move(device_->GetDmabufsForV4L2Buffer( | 1545 std::move(device_->GetDmabufsForV4L2Buffer( |
1541 i, output_planes_count_, V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE)); | 1546 i, output_planes_count_, V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE)); |
1542 if (dmabuf_fds.empty()) { | 1547 if (dmabuf_fds.empty()) { |
1543 NOTIFY_ERROR(PLATFORM_FAILURE); | 1548 NOTIFY_ERROR(PLATFORM_FAILURE); |
1544 return; | 1549 return; |
1545 } | 1550 } |
1546 | 1551 |
1547 auto passed_dmabuf_fds(base::WrapUnique( | 1552 auto passed_dmabuf_fds(base::WrapUnique( |
1548 new std::vector<base::ScopedFD>(std::move(dmabuf_fds)))); | 1553 new std::vector<base::ScopedFD>(std::move(dmabuf_fds)))); |
(...skipping 81 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1630 return; | 1635 return; |
1631 } | 1636 } |
1632 | 1637 |
1633 OutputRecord& output_record = output_buffer_map_[buffer_index]; | 1638 OutputRecord& output_record = output_buffer_map_[buffer_index]; |
1634 DCHECK_EQ(output_record.egl_image, EGL_NO_IMAGE_KHR); | 1639 DCHECK_EQ(output_record.egl_image, EGL_NO_IMAGE_KHR); |
1635 DCHECK_EQ(output_record.egl_sync, EGL_NO_SYNC_KHR); | 1640 DCHECK_EQ(output_record.egl_sync, EGL_NO_SYNC_KHR); |
1636 DCHECK(!output_record.at_client); | 1641 DCHECK(!output_record.at_client); |
1637 DCHECK(!output_record.at_device); | 1642 DCHECK(!output_record.at_device); |
1638 | 1643 |
1639 output_record.egl_image = egl_image; | 1644 output_record.egl_image = egl_image; |
1640 if (output_mode_ == Config::OutputMode::IMPORT) { | 1645 if (config_.output_mode == Config::OutputMode::IMPORT) { |
1641 DCHECK(output_record.dmabuf_fds.empty()); | 1646 DCHECK(output_record.dmabuf_fds.empty()); |
1642 output_record.dmabuf_fds = std::move(*passed_dmabuf_fds); | 1647 output_record.dmabuf_fds = std::move(*passed_dmabuf_fds); |
1643 } | 1648 } |
1644 | 1649 |
1645 DCHECK_EQ(std::count(free_output_buffers_.begin(), free_output_buffers_.end(), | 1650 DCHECK_EQ(std::count(free_output_buffers_.begin(), free_output_buffers_.end(), |
1646 buffer_index), | 1651 buffer_index), |
1647 0); | 1652 0); |
1648 free_output_buffers_.push_back(buffer_index); | 1653 free_output_buffers_.push_back(buffer_index); |
1649 ScheduleDecodeBufferTaskIfNeeded(); | 1654 ScheduleDecodeBufferTaskIfNeeded(); |
1650 } | 1655 } |
1651 | 1656 |
1652 void V4L2SliceVideoDecodeAccelerator::ImportBufferForPicture( | 1657 void V4L2SliceVideoDecodeAccelerator::ImportBufferForPicture( |
1653 int32_t picture_buffer_id, | 1658 int32_t picture_buffer_id, |
1654 const std::vector<gfx::GpuMemoryBufferHandle>& gpu_memory_buffer_handles) { | 1659 const std::vector<gfx::GpuMemoryBufferHandle>& gpu_memory_buffer_handles) { |
1655 DVLOGF(3) << "picture_buffer_id=" << picture_buffer_id; | 1660 DVLOGF(3) << "picture_buffer_id=" << picture_buffer_id; |
1656 DCHECK(child_task_runner_->BelongsToCurrentThread()); | 1661 DCHECK(child_task_runner_->BelongsToCurrentThread()); |
1657 | 1662 |
1658 auto passed_dmabuf_fds(base::WrapUnique(new std::vector<base::ScopedFD>())); | 1663 auto passed_dmabuf_fds(base::WrapUnique(new std::vector<base::ScopedFD>())); |
1659 for (const auto& handle : gpu_memory_buffer_handles) { | 1664 for (const auto& handle : gpu_memory_buffer_handles) { |
1660 int fd = -1; | 1665 int fd = -1; |
1661 #if defined(USE_OZONE) | 1666 #if defined(USE_OZONE) |
1662 fd = handle.native_pixmap_handle.fd.fd; | 1667 fd = handle.native_pixmap_handle.fd.fd; |
1663 #endif | 1668 #endif |
1664 DCHECK_NE(fd, -1); | 1669 DCHECK_NE(fd, -1); |
1665 passed_dmabuf_fds->push_back(base::ScopedFD(fd)); | 1670 passed_dmabuf_fds->push_back(base::ScopedFD(fd)); |
1666 } | 1671 } |
1667 | 1672 |
1668 if (output_mode_ != Config::OutputMode::IMPORT) { | 1673 if (config_.output_mode != Config::OutputMode::IMPORT) { |
1669 LOGF(ERROR) << "Cannot import in non-import mode"; | 1674 LOGF(ERROR) << "Cannot import in non-import mode"; |
1670 NOTIFY_ERROR(INVALID_ARGUMENT); | 1675 NOTIFY_ERROR(INVALID_ARGUMENT); |
1671 return; | 1676 return; |
1672 } | 1677 } |
1673 | 1678 |
1674 decoder_thread_task_runner_->PostTask( | 1679 decoder_thread_task_runner_->PostTask( |
1675 FROM_HERE, | 1680 FROM_HERE, |
1676 base::Bind(&V4L2SliceVideoDecodeAccelerator::ImportBufferForPictureTask, | 1681 base::Bind(&V4L2SliceVideoDecodeAccelerator::ImportBufferForPictureTask, |
1677 base::Unretained(this), picture_buffer_id, | 1682 base::Unretained(this), picture_buffer_id, |
1678 base::Passed(&passed_dmabuf_fds))); | 1683 base::Passed(&passed_dmabuf_fds))); |
(...skipping 186 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1865 // respective PictureReady calls have been posted (or they have been queued on | 1870 // respective PictureReady calls have been posted (or they have been queued on |
1866 // pending_picture_ready_). So at this time, once we SendPictureReady(), | 1871 // pending_picture_ready_). So at this time, once we SendPictureReady(), |
1867 // we will have all remaining PictureReady() posted to the client and we | 1872 // we will have all remaining PictureReady() posted to the client and we |
1868 // can post NotifyFlushDone(). | 1873 // can post NotifyFlushDone(). |
1869 DCHECK(decoder_display_queue_.empty()); | 1874 DCHECK(decoder_display_queue_.empty()); |
1870 | 1875 |
1871 // Decoder should have already returned all surfaces and all surfaces are | 1876 // Decoder should have already returned all surfaces and all surfaces are |
1872 // out of hardware. There can be no other owners of input buffers. | 1877 // out of hardware. There can be no other owners of input buffers. |
1873 DCHECK_EQ(free_input_buffers_.size(), input_buffer_map_.size()); | 1878 DCHECK_EQ(free_input_buffers_.size(), input_buffer_map_.size()); |
1874 | 1879 |
1875 SendPictureReady(); | 1880 if (config_.flush_mode == Config::FlushMode::RETURN_OUTPUT_BUFFERS) { |
| 1881 for (auto& output : free_output_buffers_) { |
| 1882 scoped_refptr<V4L2DecodeSurface> dec_surface = new V4L2DecodeSurface( |
| 1883 -1, -1, output, |
| 1884 base::Bind(&V4L2SliceVideoDecodeAccelerator::ReuseOutputBuffer, |
| 1885 base::Unretained(this))); |
| 1886 OutputSurface(dec_surface); |
| 1887 } |
| 1888 |
| 1889 free_output_buffers_.clear(); |
| 1890 } |
1876 | 1891 |
1877 decoder_flushing_ = false; | 1892 decoder_flushing_ = false; |
| 1893 |
1878 DVLOGF(3) << "Flush finished"; | 1894 DVLOGF(3) << "Flush finished"; |
1879 | 1895 |
1880 child_task_runner_->PostTask(FROM_HERE, | 1896 child_task_runner_->PostTask(FROM_HERE, |
1881 base::Bind(&Client::NotifyFlushDone, client_)); | 1897 base::Bind(&Client::NotifyFlushDone, client_)); |
1882 | |
1883 return true; | 1898 return true; |
1884 } | 1899 } |
1885 | 1900 |
1886 void V4L2SliceVideoDecodeAccelerator::Reset() { | 1901 void V4L2SliceVideoDecodeAccelerator::Reset() { |
1887 DVLOGF(3); | 1902 DVLOGF(3); |
1888 DCHECK(child_task_runner_->BelongsToCurrentThread()); | 1903 DCHECK(child_task_runner_->BelongsToCurrentThread()); |
1889 | 1904 |
1890 decoder_thread_task_runner_->PostTask( | 1905 decoder_thread_task_runner_->PostTask( |
1891 FROM_HERE, base::Bind(&V4L2SliceVideoDecodeAccelerator::ResetTask, | 1906 FROM_HERE, base::Bind(&V4L2SliceVideoDecodeAccelerator::ResetTask, |
1892 base::Unretained(this))); | 1907 base::Unretained(this))); |
(...skipping 775 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2668 bool inserted = | 2683 bool inserted = |
2669 surfaces_at_display_.insert(std::make_pair(output_record.picture_id, | 2684 surfaces_at_display_.insert(std::make_pair(output_record.picture_id, |
2670 dec_surface)).second; | 2685 dec_surface)).second; |
2671 DCHECK(inserted); | 2686 DCHECK(inserted); |
2672 | 2687 |
2673 DCHECK(!output_record.at_client); | 2688 DCHECK(!output_record.at_client); |
2674 DCHECK(!output_record.at_device); | 2689 DCHECK(!output_record.at_device); |
2675 DCHECK_NE(output_record.picture_id, -1); | 2690 DCHECK_NE(output_record.picture_id, -1); |
2676 output_record.at_client = true; | 2691 output_record.at_client = true; |
2677 | 2692 |
| 2693 // If the surface still has a sync object assigned, destroy it. This means |
| 2694 // we didn't use this buffer for decode and we did not need to wait on it |
| 2695 // before enqueuing the buffer to the device. |
| 2696 if (output_record.egl_sync != EGL_NO_SYNC_KHR) { |
| 2697 if (eglDestroySyncKHR(egl_display_, output_record.egl_sync) != EGL_TRUE) { |
| 2698 LOGF(ERROR) << "eglDestroySyncKHR failed!"; |
| 2699 NOTIFY_ERROR(PLATFORM_FAILURE); |
| 2700 return; |
| 2701 } |
| 2702 output_record.egl_sync = EGL_NO_SYNC_KHR; |
| 2703 } |
| 2704 |
2678 // TODO(posciak): Use visible size from decoder here instead | 2705 // TODO(posciak): Use visible size from decoder here instead |
2679 // (crbug.com/402760). Passing (0, 0) results in the client using the | 2706 // (crbug.com/402760). Passing (0, 0) results in the client using the |
2680 // visible size extracted from the container instead. | 2707 // visible size extracted from the container instead. |
2681 media::Picture picture(output_record.picture_id, dec_surface->bitstream_id(), | 2708 media::Picture picture(output_record.picture_id, dec_surface->bitstream_id(), |
2682 gfx::Rect(0, 0), false); | 2709 gfx::Rect(0, 0), false); |
2683 DVLOGF(3) << dec_surface->ToString() | 2710 DVLOGF(3) << dec_surface->ToString() |
2684 << ", bitstream_id: " << picture.bitstream_buffer_id() | 2711 << ", bitstream_id: " << picture.bitstream_buffer_id() |
2685 << ", picture_id: " << picture.picture_buffer_id(); | 2712 << ", picture_id: " << picture.picture_buffer_id(); |
2686 pending_picture_ready_.push(PictureRecord(output_record.cleared, picture)); | 2713 pending_picture_ready_.push(PictureRecord(output_record.cleared, picture)); |
2687 SendPictureReady(); | 2714 SendPictureReady(); |
(...skipping 99 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2787 V4L2SliceVideoDecodeAccelerator::GetSupportedProfiles() { | 2814 V4L2SliceVideoDecodeAccelerator::GetSupportedProfiles() { |
2788 scoped_refptr<V4L2Device> device = V4L2Device::Create(V4L2Device::kDecoder); | 2815 scoped_refptr<V4L2Device> device = V4L2Device::Create(V4L2Device::kDecoder); |
2789 if (!device) | 2816 if (!device) |
2790 return SupportedProfiles(); | 2817 return SupportedProfiles(); |
2791 | 2818 |
2792 return device->GetSupportedDecodeProfiles(arraysize(supported_input_fourccs_), | 2819 return device->GetSupportedDecodeProfiles(arraysize(supported_input_fourccs_), |
2793 supported_input_fourccs_); | 2820 supported_input_fourccs_); |
2794 } | 2821 } |
2795 | 2822 |
2796 } // namespace content | 2823 } // namespace content |
OLD | NEW |