120 lines
5.2 KiB
Diff
120 lines
5.2 KiB
Diff
From: Michael Froman <mfroman@mozilla.com>
|
|
Date: Thu, 20 Aug 2026 15:17:00 +0000
|
|
Subject: Bug 1996020 - Add I420Buffer::CreateOrNull and use it in
|
|
VideoCaptureImpl::IncomingFrame. r=bwc
|
|
|
|
Differential Revision: https://phabricator.services.mozilla.com/D318847
|
|
Mercurial Revision: https://hg.mozilla.org/mozilla-central/rev/f0c6e846e0d33294378079b83208d1a91c5bf293
|
|
---
|
|
api/video/i420_buffer.cc | 27 ++++++++++++++++++---
|
|
api/video/i420_buffer.h | 15 +++++++++++-
|
|
modules/video_capture/video_capture_impl.cc | 11 ++++++++-
|
|
3 files changed, 47 insertions(+), 6 deletions(-)
|
|
|
|
diff --git a/api/video/i420_buffer.cc b/api/video/i420_buffer.cc
|
|
index e9320ced2a..4eec83cd3a 100644
|
|
--- a/api/video/i420_buffer.cc
|
|
+++ b/api/video/i420_buffer.cc
|
|
@@ -54,15 +54,18 @@ I420Buffer::I420Buffer(int width,
|
|
int height,
|
|
int stride_y,
|
|
int stride_u,
|
|
- int stride_v)
|
|
+ int stride_v,
|
|
+ uint8_t* data)
|
|
: width_(width),
|
|
height_(height),
|
|
stride_y_(stride_y),
|
|
stride_u_(stride_u),
|
|
stride_v_(stride_v),
|
|
- data_(static_cast<uint8_t*>(AlignedMalloc(
|
|
- I420DataSize(width, height, stride_y, stride_u, stride_v),
|
|
- kBufferAlignment))) {
|
|
+ data_(data ? data
|
|
+ : static_cast<uint8_t*>(AlignedMalloc(
|
|
+ I420DataSize(width, height, stride_y, stride_u,
|
|
+ stride_v),
|
|
+ kBufferAlignment))) {
|
|
RTC_DCHECK_GE(stride_u, (width + 1) / 2);
|
|
RTC_DCHECK_GE(stride_v, (width + 1) / 2);
|
|
}
|
|
@@ -84,6 +87,22 @@ scoped_refptr<I420Buffer> I420Buffer::Create(int width,
|
|
stride_v);
|
|
}
|
|
|
|
+// static
|
|
+scoped_refptr<I420Buffer> I420Buffer::CreateOrNull(int width,
|
|
+ int height,
|
|
+ int stride_y,
|
|
+ int stride_u,
|
|
+ int stride_v) {
|
|
+ uint8_t* data = AlignedMallocOrNull<uint8_t>(
|
|
+ I420DataSize(width, height, stride_y, stride_u, stride_v),
|
|
+ kBufferAlignment);
|
|
+ if (!data) {
|
|
+ return nullptr;
|
|
+ }
|
|
+ return make_ref_counted<I420Buffer>(width, height, stride_y, stride_u,
|
|
+ stride_v, data);
|
|
+}
|
|
+
|
|
// static
|
|
scoped_refptr<I420Buffer> I420Buffer::Copy(const I420BufferInterface& source) {
|
|
return Copy(source.width(), source.height(), source.DataY(), source.StrideY(),
|
|
diff --git a/api/video/i420_buffer.h b/api/video/i420_buffer.h
|
|
index a7a0fb014d..e4935b430c 100644
|
|
--- a/api/video/i420_buffer.h
|
|
+++ b/api/video/i420_buffer.h
|
|
@@ -32,6 +32,11 @@ class RTC_EXPORT I420Buffer : public I420BufferInterface {
|
|
int stride_y,
|
|
int stride_u,
|
|
int stride_v);
|
|
+ static scoped_refptr<I420Buffer> CreateOrNull(int width,
|
|
+ int height,
|
|
+ int stride_y,
|
|
+ int stride_u,
|
|
+ int stride_v);
|
|
|
|
// Create a new buffer and copy the pixel data.
|
|
static scoped_refptr<I420Buffer> Copy(const I420BufferInterface& buffer);
|
|
@@ -100,7 +105,15 @@ class RTC_EXPORT I420Buffer : public I420BufferInterface {
|
|
|
|
protected:
|
|
I420Buffer(int width, int height);
|
|
- I420Buffer(int width, int height, int stride_y, int stride_u, int stride_v);
|
|
+ // If `data` is non-null, it must have been allocated with AlignedMalloc and
|
|
+ // be large enough to hold the planes described by the strides; the buffer
|
|
+ // takes ownership of it. Otherwise the data is allocated by the constructor.
|
|
+ I420Buffer(int width,
|
|
+ int height,
|
|
+ int stride_y,
|
|
+ int stride_u,
|
|
+ int stride_v,
|
|
+ uint8_t* data = nullptr);
|
|
|
|
~I420Buffer() override;
|
|
|
|
diff --git a/modules/video_capture/video_capture_impl.cc b/modules/video_capture/video_capture_impl.cc
|
|
index ed83ab6e57..7bf88028ef 100644
|
|
--- a/modules/video_capture/video_capture_impl.cc
|
|
+++ b/modules/video_capture/video_capture_impl.cc
|
|
@@ -200,8 +200,17 @@ int32_t VideoCaptureImpl::IncomingFrame(uint8_t* videoFrame,
|
|
// Setting absolute height (in case it was negative).
|
|
// In Windows, the image starts bottom left, instead of top left.
|
|
// Setting a negative source height, inverts the image (within LibYuv).
|
|
- scoped_refptr<I420Buffer> buffer = I420Buffer::Create(
|
|
+ scoped_refptr<I420Buffer> buffer = I420Buffer::CreateOrNull(
|
|
target_width, target_height, stride_y, stride_uv, stride_uv);
|
|
+ if (!buffer) {
|
|
+ RTC_LOG(LS_ERROR) << "Unable to allocate I420Buffer"
|
|
+ << " (w: " << target_width
|
|
+ << ", h: " << target_height
|
|
+ << ", stride_y: " << stride_y
|
|
+ << ", stride_u: " << stride_uv
|
|
+ << ", stride_v: " << stride_uv << ")";
|
|
+ return -1;
|
|
+ }
|
|
|
|
libyuv::RotationMode rotation_mode = libyuv::kRotate0;
|
|
if (apply_rotation_) {
|