Commit a883b84a authored by Dan Sanders's avatar Dan Sanders Committed by Commit Bot

[media] Remove Promises from WebCodecs VideoDecoder.

Bug: 897297
Change-Id: I7bc070913b53a88a9588836c424cb9f5b6fe8283
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2231593
Commit-Queue: Dan Sanders <sandersd@chromium.org>
Reviewed-by: default avatarChrome Cunningham <chcunningham@chromium.org>
Cr-Commit-Position: refs/heads/master@{#778616}
parent 1c8a83ec
...@@ -101,51 +101,45 @@ int32_t VideoDecoder::decodeQueueSize() { ...@@ -101,51 +101,45 @@ int32_t VideoDecoder::decodeQueueSize() {
return requested_decodes_; return requested_decodes_;
} }
int32_t VideoDecoder::decodeProcessingCount() { void VideoDecoder::configure(const EncodedVideoConfig* config,
return pending_decodes_.size(); ExceptionState&) {
}
ScriptPromise VideoDecoder::configure(const EncodedVideoConfig* config,
ExceptionState&) {
DVLOG(1) << __func__; DVLOG(1) << __func__;
Request* request = MakeGarbageCollected<Request>(); Request* request = MakeGarbageCollected<Request>();
request->type = Request::Type::kConfigure; request->type = Request::Type::kConfigure;
request->config = config; request->config = config;
return EnqueueRequest(request); requests_.push_back(request);
ProcessRequests();
} }
ScriptPromise VideoDecoder::decode(const EncodedVideoChunk* chunk, void VideoDecoder::decode(const EncodedVideoChunk* chunk, ExceptionState&) {
ExceptionState&) {
DVLOG(3) << __func__; DVLOG(3) << __func__;
requested_decodes_++;
Request* request = MakeGarbageCollected<Request>(); Request* request = MakeGarbageCollected<Request>();
request->type = Request::Type::kDecode; request->type = Request::Type::kDecode;
request->chunk = chunk; request->chunk = chunk;
return EnqueueRequest(request); requests_.push_back(request);
++requested_decodes_;
ProcessRequests();
} }
ScriptPromise VideoDecoder::flush(ExceptionState&) { ScriptPromise VideoDecoder::flush(ExceptionState&) {
DVLOG(3) << __func__; DVLOG(3) << __func__;
Request* request = MakeGarbageCollected<Request>(); Request* request = MakeGarbageCollected<Request>();
request->type = Request::Type::kFlush; request->type = Request::Type::kFlush;
return EnqueueRequest(request); ScriptPromiseResolver* resolver =
MakeGarbageCollected<ScriptPromiseResolver>(script_state_);
request->resolver = resolver;
requests_.push_back(request);
ProcessRequests();
return resolver->Promise();
} }
ScriptPromise VideoDecoder::reset(ExceptionState&) { void VideoDecoder::reset(ExceptionState&) {
DVLOG(3) << __func__; DVLOG(3) << __func__;
requested_resets_++;
Request* request = MakeGarbageCollected<Request>(); Request* request = MakeGarbageCollected<Request>();
request->type = Request::Type::kReset; request->type = Request::Type::kReset;
return EnqueueRequest(request);
}
ScriptPromise VideoDecoder::EnqueueRequest(Request* request) {
ScriptPromiseResolver* resolver =
MakeGarbageCollected<ScriptPromiseResolver>(script_state_);
request->resolver = resolver;
requests_.push_back(request); requests_.push_back(request);
++requested_resets_;
ProcessRequests(); ProcessRequests();
return resolver->Promise();
} }
void VideoDecoder::ProcessRequests() { void VideoDecoder::ProcessRequests() {
...@@ -191,9 +185,6 @@ bool VideoDecoder::ProcessConfigureRequest(Request* request) { ...@@ -191,9 +185,6 @@ bool VideoDecoder::ProcessConfigureRequest(Request* request) {
media_log_ = std::make_unique<media::NullMediaLog>(); media_log_ = std::make_unique<media::NullMediaLog>();
decoder_ = CreateVideoDecoder(media_log_.get()); decoder_ = CreateVideoDecoder(media_log_.get());
if (!decoder_) { if (!decoder_) {
request->resolver.Release()->Reject(MakeGarbageCollected<DOMException>(
DOMExceptionCode::kNotSupportedError,
"Codec initialization failed."));
// TODO(sandersd): This is a bit awkward because |request| is still in the // TODO(sandersd): This is a bit awkward because |request| is still in the
// queue. // queue.
HandleError(); HandleError();
...@@ -236,11 +227,10 @@ bool VideoDecoder::ProcessDecodeRequest(Request* request) { ...@@ -236,11 +227,10 @@ bool VideoDecoder::ProcessDecodeRequest(Request* request) {
DCHECK(request->chunk); DCHECK(request->chunk);
DCHECK_GT(requested_decodes_, 0); DCHECK_GT(requested_decodes_, 0);
// TODO(sandersd): If a reset has been requested, resolve immediately. // TODO(sandersd): If a reset has been requested, complete immediately.
if (!decoder_) { if (!decoder_) {
// TODO(sandersd): Add explanation (no valid configuration). // TODO(sandersd): Emit an error?
request->resolver.Release()->Reject();
return true; return true;
} }
...@@ -348,14 +338,11 @@ void VideoDecoder::OnInitializeDone(media::Status status) { ...@@ -348,14 +338,11 @@ void VideoDecoder::OnInitializeDone(media::Status status) {
if (!status.is_ok()) { if (!status.is_ok()) {
// TODO(tmathmeyer) this drops the media error - should we consider logging // TODO(tmathmeyer) this drops the media error - should we consider logging
// it or converting it to the DOMException type somehow? // it or converting it to the DOMException type somehow?
pending_request_.Release()->resolver.Release()->Reject(
MakeGarbageCollected<DOMException>(DOMExceptionCode::kNotSupportedError,
"Codec initialization failed."));
HandleError(); HandleError();
return; return;
} }
pending_request_.Release()->resolver.Release()->Resolve(); pending_request_.Release();
ProcessRequests(); ProcessRequests();
} }
...@@ -370,7 +357,6 @@ void VideoDecoder::OnDecodeDone(uint32_t id, media::DecodeStatus status) { ...@@ -370,7 +357,6 @@ void VideoDecoder::OnDecodeDone(uint32_t id, media::DecodeStatus status) {
} }
auto it = pending_decodes_.find(id); auto it = pending_decodes_.find(id);
it->value->resolver.Release()->Resolve();
pending_decodes_.erase(it); pending_decodes_.erase(it);
ProcessRequests(); ProcessRequests();
} }
...@@ -394,7 +380,7 @@ void VideoDecoder::OnResetDone() { ...@@ -394,7 +380,7 @@ void VideoDecoder::OnResetDone() {
DCHECK(pending_request_); DCHECK(pending_request_);
DCHECK_EQ(pending_request_->type, Request::Type::kReset); DCHECK_EQ(pending_request_->type, Request::Type::kReset);
pending_request_.Release()->resolver.Release()->Resolve(); pending_request_.Release();
ProcessRequests(); ProcessRequests();
} }
......
...@@ -43,11 +43,10 @@ class MODULES_EXPORT VideoDecoder final : public ScriptWrappable { ...@@ -43,11 +43,10 @@ class MODULES_EXPORT VideoDecoder final : public ScriptWrappable {
// video_decoder.idl implementation. // video_decoder.idl implementation.
int32_t decodeQueueSize(); int32_t decodeQueueSize();
int32_t decodeProcessingCount(); void configure(const EncodedVideoConfig*, ExceptionState&);
ScriptPromise configure(const EncodedVideoConfig*, ExceptionState&); void decode(const EncodedVideoChunk*, ExceptionState&);
ScriptPromise decode(const EncodedVideoChunk*, ExceptionState&);
ScriptPromise flush(ExceptionState&); ScriptPromise flush(ExceptionState&);
ScriptPromise reset(ExceptionState&); void reset(ExceptionState&);
// GarbageCollected override. // GarbageCollected override.
void Trace(Visitor*) const override; void Trace(Visitor*) const override;
...@@ -64,8 +63,14 @@ class MODULES_EXPORT VideoDecoder final : public ScriptWrappable { ...@@ -64,8 +63,14 @@ class MODULES_EXPORT VideoDecoder final : public ScriptWrappable {
void Trace(Visitor*) const; void Trace(Visitor*) const;
Type type; Type type;
// For kConfigure Requests.
Member<const EncodedVideoConfig> config; Member<const EncodedVideoConfig> config;
// For kDecode Requests.
Member<const EncodedVideoChunk> chunk; Member<const EncodedVideoChunk> chunk;
// For kFlush Requests.
Member<ScriptPromiseResolver> resolver; Member<ScriptPromiseResolver> resolver;
}; };
......
...@@ -21,69 +21,50 @@ ...@@ -21,69 +21,50 @@
// When in an error state, methods other than reset() will fail. // When in an error state, methods other than reset() will fail.
// //
// TODO(sandersd): Consider adding a state or last error attribute. // TODO(sandersd): Consider adding a state or last error attribute.
// TODO(sandersd): Consider aborting pending decodes on error, rather than
// waiting for reset().
[CallWith=ScriptState, RaisesException] constructor(VideoDecoderInit init); [CallWith=ScriptState, RaisesException] constructor(VideoDecoderInit init);
// The number of queued decode requests. This does not include requests that // The number of pending decode requests. This does not include requests that
// have been taken for processing. // have been sent to the underlying codec.
// //
// Applications can minimize underflow by enqueueing decode requests until // Applications can minimize underflow by enqueueing decode requests until
// |decodeQueueSize| is greater than a constant. // |decodeQueueSize| is greater than a constant.
readonly attribute long decodeQueueSize;
// The number of decode requests currently being processed.
// //
// Applications can minimize resource consumption and decode latency by // TODO(sandersd): Consider adding a predicted output count or other
// enqueueing decode requests only when |decodeQueueSize| and // backpressure mechanism that considers the state of the underlying codec.
// |decodeProcessingCount| are small. // TODO(sandersd): Consider emitting an event when this number decreases.
// readonly attribute long decodeQueueSize;
// TODO(sandersd): Consider counting queued decode requests as well. This
// could be simpler for apps.
readonly attribute long decodeProcessingCount;
// Enqueue a request to set or change the stream configuration. // Set the stream configuration for future decode() requests.
// //
// The next enqueued decode request must be for a keyframe. // The next decode request must be for a keyframe.
// //
// Resolved after emitting output for all earlier decode requests.
//
// TODO(sandersd): Test that resolution (a microtask) interleaves between
// outputs callback calls in all cases.
// TODO(sandersd): Move the keyframe rule into the bytestream registry. // TODO(sandersd): Move the keyframe rule into the bytestream registry.
[RaisesException] Promise<void> configure(EncodedVideoConfig config); [RaisesException] void configure(EncodedVideoConfig config);
// Enqueue a request to decode an input chunk. // Request decoding of an input chunk.
//
// You must call configure() before calling enqueue() for the first time.
// //
// Resolved after decoding of the input chunk has started (that is, after // You must call configure() before calling decode() for the first time.
// decreasing |decodeQueueSize|).
// //
// TODO(sandersd): Change to a dictionary type. // TODO(sandersd): Change to a dictionary type.
// TODO(sandersd): Should we guarantee that resolution occurs in order? [RaisesException] void decode(EncodedVideoChunk chunk);
// TODO(sandersd): Add status to result.
// TODO(sandersd): Buffer return.
[RaisesException] Promise<void> decode(EncodedVideoChunk chunk);
// Enqueue a request to finish decoding queued input chunks. // Request output from all previous decode requests.
// //
// The next enqueued input chunk must be a keyframe. // Resolved after all output for earlier decode requests has been emitted.
// //
// Resolved after emitting output for all earlier decode requests. // The next decode request must be for a keyframe.
// //
// TODO(sandersd): Consider relaxing the keyframe requirement. // TODO(sandersd): Consider relaxing the keyframe requirement.
// TODO(sandersd): Indicate whether the flush() completed successfully or due
// to a reset.
[RaisesException] Promise<void> flush(); [RaisesException] Promise<void> flush();
// Discard all pending work. // Discard all pending decode requests.
//
// Output for earlier decode requests will not be emitted, even if processing
// has already started.
//
// The next enqueued input chunk must be a keyframe.
// //
// Resolved after all earlier enqueue() promises have been resolved. // The next decode request must be for a keyframe.
// //
// TODO(sandersd): Require configure() after reset()? // Note: It may be possible to call reset() after a flush() promise has been
[RaisesException] Promise<void> reset(); // resolved but before it is fulfilled. In that case the flush() promise will
// be fulfilled successfully even though reset() was called.
[RaisesException] void reset();
}; };
...@@ -8720,7 +8720,6 @@ interface ValidityState ...@@ -8720,7 +8720,6 @@ interface ValidityState
method constructor method constructor
interface VideoDecoder interface VideoDecoder
attribute @@toStringTag attribute @@toStringTag
getter decodeProcessingCount
getter decodeQueueSize getter decodeQueueSize
method configure method configure
method constructor method constructor
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment