Bug 1749048 - Part 2. Implement WebCodecs image decoding API. r=webidl,media-playback-reviewers,smaug,padenot

This leverages the promise based image decoding API added in bug
1901078 to remap that onto the WebCodecs specification.

Differential Revision: https://phabricator.services.mozilla.com/D212835
This commit is contained in:
Andrew Osmond 2024-07-24 03:16:17 +00:00
Родитель b31f8cc7bc
Коммит 2df9204445
22 изменённых файлов: 2156 добавлений и 828 удалений

Разница между файлами не показана из-за своего большого размера Загрузить разницу

Просмотреть файл

@ -0,0 +1,159 @@
/* -*- 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 mozilla_dom_ImageDecoder_h
#define mozilla_dom_ImageDecoder_h
#include "FrameTimeout.h"
#include "mozilla/Attributes.h"
#include "mozilla/ErrorResult.h"
#include "mozilla/NotNull.h"
#include "mozilla/WeakPtr.h"
#include "mozilla/dom/ImageDecoderBinding.h"
#include "mozilla/dom/WebCodecsUtils.h"
#include "nsCycleCollectionParticipant.h"
#include "nsWrapperCache.h"
class nsIGlobalObject;
namespace mozilla {
class MediaResult;
namespace image {
class AnonymousDecoder;
class SourceBuffer;
enum class DecoderType;
enum class SurfaceFlags : uint8_t;
struct DecodeFramesResult;
struct DecodeFrameCountResult;
struct DecodeMetadataResult;
} // namespace image
namespace dom {
class Promise;
struct ImageDecoderReadRequest;
class ImageDecoder final : public nsISupports,
public nsWrapperCache,
public SupportsWeakPtr {
public:
NS_DECL_CYCLE_COLLECTING_ISUPPORTS
NS_DECL_CYCLE_COLLECTION_WRAPPERCACHE_CLASS(ImageDecoder)
public:
ImageDecoder(nsCOMPtr<nsIGlobalObject>&& aParent, const nsAString& aType);
public:
nsIGlobalObject* GetParentObject() const { return mParent; }
JSObject* WrapObject(JSContext* aCx,
JS::Handle<JSObject*> aGivenProto) override;
static bool PrefEnabled(JSContext* aCx, JSObject* aObj);
static already_AddRefed<ImageDecoder> Constructor(
const GlobalObject& aGlobal, const ImageDecoderInit& aInit,
ErrorResult& aRv);
static already_AddRefed<Promise> IsTypeSupported(const GlobalObject& aGlobal,
const nsAString& aType,
ErrorResult& aRv);
void GetType(nsAString& aType) const;
bool Complete() const { return mComplete; }
Promise* Completed() const { return mCompletePromise; }
ImageTrackList* Tracks() const { return mTracks; }
already_AddRefed<Promise> Decode(const ImageDecodeOptions& aOptions,
ErrorResult& aRv);
void Reset();
void Close();
void OnSourceBufferComplete(const MediaResult& aResult);
void QueueSelectTrackMessage(uint32_t aSelectedIndex);
void ProcessControlMessageQueue();
private:
~ImageDecoder();
class ControlMessage;
class ConfigureMessage;
class DecodeMetadataMessage;
class DecodeFrameMessage;
class SelectTrackMessage;
std::queue<UniquePtr<ControlMessage>> mControlMessageQueue;
bool mMessageQueueBlocked = false;
bool mTracksEstablished = false;
struct OutstandingDecode {
RefPtr<Promise> mPromise;
uint32_t mFrameIndex = 0;
bool mCompleteFramesOnly = true;
};
// VideoFrame can run on either main thread or worker thread.
void AssertIsOnOwningThread() const { NS_ASSERT_OWNINGTHREAD(ImageDecoder); }
void Initialize(const GlobalObject& aGLobal, const ImageDecoderInit& aInit,
ErrorResult& aRv);
void Destroy();
void Reset(const MediaResult& aResult);
void Close(const MediaResult& aResult);
void QueueConfigureMessage(ColorSpaceConversion aColorSpaceConversion);
void QueueDecodeMetadataMessage();
void QueueDecodeFrameMessage();
void ResumeControlMessageQueue();
MessageProcessedResult ProcessConfigureMessage(ConfigureMessage* aMsg);
MessageProcessedResult ProcessDecodeMetadataMessage(
DecodeMetadataMessage* aMsg);
MessageProcessedResult ProcessDecodeFrameMessage(DecodeFrameMessage* aMsg);
MessageProcessedResult ProcessSelectTrackMessage(SelectTrackMessage* aMsg);
void CheckOutstandingDecodes();
void OnCompleteSuccess();
void OnCompleteFailed(const MediaResult& aResult);
void OnMetadataSuccess(const image::DecodeMetadataResult& aMetadata);
void OnMetadataFailed(const nsresult& aErr);
void RequestFrameCount(uint32_t aKnownFrameCount);
void OnFrameCountSuccess(const image::DecodeFrameCountResult& aResult);
void OnFrameCountFailed(const nsresult& aErr);
void RequestDecodeFrames(uint32_t aFramesToDecode);
void OnDecodeFramesSuccess(const image::DecodeFramesResult& aResult);
void OnDecodeFramesFailed(const nsresult& aErr);
nsCOMPtr<nsIGlobalObject> mParent;
RefPtr<ImageTrackList> mTracks;
RefPtr<ImageDecoderReadRequest> mReadRequest;
RefPtr<Promise> mCompletePromise;
RefPtr<image::SourceBuffer> mSourceBuffer;
RefPtr<image::AnonymousDecoder> mDecoder;
AutoTArray<OutstandingDecode, 1> mOutstandingDecodes;
nsAutoString mType;
image::FrameTimeout mFramesTimestamp;
bool mComplete = false;
bool mHasFrameCount = false;
bool mHasFramePending = false;
bool mTypeNotSupported = false;
bool mClosed = false;
};
} // namespace dom
} // namespace mozilla
#endif // mozilla_dom_ImageDecoder_h

Просмотреть файл

@ -0,0 +1,294 @@
/* -*- 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/. */
#include "ImageDecoderReadRequest.h"
#include "MediaResult.h"
#include "mozilla/CycleCollectedJSContext.h"
#include "mozilla/dom/ImageDecoder.h"
#include "mozilla/dom/ReadableStream.h"
#include "mozilla/dom/ReadableStreamDefaultReader.h"
#include "mozilla/dom/WorkerCommon.h"
#include "mozilla/dom/WorkerRef.h"
#include "mozilla/image/SourceBuffer.h"
#include "mozilla/Logging.h"
extern mozilla::LazyLogModule gWebCodecsLog;
namespace mozilla::dom {
NS_IMPL_CYCLE_COLLECTION_INHERITED(ImageDecoderReadRequest, ReadRequest,
mDecoder, mReader)
NS_IMPL_ADDREF_INHERITED(ImageDecoderReadRequest, ReadRequest)
NS_IMPL_RELEASE_INHERITED(ImageDecoderReadRequest, ReadRequest)
NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(ImageDecoderReadRequest)
NS_INTERFACE_MAP_END_INHERITING(ReadRequest)
ImageDecoderReadRequest::ImageDecoderReadRequest(
image::SourceBuffer* aSourceBuffer)
: mSourceBuffer(std::move(aSourceBuffer)) {
MOZ_LOG(gWebCodecsLog, LogLevel::Debug,
("ImageDecoderReadRequest %p ImageDecoderReadRequest", this));
}
ImageDecoderReadRequest::~ImageDecoderReadRequest() {
MOZ_LOG(gWebCodecsLog, LogLevel::Debug,
("ImageDecoderReadRequest %p ~ImageDecoderReadRequest", this));
}
bool ImageDecoderReadRequest::Initialize(const GlobalObject& aGlobal,
ImageDecoder* aDecoder,
ReadableStream& aStream) {
if (WorkerPrivate* wp = GetCurrentThreadWorkerPrivate()) {
mWorkerRef = WeakWorkerRef::Create(wp, [self = RefPtr{this}]() {
self->Destroy(/* aCycleCollect */ false);
});
if (NS_WARN_IF(!mWorkerRef)) {
MOZ_LOG(gWebCodecsLog, LogLevel::Error,
("ImageDecoderReadRequest %p Initialize -- cannot get worker ref",
this));
mSourceBuffer->Complete(NS_ERROR_FAILURE);
Destroy(/* aCycleCollect */ false);
return false;
}
}
IgnoredErrorResult rv;
mReader = aStream.GetReader(rv);
if (NS_WARN_IF(rv.Failed())) {
MOZ_LOG(
gWebCodecsLog, LogLevel::Error,
("ImageDecoderReadRequest %p Initialize -- cannot get stream reader",
this));
mSourceBuffer->Complete(NS_ERROR_FAILURE);
Destroy(/* aCycleCollect */ false);
return false;
}
mDecoder = aDecoder;
QueueRead();
return true;
}
void ImageDecoderReadRequest::Destroy(bool aCycleCollect /* = true */) {
MOZ_LOG(gWebCodecsLog, LogLevel::Debug,
("ImageDecoderReadRequest %p Destroy", this));
if (!aCycleCollect) {
// Ensure we stop reading from the ReadableStream.
Cancel();
}
if (mSourceBuffer) {
if (!mSourceBuffer->IsComplete()) {
mSourceBuffer->Complete(NS_ERROR_ABORT);
}
mSourceBuffer = nullptr;
}
mDecoder = nullptr;
mReader = nullptr;
}
void ImageDecoderReadRequest::QueueRead() {
class ReadRunnable final : public CancelableRunnable {
public:
explicit ReadRunnable(ImageDecoderReadRequest* aOwner)
: CancelableRunnable(
"mozilla::dom::ImageDecoderReadRequest::QueueRead"),
mOwner(aOwner) {}
NS_IMETHODIMP Run() override {
mOwner->Read();
mOwner = nullptr;
return NS_OK;
}
nsresult Cancel() override {
mOwner->Complete(
MediaResult(NS_ERROR_DOM_MEDIA_ABORT_ERR, "Read cancelled"_ns));
mOwner = nullptr;
return NS_OK;
}
private:
virtual ~ReadRunnable() {
if (mOwner) {
Cancel();
}
}
RefPtr<ImageDecoderReadRequest> mOwner;
};
if (!mReader) {
MOZ_LOG(gWebCodecsLog, LogLevel::Debug,
("ImageDecoderReadRequest %p QueueRead -- destroyed", this));
return;
}
MOZ_LOG(gWebCodecsLog, LogLevel::Debug,
("ImageDecoderReadRequest %p QueueRead -- queue", this));
auto task = MakeRefPtr<ReadRunnable>(this);
NS_DispatchToCurrentThread(task.forget());
}
void ImageDecoderReadRequest::Read() {
if (!mReader || !mDecoder) {
MOZ_LOG(gWebCodecsLog, LogLevel::Debug,
("ImageDecoderReadRequest %p Read -- destroyed", this));
return;
}
AutoJSAPI jsapi;
if (!jsapi.Init(mDecoder->GetParentObject())) {
MOZ_LOG(gWebCodecsLog, LogLevel::Debug,
("ImageDecoderReadRequest %p Read -- no jsapi", this));
Complete(MediaResult(NS_ERROR_DOM_FILE_NOT_READABLE_ERR,
"Reader cannot init jsapi"_ns));
return;
}
RefPtr<ImageDecoderReadRequest> self(this);
RefPtr<ReadableStreamDefaultReader> reader(mReader);
MOZ_LOG(gWebCodecsLog, LogLevel::Debug,
("ImageDecoderReadRequest %p Read -- begin read chunk", this));
IgnoredErrorResult err;
reader->ReadChunk(jsapi.cx(), *self, err);
if (NS_WARN_IF(err.Failed())) {
MOZ_LOG(gWebCodecsLog, LogLevel::Error,
("ImageDecoderReadRequest %p Read -- read chunk failed", this));
Complete(MediaResult(NS_ERROR_DOM_FILE_NOT_READABLE_ERR,
"Reader cannot read chunk from stream"_ns));
}
MOZ_LOG(gWebCodecsLog, LogLevel::Debug,
("ImageDecoderReadRequest %p Read -- end read chunk", this));
}
void ImageDecoderReadRequest::Cancel() {
RefPtr<ReadableStreamDefaultReader> reader = std::move(mReader);
if (!reader || !mDecoder) {
return;
}
RefPtr<ImageDecoderReadRequest> self(this);
AutoJSAPI jsapi;
if (!jsapi.Init(mDecoder->GetParentObject())) {
MOZ_LOG(gWebCodecsLog, LogLevel::Debug,
("ImageDecoderReadRequest %p Cancel -- no jsapi", this));
return;
}
ErrorResult rv;
rv.ThrowAbortError("ImageDecoderReadRequest destroyed");
JS::Rooted<JS::Value> errorValue(jsapi.cx());
if (ToJSValue(jsapi.cx(), std::move(rv), &errorValue)) {
IgnoredErrorResult ignoredRv;
if (RefPtr<Promise> p = reader->Cancel(jsapi.cx(), errorValue, ignoredRv)) {
MOZ_ALWAYS_TRUE(p->SetAnyPromiseIsHandled());
}
}
jsapi.ClearException();
}
void ImageDecoderReadRequest::Complete(const MediaResult& aResult) {
if (!mReader) {
return;
}
MOZ_LOG(gWebCodecsLog, LogLevel::Debug,
("ImageDecoderReadRequest %p Read -- complete, success %d", this,
NS_SUCCEEDED(aResult.Code())));
if (mSourceBuffer && !mSourceBuffer->IsComplete()) {
mSourceBuffer->Complete(aResult.Code());
}
if (mDecoder) {
mDecoder->OnSourceBufferComplete(aResult);
}
Destroy(/* aCycleComplete */ false);
}
void ImageDecoderReadRequest::ChunkSteps(JSContext* aCx,
JS::Handle<JS::Value> aChunk,
ErrorResult& aRv) {
// 10.2.5. Fetch Stream Data Loop (with reader) - chunk steps
// 1. If [[closed]] is true, abort these steps.
if (!mSourceBuffer) {
return;
}
// 2. If chunk is not a Uint8Array object, queue a task to run the Close
// ImageDecoder algorithm with a DataError DOMException and abort these steps.
RootedSpiderMonkeyInterface<Uint8Array> chunk(aCx);
if (!aChunk.isObject() || !chunk.Init(&aChunk.toObject())) {
MOZ_LOG(gWebCodecsLog, LogLevel::Error,
("ImageDecoderReadRequest %p ChunkSteps -- bad chunk", this));
Complete(MediaResult(NS_ERROR_DOM_DATA_ERR,
"Reader cannot read chunk from stream"_ns));
return;
}
chunk.ProcessFixedData([&](const Span<uint8_t>& aData) {
MOZ_LOG(gWebCodecsLog, LogLevel::Debug,
("ImageDecoderReadRequest %p ChunkSteps -- write %zu bytes", this,
aData.Length()));
// 3. Let bytes be the byte sequence represented by the Uint8Array object.
// 4. Append bytes to the [[encoded data]] internal slot.
nsresult rv = mSourceBuffer->Append(
reinterpret_cast<const char*>(aData.Elements()), aData.Length());
if (NS_WARN_IF(NS_FAILED(rv))) {
MOZ_LOG(
gWebCodecsLog, LogLevel::Debug,
("ImageDecoderReadRequest %p ChunkSteps -- failed to append", this));
Complete(MediaResult(NS_ERROR_DOM_UNKNOWN_ERR,
"Reader cannot allocate storage for chunk"_ns));
}
// 5. If [[tracks established]] is false, run the Establish Tracks
// algorithm.
// 6. Otherwise, run the Update Tracks algorithm.
//
// Note that these steps will be triggered by the decoder promise callbacks.
});
// 7. Run the Fetch Stream Data Loop algorithm with reader.
QueueRead();
}
void ImageDecoderReadRequest::CloseSteps(JSContext* aCx, ErrorResult& aRv) {
MOZ_LOG(gWebCodecsLog, LogLevel::Debug,
("ImageDecoderReadRequest %p CloseSteps", this));
// 10.2.5. Fetch Stream Data Loop (with reader) - close steps
// 1. Assign true to [[complete]]
// 2. Resolve [[completed promise]].
Complete(MediaResult(NS_OK));
}
void ImageDecoderReadRequest::ErrorSteps(JSContext* aCx,
JS::Handle<JS::Value> aError,
ErrorResult& aRv) {
MOZ_LOG(gWebCodecsLog, LogLevel::Debug,
("ImageDecoderReadRequest %p ErrorSteps", this));
// 10.2.5. Fetch Stream Data Loop (with reader) - error steps
// 1. Queue a task to run the Close ImageDecoder algorithm with a
// NotReadableError DOMException
Complete(MediaResult(NS_ERROR_DOM_FILE_NOT_READABLE_ERR,
"Reader failed while waiting for chunk from stream"_ns));
}
} // namespace mozilla::dom

