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

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
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 704 matching lines...) Expand 10 before | Expand all | Expand 10 after
738 *endpos = size; 739 *endpos = size;
739 return true; 740 return true;
740 } 741 }
741 742
742 // Run this initialization only on first startup. 743 // Run this initialization only on first startup.
743 if (decoder_state_ == kInitialized) { 744 if (decoder_state_ == kInitialized) {
744 DVLOG(3) << "DecodeBufferInitial(): running initialization"; 745 DVLOG(3) << "DecodeBufferInitial(): running initialization";
745 // Success! Setup our parameters. 746 // Success! Setup our parameters.
746 if (!CreateBuffersForFormat(format)) 747 if (!CreateBuffersForFormat(format))
747 return false; 748 return false;
749 if (!GetCropSize(frame_buffer_size_, &frame_visible_size_))
750 frame_visible_size_ = frame_buffer_size_;
748 751
749 // We expect to process the initial buffer once during stream init to 752 // 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 753 // configure stream parameters, but will not consume the steam data on that
751 // iteration. Subsequent iterations (including after reset) do not require 754 // iteration. Subsequent iterations (including after reset) do not require
752 // the stream init step. 755 // the stream init step.
753 *endpos = 0; 756 *endpos = 0;
754 } else { 757 } else {
755 *endpos = size; 758 *endpos = size;
756 } 759 }
757 760
(...skipping 319 matching lines...) Expand 10 before | Expand all | Expand 10 after
1077 output_record.at_device = false; 1080 output_record.at_device = false;
1078 if (dqbuf.m.planes[0].bytesused == 0) { 1081 if (dqbuf.m.planes[0].bytesused == 0) {
1079 // This is an empty output buffer returned as part of a flush. 1082 // This is an empty output buffer returned as part of a flush.
1080 free_output_buffers_.push(dqbuf.index); 1083 free_output_buffers_.push(dqbuf.index);
1081 } else { 1084 } else {
1082 DCHECK_GE(dqbuf.timestamp.tv_sec, 0); 1085 DCHECK_GE(dqbuf.timestamp.tv_sec, 0);
1083 output_record.at_client = true; 1086 output_record.at_client = true;
1084 DVLOG(3) << "Dequeue(): returning input_id=" << dqbuf.timestamp.tv_sec 1087 DVLOG(3) << "Dequeue(): returning input_id=" << dqbuf.timestamp.tv_sec
1085 << " as picture_id=" << output_record.picture_id; 1088 << " as picture_id=" << output_record.picture_id;
1086 const media::Picture& picture = 1089 const media::Picture& picture =
1087 media::Picture(output_record.picture_id, 1090 media::Picture(output_record.picture_id, dqbuf.timestamp.tv_sec,
1088 dqbuf.timestamp.tv_sec, 1091 gfx::Rect(frame_visible_size_));
1089 gfx::Rect(frame_buffer_size_));
1090 pending_picture_ready_.push( 1092 pending_picture_ready_.push(
1091 PictureRecord(output_record.cleared, picture)); 1093 PictureRecord(output_record.cleared, picture));
1092 SendPictureReady(); 1094 SendPictureReady();
1093 output_record.cleared = true; 1095 output_record.cleared = true;
1094 decoder_frames_at_client_++; 1096 decoder_frames_at_client_++;
1095 } 1097 }
1096 output_buffer_queued_count_--; 1098 output_buffer_queued_count_--;
1097 } 1099 }
1098 1100
1099 NotifyFlushDoneIfNeeded(); 1101 NotifyFlushDoneIfNeeded();
(...skipping 439 matching lines...) Expand 10 before | Expand all | Expand 10 after
1539 LOG(ERROR) << "Couldn't get format information after resolution change"; 1541 LOG(ERROR) << "Couldn't get format information after resolution change";
1540 NOTIFY_ERROR(PLATFORM_FAILURE); 1542 NOTIFY_ERROR(PLATFORM_FAILURE);
1541 return; 1543 return;
1542 } 1544 }
1543 1545
1544 if (!CreateBuffersForFormat(format)) { 1546 if (!CreateBuffersForFormat(format)) {
1545 LOG(ERROR) << "Couldn't reallocate buffers after resolution change"; 1547 LOG(ERROR) << "Couldn't reallocate buffers after resolution change";
1546 NOTIFY_ERROR(PLATFORM_FAILURE); 1548 NOTIFY_ERROR(PLATFORM_FAILURE);
1547 return; 1549 return;
1548 } 1550 }
1551 if (!GetCropSize(frame_buffer_size_, &frame_visible_size_))
Pawel Osciak 2015/01/29 05:02:04 Could we call this from GetFormatInfo()?
kcwu 2015/01/29 09:33:11 Done.
1552 frame_visible_size_ = frame_buffer_size_;
1549 1553
1550 decoder_state_ = kDecoding; 1554 decoder_state_ = kDecoding;
1551 1555
1552 if (resolution_change_reset_pending_) { 1556 if (resolution_change_reset_pending_) {
1553 resolution_change_reset_pending_ = false; 1557 resolution_change_reset_pending_ = false;
1554 ResetTask(); 1558 ResetTask();
1555 return; 1559 return;
1556 } 1560 }
1557 1561
1558 if (!StartDevicePoll()) 1562 if (!StartDevicePoll())
(...skipping 81 matching lines...) Expand 10 before | Expand all | Expand 10 after
1640 return false; 1644 return false;
1641 } 1645 }
1642 1646
1643 return true; 1647 return true;
1644 } 1648 }
1645 1649
1646 bool V4L2VideoDecodeAccelerator::CreateBuffersForFormat( 1650 bool V4L2VideoDecodeAccelerator::CreateBuffersForFormat(
1647 const struct v4l2_format& format) { 1651 const struct v4l2_format& format) {
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 frame_buffer_size_.SetSize(
Owen Lin 2015/01/29 02:42:09 Since we set |frame_buffer_size_| here, how about
kcwu 2015/01/29 02:58:38 I'm not sure ... since this function is named "Cre
Owen Lin 2015/01/29 03:40:11 But we have already set |frame_buffer_size_| insid
kcwu 2015/01/29 09:33:10 Moved to GetFormatInfo()
1651 format.fmt.pix_mp.width, format.fmt.pix_mp.height); 1655 format.fmt.pix_mp.width, format.fmt.pix_mp.height);
1652 DVLOG(3) << "CreateBuffersForFormat(): new resolution: " 1656 DVLOG(3) << "CreateBuffersForFormat(): new resolution: "
1653 << frame_buffer_size_.ToString(); 1657 << frame_buffer_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::GetCropSize(const gfx::Size& buffer_size,
1666 gfx::Size* crop_size) {
1667 DCHECK_EQ(decoder_thread_.message_loop(), base::MessageLoop::current());
1668
1669 struct v4l2_crop crop_arg;
Pawel Osciak 2015/01/29 05:02:04 memset to 0 please.
kcwu 2015/01/29 09:33:10 Done.
1670 crop_arg.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
1671
1672 IOCTL_OR_ERROR_RETURN_FALSE(VIDIOC_G_CROP, &crop_arg);
1673
1674 gfx::Rect rect(crop_arg.c.left, crop_arg.c.top, crop_arg.c.width,
1675 crop_arg.c.height);
1676 DVLOG(3) << "Crop rectangle is " << rect.ToString();
Pawel Osciak 2015/01/29 05:02:04 Let's stop calling this crop and say visible size
kcwu 2015/01/29 09:33:11 Done.
1677 if (!gfx::Rect(buffer_size).Contains(rect)) {
Pawel Osciak 2015/01/29 05:02:04 Please also check if it's !Empty()
kcwu 2015/01/29 09:33:10 Done.
1678 DLOG(ERROR) << "crop rectangle " << rect.ToString()
1679 << " is not inside buffer size " << buffer_size.ToString();
1680 return false;
1681 }
1682
1683 if (!rect.origin().IsOrigin()) {
Pawel Osciak 2015/01/29 05:02:04 Please add a comment why.
kcwu 2015/01/29 09:33:10 Done.
1684 DLOG(ERROR) << "Unexpected crop rectangle " << rect.ToString()
1685 << ", top-left is not origin";
1686 return false;
1687 }
1688 *crop_size = rect.size();
1689
1690 return true;
1691 }
1692
1661 bool V4L2VideoDecodeAccelerator::CreateInputBuffers() { 1693 bool V4L2VideoDecodeAccelerator::CreateInputBuffers() {
1662 DVLOG(3) << "CreateInputBuffers()"; 1694 DVLOG(3) << "CreateInputBuffers()";
1663 // We always run this as we prepare to initialize. 1695 // We always run this as we prepare to initialize.
1664 DCHECK_EQ(decoder_state_, kUninitialized); 1696 DCHECK_EQ(decoder_state_, kUninitialized);
1665 DCHECK(!input_streamon_); 1697 DCHECK(!input_streamon_);
1666 DCHECK(input_buffer_map_.empty()); 1698 DCHECK(input_buffer_map_.empty());
1667 1699
1668 struct v4l2_requestbuffers reqbufs; 1700 struct v4l2_requestbuffers reqbufs;
1669 memset(&reqbufs, 0, sizeof(reqbufs)); 1701 memset(&reqbufs, 0, sizeof(reqbufs));
1670 reqbufs.count = kInputBufferCount; 1702 reqbufs.count = kInputBufferCount;
(...skipping 300 matching lines...) Expand 10 before | Expand all | Expand 10 after
1971 if (!ret || again) { 2003 if (!ret || again) {
1972 DVLOG(3) << "IsResolutionChangeNecessary(): GetFormatInfo() failed"; 2004 DVLOG(3) << "IsResolutionChangeNecessary(): GetFormatInfo() failed";
1973 return false; 2005 return false;
1974 } 2006 }
1975 gfx::Size new_size(base::checked_cast<int>(format.fmt.pix_mp.width), 2007 gfx::Size new_size(base::checked_cast<int>(format.fmt.pix_mp.width),
1976 base::checked_cast<int>(format.fmt.pix_mp.height)); 2008 base::checked_cast<int>(format.fmt.pix_mp.height));
1977 if (frame_buffer_size_ != new_size) { 2009 if (frame_buffer_size_ != new_size) {
1978 DVLOG(3) << "IsResolutionChangeNecessary(): Resolution change detected"; 2010 DVLOG(3) << "IsResolutionChangeNecessary(): Resolution change detected";
1979 return true; 2011 return true;
1980 } 2012 }
2013
2014 gfx::Size new_crop_size;
2015 if (GetCropSize(new_size, &new_crop_size) &&
2016 new_crop_size != frame_visible_size_) {
2017 DVLOG(3) << "IsResolutionChangeNecessary(): crop size change detected";
Pawel Osciak 2015/01/29 05:02:04 Crop size does not influence resolution change. If
kcwu 2015/01/29 09:33:11 Done.
2018 return true;
2019 }
2020
1981 return false; 2021 return false;
1982 } 2022 }
1983 2023
1984 } // namespace content 2024 } // namespace content
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698