aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDavid Staessens <dstaessens@google.com>2021-03-22 15:50:09 +0900
committerChih-Yu Huang <akahuang@google.com>2021-05-12 11:37:14 +0900
commit8038171d9b86abf49530a11e21cecf0b75062dfa (patch)
tree371397cef6acd322fc6cdb7f3bc90c15a862aefd
parent22e83fd3138d5e79aa1b9dcc46e8f1f8b2ff4a9e (diff)
downloadv4l2_codec2-8038171d9b86abf49530a11e21cecf0b75062dfa.tar.gz
v4l2_codec2: Use Android Rect instead of Chrome Rect.
This CL changes the V4L2 decoder and encoder to use the Android rect structure instead of the one copied from Chrome, the Chrome rect.h file is removed. Bug: 155138142 Test: arc.VideoEncodeAccel.h264_192p_i420_vm arc.VideoDecodeAccel.h264_vm Change-Id: Ie581deee6b4b43a27c45e48269a6902526727933
-rw-r--r--accel/rect.h148
-rw-r--r--accel/video_frame.h1
-rw-r--r--common/Android.bp1
-rw-r--r--common/Common.cpp19
-rw-r--r--common/include/v4l2_codec2/common/Common.h10
-rw-r--r--components/V4L2Decoder.cpp24
-rw-r--r--components/V4L2Encoder.cpp19
-rw-r--r--components/VideoFrame.cpp4
-rw-r--r--components/include/v4l2_codec2/components/V4L2Decoder.h6
-rw-r--r--components/include/v4l2_codec2/components/VideoFrame.h8
10 files changed, 63 insertions, 177 deletions
diff --git a/accel/rect.h b/accel/rect.h
deleted file mode 100644
index b98522d..0000000
--- a/accel/rect.h
+++ /dev/null
@@ -1,148 +0,0 @@
-// Copyright 2017 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-// Note: ported from Chromium commit head: 8a796386c11a
-// Note: only necessary functions are ported from gfx::Rect
-
-// Defines a simple integer rectangle class. The containment semantics
-// are array-like; that is, the coordinate (x, y) is considered to be
-// contained by the rectangle, but the coordinate (x + width, y) is not.
-// The class will happily let you create malformed rectangles (that is,
-// rectangles with negative width and/or height), but there will be assertions
-// in the operations (such as Contains()) to complain in this case.
-
-#ifndef RECT_H_
-#define RECT_H_
-
-#include <string>
-
-#include "base/strings/stringprintf.h"
-#include "size.h"
-
-namespace media {
-
-// Helper struct for rect to replace gfx::Rect usage from original code.
-// Only partial functions of gfx::Rect is implemented here.
-class Rect {
- public:
- constexpr Rect() = default;
- constexpr Rect(int width, int height) : size_(width, height) {}
- constexpr Rect(int x, int y, int width, int height)
- : x_(x),
- y_(y),
- size_(GetClampedValue(x, width), GetClampedValue(y, height)) {}
- constexpr explicit Rect(const Size& size) : size_(size) {}
-
- constexpr int x() const { return x_; }
- // Sets the X position while preserving the width.
- void set_x(int x) {
- x_ = x;
- size_.set_width(GetClampedValue(x, width()));
- }
-
- constexpr int y() const { return y_; }
- // Sets the Y position while preserving the height.
- void set_y(int y) {
- y_ = y;
- size_.set_height(GetClampedValue(y, height()));
- }
-
- constexpr int width() const { return size_.width(); }
- void set_width(int width) { size_.set_width(GetClampedValue(x(), width)); }
-
- constexpr int height() const { return size_.height(); }
- void set_height(int height) {
- size_.set_height(GetClampedValue(y(), height));
- }
-
- constexpr const Size& size() const { return size_; }
- void set_size(const Size& size) {
- set_width(size.width());
- set_height(size.height());
- }
-
- constexpr int right() const { return x() + width(); }
- constexpr int bottom() const { return y() + height(); }
-
- void SetRect(int x, int y, int width, int height) {
- set_x(x);
- set_y(y);
- // Ensure that width and height remain valid.
- set_width(width);
- set_height(height);
- }
-
- // Returns true if the area of the rectangle is zero.
- bool IsEmpty() const { return size_.IsEmpty(); }
-
- // Returns true if this rectangle contains the specified rectangle.
- bool Contains(const Rect& rect) const {
- return (rect.x() >= x() && rect.right() <= right() && rect.y() >= y() &&
- rect.bottom() <= bottom());
- }
-
- // Computes the intersection of this rectangle with the given rectangle.
- void Intersect(const Rect& rect) {
- if (IsEmpty() || rect.IsEmpty()) {
- SetRect(0, 0, 0, 0); // Throws away empty position.
- return;
- }
-
- int left = std::max(x(), rect.x());
- int top = std::max(y(), rect.y());
- int new_right = std::min(right(), rect.right());
- int new_bottom = std::min(bottom(), rect.bottom());
-
- if (left >= new_right || top >= new_bottom) {
- SetRect(0, 0, 0, 0); // Throws away empty position.
- return;
- }
-
- SetRect(left, top, new_right - left, new_bottom - top);
- }
-
- std::string ToString() const {
- return base::StringPrintf("(%d,%d) %s",
- x_, y_, size().ToString().c_str());
- }
-
- private:
- int x_ = 0;
- int y_ = 0;
- Size size_;
-
- // Returns true iff a+b would overflow max int.
- static constexpr bool AddWouldOverflow(int a, int b) {
- // In this function, GCC tries to make optimizations that would only work if
- // max - a wouldn't overflow but it isn't smart enough to notice that a > 0.
- // So cast everything to unsigned to avoid this. As it is guaranteed that
- // max - a and b are both already positive, the cast is a noop.
- //
- // This is intended to be: a > 0 && max - a < b
- return a > 0 && b > 0 &&
- static_cast<unsigned>(std::numeric_limits<int>::max() - a) <
- static_cast<unsigned>(b);
- }
-
- // Clamp the size to avoid integer overflow in bottom() and right().
- // This returns the width given an origin and a width.
- // TODO(enne): this should probably use base::ClampAdd, but that
- // function is not a constexpr.
- static constexpr int GetClampedValue(int origin, int size) {
- return AddWouldOverflow(origin, size)
- ? std::numeric_limits<int>::max() - origin
- : size;
- }
-};
-
-inline bool operator==(const Rect& lhs, const Rect& rhs) {
- return lhs.x() == rhs.x() && lhs.y() == rhs.y() && lhs.size() == rhs.size();
-}
-
-inline bool operator!=(const Rect& lhs, const Rect& rhs) {
- return !(lhs == rhs);
-}
-
-} // namespace media
-
-#endif // RECT_H_
diff --git a/accel/video_frame.h b/accel/video_frame.h
index 55edc15..397c7a1 100644
--- a/accel/video_frame.h
+++ b/accel/video_frame.h
@@ -21,7 +21,6 @@
#include <vector>
#include "base/memory/ref_counted.h"
-#include "rect.h"
#include "size.h"
#include "video_frame_layout.h"
#include "video_pixel_format.h"
diff --git a/common/Android.bp b/common/Android.bp
index ae682c1..e2575d3 100644
--- a/common/Android.bp
+++ b/common/Android.bp
@@ -16,6 +16,7 @@ cc_library {
],
srcs: [
+ "Common.cpp",
"EncodeHelpers.cpp",
"FormatConverter.cpp",
"NalParser.cpp",
diff --git a/common/Common.cpp b/common/Common.cpp
new file mode 100644
index 0000000..d9bbf66
--- /dev/null
+++ b/common/Common.cpp
@@ -0,0 +1,19 @@
+// Copyright 2021 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include <v4l2_codec2/common/Common.h>
+
+namespace android {
+
+bool contains(const Rect& rect1, const Rect& rect2) {
+ return (rect2.left >= rect1.left && rect2.right <= rect1.right && rect2.top >= rect1.top &&
+ rect2.bottom <= rect1.bottom);
+}
+
+std::string toString(const Rect& rect) {
+ return std::string("(") + std::to_string(rect.left) + "," + std::to_string(rect.top) + ") " +
+ std::to_string(rect.width()) + "x" + std::to_string(rect.height());
+}
+
+} // namespace android
diff --git a/common/include/v4l2_codec2/common/Common.h b/common/include/v4l2_codec2/common/Common.h
index 650b7a7..bf4514c 100644
--- a/common/include/v4l2_codec2/common/Common.h
+++ b/common/include/v4l2_codec2/common/Common.h
@@ -7,6 +7,10 @@
#include <inttypes.h>
+#include <string>
+
+#include <ui/Rect.h>
+
namespace android {
// The offset and stride of a video frame plane.
@@ -15,6 +19,12 @@ struct VideoFramePlane {
uint32_t mStride;
};
+// Check whether |rect1| completely contains |rect2|.
+bool contains(const Rect& rect1, const Rect& rect2);
+
+// Convert the specified |rect| to a string.
+std::string toString(const Rect& rect);
+
} // namespace android
#endif // ANDROID_V4L2_CODEC2_COMMON_COMMON_H
diff --git a/components/V4L2Decoder.cpp b/components/V4L2Decoder.cpp
index d6b9d0e..5134826 100644
--- a/components/V4L2Decoder.cpp
+++ b/components/V4L2Decoder.cpp
@@ -16,6 +16,8 @@
#include <base/memory/ptr_util.h>
#include <log/log.h>
+#include <v4l2_codec2/common/Common.h>
+
namespace android {
namespace {
@@ -491,7 +493,7 @@ bool V4L2Decoder::changeResolution() {
mVisibleRect = getVisibleRect(mCodedSize);
ALOGI("Need %zu output buffers. coded size: %s, visible rect: %s", *numOutputBuffers,
- mCodedSize.ToString().c_str(), mVisibleRect.ToString().c_str());
+ mCodedSize.ToString().c_str(), toString(mVisibleRect).c_str());
if (mCodedSize.IsEmpty()) {
ALOGE("Failed to get resolution from V4L2 driver.");
return false;
@@ -636,7 +638,7 @@ std::optional<struct v4l2_format> V4L2Decoder::getFormatInfo() {
return format;
}
-media::Rect V4L2Decoder::getVisibleRect(const media::Size& codedSize) {
+Rect V4L2Decoder::getVisibleRect(const media::Size& codedSize) {
ALOGV("%s()", __func__);
ALOG_ASSERT(mTaskRunner->RunsTasksInCurrentSequence());
@@ -657,22 +659,22 @@ media::Rect V4L2Decoder::getVisibleRect(const media::Size& codedSize) {
if (mDevice->ioctl(VIDIOC_G_CROP, &crop_arg) != 0) {
ALOGW("ioctl() VIDIOC_G_CROP failed");
- return media::Rect(codedSize);
+ return Rect(codedSize.width(), codedSize.height());
}
visible_rect = &crop_arg.c;
}
- media::Rect rect(visible_rect->left, visible_rect->top, visible_rect->width,
- visible_rect->height);
- ALOGV("visible rectangle is %s", rect.ToString().c_str());
- if (!media::Rect(codedSize).Contains(rect)) {
- ALOGW("visible rectangle %s is not inside coded size %s", rect.ToString().c_str(),
+ Rect rect(visible_rect->left, visible_rect->top, visible_rect->left + visible_rect->width,
+ visible_rect->top + visible_rect->height);
+ ALOGV("visible rectangle is %s", toString(rect).c_str());
+ if (!contains(Rect(codedSize.width(), codedSize.height()), rect)) {
+ ALOGW("visible rectangle %s is not inside coded size %s", toString(rect).c_str(),
codedSize.ToString().c_str());
- return media::Rect(codedSize);
+ return Rect(codedSize.width(), codedSize.height());
}
- if (rect.IsEmpty()) {
+ if (rect.isEmpty()) {
ALOGW("visible size is empty");
- return media::Rect(codedSize);
+ return Rect(codedSize.width(), codedSize.height());
}
return rect;
diff --git a/components/V4L2Encoder.cpp b/components/V4L2Encoder.cpp
index a93998a..4080658 100644
--- a/components/V4L2Encoder.cpp
+++ b/components/V4L2Encoder.cpp
@@ -15,8 +15,8 @@
#include <base/files/scoped_file.h>
#include <base/memory/ptr_util.h>
#include <log/log.h>
+#include <ui/Rect.h>
-#include <rect.h>
#include <v4l2_codec2/common/V4L2Device.h>
#include <v4l2_codec2/components/BitstreamBuffer.h>
@@ -472,7 +472,8 @@ bool V4L2Encoder::configureInputFormat(media::VideoPixelFormat inputFormat, uint
}
mInputLayout = layout.value();
- if (!media::Rect(mInputLayout->coded_size()).Contains(media::Rect(mVisibleSize))) {
+ if (!contains(Rect(mInputLayout->coded_size().width(), mInputLayout->coded_size().height()),
+ Rect(mVisibleSize.width(), mVisibleSize.height()))) {
ALOGE("Input size %s exceeds encoder capability, encoder can handle %s",
mVisibleSize.ToString().c_str(), mInputLayout->coded_size().ToString().c_str());
return false;
@@ -497,12 +498,12 @@ bool V4L2Encoder::configureInputFormat(media::VideoPixelFormat inputFormat, uint
// The coded input size might be different from the visible size due to alignment requirements,
// So we need to specify the visible rectangle. Note that this rectangle might still be adjusted
// due to hardware limitations.
- media::Rect visibleRectangle(mVisibleSize.width(), mVisibleSize.height());
+ Rect visibleRectangle(mVisibleSize.width(), mVisibleSize.height());
struct v4l2_rect rect;
memset(&rect, 0, sizeof(rect));
- rect.left = visibleRectangle.x();
- rect.top = visibleRectangle.y();
+ rect.left = visibleRectangle.left;
+ rect.top = visibleRectangle.top;
rect.width = visibleRectangle.width();
rect.height = visibleRectangle.height();
@@ -516,8 +517,9 @@ bool V4L2Encoder::configureInputFormat(media::VideoPixelFormat inputFormat, uint
selection_arg.target = V4L2_SEL_TGT_CROP;
selection_arg.r = rect;
if (mDevice->ioctl(VIDIOC_S_SELECTION, &selection_arg) == 0) {
- visibleRectangle = media::Rect(selection_arg.r.left, selection_arg.r.top,
- selection_arg.r.width, selection_arg.r.height);
+ visibleRectangle = Rect(selection_arg.r.left, selection_arg.r.top,
+ selection_arg.r.left + selection_arg.r.width,
+ selection_arg.r.top + selection_arg.r.height);
} else {
struct v4l2_crop crop;
memset(&crop, 0, sizeof(v4l2_crop));
@@ -528,7 +530,8 @@ bool V4L2Encoder::configureInputFormat(media::VideoPixelFormat inputFormat, uint
ALOGE("Failed to crop to specified visible rectangle");
return false;
}
- visibleRectangle = media::Rect(crop.c.left, crop.c.top, crop.c.width, crop.c.height);
+ visibleRectangle = Rect(crop.c.left, crop.c.top, crop.c.left + crop.c.width,
+ crop.c.top + crop.c.height);
}
ALOGV("Input format set to %s (size: %s, adjusted size: %dx%d, coded size: %s)",
diff --git a/components/VideoFrame.cpp b/components/VideoFrame.cpp
index cb5efb7..b7481ad 100644
--- a/components/VideoFrame.cpp
+++ b/components/VideoFrame.cpp
@@ -34,11 +34,11 @@ const std::vector<int>& VideoFrame::getFDs() const {
return mFds;
}
-void VideoFrame::setVisibleRect(const media::Rect& visibleRect) {
+void VideoFrame::setVisibleRect(const Rect& visibleRect) {
mVisibleRect = visibleRect;
}
-const media::Rect& VideoFrame::getVisibleRect() const {
+const Rect& VideoFrame::getVisibleRect() const {
return mVisibleRect;
}
diff --git a/components/include/v4l2_codec2/components/V4L2Decoder.h b/components/include/v4l2_codec2/components/V4L2Decoder.h
index 3a0b166..3ecadca 100644
--- a/components/include/v4l2_codec2/components/V4L2Decoder.h
+++ b/components/include/v4l2_codec2/components/V4L2Decoder.h
@@ -13,8 +13,8 @@
#include <base/callback.h>
#include <base/memory/weak_ptr.h>
-#include <rect.h>
#include <size.h>
+#include <ui/Rect.h>
#include <v4l2_codec2/common/V4L2Device.h>
#include <v4l2_codec2/common/VideoTypes.h>
#include <v4l2_codec2/components/VideoDecoder.h>
@@ -69,7 +69,7 @@ private:
std::optional<size_t> getNumOutputBuffers();
std::optional<struct v4l2_format> getFormatInfo();
- media::Rect getVisibleRect(const media::Size& codedSize);
+ Rect getVisibleRect(const media::Size& codedSize);
bool sendV4L2DecoderCmd(bool start);
void setState(State newState);
@@ -90,7 +90,7 @@ private:
ErrorCB mErrorCb;
media::Size mCodedSize;
- media::Rect mVisibleRect;
+ Rect mVisibleRect;
std::map<size_t, std::unique_ptr<VideoFrame>> mFrameAtDevice;
diff --git a/components/include/v4l2_codec2/components/VideoFrame.h b/components/include/v4l2_codec2/components/VideoFrame.h
index 2686002..b5d7b99 100644
--- a/components/include/v4l2_codec2/components/VideoFrame.h
+++ b/components/include/v4l2_codec2/components/VideoFrame.h
@@ -10,7 +10,7 @@
#include <C2Buffer.h>
-#include <rect.h>
+#include <ui/Rect.h>
namespace android {
@@ -25,8 +25,8 @@ public:
const std::vector<int>& getFDs() const;
// Getter and setter of the visible rectangle.
- void setVisibleRect(const media::Rect& visibleRect);
- const media::Rect& getVisibleRect() const;
+ void setVisibleRect(const Rect& visibleRect);
+ const Rect& getVisibleRect() const;
// Getter and setter of the bitstream ID of the corresponding input bitstream.
void setBitstreamId(int32_t bitstreamId);
@@ -40,7 +40,7 @@ private:
std::shared_ptr<C2GraphicBlock> mGraphicBlock;
std::vector<int> mFds;
- media::Rect mVisibleRect;
+ Rect mVisibleRect;
int32_t mBitstreamId = -1;
};