Просмотреть файл

@ -0,0 +1,66 @@
/* -*- 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 mozilla_dom_ImageDecoderReadRequest_h
#define mozilla_dom_ImageDecoderReadRequest_h
#include "mozilla/dom/BindingDeclarations.h"
#include "mozilla/dom/ReadRequest.h"
namespace mozilla {
class MediaResult;
namespace image {
class SourceBuffer;
}
namespace dom {
class ImageDecoder;
class ReadableStream;
class ReadableStreamDefaultReader;
class WeakWorkerRef;
struct ImageDecoderReadRequest final : public ReadRequest {
public:
NS_DECL_ISUPPORTS_INHERITED
NS_DECL_CYCLE_COLLECTION_CLASS_INHERITED(ImageDecoderReadRequest, ReadRequest)
public:
explicit ImageDecoderReadRequest(image::SourceBuffer* aSourceBuffer);
bool Initialize(const GlobalObject& aGlobal, ImageDecoder* aDecoder,
ReadableStream& aStream);
void Destroy(bool aCycleCollect = true);
MOZ_CAN_RUN_SCRIPT_BOUNDARY void ChunkSteps(JSContext* aCx,
JS::Handle<JS::Value> aChunk,
ErrorResult& aRv) override;
MOZ_CAN_RUN_SCRIPT_BOUNDARY void CloseSteps(JSContext* aCx,
ErrorResult& aRv) override;
MOZ_CAN_RUN_SCRIPT_BOUNDARY void ErrorSteps(JSContext* aCx,
JS::Handle<JS::Value> aError,
ErrorResult& aRv) override;
private:
~ImageDecoderReadRequest() override;
void QueueRead();
MOZ_CAN_RUN_SCRIPT_BOUNDARY void Read();
MOZ_CAN_RUN_SCRIPT_BOUNDARY void Cancel();
void Complete(const MediaResult& aResult);
RefPtr<WeakWorkerRef> mWorkerRef;
RefPtr<ImageDecoder> mDecoder;
RefPtr<ReadableStreamDefaultReader> mReader;
RefPtr<image::SourceBuffer> mSourceBuffer;
};
} // namespace dom
} // namespace mozilla
#endif // mozilla_dom_ImageDecoderReadRequest_h

Просмотреть файл

@ -0,0 +1,107 @@
/* -*- 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/. */
#include "mozilla/dom/ImageTrack.h"
#include "ImageContainer.h"
#include "mozilla/dom/ImageTrackList.h"
#include "mozilla/dom/WebCodecsUtils.h"
#include "mozilla/gfx/2D.h"
#include "mozilla/image/ImageUtils.h"
extern mozilla::LazyLogModule gWebCodecsLog;
namespace mozilla::dom {
NS_IMPL_CYCLE_COLLECTION_WRAPPERCACHE(ImageTrack, mParent, mTrackList,
mDecodedFrames)
NS_IMPL_CYCLE_COLLECTING_ADDREF(ImageTrack)
NS_IMPL_CYCLE_COLLECTING_RELEASE(ImageTrack)
NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(ImageTrack)
NS_WRAPPERCACHE_INTERFACE_MAP_ENTRY
NS_INTERFACE_MAP_ENTRY(nsISupports)
NS_INTERFACE_MAP_END
ImageTrack::ImageTrack(ImageTrackList* aTrackList, int32_t aIndex,
bool aSelected, bool aAnimated, uint32_t aFrameCount,
bool aFrameCountComplete, float aRepetitionCount)
: mParent(aTrackList->GetParentObject()),
mTrackList(aTrackList),
mFramesTimestamp(image::FrameTimeout::Zero()),
mIndex(aIndex),
mRepetitionCount(aRepetitionCount),
mFrameCount(aFrameCount),
mFrameCountComplete(aFrameCountComplete),
mAnimated(aAnimated),
mSelected(aSelected) {}
ImageTrack::~ImageTrack() = default;
void ImageTrack::Destroy() { mTrackList = nullptr; }
JSObject* ImageTrack::WrapObject(JSContext* aCx,
JS::Handle<JSObject*> aGivenProto) {
AssertIsOnOwningThread();
return ImageTrack_Binding::Wrap(aCx, this, aGivenProto);
}
void ImageTrack::SetSelected(bool aSelected) {
if (mTrackList) {
mTrackList->SetSelectedIndex(mIndex, aSelected);
}
}
void ImageTrack::OnFrameCountSuccess(
const image::DecodeFrameCountResult& aResult) {
MOZ_ASSERT_IF(mFrameCountComplete, mFrameCount == aResult.mFrameCount);
MOZ_ASSERT_IF(!aResult.mFinished, !mFrameCountComplete);
MOZ_ASSERT_IF(!mAnimated, aResult.mFrameCount <= 1);
MOZ_ASSERT(aResult.mFrameCount >= mFrameCount);
mFrameCount = aResult.mFrameCount;
mFrameCountComplete = aResult.mFinished;
}
void ImageTrack::OnDecodeFramesSuccess(
const image::DecodeFramesResult& aResult) {
MOZ_LOG(gWebCodecsLog, LogLevel::Debug,
("ImageTrack %p OnDecodeFramesSuccess -- decoded %zu frames, %zu "
"total, finished %d",
this, aResult.mFrames.Length(), mDecodedFrames.Length(),
aResult.mFinished));
mDecodedFrames.SetCapacity(mDecodedFrames.Length() +
aResult.mFrames.Length());
for (const auto& f : aResult.mFrames) {
VideoColorSpaceInit colorSpace;
gfx::IntSize size = f.mSurface->GetSize();
gfx::IntRect rect(gfx::IntPoint(0, 0), size);
Maybe<VideoPixelFormat> format =
SurfaceFormatToVideoPixelFormat(f.mSurface->GetFormat());
MOZ_ASSERT(format, "Unexpected format for image!");
Maybe<uint64_t> duration;
if (f.mTimeout != image::FrameTimeout::Forever()) {
duration =
Some(static_cast<uint64_t>(f.mTimeout.AsMilliseconds()) * 1000);
}
uint64_t timestamp = UINT64_MAX;
if (mFramesTimestamp != image::FrameTimeout::Forever()) {
timestamp =
static_cast<uint64_t>(mFramesTimestamp.AsMilliseconds()) * 1000;
}
mFramesTimestamp += f.mTimeout;
auto image = MakeRefPtr<layers::SourceSurfaceImage>(size, f.mSurface);
auto frame = MakeRefPtr<VideoFrame>(mParent, image, format, size, rect,
size, duration, timestamp, colorSpace);
mDecodedFrames.AppendElement(std::move(frame));
}
}
} // namespace mozilla::dom

