fix for auto spanification for video encoder [chromium/src : main]

0 views
Skip to first unread message

Daniel Angulo (Gerrit)

unread,
Nov 7, 2025, 6:39:17 PM11/7/25
to Danilo Françoso Tedeschi, Sergio Solano, Andres Munoz Medina, Chromium LUCI CQ, AyeAye, chromotin...@chromium.org
Attention needed from Andres Munoz Medina, Danilo Françoso Tedeschi and Sergio Solano

Daniel Angulo voted Commit-Queue+1

Commit-Queue+1
Open in Gerrit

Related details

Attention is currently required from:
  • Andres Munoz Medina
  • Danilo Françoso Tedeschi
  • Sergio Solano
Submit Requirements:
  • requirement satisfiedCode-Coverage
  • requirement is not satisfiedCode-Owners
  • requirement is not satisfiedCode-Review
  • requirement is not satisfiedNo-Unresolved-Comments
  • requirement is not satisfiedReview-Enforcement
Inspect html for hidden footers to help with email filtering. To unsubscribe visit settings. DiffyGerrit
Gerrit-MessageType: comment
Gerrit-Project: chromium/src
Gerrit-Branch: main
Gerrit-Change-Id: Ic92b67ca9e64de7766e8305e76761b0c4a5c3db1
Gerrit-Change-Number: 7101649
Gerrit-PatchSet: 6
Gerrit-Owner: Daniel Angulo <angd...@google.com>
Gerrit-Reviewer: Andres Munoz Medina <amme...@google.com>
Gerrit-Reviewer: Daniel Angulo <angd...@google.com>
Gerrit-Reviewer: Danilo Françoso Tedeschi <da...@google.com>
Gerrit-Reviewer: Sergio Solano <sergio...@google.com>
Gerrit-Attention: Danilo Françoso Tedeschi <da...@google.com>
Gerrit-Attention: Sergio Solano <sergio...@google.com>
Gerrit-Attention: Andres Munoz Medina <amme...@google.com>
Gerrit-Comment-Date: Fri, 07 Nov 2025 23:39:05 +0000
Gerrit-HasComments: No
Gerrit-Has-Labels: Yes
satisfied_requirement
unsatisfied_requirement
open
diffy

Danilo Françoso Tedeschi (Gerrit)

unread,
Nov 10, 2025, 9:58:52 AM11/10/25
to Daniel Angulo, Sergio Solano, Andres Munoz Medina, Chromium LUCI CQ, AyeAye, chromotin...@chromium.org
Attention needed from Andres Munoz Medina, Daniel Angulo and Sergio Solano

Danilo Françoso Tedeschi added 1 comment

File remoting/codec/video_encoder_verbatim.cc
Line 77, Patchset 6 (Latest): auto rect_span = frame_data.subspan(rect_offset);
Danilo Françoso Tedeschi . unresolved

I'd prefer to declare the type here as base::span<const uint8_t> rather than use auto, even though it is clear that we are creating a span with subspan, but it would be nice to know it is constant and this also makes it more clear that you are not making a copy.

Open in Gerrit

Related details

Attention is currently required from:
  • Andres Munoz Medina
  • Daniel Angulo
  • Sergio Solano
Submit Requirements:
  • requirement satisfiedCode-Coverage
  • requirement is not satisfiedCode-Owners
  • requirement is not satisfiedCode-Review
  • requirement is not satisfiedNo-Unresolved-Comments
  • requirement is not satisfiedReview-Enforcement
Inspect html for hidden footers to help with email filtering. To unsubscribe visit settings. DiffyGerrit
Gerrit-MessageType: comment
Gerrit-Project: chromium/src
Gerrit-Branch: main
Gerrit-Change-Id: Ic92b67ca9e64de7766e8305e76761b0c4a5c3db1
Gerrit-Change-Number: 7101649
Gerrit-PatchSet: 6
Gerrit-Owner: Daniel Angulo <angd...@google.com>
Gerrit-Reviewer: Andres Munoz Medina <amme...@google.com>
Gerrit-Reviewer: Daniel Angulo <angd...@google.com>
Gerrit-Reviewer: Danilo Françoso Tedeschi <da...@google.com>
Gerrit-Reviewer: Sergio Solano <sergio...@google.com>
Gerrit-Attention: Daniel Angulo <angd...@google.com>
Gerrit-Attention: Sergio Solano <sergio...@google.com>
Gerrit-Attention: Andres Munoz Medina <amme...@google.com>
Gerrit-Comment-Date: Mon, 10 Nov 2025 14:58:43 +0000
Gerrit-HasComments: Yes
Gerrit-Has-Labels: No
satisfied_requirement
unsatisfied_requirement
open
diffy

