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> |
11 #include <sys/ioctl.h> | 11 #include <sys/ioctl.h> |
12 #include <sys/mman.h> | 12 #include <sys/mman.h> |
13 | 13 |
14 #include "base/bind.h" | 14 #include "base/bind.h" |
15 #include "base/command_line.h" | 15 #include "base/command_line.h" |
16 #include "base/debug/trace_event.h" | 16 #include "base/debug/trace_event.h" |
17 #include "base/memory/shared_memory.h" | 17 #include "base/memory/shared_memory.h" |
18 #include "base/message_loop/message_loop.h" | 18 #include "base/message_loop/message_loop.h" |
19 #include "base/message_loop/message_loop_proxy.h" | 19 #include "base/message_loop/message_loop_proxy.h" |
20 #include "base/numerics/safe_conversions.h" | 20 #include "base/numerics/safe_conversions.h" |
21 #include "content/common/gpu/media/v4l2_video_decode_accelerator.h" | 21 #include "content/common/gpu/media/v4l2_video_decode_accelerator.h" |
22 #include "media/base/media_switches.h" | 22 #include "media/base/media_switches.h" |
23 #include "media/filters/h264_parser.h" | 23 #include "media/filters/h264_parser.h" |
24 #include "ui/gfx/geometry/rect.h" | |
24 #include "ui/gl/scoped_binders.h" | 25 #include "ui/gl/scoped_binders.h" |
25 | 26 |
26 #define NOTIFY_ERROR(x) \ | 27 #define NOTIFY_ERROR(x) \ |
27 do { \ | 28 do { \ |
28 LOG(ERROR) << "Setting error state:" << x; \ | 29 LOG(ERROR) << "Setting error state:" << x; \ |
29 SetErrorState(x); \ | 30 SetErrorState(x); \ |
30 } while (0) | 31 } while (0) |
31 | 32 |
32 #define IOCTL_OR_ERROR_RETURN_VALUE(type, arg, value) \ | 33 #define IOCTL_OR_ERROR_RETURN_VALUE(type, arg, value) \ |
33 do { \ | 34 do { \ |
(...skipping 298 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
332 NOTIFY_ERROR(PLATFORM_FAILURE); | 333 NOTIFY_ERROR(PLATFORM_FAILURE); |
333 return; | 334 return; |
334 } | 335 } |
335 | 336 |
336 gfx::ScopedTextureBinder bind_restore(GL_TEXTURE_EXTERNAL_OES, 0); | 337 gfx::ScopedTextureBinder bind_restore(GL_TEXTURE_EXTERNAL_OES, 0); |
337 | 338 |
338 // It's safe to manipulate all the buffer state here, because the decoder | 339 // It's safe to manipulate all the buffer state here, because the decoder |
339 // thread is waiting on pictures_assigned_. | 340 // thread is waiting on pictures_assigned_. |
340 DCHECK(free_output_buffers_.empty()); | 341 DCHECK(free_output_buffers_.empty()); |
341 for (size_t i = 0; i < output_buffer_map_.size(); ++i) { | 342 for (size_t i = 0; i < output_buffer_map_.size(); ++i) { |
342 DCHECK(buffers[i].size() == frame_buffer_size_); | 343 DCHECK(buffers[i].size() == coded_size_); |
Pawel Osciak
2015/02/02 08:54:16
I have a feeling there was a reason why we didn't
kcwu
2015/02/02 09:01:47
DCHECK_EQ doesn't like objects unable send to outp
| |
343 | 344 |
344 OutputRecord& output_record = output_buffer_map_[i]; | 345 OutputRecord& output_record = output_buffer_map_[i]; |
345 DCHECK(!output_record.at_device); | 346 DCHECK(!output_record.at_device); |
346 DCHECK(!output_record.at_client); | 347 DCHECK(!output_record.at_client); |
347 DCHECK_EQ(output_record.egl_image, EGL_NO_IMAGE_KHR); | 348 DCHECK_EQ(output_record.egl_image, EGL_NO_IMAGE_KHR); |
348 DCHECK_EQ(output_record.egl_sync, EGL_NO_SYNC_KHR); | 349 DCHECK_EQ(output_record.egl_sync, EGL_NO_SYNC_KHR); |
349 DCHECK_EQ(output_record.picture_id, -1); | 350 DCHECK_EQ(output_record.picture_id, -1); |
350 DCHECK_EQ(output_record.cleared, false); | 351 DCHECK_EQ(output_record.cleared, false); |
351 | 352 |
352 EGLImageKHR egl_image = device_->CreateEGLImage(egl_display_, | 353 EGLImageKHR egl_image = device_->CreateEGLImage( |
Pawel Osciak
2015/02/02 08:54:16
To be honest I really preferred the previous inden
kcwu
2015/02/02 09:01:47
It's reindented by git-cl format. Do you still pre
wuchengli
2015/02/02 09:05:15
Let's follow git cl format. If the intent looks ba
| |
353 egl_context_, | 354 egl_display_, egl_context_, buffers[i].texture_id(), coded_size_, i, |
354 buffers[i].texture_id(), | 355 output_format_fourcc_, output_planes_count_); |
355 frame_buffer_size_, | |
356 i, | |
357 output_format_fourcc_, | |
358 output_planes_count_); | |
359 if (egl_image == EGL_NO_IMAGE_KHR) { | 356 if (egl_image == EGL_NO_IMAGE_KHR) { |
360 LOG(ERROR) << "AssignPictureBuffers(): could not create EGLImageKHR"; | 357 LOG(ERROR) << "AssignPictureBuffers(): could not create EGLImageKHR"; |
361 // Ownership of EGLImages allocated in previous iterations of this loop | 358 // Ownership of EGLImages allocated in previous iterations of this loop |
362 // has been transferred to output_buffer_map_. After we error-out here | 359 // has been transferred to output_buffer_map_. After we error-out here |
363 // the destructor will handle their cleanup. | 360 // the destructor will handle their cleanup. |
364 NOTIFY_ERROR(PLATFORM_FAILURE); | 361 NOTIFY_ERROR(PLATFORM_FAILURE); |
365 return; | 362 return; |
366 } | 363 } |
367 | 364 |
368 output_record.egl_image = egl_image; | 365 output_record.egl_image = egl_image; |
(...skipping 353 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
722 return true; | 719 return true; |
723 | 720 |
724 if (!FlushInputFrame()) | 721 if (!FlushInputFrame()) |
725 return false; | 722 return false; |
726 | 723 |
727 // Recycle buffers. | 724 // Recycle buffers. |
728 Dequeue(); | 725 Dequeue(); |
729 | 726 |
730 // Check and see if we have format info yet. | 727 // Check and see if we have format info yet. |
731 struct v4l2_format format; | 728 struct v4l2_format format; |
729 gfx::Size visible_size; | |
732 bool again = false; | 730 bool again = false; |
733 if (!GetFormatInfo(&format, &again)) | 731 if (!GetFormatInfo(&format, &visible_size, &again)) |
734 return false; | 732 return false; |
735 | 733 |
736 if (again) { | 734 if (again) { |
737 // Need more stream to decode format, return true and schedule next buffer. | 735 // Need more stream to decode format, return true and schedule next buffer. |
738 *endpos = size; | 736 *endpos = size; |
739 return true; | 737 return true; |
740 } | 738 } |
741 | 739 |
742 // Run this initialization only on first startup. | 740 // Run this initialization only on first startup. |
743 if (decoder_state_ == kInitialized) { | 741 if (decoder_state_ == kInitialized) { |
744 DVLOG(3) << "DecodeBufferInitial(): running initialization"; | 742 DVLOG(3) << "DecodeBufferInitial(): running initialization"; |
745 // Success! Setup our parameters. | 743 // Success! Setup our parameters. |
746 if (!CreateBuffersForFormat(format)) | 744 if (!CreateBuffersForFormat(format, visible_size)) |
747 return false; | 745 return false; |
748 | 746 |
749 // We expect to process the initial buffer once during stream init to | 747 // We expect to process the initial buffer once during stream init to |
750 // configure stream parameters, but will not consume the steam data on that | 748 // configure stream parameters, but will not consume the steam data on that |
751 // iteration. Subsequent iterations (including after reset) do not require | 749 // iteration. Subsequent iterations (including after reset) do not require |
752 // the stream init step. | 750 // the stream init step. |
753 *endpos = 0; | 751 *endpos = 0; |
754 } else { | 752 } else { |
755 *endpos = size; | 753 *endpos = size; |
756 } | 754 } |
(...skipping 320 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1077 output_record.at_device = false; | 1075 output_record.at_device = false; |
1078 if (dqbuf.m.planes[0].bytesused == 0) { | 1076 if (dqbuf.m.planes[0].bytesused == 0) { |
1079 // This is an empty output buffer returned as part of a flush. | 1077 // This is an empty output buffer returned as part of a flush. |
1080 free_output_buffers_.push(dqbuf.index); | 1078 free_output_buffers_.push(dqbuf.index); |
1081 } else { | 1079 } else { |
1082 DCHECK_GE(dqbuf.timestamp.tv_sec, 0); | 1080 DCHECK_GE(dqbuf.timestamp.tv_sec, 0); |
1083 output_record.at_client = true; | 1081 output_record.at_client = true; |
1084 DVLOG(3) << "Dequeue(): returning input_id=" << dqbuf.timestamp.tv_sec | 1082 DVLOG(3) << "Dequeue(): returning input_id=" << dqbuf.timestamp.tv_sec |
1085 << " as picture_id=" << output_record.picture_id; | 1083 << " as picture_id=" << output_record.picture_id; |
1086 const media::Picture& picture = | 1084 const media::Picture& picture = |
1087 media::Picture(output_record.picture_id, | 1085 media::Picture(output_record.picture_id, dqbuf.timestamp.tv_sec, |
1088 dqbuf.timestamp.tv_sec, | 1086 gfx::Rect(visible_size_)); |
1089 gfx::Rect(frame_buffer_size_)); | |
1090 pending_picture_ready_.push( | 1087 pending_picture_ready_.push( |
1091 PictureRecord(output_record.cleared, picture)); | 1088 PictureRecord(output_record.cleared, picture)); |
1092 SendPictureReady(); | 1089 SendPictureReady(); |
1093 output_record.cleared = true; | 1090 output_record.cleared = true; |
1094 decoder_frames_at_client_++; | 1091 decoder_frames_at_client_++; |
1095 } | 1092 } |
1096 output_buffer_queued_count_--; | 1093 output_buffer_queued_count_--; |
1097 } | 1094 } |
1098 | 1095 |
1099 NotifyFlushDoneIfNeeded(); | 1096 NotifyFlushDoneIfNeeded(); |
(...skipping 427 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1527 DCHECK_EQ(decoder_state_, kChangingResolution); | 1524 DCHECK_EQ(decoder_state_, kChangingResolution); |
1528 DVLOG(3) << "FinishResolutionChange()"; | 1525 DVLOG(3) << "FinishResolutionChange()"; |
1529 | 1526 |
1530 if (decoder_state_ == kError) { | 1527 if (decoder_state_ == kError) { |
1531 DVLOG(2) << "FinishResolutionChange(): early out: kError state"; | 1528 DVLOG(2) << "FinishResolutionChange(): early out: kError state"; |
1532 return; | 1529 return; |
1533 } | 1530 } |
1534 | 1531 |
1535 struct v4l2_format format; | 1532 struct v4l2_format format; |
1536 bool again; | 1533 bool again; |
1537 bool ret = GetFormatInfo(&format, &again); | 1534 gfx::Size visible_size; |
1535 bool ret = GetFormatInfo(&format, &visible_size, &again); | |
1538 if (!ret || again) { | 1536 if (!ret || again) { |
1539 LOG(ERROR) << "Couldn't get format information after resolution change"; | 1537 LOG(ERROR) << "Couldn't get format information after resolution change"; |
1540 NOTIFY_ERROR(PLATFORM_FAILURE); | 1538 NOTIFY_ERROR(PLATFORM_FAILURE); |
1541 return; | 1539 return; |
1542 } | 1540 } |
1543 | 1541 |
1544 if (!CreateBuffersForFormat(format)) { | 1542 if (!CreateBuffersForFormat(format, visible_size)) { |
1545 LOG(ERROR) << "Couldn't reallocate buffers after resolution change"; | 1543 LOG(ERROR) << "Couldn't reallocate buffers after resolution change"; |
1546 NOTIFY_ERROR(PLATFORM_FAILURE); | 1544 NOTIFY_ERROR(PLATFORM_FAILURE); |
1547 return; | 1545 return; |
1548 } | 1546 } |
1549 | 1547 |
1550 decoder_state_ = kDecoding; | 1548 decoder_state_ = kDecoding; |
1551 | 1549 |
1552 if (resolution_change_reset_pending_) { | 1550 if (resolution_change_reset_pending_) { |
1553 resolution_change_reset_pending_ = false; | 1551 resolution_change_reset_pending_ = false; |
1554 ResetTask(); | 1552 ResetTask(); |
(...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1609 | 1607 |
1610 // Post NotifyError only if we are already initialized, as the API does | 1608 // Post NotifyError only if we are already initialized, as the API does |
1611 // not allow doing so before that. | 1609 // not allow doing so before that. |
1612 if (decoder_state_ != kError && decoder_state_ != kUninitialized) | 1610 if (decoder_state_ != kError && decoder_state_ != kUninitialized) |
1613 NotifyError(error); | 1611 NotifyError(error); |
1614 | 1612 |
1615 decoder_state_ = kError; | 1613 decoder_state_ = kError; |
1616 } | 1614 } |
1617 | 1615 |
1618 bool V4L2VideoDecodeAccelerator::GetFormatInfo(struct v4l2_format* format, | 1616 bool V4L2VideoDecodeAccelerator::GetFormatInfo(struct v4l2_format* format, |
1619 bool* again) { | 1617 gfx::Size* visible_size, |
1618 bool* again) { | |
1620 DCHECK_EQ(decoder_thread_.message_loop(), base::MessageLoop::current()); | 1619 DCHECK_EQ(decoder_thread_.message_loop(), base::MessageLoop::current()); |
1621 | 1620 |
1622 *again = false; | 1621 *again = false; |
1623 memset(format, 0, sizeof(*format)); | 1622 memset(format, 0, sizeof(*format)); |
1624 format->type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE; | 1623 format->type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE; |
1625 if (device_->Ioctl(VIDIOC_G_FMT, format) != 0) { | 1624 if (device_->Ioctl(VIDIOC_G_FMT, format) != 0) { |
1626 if (errno == EINVAL) { | 1625 if (errno == EINVAL) { |
1627 // EINVAL means we haven't seen sufficient stream to decode the format. | 1626 // EINVAL means we haven't seen sufficient stream to decode the format. |
1628 *again = true; | 1627 *again = true; |
1629 return true; | 1628 return true; |
1630 } else { | 1629 } else { |
1631 PLOG(ERROR) << __func__ << "(): ioctl() failed: VIDIOC_G_FMT"; | 1630 PLOG(ERROR) << __func__ << "(): ioctl() failed: VIDIOC_G_FMT"; |
1632 NOTIFY_ERROR(PLATFORM_FAILURE); | 1631 NOTIFY_ERROR(PLATFORM_FAILURE); |
1633 return false; | 1632 return false; |
1634 } | 1633 } |
1635 } | 1634 } |
1636 | 1635 |
1637 // Make sure we are still getting the format we set on initialization. | 1636 // Make sure we are still getting the format we set on initialization. |
1638 if (format->fmt.pix_mp.pixelformat != output_format_fourcc_) { | 1637 if (format->fmt.pix_mp.pixelformat != output_format_fourcc_) { |
1639 LOG(ERROR) << "Unexpected format from G_FMT on output"; | 1638 LOG(ERROR) << "Unexpected format from G_FMT on output"; |
1640 return false; | 1639 return false; |
1641 } | 1640 } |
1642 | 1641 |
1642 gfx::Size coded_size(format->fmt.pix_mp.width, format->fmt.pix_mp.height); | |
1643 if (!GetVisibleSize(coded_size, visible_size)) | |
1644 *visible_size = coded_size; | |
1645 | |
1643 return true; | 1646 return true; |
1644 } | 1647 } |
1645 | 1648 |
1646 bool V4L2VideoDecodeAccelerator::CreateBuffersForFormat( | 1649 bool V4L2VideoDecodeAccelerator::CreateBuffersForFormat( |
1647 const struct v4l2_format& format) { | 1650 const struct v4l2_format& format, |
1651 const gfx::Size& visible_size) { | |
1648 DCHECK_EQ(decoder_thread_.message_loop(), base::MessageLoop::current()); | 1652 DCHECK_EQ(decoder_thread_.message_loop(), base::MessageLoop::current()); |
1649 output_planes_count_ = format.fmt.pix_mp.num_planes; | 1653 output_planes_count_ = format.fmt.pix_mp.num_planes; |
1650 frame_buffer_size_.SetSize( | 1654 coded_size_.SetSize(format.fmt.pix_mp.width, format.fmt.pix_mp.height); |
1651 format.fmt.pix_mp.width, format.fmt.pix_mp.height); | 1655 visible_size_ = visible_size; |
1652 DVLOG(3) << "CreateBuffersForFormat(): new resolution: " | 1656 DVLOG(3) << "CreateBuffersForFormat(): new resolution: " |
1653 << frame_buffer_size_.ToString(); | 1657 << coded_size_.ToString(); |
1654 | 1658 |
1655 if (!CreateOutputBuffers()) | 1659 if (!CreateOutputBuffers()) |
1656 return false; | 1660 return false; |
1657 | 1661 |
1658 return true; | 1662 return true; |
1659 } | 1663 } |
1660 | 1664 |
1665 bool V4L2VideoDecodeAccelerator::GetVisibleSize(const gfx::Size& coded_size, | |
1666 gfx::Size* visible_size) { | |
1667 DCHECK_EQ(decoder_thread_.message_loop(), base::MessageLoop::current()); | |
1668 | |
1669 struct v4l2_crop crop_arg; | |
1670 memset(&crop_arg, 0, sizeof(crop_arg)); | |
1671 crop_arg.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE; | |
1672 | |
1673 IOCTL_OR_ERROR_RETURN_FALSE(VIDIOC_G_CROP, &crop_arg); | |
1674 | |
1675 gfx::Rect rect(crop_arg.c.left, crop_arg.c.top, crop_arg.c.width, | |
1676 crop_arg.c.height); | |
1677 DVLOG(3) << "visible rectangle is " << rect.ToString(); | |
1678 if (!gfx::Rect(coded_size).Contains(rect)) { | |
1679 DLOG(ERROR) << "visible rectangle " << rect.ToString() | |
1680 << " is not inside coded size " << coded_size.ToString(); | |
1681 return false; | |
1682 } | |
1683 if (rect.IsEmpty()) { | |
1684 DLOG(ERROR) << "visible size is empty"; | |
1685 return false; | |
1686 } | |
1687 | |
1688 // Chrome assume picture frame is coded at (0, 0). | |
1689 if (!rect.origin().IsOrigin()) { | |
1690 DLOG(ERROR) << "Unexpected visible rectangle " << rect.ToString() | |
1691 << ", top-left is not origin"; | |
1692 return false; | |
1693 } | |
1694 *visible_size = rect.size(); | |
1695 | |
1696 return true; | |
1697 } | |
1698 | |
1661 bool V4L2VideoDecodeAccelerator::CreateInputBuffers() { | 1699 bool V4L2VideoDecodeAccelerator::CreateInputBuffers() { |
1662 DVLOG(3) << "CreateInputBuffers()"; | 1700 DVLOG(3) << "CreateInputBuffers()"; |
1663 // We always run this as we prepare to initialize. | 1701 // We always run this as we prepare to initialize. |
1664 DCHECK_EQ(decoder_state_, kUninitialized); | 1702 DCHECK_EQ(decoder_state_, kUninitialized); |
1665 DCHECK(!input_streamon_); | 1703 DCHECK(!input_streamon_); |
1666 DCHECK(input_buffer_map_.empty()); | 1704 DCHECK(input_buffer_map_.empty()); |
1667 | 1705 |
1668 struct v4l2_requestbuffers reqbufs; | 1706 struct v4l2_requestbuffers reqbufs; |
1669 memset(&reqbufs, 0, sizeof(reqbufs)); | 1707 memset(&reqbufs, 0, sizeof(reqbufs)); |
1670 reqbufs.count = kInputBufferCount; | 1708 reqbufs.count = kInputBufferCount; |
(...skipping 109 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1780 memset(&reqbufs, 0, sizeof(reqbufs)); | 1818 memset(&reqbufs, 0, sizeof(reqbufs)); |
1781 reqbufs.count = output_dpb_size_ + kDpbOutputBufferExtraCount; | 1819 reqbufs.count = output_dpb_size_ + kDpbOutputBufferExtraCount; |
1782 reqbufs.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE; | 1820 reqbufs.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE; |
1783 reqbufs.memory = V4L2_MEMORY_MMAP; | 1821 reqbufs.memory = V4L2_MEMORY_MMAP; |
1784 IOCTL_OR_ERROR_RETURN_FALSE(VIDIOC_REQBUFS, &reqbufs); | 1822 IOCTL_OR_ERROR_RETURN_FALSE(VIDIOC_REQBUFS, &reqbufs); |
1785 | 1823 |
1786 output_buffer_map_.resize(reqbufs.count); | 1824 output_buffer_map_.resize(reqbufs.count); |
1787 | 1825 |
1788 DVLOG(3) << "CreateOutputBuffers(): ProvidePictureBuffers(): " | 1826 DVLOG(3) << "CreateOutputBuffers(): ProvidePictureBuffers(): " |
1789 << "buffer_count=" << output_buffer_map_.size() | 1827 << "buffer_count=" << output_buffer_map_.size() |
1790 << ", width=" << frame_buffer_size_.width() | 1828 << ", coded_size=" << coded_size_.ToString(); |
1791 << ", height=" << frame_buffer_size_.height(); | 1829 child_message_loop_proxy_->PostTask( |
1792 child_message_loop_proxy_->PostTask(FROM_HERE, | 1830 FROM_HERE, base::Bind(&Client::ProvidePictureBuffers, client_, |
Pawel Osciak
2015/02/02 08:54:16
Ditto preferred the old indent...
kcwu
2015/02/02 09:01:47
It's reindented by git-cl format. Do you still pre
| |
1793 base::Bind(&Client::ProvidePictureBuffers, | 1831 output_buffer_map_.size(), coded_size_, |
1794 client_, | 1832 device_->GetTextureTarget())); |
1795 output_buffer_map_.size(), | |
1796 frame_buffer_size_, | |
1797 device_->GetTextureTarget())); | |
1798 | 1833 |
1799 // Wait for the client to call AssignPictureBuffers() on the Child thread. | 1834 // Wait for the client to call AssignPictureBuffers() on the Child thread. |
1800 // We do this, because if we continue decoding without finishing buffer | 1835 // We do this, because if we continue decoding without finishing buffer |
1801 // allocation, we may end up Resetting before AssignPictureBuffers arrives, | 1836 // allocation, we may end up Resetting before AssignPictureBuffers arrives, |
1802 // resulting in unnecessary complications and subtle bugs. | 1837 // resulting in unnecessary complications and subtle bugs. |
1803 // For example, if the client calls Decode(Input1), Reset(), Decode(Input2) | 1838 // For example, if the client calls Decode(Input1), Reset(), Decode(Input2) |
1804 // in a sequence, and Decode(Input1) results in us getting here and exiting | 1839 // in a sequence, and Decode(Input1) results in us getting here and exiting |
1805 // without waiting, we might end up running Reset{,Done}Task() before | 1840 // without waiting, we might end up running Reset{,Done}Task() before |
1806 // AssignPictureBuffers is scheduled, thus cleaning up and pushing buffers | 1841 // AssignPictureBuffers is scheduled, thus cleaning up and pushing buffers |
1807 // to the free_output_buffers_ map twice. If we somehow marked buffers as | 1842 // to the free_output_buffers_ map twice. If we somehow marked buffers as |
(...skipping 151 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1959 struct v4l2_control ctrl; | 1994 struct v4l2_control ctrl; |
1960 memset(&ctrl, 0, sizeof(ctrl)); | 1995 memset(&ctrl, 0, sizeof(ctrl)); |
1961 ctrl.id = V4L2_CID_MIN_BUFFERS_FOR_CAPTURE; | 1996 ctrl.id = V4L2_CID_MIN_BUFFERS_FOR_CAPTURE; |
1962 IOCTL_OR_ERROR_RETURN_FALSE(VIDIOC_G_CTRL, &ctrl); | 1997 IOCTL_OR_ERROR_RETURN_FALSE(VIDIOC_G_CTRL, &ctrl); |
1963 if (ctrl.value != output_dpb_size_) { | 1998 if (ctrl.value != output_dpb_size_) { |
1964 DVLOG(3) | 1999 DVLOG(3) |
1965 << "IsResolutionChangeNecessary(): Returning true since DPB mismatch "; | 2000 << "IsResolutionChangeNecessary(): Returning true since DPB mismatch "; |
1966 return true; | 2001 return true; |
1967 } | 2002 } |
1968 struct v4l2_format format; | 2003 struct v4l2_format format; |
2004 gfx::Size visible_size; | |
1969 bool again = false; | 2005 bool again = false; |
1970 bool ret = GetFormatInfo(&format, &again); | 2006 bool ret = GetFormatInfo(&format, &visible_size, &again); |
1971 if (!ret || again) { | 2007 if (!ret || again) { |
1972 DVLOG(3) << "IsResolutionChangeNecessary(): GetFormatInfo() failed"; | 2008 DVLOG(3) << "IsResolutionChangeNecessary(): GetFormatInfo() failed"; |
1973 return false; | 2009 return false; |
1974 } | 2010 } |
1975 gfx::Size new_size(base::checked_cast<int>(format.fmt.pix_mp.width), | 2011 gfx::Size new_coded_size(base::checked_cast<int>(format.fmt.pix_mp.width), |
1976 base::checked_cast<int>(format.fmt.pix_mp.height)); | 2012 base::checked_cast<int>(format.fmt.pix_mp.height)); |
1977 if (frame_buffer_size_ != new_size) { | 2013 if (coded_size_ != new_coded_size) { |
1978 DVLOG(3) << "IsResolutionChangeNecessary(): Resolution change detected"; | 2014 DVLOG(3) << "IsResolutionChangeNecessary(): Resolution change detected"; |
1979 return true; | 2015 return true; |
1980 } | 2016 } |
1981 return false; | 2017 return false; |
1982 } | 2018 } |
1983 | 2019 |
1984 } // namespace content | 2020 } // namespace content |
OLD | NEW |