Просмотреть файл

@ -0,0 +1,100 @@
/* -*- 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 mozilla_dom_ImageTrack_h
#define mozilla_dom_ImageTrack_h
#include "FrameTimeout.h"
#include "mozilla/Attributes.h"
#include "mozilla/ErrorResult.h"
#include "mozilla/NotNull.h"
#include "mozilla/dom/ImageDecoderBinding.h"
#include "nsCycleCollectionParticipant.h"
#include "nsTArray.h"
#include "nsWrapperCache.h"
class nsIGlobalObject;
namespace mozilla {
namespace image {
struct DecodeFrameCountResult;
struct DecodeFramesResult;
} // namespace image
namespace dom {
class ImageTrackList;
class VideoFrame;
class ImageTrack final : public nsISupports, public nsWrapperCache {
public:
NS_DECL_CYCLE_COLLECTING_ISUPPORTS
NS_DECL_CYCLE_COLLECTION_WRAPPERCACHE_CLASS(ImageTrack)
public:
ImageTrack(ImageTrackList* aTrackList, int32_t aIndex, bool aSelected,
bool aAnimated, uint32_t aFrameCount, bool aFrameCountComplete,
float aRepetitionCount);
protected:
~ImageTrack();
public:
nsIGlobalObject* GetParentObject() const { return mParent; }
void Destroy();
JSObject* WrapObject(JSContext* aCx,
JS::Handle<JSObject*> aGivenProto) override;
int32_t Index() const { return mIndex; }
bool Animated() const { return mAnimated; }
uint32_t FrameCount() const { return mFrameCount; }
bool FrameCountComplete() const { return mFrameCountComplete; }
float RepetitionCount() const { return mRepetitionCount; }
bool Selected() const { return mSelected; }
void SetSelected(bool aSelected);
void ClearSelected() { mSelected = false; }
void MarkSelected() { mSelected = true; }
size_t DecodedFrameCount() const { return mDecodedFrames.Length(); }
VideoFrame* GetDecodedFrame(uint32_t aIndex) const {
if (mDecodedFrames.Length() <= aIndex) {
return nullptr;
}
return mDecodedFrames[aIndex];
}
void OnFrameCountSuccess(const image::DecodeFrameCountResult& aResult);
void OnDecodeFramesSuccess(const image::DecodeFramesResult& aResult);
private:
// ImageTrack can run on either main thread or worker thread.
void AssertIsOnOwningThread() const { NS_ASSERT_OWNINGTHREAD(ImageTrack); }
nsCOMPtr<nsIGlobalObject> mParent;
RefPtr<ImageTrackList> mTrackList;
AutoTArray<RefPtr<VideoFrame>, 1> mDecodedFrames;
image::FrameTimeout mFramesTimestamp;
int32_t mIndex = 0;
float mRepetitionCount = 0.0f;
uint32_t mFrameCount = 0;
bool mFrameCountComplete = false;
bool mAnimated = false;
bool mSelected = false;
};
} // namespace dom
} // namespace mozilla
#endif // mozilla_dom_ImageTrack_h

Просмотреть файл

@ -0,0 +1,206 @@
/* -*- 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/. */
#include "mozilla/dom/ImageTrackList.h"
#include "MediaResult.h"
#include "mozilla/dom/ImageDecoder.h"
#include "mozilla/dom/ImageTrack.h"
#include "mozilla/dom/Promise.h"
#include "mozilla/image/ImageUtils.h"
namespace mozilla::dom {
NS_IMPL_CYCLE_COLLECTION_WRAPPERCACHE(ImageTrackList, mParent, mDecoder,
mReadyPromise, mTracks)
NS_IMPL_CYCLE_COLLECTING_ADDREF(ImageTrackList)
NS_IMPL_CYCLE_COLLECTING_RELEASE(ImageTrackList)
NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(ImageTrackList)
NS_WRAPPERCACHE_INTERFACE_MAP_ENTRY
NS_INTERFACE_MAP_ENTRY(nsISupports)
NS_INTERFACE_MAP_END
ImageTrackList::ImageTrackList(nsIGlobalObject* aParent, ImageDecoder* aDecoder)
: mParent(aParent), mDecoder(aDecoder) {}
ImageTrackList::~ImageTrackList() = default;
JSObject* ImageTrackList::WrapObject(JSContext* aCx,
JS::Handle<JSObject*> aGivenProto) {
AssertIsOnOwningThread();
return ImageTrackList_Binding::Wrap(aCx, this, aGivenProto);
}
void ImageTrackList::Initialize(ErrorResult& aRv) {
mReadyPromise = Promise::Create(mParent, aRv);
if (NS_WARN_IF(aRv.Failed())) {
return;
}
}
void ImageTrackList::Destroy() {
if (!mIsReady && mReadyPromise && mReadyPromise->PromiseObj()) {
mReadyPromise->MaybeRejectWithAbortError("ImageTrackList destroyed");
mIsReady = true;
}
for (auto& track : mTracks) {
track->Destroy();
}
mTracks.Clear();
mDecoder = nullptr;
mSelectedIndex = -1;
}
void ImageTrackList::MaybeRejectReady(const MediaResult& aResult) {
if (mIsReady || !mReadyPromise || !mReadyPromise->PromiseObj()) {
return;
}
aResult.RejectTo(mReadyPromise);
mIsReady = true;
}
void ImageTrackList::OnMetadataSuccess(
const image::DecodeMetadataResult& aMetadata) {
// 10.2.5. Establish Tracks
//
// Note that our implementation only supports one track, so many of these
// steps are simplified.
// 4. Let newTrackList be a new list.
MOZ_ASSERT(mTracks.IsEmpty());
// 5. For each image track found in [[encoded data]]:
// 5.1. Let newTrack be a new ImageTrack, initialized as follows:
// 5.1.1. Assign this to [[ImageDecoder]].
// 5.1.2. Assign tracks to [[ImageTrackList]].
// 5.1.3. If image track is found to be animated, assign true to newTrack's
// [[animated]] internal slot. Otherwise, assign false.
// 5.1.4. If image track is found to describe a frame count, assign that
// count to newTrack's [[frame count]] internal slot. Otherwise, assign
// 0.
// 5.1.5. If image track is found to describe a repetition count, assign that
// count to [[repetition count]] internal slot. Otherwise, assign 0.
// 5.1.6. Assign false to newTracks [[selected]] internal slot.
// 5.2. Append newTrack to newTrackList.
// 6. Let selectedTrackIndex be the result of running the Get Default Selected
// Track Index algorithm with newTrackList.
// 7. Let selectedTrack be the track at position selectedTrackIndex within
// newTrackList.
// 8. Assign true to selectedTracks [[selected]] internal slot.
// 9. Assign selectedTrackIndex to [[internal selected track index]].
const float repetitions = aMetadata.mRepetitions < 0
? std::numeric_limits<float>::infinity()
: static_cast<float>(aMetadata.mRepetitions);
auto track = MakeRefPtr<ImageTrack>(
this, /* aIndex */ 0, /* aSelected */ true, aMetadata.mAnimated,
aMetadata.mFrameCount, aMetadata.mFrameCountComplete, repetitions);
// 11. Queue a task to perform the following steps:
//
// Note that we were already dispatched by the image decoder.
// 11.1. Assign newTrackList to the tracks [[track list]] internal slot.
mTracks.AppendElement(std::move(track));
// 11.2. Assign selectedTrackIndex to tracks [[selected index]].
mSelectedIndex = 0;
// 11.3. Resolve [[ready promise]].
MOZ_ASSERT(!mIsReady);
mReadyPromise->MaybeResolveWithUndefined();
mIsReady = true;
}
void ImageTrackList::OnFrameCountSuccess(
const image::DecodeFrameCountResult& aResult) {
if (mTracks.IsEmpty()) {
return;
}
// 10.2.5. Update Tracks
//
// Note that we were already dispatched from the decoding threads.
// 3. Let trackList be a copy of tracks' [[track list]].
// 4. For each track in trackList:
// 4.1. Let trackIndex be the position of track in trackList.
// 4.2. Let latestFrameCount be the frame count as indicated by
// [[encoded data]] for the track corresponding to track.
// 4.3. Assert that latestFrameCount is greater than or equal to
// track.frameCount.
// 4.4. If latestFrameCount is greater than track.frameCount:
// 4.4.1. Let change be a track update struct whose track index is trackIndex
// and frame count is latestFrameCount.
// 4.4.2. Append change to tracksChanges.
// 5. If tracksChanges is empty, abort these steps.
// 6. Queue a task to perform the following steps:
// 6.1. For each update in trackChanges:
// 6.1.1. Let updateTrack be the ImageTrack at position update.trackIndex
// within tracks' [[track list]].
// 6.1.2. Assign update.frameCount to updateTracks [[frame count]].
mTracks.LastElement()->OnFrameCountSuccess(aResult);
}
void ImageTrackList::SetSelectedIndex(int32_t aIndex, bool aSelected) {
MOZ_ASSERT(aIndex >= 0);
MOZ_ASSERT(uint32_t(aIndex) < mTracks.Length());
// 10.7.2. Attributes - selected, of type boolean
// 1. If [[ImageDecoder]]'s [[closed]] slot is true, abort these steps.
if (!mDecoder) {
return;
}
// 2. Let newValue be the given value.
// 3. If newValue equals [[selected]], abort these steps.
// 4. Assign newValue to [[selected]].
// 5. Let parentTrackList be [[ImageTrackList]]
// 6. Let oldSelectedIndex be the value of parentTrackList [[selected index]].
// 7. If oldSelectedIndex is not -1:
// 7.1. Let oldSelectedTrack be the ImageTrack in parentTrackList
// [[track list]] at the position of oldSelectedIndex.
// 7.2. Assign false to oldSelectedTrack [[selected]]
// 8. If newValue is true, let selectedIndex be the index of this ImageTrack
// within parentTrackList's [[track list]]. Otherwise, let selectedIndex be
// -1.
// 9. Assign selectedIndex to parentTrackList [[selected index]].
if (aSelected) {
if (mSelectedIndex == -1) {
MOZ_ASSERT(!mTracks[aIndex]->Selected());
mTracks[aIndex]->MarkSelected();
mSelectedIndex = aIndex;
} else if (mSelectedIndex != aIndex) {
MOZ_ASSERT(mTracks[mSelectedIndex]->Selected());
MOZ_ASSERT(!mTracks[aIndex]->Selected());
mTracks[mSelectedIndex]->ClearSelected();
mTracks[aIndex]->MarkSelected();
mSelectedIndex = aIndex;
} else {
MOZ_ASSERT(mTracks[mSelectedIndex]->Selected());
return;
}
} else if (mSelectedIndex == aIndex) {
mTracks[mSelectedIndex]->ClearSelected();
mSelectedIndex = -1;
} else {
MOZ_ASSERT(!mTracks[aIndex]->Selected());
return;
}
// 10. Run the Reset ImageDecoder algorithm on [[ImageDecoder]].
mDecoder->Reset();
// 11. Queue a control message to [[ImageDecoder]]'s control message queue to
// update the internal selected track index with selectedIndex.
mDecoder->QueueSelectTrackMessage(mSelectedIndex);
// 12. Process the control message queue belonging to [[ImageDecoder]].
mDecoder->ProcessControlMessageQueue();
}
} // namespace mozilla::dom