Daniel Angulo (Gerrit)

unread,
Nov 10, 2025, 12:20:33 PM11/10/25
to Danilo Françoso Tedeschi, Sergio Solano, Andres Munoz Medina, Chromium LUCI CQ, AyeAye, chromotin...@chromium.org
Attention needed from Andres Munoz Medina, Danilo Françoso Tedeschi and Sergio Solano

Daniel Angulo added 1 comment

File remoting/codec/video_encoder_verbatim.cc
Line 77, Patchset 6: auto rect_span = frame_data.subspan(rect_offset);
Danilo Françoso Tedeschi . resolved

I'd prefer to declare the type here as base::span<const uint8_t> rather than use auto, even though it is clear that we are creating a span with subspan, but it would be nice to know it is constant and this also makes it more clear that you are not making a copy.

Daniel Angulo

sure

Open in Gerrit

Related details

Attention is currently required from:
  • Andres Munoz Medina
  • Danilo Françoso Tedeschi
  • Sergio Solano
Submit Requirements:
  • requirement satisfiedCode-Coverage
  • requirement is not satisfiedCode-Owners
  • requirement is not satisfiedCode-Review
  • requirement is not satisfiedNo-Unresolved-Comments
  • requirement is not satisfiedReview-Enforcement
Inspect html for hidden footers to help with email filtering. To unsubscribe visit settings. DiffyGerrit
Gerrit-MessageType: comment
Gerrit-Project: chromium/src
Gerrit-Branch: main
Gerrit-Change-Id: Ic92b67ca9e64de7766e8305e76761b0c4a5c3db1
Gerrit-Change-Number: 7101649
Gerrit-PatchSet: 8
Gerrit-Owner: Daniel Angulo <angd...@google.com>
Gerrit-Reviewer: Andres Munoz Medina <amme...@google.com>
Gerrit-Reviewer: Daniel Angulo <angd...@google.com>
Gerrit-Reviewer: Danilo Françoso Tedeschi <da...@google.com>
Gerrit-Reviewer: Sergio Solano <sergio...@google.com>
Gerrit-Attention: Danilo Françoso Tedeschi <da...@google.com>
Gerrit-Attention: Sergio Solano <sergio...@google.com>
Gerrit-Attention: Andres Munoz Medina <amme...@google.com>
Gerrit-Comment-Date: Mon, 10 Nov 2025 17:20:22 +0000
Gerrit-HasComments: Yes
Gerrit-Has-Labels: No
Comment-In-Reply-To: Danilo Françoso Tedeschi <da...@google.com>
satisfied_requirement
unsatisfied_requirement
open
diffy

Stephen Nusko (Gerrit)

unread,
Nov 11, 2025, 6:47:19 PM11/11/25
to Daniel Angulo, Danilo Françoso Tedeschi, Sergio Solano, Andres Munoz Medina, Chromium LUCI CQ, AyeAye, chromotin...@chromium.org
Attention needed from Andres Munoz Medina, Daniel Angulo, Danilo Françoso Tedeschi and Sergio Solano

Stephen Nusko added 4 comments

File remoting/codec/video_encoder_verbatim.cc
Line 27, Patchset 9 (Latest): return base::as_writable_bytes(base::span(*packet->mutable_data()));
Stephen Nusko . unresolved

nit: you don't need base::span the vector will implicitly convert to base::span.

