chromium/third_party/blink/renderer/modules/mediasource/source_buffer.cc

/*
 * Copyright (C) 2013 Google Inc. All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are
 * met:
 *
 *     * Redistributions of source code must retain the above copyright
 * notice, this list of conditions and the following disclaimer.
 *     * Redistributions in binary form must reproduce the above
 * copyright notice, this list of conditions and the following disclaimer
 * in the documentation and/or other materials provided with the
 * distribution.
 *     * Neither the name of Google Inc. nor the names of its
 * contributors may be used to endorse or promote products derived from
 * this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */

#include "third_party/blink/renderer/modules/mediasource/source_buffer.h"

#include <limits>
#include <memory>
#include <sstream>
#include <tuple>
#include <utility>

#include "base/numerics/checked_math.h"
#include "media/base/logging_override_if_enabled.h"
#include "media/base/stream_parser_buffer.h"
#include "partition_alloc/partition_alloc.h"
#include "third_party/blink/public/platform/task_type.h"
#include "third_party/blink/public/platform/web_source_buffer.h"
#include "third_party/blink/renderer/bindings/core/v8/script_promise_resolver.h"
#include "third_party/blink/renderer/bindings/core/v8/v8_throw_dom_exception.h"
#include "third_party/blink/renderer/bindings/modules/v8/v8_audio_decoder_config.h"
#include "third_party/blink/renderer/bindings/modules/v8/v8_encoded_audio_chunk.h"
#include "third_party/blink/renderer/bindings/modules/v8/v8_encoded_video_chunk.h"
#include "third_party/blink/renderer/bindings/modules/v8/v8_source_buffer_config.h"
#include "third_party/blink/renderer/bindings/modules/v8/v8_union_encodedaudiochunk_encodedaudiochunkorencodedvideochunksequence_encodedvideochunk.h"
#include "third_party/blink/renderer/bindings/modules/v8/v8_union_encodedaudiochunk_encodedvideochunk.h"
#include "third_party/blink/renderer/bindings/modules/v8/v8_video_decoder_config.h"
#include "third_party/blink/renderer/core/dom/document.h"
#include "third_party/blink/renderer/core/dom/dom_exception.h"
#include "third_party/blink/renderer/core/dom/events/event.h"
#include "third_party/blink/renderer/core/dom/events/event_queue.h"
#include "third_party/blink/renderer/core/execution_context/execution_context.h"
#include "third_party/blink/renderer/core/frame/deprecation/deprecation.h"
#include "third_party/blink/renderer/core/html/media/html_media_element.h"
#include "third_party/blink/renderer/core/html/time_ranges.h"
#include "third_party/blink/renderer/core/html/track/audio_track.h"
#include "third_party/blink/renderer/core/html/track/audio_track_list.h"
#include "third_party/blink/renderer/core/html/track/video_track.h"
#include "third_party/blink/renderer/core/html/track/video_track_list.h"
#include "third_party/blink/renderer/core/typed_arrays/dom_array_buffer.h"
#include "third_party/blink/renderer/core/typed_arrays/dom_array_buffer_view.h"
#include "third_party/blink/renderer/modules/mediasource/media_source.h"
#include "third_party/blink/renderer/modules/mediasource/source_buffer_track_base_supplement.h"
#include "third_party/blink/renderer/modules/webcodecs/encoded_audio_chunk.h"
#include "third_party/blink/renderer/modules/webcodecs/encoded_video_chunk.h"
#include "third_party/blink/renderer/platform/bindings/exception_messages.h"
#include "third_party/blink/renderer/platform/bindings/exception_state.h"
#include "third_party/blink/renderer/platform/heap/garbage_collected.h"
#include "third_party/blink/renderer/platform/instrumentation/tracing/trace_event.h"
#include "third_party/blink/renderer/platform/instrumentation/use_counter.h"
#include "third_party/blink/renderer/platform/network/mime/content_type.h"
#include "third_party/blink/renderer/platform/runtime_enabled_features.h"
#include "third_party/blink/renderer/platform/wtf/allocator/partition_allocator.h"
#include "third_party/blink/renderer/platform/wtf/allocator/partitions.h"
#include "third_party/blink/renderer/platform/wtf/functional.h"
#include "third_party/blink/renderer/platform/wtf/math_extras.h"
#include "third_party/blink/renderer/platform/wtf/text/string_builder.h"

WebSourceBuffer;