Просмотреть файл

@ -0,0 +1,104 @@
/* -*- 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 mozilla_dom_ImageTrackList_h
#define mozilla_dom_ImageTrackList_h
#include "mozilla/Attributes.h"
#include "mozilla/dom/ImageDecoderBinding.h"
#include "nsCycleCollectionParticipant.h"
#include "nsWrapperCache.h"
class nsIGlobalObject;
namespace mozilla {
class MediaResult;
namespace image {
struct DecodeFrameCountResult;
struct DecodeMetadataResult;
} // namespace image
namespace dom {
class ImageTrack;
class Promise;
class ImageTrackList final : public nsISupports, public nsWrapperCache {
public:
NS_DECL_CYCLE_COLLECTING_ISUPPORTS
NS_DECL_CYCLE_COLLECTION_WRAPPERCACHE_CLASS(ImageTrackList)
public:
ImageTrackList(nsIGlobalObject* aParent, ImageDecoder* aDecoder);
void Initialize(ErrorResult& aRv);
void MaybeRejectReady(const MediaResult& aResult);
void Destroy();
void OnMetadataSuccess(const image::DecodeMetadataResult& aMetadata);
void OnFrameCountSuccess(const image::DecodeFrameCountResult& aResult);
void SetSelectedIndex(int32_t aIndex, bool aSelected);
protected:
~ImageTrackList();
public:
nsIGlobalObject* GetParentObject() const { return mParent; }
JSObject* WrapObject(JSContext* aCx,
JS::Handle<JSObject*> aGivenProto) override;
Promise* Ready() const { return mReadyPromise; }
bool IsReady() const { return mIsReady; }
uint32_t Length() const { return mTracks.Length(); }
int32_t SelectedIndex() const { return mSelectedIndex; }
ImageTrack* GetSelectedTrack() const {
if (mSelectedIndex < 0) {
return nullptr;
}
return mTracks[mSelectedIndex];
}
ImageTrack* GetDefaultTrack() const {
if (mTracks.IsEmpty()) {
return nullptr;
}
return mTracks[0];
}
ImageTrack* IndexedGetter(uint32_t aIndex, bool& aFound) const {
if (aIndex >= mTracks.Length()) {
aFound = false;
return nullptr;
}
MOZ_ASSERT(mTracks[aIndex]);
aFound = true;
return mTracks[aIndex];
}
private:
// ImageTrackList can run on either main thread or worker thread.
void AssertIsOnOwningThread() const {
NS_ASSERT_OWNINGTHREAD(ImageTrackList);
}
nsCOMPtr<nsIGlobalObject> mParent;
RefPtr<ImageDecoder> mDecoder;
AutoTArray<RefPtr<ImageTrack>, 1> mTracks;
RefPtr<Promise> mReadyPromise;
int32_t mSelectedIndex = -1;
bool mIsReady = false;
};
} // namespace dom
} // namespace mozilla
#endif // mozilla_dom_ImageTrackList_h

Просмотреть файл

@ -31,6 +31,9 @@ EXPORTS.mozilla.dom += [
"EncoderAgent.h",
"EncoderTemplate.h",
"EncoderTypes.h",
"ImageDecoder.h",
"ImageTrack.h",
"ImageTrackList.h",
"VideoColorSpace.h",
"VideoDecoder.h",
"VideoEncoder.h",
@ -48,6 +51,10 @@ UNIFIED_SOURCES += [
"EncodedVideoChunk.cpp",
"EncoderAgent.cpp",
"EncoderTemplate.cpp",
"ImageDecoder.cpp",
"ImageDecoderReadRequest.cpp",
"ImageTrack.cpp",
"ImageTrackList.cpp",
"VideoColorSpace.cpp",
"VideoDecoder.cpp",
"VideoEncoder.cpp",

Просмотреть файл

@ -770,6 +770,12 @@ let interfaceNamesInGlobalScope = [
// IMPORTANT: Do not change this list without review from a DOM peer!
{ name: "ImageData", insecureContext: true },
// IMPORTANT: Do not change this list without review from a DOM peer!
{ name: "ImageDecoder", nightly: true },
// IMPORTANT: Do not change this list without review from a DOM peer!
{ name: "ImageTrack", nightly: true },
// IMPORTANT: Do not change this list without review from a DOM peer!
{ name: "ImageTrackList", nightly: true },
// IMPORTANT: Do not change this list without review from a DOM peer!
{ name: "InputEvent", insecureContext: true },
// IMPORTANT: Do not change this list without review from a DOM peer!
{

Просмотреть файл

@ -0,0 +1,73 @@
/* -*- Mode: IDL; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* 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/.
*
* The origin of this IDL file is
* https://w3c.github.io/webcodecs/#image-decoding
*/
// Bug 1696216: Should be AllowSharedBufferSource or ReadableStream
typedef ([AllowShared] ArrayBufferView or [AllowShared] ArrayBuffer or ReadableStream) ImageBufferSource;
dictionary ImageDecoderInit {
required DOMString type;
required ImageBufferSource data;
ColorSpaceConversion colorSpaceConversion = "default";
[EnforceRange] unsigned long desiredWidth;
[EnforceRange] unsigned long desiredHeight;
boolean preferAnimation;
sequence<ArrayBuffer> transfer = [];
};
dictionary ImageDecodeOptions {
[EnforceRange] unsigned long frameIndex = 0;
boolean completeFramesOnly = true;
};
dictionary ImageDecodeResult {
required VideoFrame image;
required boolean complete;
};
[Exposed=(Window,DedicatedWorker),
SecureContext,
Func="mozilla::dom::ImageDecoder::PrefEnabled"]
interface ImageTrack {
readonly attribute boolean animated;
readonly attribute unsigned long frameCount;
readonly attribute unrestricted float repetitionCount;
attribute boolean selected;
};
[Exposed=(Window,DedicatedWorker),
SecureContext,
Func="mozilla::dom::ImageDecoder::PrefEnabled"]
interface ImageTrackList {
getter ImageTrack (unsigned long index);
readonly attribute Promise<undefined> ready;
readonly attribute unsigned long length;
readonly attribute long selectedIndex;
readonly attribute ImageTrack? selectedTrack;
};
[Exposed=(Window,DedicatedWorker),
SecureContext,
Func="mozilla::dom::ImageDecoder::PrefEnabled"]
interface ImageDecoder {
[Throws]
constructor(ImageDecoderInit init);
readonly attribute DOMString type;
readonly attribute boolean complete;
readonly attribute Promise<undefined> completed;
readonly attribute ImageTrackList tracks;
[Throws]
Promise<ImageDecodeResult> decode(optional ImageDecodeOptions options = {});
undefined reset();
undefined close();
[Throws]
static Promise<boolean> isTypeSupported(DOMString type);
};

