#include "third_party/blink/renderer/modules/mediasource/media_source.h"
#include <memory>
#include <tuple>
#include "base/feature_list.h"
#include "base/memory/ptr_util.h"
#include "base/memory/scoped_refptr.h"
#include "base/metrics/histogram_functions.h"
#include "build/chromeos_buildflags.h"
#include "media/base/audio_decoder_config.h"
#include "media/base/logging_override_if_enabled.h"
#include "media/base/media_switches.h"
#include "media/base/media_types.h"
#include "media/base/mime_util.h"
#include "media/base/supported_types.h"
#include "media/base/video_decoder_config.h"
#include "media/media_buildflags.h"
#include "third_party/blink/public/common/privacy_budget/identifiability_metric_builder.h"
#include "third_party/blink/public/common/privacy_budget/identifiability_study_settings.h"
#include "third_party/blink/public/common/privacy_budget/identifiable_surface.h"
#include "third_party/blink/public/platform/web_media_source.h"
#include "third_party/blink/public/platform/web_source_buffer.h"
#include "third_party/blink/renderer/bindings/modules/v8/v8_audio_decoder_config.h"
#include "third_party/blink/renderer/bindings/modules/v8/v8_source_buffer_config.h"
#include "third_party/blink/renderer/bindings/modules/v8/v8_video_decoder_config.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/frame/deprecation/deprecation.h"
#include "third_party/blink/renderer/core/html/media/html_media_element.h"
#include "third_party/blink/renderer/core/html/track/audio_track_list.h"
#include "third_party/blink/renderer/core/html/track/video_track_list.h"
#include "third_party/blink/renderer/modules/mediasource/attachment_creation_pass_key_provider.h"
#include "third_party/blink/renderer/modules/mediasource/cross_thread_media_source_attachment.h"
#include "third_party/blink/renderer/modules/mediasource/handle_attachment_provider.h"
#include "third_party/blink/renderer/modules/mediasource/media_source_handle_impl.h"
#include "third_party/blink/renderer/modules/mediasource/same_thread_media_source_attachment.h"
#include "third_party/blink/renderer/modules/mediasource/same_thread_media_source_tracer.h"
#include "third_party/blink/renderer/modules/mediasource/source_buffer_track_base_supplement.h"
#include "third_party/blink/renderer/modules/webcodecs/audio_decoder.h"
#include "third_party/blink/renderer/modules/webcodecs/video_decoder.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/blob/blob_url.h"
#include "third_party/blink/renderer/platform/heap/garbage_collected.h"
#include "third_party/blink/renderer/platform/heap/persistent.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/network/mime/mime_type_registry.h"
#include "third_party/blink/renderer/platform/privacy_budget/identifiability_digest_helpers.h"
#include "third_party/blink/renderer/platform/runtime_enabled_features.h"
#include "third_party/blink/renderer/platform/wtf/functional.h"
#include "third_party/blink/renderer/platform/wtf/text/wtf_string.h"
WebMediaSource;
WebSourceBuffer;
namespace blink {
namespace {
#if BUILDFLAG(ENABLE_MSE_MPEG2TS_STREAM_PARSER)
bool IsMp2tCodecSupported(std::string_view codec_id) {
if (auto result =
media::ParseVideoCodecString("", codec_id,
false)) {
if (result->codec != media::VideoCodec::kH264) {
return false;
}
return true;
}
auto audio_codec = media::AudioCodec::kUnknown;
bool is_codec_ambiguous = false;
if (media::ParseAudioCodecString("", codec_id, &is_codec_ambiguous,
&audio_codec)) {
if (is_codec_ambiguous) {
return false;
}
if (audio_codec != media::AudioCodec::kAAC &&
audio_codec != media::AudioCodec::kMP3) {
return false;
}
return true;
}
return false;
}
#endif
}
static AtomicString ReadyStateToString(MediaSource::ReadyState state) { … }
static bool ThrowExceptionIfClosed(bool is_open,
ExceptionState& exception_state) { … }
static bool ThrowExceptionIfClosedOrUpdating(bool is_open,
bool is_updating,
ExceptionState& exception_state) { … }
MediaSource* MediaSource::Create(ExecutionContext* context) { … }
MediaSource::MediaSource(ExecutionContext* context)
: … { … }
MediaSource::~MediaSource() { … }
void MediaSource::LogAndThrowDOMException(ExceptionState& exception_state,
DOMExceptionCode error,
const String& message) { … }
void MediaSource::LogAndThrowTypeError(ExceptionState& exception_state,
const String& message) { … }
SourceBuffer* MediaSource::addSourceBuffer(const String& type,
ExceptionState& exception_state) { … }
SourceBuffer* MediaSource::AddSourceBufferUsingConfig(
ExecutionContext* execution_context,
const SourceBufferConfig* config,
ExceptionState& exception_state) { … }
void MediaSource::AddSourceBuffer_Locked(
const String& type,
std::unique_ptr<media::AudioDecoderConfig> audio_config,
std::unique_ptr<media::VideoDecoderConfig> video_config,
ExceptionState* exception_state,
SourceBuffer** created_buffer,
MediaSourceAttachmentSupplement::ExclusiveKey pass_key) { … }
void MediaSource::removeSourceBuffer(SourceBuffer* buffer,
ExceptionState& exception_state) { … }
void MediaSource::RemoveSourceBuffer_Locked(
SourceBuffer* buffer,
MediaSourceAttachmentSupplement::ExclusiveKey ) { … }
void MediaSource::OnReadyStateChange(const ReadyState old_state,
const ReadyState new_state) { … }
bool MediaSource::IsUpdating() const { … }
bool MediaSource::isTypeSupported(ExecutionContext* context,
const String& type) { … }
bool MediaSource::IsTypeSupportedInternal(ExecutionContext* context,
const String& type,
bool enforce_codec_specificity) { … }
bool MediaSource::canConstructInDedicatedWorker(ExecutionContext* context) { … }
void MediaSource::RecordIdentifiabilityMetric(ExecutionContext* context,
const String& type,
bool result) { … }
const AtomicString& MediaSource::InterfaceName() const { … }
ExecutionContext* MediaSource::GetExecutionContext() const { … }
bool MediaSource::RunUnlessElementGoneOrClosingUs(
MediaSourceAttachmentSupplement::RunExclusivelyCB cb) { … }
void MediaSource::AssertAttachmentsMutexHeldIfCrossThreadForDebugging() const { … }
void MediaSource::SendUpdatedInfoToMainThreadCache() { … }
void MediaSource::Trace(Visitor* visitor) const { … }
void MediaSource::CompleteAttachingToMediaElement(
std::unique_ptr<WebMediaSource> web_media_source) { … }
double MediaSource::GetDuration_Locked(
MediaSourceAttachmentSupplement::ExclusiveKey ) const { … }
WebTimeRanges MediaSource::BufferedInternal(
MediaSourceAttachmentSupplement::ExclusiveKey pass_key) const { … }
WebTimeRanges MediaSource::SeekableInternal(
MediaSourceAttachmentSupplement::ExclusiveKey pass_key) const { … }
void MediaSource::OnTrackChanged(TrackBase* track) { … }
void MediaSource::setDuration(double duration,
ExceptionState& exception_state) { … }
double MediaSource::duration() { … }
void MediaSource::DurationChangeAlgorithm(
double new_duration,
ExceptionState* exception_state,
MediaSourceAttachmentSupplement::ExclusiveKey pass_key) { … }
void MediaSource::SetReadyState(const ReadyState state) { … }
AtomicString MediaSource::readyState() const { … }
void MediaSource::endOfStream(const AtomicString& error,
ExceptionState& exception_state) { … }
void MediaSource::endOfStream(ExceptionState& exception_state) { … }
void MediaSource::setLiveSeekableRange(double start,
double end,
ExceptionState& exception_state) { … }
void MediaSource::SetLiveSeekableRange_Locked(
double start,
double end,
MediaSourceAttachmentSupplement::ExclusiveKey ) { … }
void MediaSource::clearLiveSeekableRange(ExceptionState& exception_state) { … }
void MediaSource::ClearLiveSeekableRange_Locked(
MediaSourceAttachmentSupplement::ExclusiveKey ) { … }
MediaSourceHandleImpl* MediaSource::handle() { … }
bool MediaSource::IsOpen() const { … }
void MediaSource::SetSourceBufferActive(SourceBuffer* source_buffer,
bool is_active) { … }
std::pair<scoped_refptr<MediaSourceAttachmentSupplement>, MediaSourceTracer*>
MediaSource::AttachmentAndTracer() const { … }
void MediaSource::EndOfStreamAlgorithm(
const WebMediaSource::EndOfStreamStatus eos_status,
MediaSourceAttachmentSupplement::ExclusiveKey pass_key) { … }
bool MediaSource::IsClosed() const { … }
void MediaSource::Close() { … }
MediaSourceTracer* MediaSource::StartAttachingToMediaElement(
scoped_refptr<SameThreadMediaSourceAttachment> attachment,
HTMLMediaElement* element) { … }
bool MediaSource::StartWorkerAttachingToMainThreadMediaElement(
scoped_refptr<CrossThreadMediaSourceAttachment> attachment) { … }
void MediaSource::OpenIfInEndedState() { … }
bool MediaSource::HasPendingActivity() const { … }
void MediaSource::ContextDestroyed() { … }
void MediaSource::DetachWorkerOnContextDestruction_Locked(
bool notify_close,
MediaSourceAttachmentSupplement::ExclusiveKey ) { … }
std::unique_ptr<WebSourceBuffer> MediaSource::CreateWebSourceBuffer(
const String& type,
const String& codecs,
std::unique_ptr<media::AudioDecoderConfig> audio_config,
std::unique_ptr<media::VideoDecoderConfig> video_config,
ExceptionState& exception_state) { … }
void MediaSource::ScheduleEvent(const AtomicString& event_name) { … }
}