namespace blink {

namespace {

static bool ThrowExceptionIfRemovedOrUpdating(bool is_removed,
                                              bool is_updating,
                                              ExceptionState& exception_state) {}

WTF::String WebTimeRangesToString(const WebTimeRanges& ranges) {}

// These track IDs are used as to differentiate tracks within a SourceBuffer.
// They can be duplicated across SourceBuffers, since these are not the
// TrackList identifiers exposed to the web app; these are instead equivalents
// of bytestream format's in-band track identifiers.
// TODO(crbug.com/1144908): Consider standardizing these especially if
// TrackDefaults makes a return to MSE spec, so that apps can provide
// name/label/kind/etc metadata for tracks originating from appended WebCodecs
// chunks.
// TODO(crbug.com/1144908): Since these must be identical to those generated
// in the underlying WebCodecsEncodedChunkStreamParser, consider moving these
// to possibly stream_parser.h. Meanwhile, must be kept in sync with similar
// constexpr in that parser manually.
constexpr media::StreamParser::TrackId kWebCodecsAudioTrackId =;
constexpr media::StreamParser::TrackId kWebCodecsVideoTrackId =;

// TODO(crbug.com/1144908): Move these converters into a WebCodecs decoder
// helper abstraction. Beyond reuse (instead of copying the various
// MakeDecoderBuffer methods), that will also help enable buffering h264 where
// bitstream conversion might be necessary during conversion.
// Note, caller updates results further as necessary (e.g. duration, DTS, etc).
scoped_refptr<media::StreamParserBuffer> MakeAudioStreamParserBuffer(
    const EncodedAudioChunk& audio_chunk) {}

// Caller must verify that video_chunk.duration().has_value().
scoped_refptr<media::StreamParserBuffer> MakeVideoStreamParserBuffer(
    const EncodedVideoChunk& video_chunk) {}

}  // namespace

SourceBuffer::SourceBuffer(std::unique_ptr<WebSourceBuffer> web_source_buffer,
                           MediaSource* source,
                           EventQueue* async_event_queue)
    :{}

SourceBuffer::~SourceBuffer() {}

void SourceBuffer::Dispose() {}

AtomicString SourceBuffer::SegmentsKeyword() {}

AtomicString SourceBuffer::SequenceKeyword() {}

void SourceBuffer::setMode(const AtomicString& new_mode,
                           ExceptionState& exception_state) {}

void SourceBuffer::SetMode_Locked(
    AtomicString new_mode,
    ExceptionState* exception_state,
    MediaSourceAttachmentSupplement::ExclusiveKey /* passkey */) {}

TimeRanges* SourceBuffer::buffered(ExceptionState& exception_state) const {}

void SourceBuffer::GetBuffered_Locked(
    WebTimeRanges* ranges /* out parameter */,
    MediaSourceAttachmentSupplement::ExclusiveKey /* passkey */) const {}

double SourceBuffer::timestampOffset() const {}

void SourceBuffer::setTimestampOffset(double offset,
                                      ExceptionState& exception_state) {}

void SourceBuffer::SetTimestampOffset_Locked(
    double offset,
    ExceptionState* exception_state,
    MediaSourceAttachmentSupplement::ExclusiveKey /* passkey */) {}

AudioTrackList& SourceBuffer::audioTracks() {}

VideoTrackList& SourceBuffer::videoTracks() {}

double SourceBuffer::appendWindowStart() const {}

void SourceBuffer::setAppendWindowStart(double start,
                                        ExceptionState& exception_state) {}

void SourceBuffer::SetAppendWindowStart_Locked(
    double start,
    MediaSourceAttachmentSupplement::ExclusiveKey /* passkey */) {}

double SourceBuffer::appendWindowEnd() const {}

void SourceBuffer::setAppendWindowEnd(double end,
                                      ExceptionState& exception_state) {}

void SourceBuffer::SetAppendWindowEnd_Locked(
    double end,
    MediaSourceAttachmentSupplement::ExclusiveKey /* passkey */) {}

void SourceBuffer::appendBuffer(DOMArrayBuffer* data,
                                ExceptionState& exception_state) {}

void SourceBuffer::appendBuffer(NotShared<DOMArrayBufferView> data,
                                ExceptionState& exception_state) {}

// Note that |chunks| may be a sequence of mixed audio and video encoded chunks
// (which should cause underlying buffering validation to emit error akin to
// appending video to an audio track or vice-versa). It was impossible to get
// the bindings generator to disambiguate sequence<audio> vs sequence<video>,
// hence we could not use simple overloading in the IDL for these two. Neither
// could the IDL union attempt similar. We must enforce that semantic in
// implementation. Further note, |chunks| may instead be a single audio or a
// single video chunk as a helpful additional overload for one-chunk-at-a-time
// append use-cases.
ScriptPromise<IDLUndefined> SourceBuffer::appendEncodedChunks(
    ScriptState* script_state,
    const V8EncodedChunks* chunks,
    ExceptionState& exception_state) {}

void SourceBuffer::AppendEncodedChunks_Locked(
    std::unique_ptr<media::StreamParser::BufferQueue> buffer_queue,
    size_t size,
    ExceptionState* exception_state,
    MediaSourceAttachmentSupplement::ExclusiveKey /* passkey */) {}

void SourceBuffer::abort(ExceptionState& exception_state) {}

void SourceBuffer::Abort_Locked(
    MediaSourceAttachmentSupplement::ExclusiveKey pass_key) {}

void SourceBuffer::remove(double start,
                          double end,
                          ExceptionState& exception_state) {}

void SourceBuffer::Remove_Locked(
    double start,
    double end,
    ExceptionState* exception_state,
    MediaSourceAttachmentSupplement::ExclusiveKey pass_key) {}

void SourceBuffer::changeType(const String& type,
                              ExceptionState& exception_state) {}

void SourceBuffer::ChangeTypeUsingConfig(ExecutionContext* execution_context,
                                         const SourceBufferConfig* config,
                                         ExceptionState& exception_state) {}

void SourceBuffer::ChangeType_Locked(
    const String& type,
    ExceptionState* exception_state,
    MediaSourceAttachmentSupplement::ExclusiveKey pass_key) {}

void SourceBuffer::setTrackDefaults(TrackDefaultList* track_defaults,
                                    ExceptionState& exception_state) {}

void SourceBuffer::CancelRemove() {}

void SourceBuffer::AbortIfUpdating() {}

void SourceBuffer::RemovedFromMediaSource() {}

double SourceBuffer::HighestPresentationTimestamp() {}

void SourceBuffer::RemoveMediaTracks() {}

double SourceBuffer::GetMediaTime() {}

template <class T>
T* FindExistingTrackById(const TrackListBase<T>& track_list, const String& id) {}

const TrackDefault* SourceBuffer::GetTrackDefault(
    const AtomicString& track_type,
    const AtomicString& byte_stream_track_id) const {}

AtomicString SourceBuffer::DefaultTrackLabel(
    const AtomicString& track_type,
    const AtomicString& byte_stream_track_id) const {}

AtomicString SourceBuffer::DefaultTrackLanguage(
    const AtomicString& track_type,
    const AtomicString& byte_stream_track_id) const {}

void SourceBuffer::AddPlaceholderCrossThreadTracks(
    const WebVector<MediaTrackInfo>& new_tracks,
    scoped_refptr<MediaSourceAttachmentSupplement> attachment) {}

void SourceBuffer::RemovePlaceholderCrossThreadTracks(
    scoped_refptr<MediaSourceAttachmentSupplement> attachment,
    MediaSourceTracer* tracer) {}

bool SourceBuffer::InitializationSegmentReceived(
    const WebVector<MediaTrackInfo>& new_tracks) {}

void SourceBuffer::NotifyParseWarning(const ParseWarning warning) {}

bool SourceBuffer::HasPendingActivity() const {}

void SourceBuffer::ContextDestroyed() {}

ExecutionContext* SourceBuffer::GetExecutionContext() const {}

const AtomicString& SourceBuffer::InterfaceName() const {}

bool SourceBuffer::IsRemoved() const {}

void SourceBuffer::ScheduleEvent(const AtomicString& event_name) {}

bool SourceBuffer::PrepareAppend(double media_time,
                                 size_t new_data_size,
                                 ExceptionState& exception_state) {}

bool SourceBuffer::EvictCodedFrames(double media_time, size_t new_data_size) {}

void SourceBuffer::AppendBufferInternal(base::span<const unsigned char> data,
                                        ExceptionState& exception_state) {}

void SourceBuffer::AppendBufferInternal_Locked(
    base::span<const unsigned char> data,
    ExceptionState* exception_state,
    MediaSourceAttachmentSupplement::ExclusiveKey /* passkey */) {}

void SourceBuffer::AppendEncodedChunksAsyncPart() {}

void SourceBuffer::AppendBufferAsyncPart() {}

void SourceBuffer::AppendEncodedChunksAsyncPart_Locked(
    MediaSourceAttachmentSupplement::ExclusiveKey pass_key) {}

void SourceBuffer::AppendBufferAsyncPart_Locked(
    MediaSourceAttachmentSupplement::ExclusiveKey pass_key) {}

void SourceBuffer::RemoveAsyncPart() {}

void SourceBuffer::RemoveAsyncPart_Locked(
    MediaSourceAttachmentSupplement::ExclusiveKey /* passkey */) {}

void SourceBuffer::AppendError(
    MediaSourceAttachmentSupplement::ExclusiveKey pass_key) {}

void SourceBuffer::Trace(Visitor* visitor) const {}

}  // namespace blink