Просмотреть файл

@ -166,6 +166,9 @@ with Files("ImageBitmap*"):
with Files("ImageCapture*"):
BUG_COMPONENT = ("Core", "Audio/Video")
with Files("ImageDecoder.webidl"):
BUG_COMPONENT = ("Core", "Audio/Video: Web Codecs")
with Files("InputEvent.webidl"):
BUG_COMPONENT = ("Core", "DOM: UI Events & Focus Handling")
@ -692,6 +695,7 @@ WEBIDL_FILES = [
"ImageBitmapRenderingContext.webidl",
"ImageCapture.webidl",
"ImageData.webidl",
"ImageDecoder.webidl",
"ImageDocument.webidl",
"InputEvent.webidl",
"IntersectionObserver.webidl",

Просмотреть файл

@ -259,6 +259,12 @@ let interfaceNamesInGlobalScope = [
// IMPORTANT: Do not change this list without review from a DOM peer!
{ name: "ImageData", insecureContext: true },
// IMPORTANT: Do not change this list without review from a DOM peer!
{ name: "ImageDecoder", nightly: true },
// IMPORTANT: Do not change this list without review from a DOM peer!
{ name: "ImageTrack", nightly: true },
// IMPORTANT: Do not change this list without review from a DOM peer!
{ name: "ImageTrackList", nightly: true },
// IMPORTANT: Do not change this list without review from a DOM peer!
"Lock",
// IMPORTANT: Do not change this list without review from a DOM peer!
"LockManager",

Просмотреть файл

@ -3149,6 +3149,12 @@
value: @IS_NIGHTLY_BUILD@
mirror: always
# WebCodecs API - Image decoder
- name: dom.media.webcodecs.image-decoder.enabled
type: RelaxedAtomicBool
value: @IS_NIGHTLY_BUILD@
mirror: always
# Number of seconds of very quiet or silent audio before considering the audio
# inaudible.
- name: dom.media.silence_duration_for_audibility

Просмотреть файл

@ -131,7 +131,7 @@ class OpaqueResponseBlocker final : public nsIStreamListener {
nsILoadInfo* aLoadInfo);
void ResolveAndProcessData(HttpBaseChannel* aChannel, bool aAllowed,
Maybe<ipc::Shmem>& aSharedData);
Maybe<mozilla::ipc::Shmem>& aSharedData);
void MaybeRunOnStopRequest(HttpBaseChannel* aChannel);

Просмотреть файл

@ -1,4 +1,4 @@
prefs: [dom.media.webcodecs.enabled:true, media.ffmpeg.encoder.enabled:true]
prefs: [dom.media.webcodecs.enabled:true, dom.media.webcodecs.image-decoder.enabled:true, media.ffmpeg.encoder.enabled:true]
tags: [webcodecs]
disabled:
if (os == "linux") and (bits == 32): Not implemented

Просмотреть файл

@ -1,619 +1,14 @@
prefs: [dom.media.webcodecs.enabled:true]
prefs: [dom.media.webcodecs.enabled:true, dom.media.webcodecs.image-decoder.enabled:true]
[idlharness.https.any.html]
[VideoFrame interface: operation metadata()]
expected: FAIL
[ImageDecoder interface: existence and properties of interface object]
[VideoFrame interface: new VideoFrame(makeImageBitmap(32, 16), {timestamp: 100, duration: 33}) must inherit property "metadata()" with the proper type]
expected: FAIL
[ImageDecoder interface object length]
expected: FAIL
[ImageDecoder interface object name]
expected: FAIL
[ImageDecoder interface: existence and properties of interface prototype object]
expected: FAIL
[ImageDecoder interface: existence and properties of interface prototype object's "constructor" property]
expected: FAIL
[ImageDecoder interface: existence and properties of interface prototype object's @@unscopables property]
expected: FAIL
[ImageDecoder interface: attribute type]
expected: FAIL
[ImageDecoder interface: attribute complete]
expected: FAIL
[ImageDecoder interface: attribute completed]
expected: FAIL
[ImageDecoder interface: attribute tracks]
expected: FAIL
[ImageDecoder interface: operation decode(optional ImageDecodeOptions)]
expected: FAIL
[ImageDecoder interface: operation reset()]
expected: FAIL
[ImageDecoder interface: operation close()]
expected: FAIL
[ImageDecoder interface: operation isTypeSupported(DOMString)]
expected: FAIL
[ImageTrackList interface: existence and properties of interface object]
expected: FAIL
[ImageTrackList interface object length]
expected: FAIL
[ImageTrackList interface object name]
expected: FAIL
[ImageTrackList interface: existence and properties of interface prototype object]
expected: FAIL
[ImageTrackList interface: existence and properties of interface prototype object's "constructor" property]
expected: FAIL
[ImageTrackList interface: existence and properties of interface prototype object's @@unscopables property]
expected: FAIL
[ImageTrackList interface: attribute ready]
expected: FAIL
[ImageTrackList interface: attribute length]
expected: FAIL
[ImageTrackList interface: attribute selectedIndex]
expected: FAIL
[ImageTrackList interface: attribute selectedTrack]
expected: FAIL
[ImageTrack interface: existence and properties of interface object]
expected: FAIL
[ImageTrack interface object length]
expected: FAIL
[ImageTrack interface object name]
expected: FAIL
[ImageTrack interface: existence and properties of interface prototype object]
expected: FAIL
[ImageTrack interface: existence and properties of interface prototype object's "constructor" property]
expected: FAIL
[ImageTrack interface: existence and properties of interface prototype object's @@unscopables property]
expected: FAIL
[ImageTrack interface: attribute animated]
expected: FAIL
[ImageTrack interface: attribute frameCount]
expected: FAIL
[ImageTrack interface: attribute repetitionCount]
expected: FAIL
[ImageTrack interface: attribute selected]
expected: FAIL
[idl_test setup]
expected: FAIL
[idl_test setup]
expected: FAIL
[idlharness.https.any.worker.html]
[VideoEncoder interface: existence and properties of interface object]
expected: FAIL
[VideoEncoder interface object length]
expected: FAIL
[VideoEncoder interface object name]
expected: FAIL
[VideoEncoder interface: existence and properties of interface prototype object]
expected: FAIL
[VideoEncoder interface: existence and properties of interface prototype object's "constructor" property]
expected: FAIL
[VideoEncoder interface: existence and properties of interface prototype object's @@unscopables property]
expected: FAIL
[VideoEncoder interface: attribute state]
expected: FAIL
[VideoEncoder interface: attribute encodeQueueSize]
expected: FAIL
[VideoEncoder interface: attribute ondequeue]
expected: FAIL
[VideoEncoder interface: operation configure(VideoEncoderConfig)]
expected: FAIL
[VideoEncoder interface: operation encode(VideoFrame, optional VideoEncoderEncodeOptions)]
expected: FAIL
[VideoEncoder interface: operation flush()]
expected: FAIL
[VideoEncoder interface: operation reset()]
expected: FAIL
[VideoEncoder interface: operation close()]
expected: FAIL
[VideoEncoder interface: operation isConfigSupported(VideoEncoderConfig)]
expected: FAIL
[VideoFrame interface: operation metadata()]
expected: FAIL
[ImageDecoder interface: existence and properties of interface object]
expected: FAIL
[ImageDecoder interface object length]
expected: FAIL
[ImageDecoder interface object name]
expected: FAIL
[ImageDecoder interface: existence and properties of interface prototype object]
expected: FAIL
[ImageDecoder interface: existence and properties of interface prototype object's "constructor" property]
expected: FAIL
[ImageDecoder interface: existence and properties of interface prototype object's @@unscopables property]
expected: FAIL
[ImageDecoder interface: attribute type]
expected: FAIL
[ImageDecoder interface: attribute complete]
expected: FAIL
[ImageDecoder interface: attribute completed]
expected: FAIL
[ImageDecoder interface: attribute tracks]
expected: FAIL
[ImageDecoder interface: operation decode(optional ImageDecodeOptions)]
expected: FAIL
[ImageDecoder interface: operation reset()]
expected: FAIL
[ImageDecoder interface: operation close()]
expected: FAIL
[ImageDecoder interface: operation isTypeSupported(DOMString)]
expected: FAIL
[ImageTrackList interface: existence and properties of interface object]
expected: FAIL
[ImageTrackList interface object length]
expected: FAIL
[ImageTrackList interface object name]
expected: FAIL
[ImageTrackList interface: existence and properties of interface prototype object]
expected: FAIL
[ImageTrackList interface: existence and properties of interface prototype object's "constructor" property]
expected: FAIL
[ImageTrackList interface: existence and properties of interface prototype object's @@unscopables property]
expected: FAIL
[ImageTrackList interface: attribute ready]
expected: FAIL
[ImageTrackList interface: attribute length]
expected: FAIL
[ImageTrackList interface: attribute selectedIndex]
expected: FAIL
[ImageTrackList interface: attribute selectedTrack]
expected: FAIL
[ImageTrack interface: existence and properties of interface object]
expected: FAIL
[ImageTrack interface object length]
expected: FAIL
[ImageTrack interface object name]
expected: FAIL
[ImageTrack interface: existence and properties of interface prototype object]
expected: FAIL
[ImageTrack interface: existence and properties of interface prototype object's "constructor" property]
expected: FAIL
[ImageTrack interface: existence and properties of interface prototype object's @@unscopables property]
expected: FAIL
[ImageTrack interface: attribute animated]
expected: FAIL
[ImageTrack interface: attribute frameCount]
expected: FAIL
[ImageTrack interface: attribute repetitionCount]
expected: FAIL
[ImageTrack interface: attribute selected]
expected: FAIL
[idl_test setup]
expected: FAIL
[idl_test setup]
expected: FAIL
[idlharness.https.any.worker.html]
[AudioDecoder interface: existence and properties of interface object]
expected: FAIL
[AudioDecoder interface object length]
expected: FAIL
[AudioDecoder interface object name]
expected: FAIL
[AudioDecoder interface: existence and properties of interface prototype object]
expected: FAIL
[AudioDecoder interface: existence and properties of interface prototype object's "constructor" property]
expected: FAIL
[AudioDecoder interface: existence and properties of interface prototype object's @@unscopables property]
expected: FAIL
[AudioDecoder interface: attribute state]
expected: FAIL
[AudioDecoder interface: attribute decodeQueueSize]
expected: FAIL
[AudioDecoder interface: attribute ondequeue]
expected: FAIL
[AudioDecoder interface: operation configure(AudioDecoderConfig)]
expected: FAIL
[AudioDecoder interface: operation decode(EncodedAudioChunk)]
expected: FAIL
[AudioDecoder interface: operation flush()]
expected: FAIL
[AudioDecoder interface: operation reset()]
expected: FAIL
[AudioDecoder interface: operation close()]
expected: FAIL
[AudioDecoder interface: operation isConfigSupported(AudioDecoderConfig)]
expected: FAIL
[EncodedAudioChunk interface: existence and properties of interface object]
expected: FAIL
[EncodedAudioChunk interface object length]
expected: FAIL
[EncodedAudioChunk interface object name]
expected: FAIL
[EncodedAudioChunk interface: existence and properties of interface prototype object]
expected: FAIL
[EncodedAudioChunk interface: existence and properties of interface prototype object's "constructor" property]
expected: FAIL
[EncodedAudioChunk interface: existence and properties of interface prototype object's @@unscopables property]
expected: FAIL
[EncodedAudioChunk interface: attribute type]
expected: FAIL
[EncodedAudioChunk interface: attribute timestamp]
expected: FAIL
[EncodedAudioChunk interface: attribute duration]
expected: FAIL
[EncodedAudioChunk interface: attribute byteLength]
expected: FAIL
[AudioData interface: existence and properties of interface object]
expected: FAIL
[AudioData interface object length]
expected: FAIL
[AudioData interface object name]
expected: FAIL
[AudioData interface: existence and properties of interface prototype object]
expected: FAIL
[AudioData interface: existence and properties of interface prototype object's "constructor" property]
expected: FAIL
[AudioData interface: existence and properties of interface prototype object's @@unscopables property]
expected: FAIL
[AudioData interface: attribute format]
expected: FAIL
[AudioData interface: attribute sampleRate]
expected: FAIL
[AudioData interface: attribute numberOfFrames]
expected: FAIL
[AudioData interface: attribute numberOfChannels]
expected: FAIL
[AudioData interface: attribute duration]
expected: FAIL
[AudioData interface: attribute timestamp]
expected: FAIL
[AudioData interface: operation allocationSize(AudioDataCopyToOptions)]
expected: FAIL
[AudioData interface: operation clone()]
expected: FAIL
[AudioData interface: operation close()]
expected: FAIL
[VideoFrame interface: operation metadata()]
expected: FAIL
[ImageDecoder interface: existence and properties of interface object]
expected: FAIL
[ImageDecoder interface object length]
expected: FAIL
[ImageDecoder interface object name]
expected: FAIL
[ImageDecoder interface: existence and properties of interface prototype object]
expected: FAIL
[ImageDecoder interface: existence and properties of interface prototype object's "constructor" property]
expected: FAIL
[ImageDecoder interface: existence and properties of interface prototype object's @@unscopables property]
expected: FAIL
[ImageDecoder interface: attribute type]
expected: FAIL
[ImageDecoder interface: attribute complete]
expected: FAIL
[ImageDecoder interface: attribute completed]
expected: FAIL
[ImageDecoder interface: attribute tracks]
expected: FAIL
[ImageDecoder interface: operation decode(optional ImageDecodeOptions)]
expected: FAIL
[ImageDecoder interface: operation reset()]
expected: FAIL
[ImageDecoder interface: operation close()]
expected: FAIL
[ImageDecoder interface: operation isTypeSupported(DOMString)]
expected: FAIL
[ImageTrackList interface: existence and properties of interface object]
expected: FAIL
[ImageTrackList interface object length]
expected: FAIL
[ImageTrackList interface object name]
expected: FAIL
[ImageTrackList interface: existence and properties of interface prototype object]
expected: FAIL
[ImageTrackList interface: existence and properties of interface prototype object's "constructor" property]
expected: FAIL
[ImageTrackList interface: existence and properties of interface prototype object's @@unscopables property]
expected: FAIL
[ImageTrackList interface: attribute ready]
expected: FAIL
[ImageTrackList interface: attribute length]
expected: FAIL
[ImageTrackList interface: attribute selectedIndex]
expected: FAIL
[ImageTrackList interface: attribute selectedTrack]
expected: FAIL
[ImageTrack interface: existence and properties of interface object]
expected: FAIL
[ImageTrack interface object length]
expected: FAIL
[ImageTrack interface object name]
expected: FAIL
[ImageTrack interface: existence and properties of interface prototype object]
expected: FAIL
[ImageTrack interface: existence and properties of interface prototype object's "constructor" property]
expected: FAIL
[ImageTrack interface: existence and properties of interface prototype object's @@unscopables property]
expected: FAIL
[ImageTrack interface: attribute animated]
expected: FAIL
[ImageTrack interface: attribute frameCount]
expected: FAIL
[ImageTrack interface: attribute repetitionCount]
expected: FAIL
[ImageTrack interface: attribute selected]
expected: FAIL
[idl_test setup]
expected: FAIL
[idl_test setup]
expected: FAIL
[EncodedAudioChunk interface: operation copyTo(AllowSharedBufferSource)]
expected: FAIL
[AudioData interface: operation copyTo(AllowSharedBufferSource, AudioDataCopyToOptions)]
expected: FAIL
[idlharness.https.any.worker.html]
[VideoFrame interface: operation metadata()]
expected: FAIL
[ImageDecoder interface: existence and properties of interface object]
expected: FAIL
[ImageDecoder interface object length]
expected: FAIL
[ImageDecoder interface object name]
expected: FAIL
[ImageDecoder interface: existence and properties of interface prototype object]
expected: FAIL
[ImageDecoder interface: existence and properties of interface prototype object's "constructor" property]
expected: FAIL
[ImageDecoder interface: existence and properties of interface prototype object's @@unscopables property]
expected: FAIL
[ImageDecoder interface: attribute type]
expected: FAIL
[ImageDecoder interface: attribute complete]
expected: FAIL
[ImageDecoder interface: attribute completed]
expected: FAIL
[ImageDecoder interface: attribute tracks]
expected: FAIL
[ImageDecoder interface: operation decode(optional ImageDecodeOptions)]
expected: FAIL
[ImageDecoder interface: operation reset()]
expected: FAIL
[ImageDecoder interface: operation close()]
expected: FAIL
[ImageDecoder interface: operation isTypeSupported(DOMString)]
expected: FAIL
[ImageTrackList interface: existence and properties of interface object]
expected: FAIL
[ImageTrackList interface object length]
expected: FAIL
[ImageTrackList interface object name]
expected: FAIL
[ImageTrackList interface: existence and properties of interface prototype object]
expected: FAIL
[ImageTrackList interface: existence and properties of interface prototype object's "constructor" property]
expected: FAIL
[ImageTrackList interface: existence and properties of interface prototype object's @@unscopables property]
expected: FAIL
[ImageTrackList interface: attribute ready]
expected: FAIL
[ImageTrackList interface: attribute length]
expected: FAIL
[ImageTrackList interface: attribute selectedIndex]
expected: FAIL
[ImageTrackList interface: attribute selectedTrack]
expected: FAIL
[ImageTrack interface: existence and properties of interface object]
expected: FAIL
[ImageTrack interface object length]
expected: FAIL
[ImageTrack interface object name]
expected: FAIL
[ImageTrack interface: existence and properties of interface prototype object]
expected: FAIL
[ImageTrack interface: existence and properties of interface prototype object's "constructor" property]
expected: FAIL
[ImageTrack interface: existence and properties of interface prototype object's @@unscopables property]
expected: FAIL
[ImageTrack interface: attribute animated]
expected: FAIL
[ImageTrack interface: attribute frameCount]
expected: FAIL
[ImageTrack interface: attribute repetitionCount]
expected: FAIL
[ImageTrack interface: attribute selected]
expected: FAIL
[idl_test setup]
[VideoFrame interface: new VideoFrame(makeImageBitmap(32, 16), {timestamp: 100, duration: 33}) must inherit property "metadata()" with the proper type]
expected: FAIL

Просмотреть файл

@ -1,3 +0,0 @@
[image-decoder-disconnect-readable-stream-crash.https.html]
expected:
if (os == "win") and not debug and (processor == "x86_64"): [PASS, TIMEOUT]

Просмотреть файл

@ -1,9 +1,5 @@
prefs: [dom.media.webcodecs.enabled:true, dom.media.webcodecs.image-decoder.enabled:true]
[image-decoder-image-orientation-none.https.html]
expected:
if (os == "android") and fission: [OK, TIMEOUT]
[Test JPEG w/ EXIF orientation top-left on canvas w/o orientation]
expected: FAIL
[Test JPEG w/ EXIF orientation top-right on canvas w/o orientation.]
expected: FAIL
@ -25,9 +21,6 @@
[Test JPEG w/ EXIF orientation left-bottom on canvas w/o orientation.]
expected: FAIL
[Test 4:2:0 JPEG w/ EXIF orientation top-left on canvas w/o orientation]
expected: FAIL
[Test 4:2:0 JPEG w/ EXIF orientation top-right on canvas w/o orientation.]
expected: FAIL

Просмотреть файл

@ -1,18 +0,0 @@
[image-decoder.crossOriginIsolated.https.any.html]
expected:
if (os == "android") and debug: [OK, TIMEOUT]
[Test ImageDecoder decoding with a SharedArrayBuffer source]
expected: FAIL
[Test ImageDecoder decoding with a Uint8Array(SharedArrayBuffer) source]
expected: FAIL
[image-decoder.crossOriginIsolated.https.any.worker.html]
expected:
if (os == "android") and debug: [OK, TIMEOUT]
[Test ImageDecoder decoding with a SharedArrayBuffer source]
expected: FAIL
[Test ImageDecoder decoding with a Uint8Array(SharedArrayBuffer) source]
expected: FAIL

Просмотреть файл

@ -1,41 +1,8 @@
prefs: [dom.media.webcodecs.enabled:true, dom.media.webcodecs.image-decoder.enabled:true]
[image-decoder.https.any.worker.html]
expected:
if (os == "android") and fission: [OK, TIMEOUT]
[Test JPEG image decoding.]
expected: FAIL
[Test JPEG w/ EXIF orientation top-left.]
expected: FAIL
[Test JPEG w/ EXIF orientation top-right.]
expected: FAIL
[Test JPEG w/ EXIF orientation bottom-right.]
expected: FAIL
[Test JPEG w/ EXIF orientation bottom-left.]
expected: FAIL
[Test JPEG w/ EXIF orientation left-top.]
expected: FAIL
[Test JPEG w/ EXIF orientation right-top.]
expected: FAIL
[Test JPEG w/ EXIF orientation right-bottom.]
expected: FAIL
[Test JPEG w/ EXIF orientation left-bottom.]
expected: FAIL
[Test PNG image decoding.]
expected: FAIL
[Test AVIF image decoding.]
expected: FAIL
[Test high bit depth HDR AVIF image decoding.]
expected: FAIL
# 'Test invalid mime type rejects ...' variants don't catch us rejecting all
# of the promises.
expected: ERROR
[Test multi-track AVIF image decoding w/ preferAnimation=false.]
expected: FAIL
@ -43,12 +10,6 @@
[Test multi-track AVIF image decoding w/ preferAnimation=true.]
expected: FAIL
[Test WEBP image decoding.]
expected: FAIL
[Test GIF image decoding.]
expected: FAIL
[Test JPEG image YUV 4:2:0 decoding.]
expected: FAIL
@ -70,99 +31,17 @@
[Test invalid mime type rejects decodeMetadata() requests]
expected: FAIL
[Test out of range index returns RangeError]
expected: FAIL
[Test partial decoding without a frame results in an error]
expected: FAIL
[Test completed property on fully buffered decode]
expected: FAIL
[Test decode, decodeMetadata after no track selected.]
expected: FAIL
[Test track selection in multi track image.]
expected: FAIL
[Test ReadableStream of gif]
expected: FAIL
[Test that decode requests are serialized.]
expected: FAIL
[Test ReadableStream aborts promises on track change]
expected: FAIL
[Test ReadableStream aborts completed on close]
expected: FAIL
[Test ReadableStream resolves completed]
expected: FAIL
[Test 4:2:0 JPEG w/ EXIF orientation top-left.]
expected: FAIL
[Test 4:2:0 JPEG w/ EXIF orientation top-right.]
expected: FAIL
[Test 4:2:0 JPEG w/ EXIF orientation bottom-right.]
expected: FAIL
[Test 4:2:0 JPEG w/ EXIF orientation bottom-left.]
expected: FAIL
[Test 4:2:0 JPEG w/ EXIF orientation left-top.]
expected: FAIL
[Test 4:2:0 JPEG w/ EXIF orientation right-top.]
expected: FAIL
[Test 4:2:0 JPEG w/ EXIF orientation right-bottom.]
expected: FAIL
[Test 4:2:0 JPEG w/ EXIF orientation left-bottom.]
expected: FAIL
[image-decoder.https.any.html]
expected:
if (os == "android") and fission: [OK, TIMEOUT]
[Test JPEG image decoding.]
expected: FAIL
[Test JPEG w/ EXIF orientation top-left.]
expected: FAIL
[Test JPEG w/ EXIF orientation top-right.]
expected: FAIL
[Test JPEG w/ EXIF orientation bottom-right.]
expected: FAIL
[Test JPEG w/ EXIF orientation bottom-left.]
expected: FAIL
[Test JPEG w/ EXIF orientation left-top.]
expected: FAIL
[Test JPEG w/ EXIF orientation right-top.]
expected: FAIL
[Test JPEG w/ EXIF orientation right-bottom.]
expected: FAIL
[Test JPEG w/ EXIF orientation left-bottom.]
expected: FAIL
[Test PNG image decoding.]
expected: FAIL
[Test AVIF image decoding.]
expected: FAIL
[Test high bit depth HDR AVIF image decoding.]
expected: FAIL
# 'Test invalid mime type rejects ...' variants don't catch us rejecting all
# of the promises.
expected: ERROR
[Test multi-track AVIF image decoding w/ preferAnimation=false.]
expected: FAIL
@ -170,12 +49,6 @@
[Test multi-track AVIF image decoding w/ preferAnimation=true.]
expected: FAIL
[Test WEBP image decoding.]
expected: FAIL
[Test GIF image decoding.]
expected: FAIL
[Test JPEG image YUV 4:2:0 decoding.]
expected: FAIL
@ -197,56 +70,8 @@
[Test invalid mime type rejects decodeMetadata() requests]
expected: FAIL
[Test out of range index returns RangeError]
expected: FAIL
[Test partial decoding without a frame results in an error]
expected: FAIL
[Test completed property on fully buffered decode]
expected: FAIL
[Test decode, decodeMetadata after no track selected.]
expected: FAIL
[Test track selection in multi track image.]
expected: FAIL
[Test ReadableStream of gif]
expected: FAIL
[Test that decode requests are serialized.]
expected: FAIL
[Test ReadableStream aborts promises on track change]
expected: FAIL
[Test ReadableStream aborts completed on close]
expected: FAIL
[Test ReadableStream resolves completed]
expected: FAIL
[Test 4:2:0 JPEG w/ EXIF orientation top-left.]
expected: FAIL
[Test 4:2:0 JPEG w/ EXIF orientation top-right.]
expected: FAIL
[Test 4:2:0 JPEG w/ EXIF orientation bottom-right.]
expected: FAIL
[Test 4:2:0 JPEG w/ EXIF orientation bottom-left.]
expected: FAIL
[Test 4:2:0 JPEG w/ EXIF orientation left-top.]
expected: FAIL
[Test 4:2:0 JPEG w/ EXIF orientation right-top.]
expected: FAIL
[Test 4:2:0 JPEG w/ EXIF orientation right-bottom.]
expected: FAIL
[Test 4:2:0 JPEG w/ EXIF orientation left-bottom.]
expected: FAIL

Просмотреть файл

@ -1,4 +1,4 @@
prefs: [dom.media.webcodecs.enabled:true]
prefs: [dom.media.webcodecs.enabled:true, dom.media.webcodecs.image-decoder.enabled:true]
[transfering.https.any.html]
[Test transfering ArrayBuffer to VideoFrame]
expected: FAIL
@ -18,9 +18,6 @@ prefs: [dom.media.webcodecs.enabled:true]
[Encoding from AudioData with transferred buffer]
expected: FAIL
[Test transfering ArrayBuffer to ImageDecoder.]
expected: FAIL
[transfering.https.any.worker.html]
[Test transfering ArrayBuffer to VideoFrame]
@ -40,6 +37,3 @@ prefs: [dom.media.webcodecs.enabled:true]
[Encoding from AudioData with transferred buffer]
expected: FAIL
[Test transfering ArrayBuffer to ImageDecoder.]
expected: FAIL