зеркало из https://github.com/mozilla/gecko-dev.git
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:
Родитель
b31f8cc7bc
Коммит
2df9204445
Разница между файлами не показана из-за своего большого размера
Загрузить разницу
|
@ -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 newTrack’s [[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 selectedTrack’s [[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 updateTrack’s [[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
|
||||
|
|
Загрузка…
Ссылка в новой задаче