Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(27)

Side by Side Diff: content/common/gpu/media/v4l2_video_decode_accelerator.cc

Issue 874083005: Fix visible size for V4L2 VDA (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Created 5 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « content/common/gpu/media/v4l2_video_decode_accelerator.h ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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
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
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
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
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
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
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
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
OLDNEW
« no previous file with comments | « content/common/gpu/media/v4l2_video_decode_accelerator.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698