Line 66, Patchset 9 (Latest): static_cast<size_t>(frame.size().height() * frame.size().width() *
Stephen Nusko . unresolved

height and/or width could be negative (see https://source.chromium.org/chromium/chromium/src/+/main:third_party/webrtc/modules/desktop_capture/desktop_geometry.h;l=69;drc=a7cdebe0e5025250794e1407e6880141e3520bb1)

we can't therefore use a static cast for these. We need to assert they are >= zero. We can either do that or rely on the fact that is_empty() function currently does that.

So we need a

`CHECK(!frame.size().is_empty() && in_stride > 0);`
or
`CHECK(frame.size().height() > 0 && frame.size().width() > 0 && in_stride > 0);`

and then we could static cast.

Or we can use

base::checked_cast<size_t> or base::CheckedNumerics<size_t> and then compute the size.

I'd probably go with the last one.

Line 62, Patchset 9 (Latest): // SAFETY: The `.data()` pointer is valid for the lifetime of `frame`, and
// the span is constructed with the correct size.
base::span<const uint8_t> frame_data = UNSAFE_BUFFERS(base::span(
frame.data(),
static_cast<size_t>(frame.size().height() * frame.size().width() *
webrtc::DesktopFrame::kBytesPerPixel)));
Stephen Nusko . unresolved

I'm not sure this is correct and the safety comment of "it is the correct size" is not enough to convince me the reader that it is.

For example take [DesktopFrameSkia](https://source.chromium.org/chromium/chromium/src/+/main:content/browser/media/capture/desktop_frame_skia.cc;l=11;drc=a7cdebe0e5025250794e1407e6880141e3520bb1)

```
DesktopFrameSkia::DesktopFrameSkia(const SkBitmap& bitmap)
: webrtc::DesktopFrame(webrtc::DesktopSize(bitmap.width(), bitmap.height()),
bitmap.rowBytes(),
static_cast<uint8_t*>(bitmap.getPixels()),
nullptr),
bitmap_(bitmap) {}
```

data is `bitmap.getPixels()`, and DesktopSize is `bitmap.width()` + `bitmap.height()`

However this doesn't account for extra padding space which might exist inside the bitmap.

You can see this in the [documentation for rowbytes](https://source.chromium.org/chromium/chromium/src/+/main:third_party/skia/include/core/SkPixmap.h;l=69;drc=a7cdebe0e5025250794e1407e6880141e3520bb1)
```
@param rowBytes size of one row of addr; width times pixel size, or larger
```

The or larger is what poses the problem. We have restricted the the span to only kBytesPerPixel but that actually isn't the right computation. You need rowBytes. I believe in this code it is instride. From DesktopFrame

```
// Distance in the buffer between two neighboring rows in bytes.
int stride() const { return stride_; }
```

Really ideally we would want to update DesktopFrame to have a method to get a span, but since WebRTC is third_party so to spanify it we would need to add a new method.

So for this CL we really really need to make sure we get this right, and as it stands I'm not so sure we've computed this properly.

It should be

```
in_stride * frame.size().width() * frame.size().height()
```

I'm not sure kBytesPerPixel is required? I think it is included in `in_stride`

Also because this is quite complex and we have no API or simple thing I would live this as UNSAFE_TODO, we aren't confident enough to do UNSAFE_BUFFERS.

Line 75, Patchset 9 (Latest): static_cast<size_t>(rect.top()) * in_stride +
Stephen Nusko . resolved

this one is "sort" of fine because if it is negative we only use it to access into our span so we'll properly bounds check so at worst we crash in the next line.

Open in Gerrit

Related details

Attention is currently required from:
  • Andres Munoz Medina
  • Daniel Angulo
  • Danilo Françoso Tedeschi
  • Sergio Solano
Submit Requirements:
  • requirement satisfiedCode-Coverage
  • requirement is not satisfiedCode-Owners
  • requirement is not satisfiedCode-Review
  • requirement is not satisfiedNo-Unresolved-Comments
  • requirement is not satisfiedReview-Enforcement
Inspect html for hidden footers to help with email filtering. To unsubscribe visit settings. DiffyGerrit
Gerrit-MessageType: comment
Gerrit-Project: chromium/src
Gerrit-Branch: main
Gerrit-Change-Id: Ic92b67ca9e64de7766e8305e76761b0c4a5c3db1
Gerrit-Change-Number: 7101649
Gerrit-PatchSet: 9
Gerrit-Owner: Daniel Angulo <angd...@google.com>
Gerrit-Reviewer: Andres Munoz Medina <amme...@google.com>
Gerrit-Reviewer: Daniel Angulo <angd...@google.com>
Gerrit-Reviewer: Danilo Françoso Tedeschi <da...@google.com>
Gerrit-Reviewer: Sergio Solano <sergio...@google.com>
Gerrit-Reviewer: Stephen Nusko <nus...@chromium.org>
Gerrit-Attention: Danilo Françoso Tedeschi <da...@google.com>
Gerrit-Attention: Daniel Angulo <angd...@google.com>
Gerrit-Attention: Sergio Solano <sergio...@google.com>
Gerrit-Attention: Andres Munoz Medina <amme...@google.com>
Gerrit-Comment-Date: Tue, 11 Nov 2025 23:47:14 +0000
Gerrit-HasComments: Yes
Gerrit-Has-Labels: No
satisfied_requirement
unsatisfied_requirement
open
diffy

Daniel Angulo (Gerrit)

unread,
Nov 28, 2025, 11:01:43 AM11/28/25
to Andres Munoz Medina, Sergio Solano, Danilo Françoso Tedeschi, Code Review Nudger, Stephen Nusko, Chromium LUCI CQ, AyeAye, chromotin...@chromium.org

Daniel Angulo added 1 comment

File remoting/codec/video_encoder_verbatim.cc
Line 72, Patchset 1: const size_t rect_offset =

static_cast<size_t>(rect.top()) * in_stride +
static_cast<size_t>(rect.left()) * webrtc::DesktopFrame::kBytesPerPixel;
auto rect_span = frame_data.subspan(rect_offset);

for (int y = 0; y < rect.height(); ++y) {
auto row_span = rect_span.subspan(static_cast<size_t>(y) * in_stride,
static_cast<size_t>(row_size));
out.first(static_cast<size_t>(row_size)).copy_from(row_span);
out = out.subspan(static_cast<size_t>(row_size));
Andres Munoz Medina . resolved

Just please triple check there is a test for this function. The change from pointer arithmetic to span arithmetic is subtle. I think it is correct but we should make sure that there's a test properly exercising this function.

Daniel Angulo

this file test calling the Encode remoting/protocol/video_frame_pump_unittest.cc:182 and this file tests the rects from encoding remoting/codec/codec_test.cc:236

Daniel Angulo

Acknowledged

Open in Gerrit

Related details

Attention set is empty
Submit Requirements:
  • requirement satisfiedCode-Coverage
  • requirement is not satisfiedCode-Owners
  • requirement is not satisfiedCode-Review
  • requirement is not satisfiedNo-Unresolved-Comments
  • requirement is not satisfiedReview-Enforcement
Inspect html for hidden footers to help with email filtering. To unsubscribe visit settings. DiffyGerrit
Gerrit-MessageType: comment
Gerrit-Project: chromium/src
Gerrit-Branch: main
Gerrit-Change-Id: Ic92b67ca9e64de7766e8305e76761b0c4a5c3db1
Gerrit-Change-Number: 7101649
Gerrit-PatchSet: 10
Gerrit-Owner: Daniel Angulo <angd...@google.com>
Gerrit-Reviewer: Daniel Angulo <angd...@google.com>
Gerrit-Reviewer: Stephen Nusko <nus...@chromium.org>
Gerrit-CC: Andres Munoz Medina <amme...@google.com>
Gerrit-CC: Code Review Nudger <android-build...@prod.google.com>
Gerrit-CC: Danilo Françoso Tedeschi <da...@google.com>
Gerrit-CC: Sergio Solano <sergio...@google.com>
Gerrit-Comment-Date: Fri, 28 Nov 2025 16:01:32 +0000
Gerrit-HasComments: Yes
Gerrit-Has-Labels: No
Comment-In-Reply-To: Daniel Angulo <angd...@google.com>
Comment-In-Reply-To: Andres Munoz Medina <amme...@google.com>
satisfied_requirement
unsatisfied_requirement
open
diffy

Daniel Angulo (Gerrit)

unread,
Jan 5, 2026, 1:11:14 PMJan 5
to Andres Munoz Medina, Sergio Solano, Danilo Françoso Tedeschi, Code Review Nudger, Stephen Nusko, Chromium LUCI CQ, AyeAye, chromotin...@chromium.org
Attention needed from Stephen Nusko

Daniel Angulo added 2 comments

File remoting/codec/video_encoder_verbatim.cc
Line 27, Patchset 9: return base::as_writable_bytes(base::span(*packet->mutable_data()));
Stephen Nusko . resolved

nit: you don't need base::span the vector will implicitly convert to base::span.

Daniel Angulo

Done

Line 66, Patchset 9: static_cast<size_t>(frame.size().height() * frame.size().width() *
Stephen Nusko . resolved

height and/or width could be negative (see https://source.chromium.org/chromium/chromium/src/+/main:third_party/webrtc/modules/desktop_capture/desktop_geometry.h;l=69;drc=a7cdebe0e5025250794e1407e6880141e3520bb1)

we can't therefore use a static cast for these. We need to assert they are >= zero. We can either do that or rely on the fact that is_empty() function currently does that.

So we need a

`CHECK(!frame.size().is_empty() && in_stride > 0);`
or
`CHECK(frame.size().height() > 0 && frame.size().width() > 0 && in_stride > 0);`

and then we could static cast.

Or we can use

base::checked_cast<size_t> or base::CheckedNumerics<size_t> and then compute the size.

I'd probably go with the last one.

Daniel Angulo

Done

Open in Gerrit

Related details

Attention is currently required from:
  • Stephen Nusko
Submit Requirements:
  • requirement satisfiedCode-Coverage
  • requirement is not satisfiedCode-Owners
  • requirement is not satisfiedCode-Review
  • requirement is not satisfiedNo-Unresolved-Comments
  • requirement is not satisfiedReview-Enforcement
Inspect html for hidden footers to help with email filtering. To unsubscribe visit settings. DiffyGerrit
Gerrit-MessageType: comment
Gerrit-Project: chromium/src
Gerrit-Branch: main
Gerrit-Change-Id: Ic92b67ca9e64de7766e8305e76761b0c4a5c3db1
Gerrit-Change-Number: 7101649
Gerrit-PatchSet: 13
Gerrit-Owner: Daniel Angulo <angd...@google.com>
Gerrit-Reviewer: Daniel Angulo <angd...@google.com>
Gerrit-Reviewer: Stephen Nusko <nus...@chromium.org>
Gerrit-CC: Andres Munoz Medina <amme...@google.com>
Gerrit-CC: Code Review Nudger <android-build...@prod.google.com>
Gerrit-CC: Danilo Françoso Tedeschi <da...@google.com>
Gerrit-CC: Sergio Solano <sergio...@google.com>
Gerrit-Attention: Stephen Nusko <nus...@chromium.org>
Gerrit-Comment-Date: Mon, 05 Jan 2026 18:11:04 +0000
Gerrit-HasComments: Yes
Gerrit-Has-Labels: No
Comment-In-Reply-To: Stephen Nusko <nus...@chromium.org>
satisfied_requirement
unsatisfied_requirement
open
diffy

Kalvin Lee (Gerrit)

unread,
Jan 6, 2026, 3:23:33 AMJan 6
to Daniel Angulo, Andres Munoz Medina, Sergio Solano, Danilo Françoso Tedeschi, Code Review Nudger, Stephen Nusko, Chromium LUCI CQ, AyeAye, chromotin...@chromium.org
Attention needed from Daniel Angulo and Stephen Nusko

Kalvin Lee added 2 comments

File remoting/codec/video_encoder_verbatim.cc
Line 28, Patchset 15 (Latest): return UNSAFE_BUFFERS(
base::span(reinterpret_cast<uint8_t*>(data->data()), size));
Kalvin Lee . unresolved

Unless I'm wrong about how `resize()` works, I think this can be much terser as

```
base::as_writable_bytes(base::span(*data))
```

and as a bonus it sheds `UNSAFE_BUFFERS`, too.

Line 64, Patchset 15 (Latest): CHECK(frame.size().height() > 0 && frame.size().width() > 0 && in_stride > 0);
Kalvin Lee . unresolved

IMHO this section is pretty hard to follow. I'm not comfortable being primary reviewer for this and I think you can consider directly roping in a proper owner for this.

However, looking at this clump of casts, I think I would prefer putting off this change for now, and

1. Look at implementing span accessors for `webrtc::DesktopFrame` (and inherited classes). [You may need to check with WebRTC folks if this should be `ArrayView` or `std::span`](https://issues.webrtc.org/issues/439801349).

1. (Wait for the WebRTC roll into Chromium --- refresh your tree)

1. Come back to this CL and see if it's possible to reorganize the casts. (Maybe you could even implement checked accessors for `webrtc::DesktopSize` --- I don't think there's any real reason we should _want_ to get negative values out of that class.)

If you feel strongly about what you have written so far, though, feel free to loop in a proper owner directly and I'm happy to cast a second CR+1 (as long as they're happy, too).

Open in Gerrit

Related details

Attention is currently required from:
  • Daniel Angulo
  • Stephen Nusko
Submit Requirements:
  • requirement satisfiedCode-Coverage
  • requirement is not satisfiedCode-Owners
  • requirement is not satisfiedCode-Review
  • requirement is not satisfiedNo-Unresolved-Comments
  • requirement is not satisfiedReview-Enforcement
Inspect html for hidden footers to help with email filtering. To unsubscribe visit settings. DiffyGerrit
Gerrit-MessageType: comment
Gerrit-Project: chromium/src
Gerrit-Branch: main
Gerrit-Change-Id: Ic92b67ca9e64de7766e8305e76761b0c4a5c3db1
Gerrit-Change-Number: 7101649
Gerrit-PatchSet: 15
Gerrit-Owner: Daniel Angulo <angd...@google.com>
Gerrit-Reviewer: Daniel Angulo <angd...@google.com>
Gerrit-Reviewer: Kalvin Lee <kd...@chromium.org>
Gerrit-Reviewer: Stephen Nusko <nus...@chromium.org>
Gerrit-CC: Andres Munoz Medina <amme...@google.com>
Gerrit-CC: Code Review Nudger <android-build...@prod.google.com>
Gerrit-CC: Danilo Françoso Tedeschi <da...@google.com>
Gerrit-CC: Sergio Solano <sergio...@google.com>
Gerrit-Attention: Stephen Nusko <nus...@chromium.org>
Gerrit-Attention: Daniel Angulo <angd...@google.com>
Gerrit-Comment-Date: Tue, 06 Jan 2026 08:23:01 +0000
Gerrit-HasComments: Yes
Gerrit-Has-Labels: No
satisfied_requirement
unsatisfied_requirement
open
diffy

Kalvin Lee (Gerrit)

unread,
Jan 6, 2026, 9:37:07 AMJan 6
to Daniel Angulo, Andres Munoz Medina, Sergio Solano, Danilo Françoso Tedeschi, Code Review Nudger, Stephen Nusko, Chromium LUCI CQ, AyeAye, chromotin...@chromium.org
Attention needed from Daniel Angulo and Stephen Nusko

Kalvin Lee added 1 comment

File remoting/codec/video_encoder_verbatim.cc
Line 28, Patchset 15 (Latest): return UNSAFE_BUFFERS(
base::span(reinterpret_cast<uint8_t*>(data->data()), size));
Kalvin Lee . unresolved

Unless I'm wrong about how `resize()` works, I think this can be much terser as

```
base::as_writable_bytes(base::span(*data))
```

and as a bonus it sheds `UNSAFE_BUFFERS`, too.

Kalvin Lee

Huh, looking at the history of this CL, my suggestion was actually what was written from patchsets 1 through 10, and then it mysteriously changed to this `UNSAFE_BUFFERS()` clump in patchset 11. What happened here? Did somebody suggest this format for some reason?

Gerrit-Comment-Date: Tue, 06 Jan 2026 14:36:37 +0000
Gerrit-HasComments: Yes
Gerrit-Has-Labels: No
Comment-In-Reply-To: Kalvin Lee <kd...@chromium.org>
satisfied_requirement
unsatisfied_requirement
open
diffy

Daniel Angulo (Gerrit)

unread,
Jan 6, 2026, 12:39:20 PMJan 6
to Yuwei Huang, Kalvin Lee, Andres Munoz Medina, Sergio Solano, Danilo Françoso Tedeschi, Code Review Nudger, Stephen Nusko, Chromium LUCI CQ, AyeAye, chromotin...@chromium.org
Attention needed from Kalvin Lee, Stephen Nusko and Yuwei Huang

Daniel Angulo added 1 comment

File remoting/codec/video_encoder_verbatim.cc
Line 28, Patchset 15 (Latest): return UNSAFE_BUFFERS(
base::span(reinterpret_cast<uint8_t*>(data->data()), size));
Kalvin Lee . unresolved

Unless I'm wrong about how `resize()` works, I think this can be much terser as

```
base::as_writable_bytes(base::span(*data))
```

and as a bonus it sheds `UNSAFE_BUFFERS`, too.

Kalvin Lee

Huh, looking at the history of this CL, my suggestion was actually what was written from patchsets 1 through 10, and then it mysteriously changed to this `UNSAFE_BUFFERS()` clump in patchset 11. What happened here? Did somebody suggest this format for some reason?

Daniel Angulo

The problem is that base::as_writable_bytes no longer accepts a std::string as an argument, std::string is not intended to be used as a raw byte buffer.

Open in Gerrit

Related details

Attention is currently required from:
  • Kalvin Lee
  • Stephen Nusko
  • Yuwei Huang
Submit Requirements:
  • requirement satisfiedCode-Coverage
  • requirement is not satisfiedCode-Owners
  • requirement is not satisfiedCode-Review
  • requirement is not satisfiedNo-Unresolved-Comments
  • requirement is not satisfiedReview-Enforcement
Inspect html for hidden footers to help with email filtering. To unsubscribe visit settings. DiffyGerrit
Gerrit-MessageType: comment
Gerrit-Project: chromium/src
Gerrit-Branch: main
Gerrit-Change-Id: Ic92b67ca9e64de7766e8305e76761b0c4a5c3db1
Gerrit-Change-Number: 7101649
Gerrit-PatchSet: 15
Gerrit-Owner: Daniel Angulo <angd...@google.com>
Gerrit-Reviewer: Daniel Angulo <angd...@google.com>
Gerrit-Reviewer: Stephen Nusko <nus...@chromium.org>
Gerrit-Reviewer: Yuwei Huang <yuw...@chromium.org>
Gerrit-CC: Andres Munoz Medina <amme...@google.com>
Gerrit-CC: Code Review Nudger <android-build...@prod.google.com>
Gerrit-CC: Danilo Françoso Tedeschi <da...@google.com>
Gerrit-CC: Kalvin Lee <kd...@chromium.org>
Gerrit-CC: Sergio Solano <sergio...@google.com>
Gerrit-Attention: Kalvin Lee <kd...@chromium.org>
Gerrit-Attention: Stephen Nusko <nus...@chromium.org>
Gerrit-Attention: Yuwei Huang <yuw...@chromium.org>
Gerrit-Comment-Date: Tue, 06 Jan 2026 17:39:11 +0000
satisfied_requirement
unsatisfied_requirement
open
diffy

Yuwei Huang (Gerrit)

unread,
Jan 6, 2026, 4:20:43 PMJan 6
to Daniel Angulo, Kalvin Lee, Andres Munoz Medina, Sergio Solano, Danilo Françoso Tedeschi, Code Review Nudger, Stephen Nusko, Chromium LUCI CQ, AyeAye, chromotin...@chromium.org
Attention needed from Daniel Angulo, Kalvin Lee and Stephen Nusko

Yuwei Huang added 1 comment

Patchset-level comments
File-level comment, Patchset 15 (Latest):
Yuwei Huang . resolved

I'm fine with this CL if the objective is just to get rid of all the `UNSAFE_TODO`s, but this CL does not seem to improve readability given the amount of introduced `UNSAFE_BUFFERS` and casts. As pointed out by kdlee@, it is more preferable to add a span/span-friendly accessor to WebRTC and update this CL accordingly.

Open in Gerrit

Related details

Attention is currently required from:
  • Daniel Angulo
  • Kalvin Lee
  • Stephen Nusko
Gerrit-Attention: Daniel Angulo <angd...@google.com>
Gerrit-Comment-Date: Tue, 06 Jan 2026 21:20:34 +0000
Gerrit-HasComments: Yes
Gerrit-Has-Labels: No
satisfied_requirement
unsatisfied_requirement
open
diffy

Kalvin Lee (Gerrit)

unread,
Jan 7, 2026, 12:50:40 AM (14 days ago) Jan 7
to Daniel Angulo, Yuwei Huang, Andres Munoz Medina, Sergio Solano, Danilo Françoso Tedeschi, Code Review Nudger, Stephen Nusko, Chromium LUCI CQ, AyeAye, chromotin...@chromium.org
Attention needed from Daniel Angulo and Stephen Nusko

Kalvin Lee added 1 comment

File remoting/codec/video_encoder_verbatim.cc
Line 28, Patchset 15 (Latest): return UNSAFE_BUFFERS(
base::span(reinterpret_cast<uint8_t*>(data->data()), size));
Kalvin Lee . unresolved

Unless I'm wrong about how `resize()` works, I think this can be much terser as

```
base::as_writable_bytes(base::span(*data))
```

and as a bonus it sheds `UNSAFE_BUFFERS`, too.

Kalvin Lee

Huh, looking at the history of this CL, my suggestion was actually what was written from patchsets 1 through 10, and then it mysteriously changed to this `UNSAFE_BUFFERS()` clump in patchset 11. What happened here? Did somebody suggest this format for some reason?

Daniel Angulo

The problem is that base::as_writable_bytes no longer accepts a std::string as an argument, std::string is not intended to be used as a raw byte buffer.

Kalvin Lee

I'm still not understanding.

I am not suggesting we feed a `std::string` as an argument to `base::as_writable_bytes()`. It's wrapped in `base::span()`.

If the concern is that `std::string` should not be used as a raw byte buffer, that is unfortunately the status quo. Your `UNSAFE_BUFFERS()` formulation does not do anything to address this, since you also force a `reinterpret_cast`.

The stated goal of this CL is to improve spatial safety. If you think there is a type issue, I suggest you tackle that in a (prequel) separate CL.

Open in Gerrit

Related details

Attention is currently required from:
  • Daniel Angulo
  • Stephen Nusko
Gerrit-Attention: Stephen Nusko <nus...@chromium.org>
Gerrit-Attention: Daniel Angulo <angd...@google.com>
Gerrit-Comment-Date: Wed, 07 Jan 2026 05:50:10 +0000
Gerrit-HasComments: Yes
Gerrit-Has-Labels: No
Comment-In-Reply-To: Kalvin Lee <kd...@chromium.org>
Comment-In-Reply-To: Daniel Angulo <angd...@google.com>
satisfied_requirement
unsatisfied_requirement
open
diffy

Stephen Nusko (Gerrit)

unread,
Jan 13, 2026, 1:46:01 AM (8 days ago) Jan 13
to Daniel Angulo, Yuwei Huang, Kalvin Lee, Andres Munoz Medina, Sergio Solano, Danilo Françoso Tedeschi, Code Review Nudger, Chromium LUCI CQ, AyeAye, chromotin...@chromium.org
Attention needed from Daniel Angulo

Stephen Nusko added 5 comments

File remoting/codec/video_encoder_verbatim.cc
Line 28, Patchset 15 (Latest): return UNSAFE_BUFFERS(
base::span(reinterpret_cast<uint8_t*>(data->data()), size));
Kalvin Lee . unresolved

Unless I'm wrong about how `resize()` works, I think this can be much terser as

```
base::as_writable_bytes(base::span(*data))
```

and as a bonus it sheds `UNSAFE_BUFFERS`, too.

Kalvin Lee

Huh, looking at the history of this CL, my suggestion was actually what was written from patchsets 1 through 10, and then it mysteriously changed to this `UNSAFE_BUFFERS()` clump in patchset 11. What happened here? Did somebody suggest this format for some reason?

Daniel Angulo

The problem is that base::as_writable_bytes no longer accepts a std::string as an argument, std::string is not intended to be used as a raw byte buffer.

Kalvin Lee

I'm still not understanding.

I am not suggesting we feed a `std::string` as an argument to `base::as_writable_bytes()`. It's wrapped in `base::span()`.

If the concern is that `std::string` should not be used as a raw byte buffer, that is unfortunately the status quo. Your `UNSAFE_BUFFERS()` formulation does not do anything to address this, since you also force a `reinterpret_cast`.

The stated goal of this CL is to improve spatial safety. If you think there is a type issue, I suggest you tackle that in a (prequel) separate CL.

Stephen Nusko

What do you mean "no longer accepts a std::string"?

+1 we should be able to remove the UNSAFE_BUFFERS and just return a correct span.

Line 64, Patchset 15 (Latest): CHECK(frame.size().height() > 0 && frame.size().width() > 0 && in_stride > 0);
Kalvin Lee . unresolved

IMHO this section is pretty hard to follow. I'm not comfortable being primary reviewer for this and I think you can consider directly roping in a proper owner for this.

However, looking at this clump of casts, I think I would prefer putting off this change for now, and

1. Look at implementing span accessors for `webrtc::DesktopFrame` (and inherited classes). [You may need to check with WebRTC folks if this should be `ArrayView` or `std::span`](https://issues.webrtc.org/issues/439801349).

1. (Wait for the WebRTC roll into Chromium --- refresh your tree)

1. Come back to this CL and see if it's possible to reorganize the casts. (Maybe you could even implement checked accessors for `webrtc::DesktopSize` --- I don't think there's any real reason we should _want_ to get negative values out of that class.)

If you feel strongly about what you have written so far, though, feel free to loop in a proper owner directly and I'm happy to cast a second CR+1 (as long as they're happy, too).

Stephen Nusko

Yeah fixing webrtc is the best "fix", however I've added a suggestion below for a UNSAFE_RTC_DESKTOP_FRAME_TO_BYTE_SPAN macro if there is push back from their side.

If they don't mind adding a span API (or ArrayView) then great! lets do that, if they do mind or there is some larger technical work on their side, adding the macro in a single location allows you to add all the checks and link to why they are correct, as well as gives us a central location to track which APIs we want to get spanified.

Line 66, Patchset 15 (Latest): // SAFETY: The `.data()` pointer is valid for the lifetime of `frame`. The
// total size of the frame's buffer is `stride * height`, stride is the
// distance in bytes between two neighboring rows. See `DesktopFrame::stride`
// for more details.

base::span<const uint8_t> frame_data = UNSAFE_BUFFERS(base::span(
frame.data(),
base::checked_cast<size_t>(in_stride) * frame.size().height()));
Stephen Nusko . unresolved

How often is a DesktopFrame converted into a span? If this occurs in other files consider adding a macro to auto_spanification_helper.h like

```
UNSAFE_RTC_DESKTOP_FRAME_TO_BYTE_SPAN()
```

Bonus you can move all those checks into the macro and verify things.

Line 85, Patchset 15 (Latest): auto row_span = rect_span.subspan(static_cast<size_t>(y) * in_stride,
Stephen Nusko . unresolved

This looks like it should be a spanReader?

Line 87, Patchset 15 (Latest): out.first(static_cast<size_t>(row_size)).copy_from(row_span);
Stephen Nusko . unresolved

This looks like it should be a spanWriter

Open in Gerrit

Related details

Attention is currently required from:
  • Daniel Angulo
Gerrit-Attention: Daniel Angulo <angd...@google.com>
Gerrit-Comment-Date: Tue, 13 Jan 2026 06:45:38 +0000
satisfied_requirement
unsatisfied_requirement
open
diffy
Reply all
Reply to author
Forward
0 new messages