| // Copyright 2019 The Chromium Authors |
| // Use of this source code is governed by a BSD-style license that can be |
| // found in the LICENSE file. |
| |
| #ifndef THIRD_PARTY_BLINK_RENDERER_MODULES_WEBCODECS_ARRAY_BUFFER_UTIL_H_ |
| #define THIRD_PARTY_BLINK_RENDERER_MODULES_WEBCODECS_ARRAY_BUFFER_UTIL_H_ |
| |
| #include "base/compiler_specific.h" |
| #include "base/containers/span.h" |
| #include "base/memory/raw_ptr_exclusion.h" |
| #include "base/types/to_address.h" |
| #include "media/base/decoder_buffer.h" |
| #include "third_party/blink/renderer/bindings/core/v8/v8_union_arraybufferallowshared_arraybufferviewallowshared.h" |
| #include "third_party/blink/renderer/core/typed_arrays/array_buffer/array_buffer_contents.h" |
| #include "third_party/blink/renderer/core/typed_arrays/dom_array_buffer.h" |
| #include "third_party/blink/renderer/platform/bindings/exception_state.h" |
| |
| namespace blink { |
| |
| using AllowSharedBufferSource = |
| V8UnionArrayBufferAllowSharedOrArrayBufferViewAllowShared; |
| |
| // Helper function for turning various DOMArray-like things into a pointer+size. |
| template <typename T> |
| base::span<T> AsSpan(const AllowSharedBufferSource* buffer_union) { |
| switch (buffer_union->GetContentType()) { |
| case AllowSharedBufferSource::ContentType::kArrayBufferAllowShared: { |
| auto* buffer = buffer_union->GetAsArrayBufferAllowShared(); |
| return (buffer && !buffer->IsDetached()) |
| ? UNSAFE_TODO(base::span<T>( |
| reinterpret_cast<T*>(buffer->DataMaybeShared()), |
| buffer->ByteLength())) |
| : base::span<T>(); |
| } |
| case AllowSharedBufferSource::ContentType::kArrayBufferViewAllowShared: { |
| auto* buffer = buffer_union->GetAsArrayBufferViewAllowShared().Get(); |
| return (buffer && !buffer->IsDetached()) |
| ? UNSAFE_TODO(base::span<T>( |
| reinterpret_cast<T*>(buffer->BaseAddressMaybeShared()), |
| buffer->byteLength())) |
| : base::span<T>(); |
| } |
| } |
| } |
| |
| // Ensures that the underlying memory for `buffer_union` remains valid |
| // (owned by a returned instance of ArrayBufferContents) |
| // even if the buffer is detached or truncated by client activity. |
| // Returns a valid ArrayBufferContents only for shared buffers, otherwise |
| // returns an empty ArrayBufferContents. |
| ArrayBufferContents PinSharedArrayBufferContent( |
| const AllowSharedBufferSource* buffer_union); |
| |
| // 1. Check if any on the array buffers from the `transfer_list` contain |
| // `data_range` and return contents of that array buffer. |
| // 2. Detach all array buffers from in the `transfer_list` |
| ArrayBufferContents TransferArrayBufferForSpan( |
| const HeapVector<Member<DOMArrayBuffer>>& transfer_list, |
| base::span<const uint8_t> data_range, |
| ExceptionState& exception_state, |
| v8::Isolate* isolate); |
| |
| // A wrapper around `ArrayBuffer` contents that allows to transfer ownership |
| // to `DecoderBuffer`. |
| class ArrayBufferContentsExternalMemory |
| : public media::DecoderBuffer::ExternalMemory { |
| public: |
| explicit ArrayBufferContentsExternalMemory(ArrayBufferContents contents, |
| base::span<const uint8_t> span) |
| : contents_(std::move(contents)), span_(span) { |
| // Check that `span` refers to the memory inside `contents`. |
| auto* contents_data = static_cast<const uint8_t*>(contents_.Data()); |
| CHECK_GE(base::to_address(span.begin()), contents_data); |
| CHECK_LE(base::to_address(span.end()), |
| UNSAFE_TODO(contents_data + contents_.DataLength())); |
| } |
| |
| const base::span<const uint8_t> Span() const override { return span_; } |
| |
| private: |
| ArrayBufferContents contents_; |
| // TODO(367764863) Rewrite to base::raw_span. |
| RAW_PTR_EXCLUSION const base::span<const uint8_t> span_; |
| }; |
| |
| } // namespace blink |
| |
| #endif // THIRD_PARTY_BLINK_RENDERER_MODULES_WEBCODECS_ARRAY_BUFFER_UTIL_H_ |