gecko-dev/dom/media/MediaDecoderOwner.h
alwu dc2950f10c Bug 1928828 : don't use ExternalEngineStateMachine if we already know the CDMProxy is not supported by WMF-based CDM. r=media-playback-reviewers,aosmond
The reason we need to switch between different state machines is that we
cannot determine the playback usage when creating the state machine.
However, if the CDMProxy is already set and is not supported by the
WMF-based CDM, we can directly use the MediaDecoderStateMachine to
avoid a later switch, which can reduce the chance of getting unnecessary
error.

Differential Revision: https://phabricator.services.mozilla.com/D227772
2024-11-05 20:56:28 +00:00

201 lines
7.6 KiB
C++

/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim:set ts=2 sw=2 sts=2 et cindent: */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#ifndef MediaDecoderOwner_h_
#define MediaDecoderOwner_h_
#include "MediaInfo.h"
#include "MediaSegment.h"
#include "mozilla/AbstractThread.h"
#include "mozilla/DefineEnum.h"
#include "mozilla/UniquePtr.h"
#include "nsSize.h"
namespace mozilla {
class CDMProxy;
class GMPCrashHelper;
class VideoFrameContainer;
class MediaInfo;
class MediaResult;
enum class RFPTarget : uint64_t;
namespace dom {
class Document;
class HTMLMediaElement;
} // namespace dom
class MediaDecoderOwner {
public:
// Called by the media decoder to indicate that the download is progressing.
virtual void DownloadProgressed() = 0;
// Dispatch an asynchronous event to the decoder owner
virtual void DispatchAsyncEvent(const nsAString& aName) = 0;
// Triggers a recomputation of readyState.
virtual void UpdateReadyState() = 0;
// Called by the decoder object to notify owner might need to dispatch the
// `timeupdate` event due to current time changes.
virtual void MaybeQueueTimeupdateEvent() = 0;
// Return true if decoding should be paused
virtual bool GetPaused() = 0;
// Called by the video decoder object, on the main thread,
// when it has read the metadata containing video dimensions,
// etc.
// Must take ownership of MetadataTags aTags argument.
virtual void MetadataLoaded(const MediaInfo* aInfo,
UniquePtr<const MetadataTags> aTags) = 0;
// Called by the decoder object, on the main thread,
// when it has read the first frame of the video or audio.
virtual void FirstFrameLoaded() = 0;
// Called by the decoder object, on the main thread,
// when the resource has a network error during loading.
// The decoder owner should call Shutdown() on the decoder and drop the
// reference to the decoder to prevent further calls into the decoder.
virtual void NetworkError(const MediaResult& aError) = 0;
// Called by the decoder object, on the main thread, when the
// resource has a decode error during metadata loading or decoding.
// The decoder owner should call Shutdown() on the decoder and drop the
// reference to the decoder to prevent further calls into the decoder.
virtual void DecodeError(const MediaResult& aError) = 0;
// Called by the decoder object, on the main thread, when the
// resource has a decode issue during metadata loading or decoding, but can
// continue decoding.
virtual void DecodeWarning(const MediaResult& aError) = 0;
// Return true if media element error attribute is not null.
virtual bool HasError() const = 0;
// Called by the video decoder object, on the main thread, when the
// resource load has been cancelled.
virtual void LoadAborted() = 0;
// Called by the video decoder object, on the main thread,
// when the video playback has ended.
virtual void PlaybackEnded() = 0;
// Called by the video decoder object, on the main thread,
// when the resource has started seeking.
virtual void SeekStarted() = 0;
// Called by the video decoder object, on the main thread,
// when the resource has completed seeking.
virtual void SeekCompleted() = 0;
// Called by the video decoder object, on the main thread,
// when the resource has aborted seeking.
virtual void SeekAborted() = 0;
// Called by the media stream, on the main thread, when the download
// has been suspended by the cache or because the element itself
// asked the decoder to suspend the download.
virtual void DownloadSuspended() = 0;
// Called by the media decoder to indicate whether the media cache has
// suspended the channel.
virtual void NotifySuspendedByCache(bool aSuspendedByCache) = 0;
// called to notify that the principal of the decoder's media resource has
// changed.
virtual void NotifyDecoderPrincipalChanged() = 0;
// The status of the next frame which might be available from the decoder
MOZ_DEFINE_ENUM_WITH_TOSTRING_AT_CLASS_SCOPE(
NextFrameStatus, (NEXT_FRAME_AVAILABLE, NEXT_FRAME_UNAVAILABLE_BUFFERING,
NEXT_FRAME_UNAVAILABLE_SEEKING, NEXT_FRAME_UNAVAILABLE,
NEXT_FRAME_UNINITIALIZED));
// Called by media decoder when the audible state changed
virtual void SetAudibleState(bool aAudible) = 0;
// Notified by the decoder that XPCOM shutdown has begun.
// The decoder owner should call Shutdown() on the decoder and drop the
// reference to the decoder to prevent further calls into the decoder.
virtual void NotifyXPCOMShutdown() = 0;
// Dispatches a "encrypted" event to the HTMLMediaElement, with the
// provided init data. Actual dispatch may be delayed until HAVE_METADATA.
// Main thread only.
virtual void DispatchEncrypted(const nsTArray<uint8_t>& aInitData,
const nsAString& aInitDataType) = 0;
// Notified by the decoder that a decryption key is required before emitting
// further output.
virtual void NotifyWaitingForKey() {}
/*
* Methods that are used only in Gecko go here. We provide defaul
* implementations so they can compile in Servo without modification.
*/
// Return an abstract thread on which to run main thread runnables.
static AbstractThread* AbstractMainThread() {
return AbstractThread::MainThread();
}
// Get the HTMLMediaElement object if the decoder is being used from an
// HTML media element, and null otherwise.
virtual dom::HTMLMediaElement* GetMediaElement() { return nullptr; }
// Called by the media decoder and the video frame to get the
// ImageContainer containing the video data.
virtual VideoFrameContainer* GetVideoFrameContainer() { return nullptr; }
// Return the decoder owner's owner document.
virtual mozilla::dom::Document* GetDocument() const { return nullptr; }
// Called by the media decoder to create a GMPCrashHelper.
virtual already_AddRefed<GMPCrashHelper> CreateGMPCrashHelper() {
return nullptr;
}
// Called by the frame container to notify the layout engine that the
// size of the image has changed, or the video needs to be be repainted
// for some other reason.
enum class ImageSizeChanged { No, Yes };
enum class ForceInvalidate { No, Yes };
virtual void Invalidate(ImageSizeChanged aImageSizeChanged,
const Maybe<nsIntSize>& aNewIntrinsicSize,
ForceInvalidate aForceInvalidate) {}
// Called after the MediaStream we're playing rendered a frame to aContainer
// with a different principalHandle than the previous frame.
virtual void PrincipalHandleChangedForVideoFrameContainer(
VideoFrameContainer* aContainer,
const PrincipalHandle& aNewPrincipalHandle) {}
// Called after the MediaDecoder has installed the given secondary video
// container and render potential frames to it.
virtual void OnSecondaryVideoContainerInstalled(
const RefPtr<VideoFrameContainer>& aSecondaryContainer) {}
// Return true is the owner is actually invisible to users.
virtual bool IsActuallyInvisible() const = 0;
// Returns true if the owner should resist fingerprinting.
virtual bool ShouldResistFingerprinting(RFPTarget aTarget) const = 0;
#ifdef MOZ_WMF_CDM
// Return CDMProxy if exists.
virtual CDMProxy* GetCDMProxy() const { return nullptr; }
#endif
/*
* Servo only methods go here. Please provide default implementations so they
* can build in Gecko without any modification.
*/
};
} // namespace mozilla
#endif