blob: 7c5374ebb680f66e342f5290c303ca119b42c07e [file] [log] [blame]
// Copyright 2021 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef THIRD_PARTY_BLINK_RENDERER_MODULES_WEBCODECS_ENCODER_BASE_H_
#define THIRD_PARTY_BLINK_RENDERER_MODULES_WEBCODECS_ENCODER_BASE_H_
#include <memory>
#include "media/base/media_log.h"
#include "media/base/status.h"
#include "third_party/blink/renderer/bindings/core/v8/active_script_wrappable.h"
#include "third_party/blink/renderer/bindings/core/v8/script_promise_resolver.h"
#include "third_party/blink/renderer/bindings/modules/v8/v8_codec_state.h"
#include "third_party/blink/renderer/bindings/modules/v8/v8_webcodecs_error_callback.h"
#include "third_party/blink/renderer/modules/modules_export.h"
#include "third_party/blink/renderer/modules/webcodecs/codec_logger.h"
#include "third_party/blink/renderer/platform/bindings/script_wrappable.h"
#include "third_party/blink/renderer/platform/context_lifecycle_observer.h"
#include "third_party/blink/renderer/platform/heap/visitor.h"
namespace blink {
class ExceptionState;
enum class DOMExceptionCode;
template <typename Traits>
class MODULES_EXPORT EncoderBase
: public ScriptWrappable,
public ActiveScriptWrappable<EncoderBase<Traits>>,
public ExecutionContextLifecycleObserver {
public:
using InitType = typename Traits::Init;
using ConfigType = typename Traits::Config;
using InternalConfigType = typename Traits::InternalConfig;
using FrameType = typename Traits::Frame;
using EncodeOptionsType = typename Traits::EncodeOptions;
using OutputChunkType = typename Traits::OutputChunk;
using OutputCallbackType = typename Traits::OutputCallback;
using MediaEncoderType = typename Traits::MediaEncoder;
EncoderBase(ScriptState*, const InitType*, ExceptionState&);
~EncoderBase() override;
// *_encoder.idl implementation.
int32_t encodeQueueSize() { return requested_encodes_; }
void configure(const ConfigType*, ExceptionState&);
void encode(FrameType* frame,
const EncodeOptionsType* opts,
ExceptionState& exception_state);
ScriptPromise flush(ExceptionState&);
void reset(ExceptionState&);
void close(ExceptionState&);
String state() { return state_; }
// ExecutionContextLifecycleObserver override.
void ContextDestroyed() override;
// ScriptWrappable override.
bool HasPendingActivity() const override;
// GarbageCollected override.
void Trace(Visitor*) const override;
protected:
struct Request final : public GarbageCollected<Request> {
enum class Type {
// Configure an encoder from scratch, possibly replacing the existing one.
kConfigure,
// Adjust options in the already configured encoder.
kReconfigure,
kEncode,
kFlush,
};
void Trace(Visitor*) const;
Type type;
// Current value of EncoderBase.reset_count_ when request was created.
uint32_t reset_count = 0;
Member<FrameType> frame; // used by kEncode
Member<const EncodeOptionsType> encodeOpts; // used by kEncode
Member<ScriptPromiseResolver> resolver; // used by kFlush
};
virtual void HandleError(DOMException* ex);
virtual void EnqueueRequest(Request* request);
virtual void ProcessRequests();
virtual void ProcessEncode(Request* request) = 0;
virtual void ProcessConfigure(Request* request) = 0;
virtual void ProcessReconfigure(Request* request) = 0;
virtual void ProcessFlush(Request* request);
virtual void ResetInternal();
virtual bool CanReconfigure(InternalConfigType& original_config,
InternalConfigType& new_config) = 0;
virtual InternalConfigType* ParseConfig(const ConfigType*,
ExceptionState&) = 0;
virtual bool VerifyCodecSupport(InternalConfigType*, ExceptionState&) = 0;
virtual FrameType* CloneFrame(FrameType*, ExecutionContext*) = 0;
std::unique_ptr<CodecLogger> logger_;
std::unique_ptr<MediaEncoderType> media_encoder_;
V8CodecState state_;
Member<InternalConfigType> active_config_;
Member<ScriptState> script_state_;
Member<OutputCallbackType> output_callback_;
Member<V8WebCodecsErrorCallback> error_callback_;
HeapDeque<Member<Request>> requests_;
int32_t requested_encodes_ = 0;
// How many times reset() was called on the encoder. It's used to decide
// when a callback needs to be dismissed because reset() was called between
// an operation and its callback.
uint32_t reset_count_ = 0;
// Some kConfigure and kFlush requests can't be executed in parallel with
// kEncode. This flag stops processing of new requests in the requests_ queue
// till the current requests are finished.
bool stall_request_processing_ = false;
SEQUENCE_CHECKER(sequence_checker_);
};
} // namespace blink
#endif // THIRD_PARTY_BLINK_RENDERER_MODULES_WEBCODECS_ENCODER_BASE_H_