// Copyright 2021 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
module media.stable.mojom;
import "gpu/ipc/common/gpu_feature_info.mojom";
import "media/mojo/mojom/stable/stable_video_decoder_types.mojom";
import "mojo/public/mojom/base/unguessable_token.mojom";
import "sandbox/policy/mojom/sandbox.mojom";
import "ui/gfx/geometry/mojom/geometry.mojom";
// This API is a stable version of VideoDecoder. This is used both by LaCrOS and
// by out-of-process video decoding to allow the GPU process to forward video
// decoding requests to a video decoder process.
// In order to avoid depending on unstable definitions or on components which
// will cause cyclic dependencies, some similar but occasionally simplified
// version of structures were used rather than directly depending on the
// structures in other components.
// Based on |media.mojom.MediaLog| but does not depend on
// |media.mojom.MediaLogRecord|.
// Next min method ID: 1
[Stable, Uuid="2e4c1aed-fd62-40e6-8601-e5c4288246c0"]
interface MediaLog {
// Adds a log record to a MediaLog service.
AddLogRecord@0(MediaLogRecord event);
};
// Based on |media.mojom.VideoFrameHandleReleaser| but does not depend on
// |gpu.mojom.SyncToken|.
// Next min method ID: 1
[Stable, Uuid="8afdcf21-99d7-4864-a957-75d2a7e17da6"]
interface VideoFrameHandleReleaser {
// Signals that the VideoFrame identified by |release_token| should be
// released.
ReleaseVideoFrame@0(mojo_base.mojom.UnguessableToken release_token);
};
// Based on |media.mojom.VideoDecoderClient| but does not depend on
// |media.mojom.VideoFrame| or |media.mojom.WaitingReason|.
// Next min method ID: 2
[Stable, Uuid="8a6fce77-7fcc-42e1-ac74-443859039696"]
interface VideoDecoderClient {
// Output a decoded frame. Frames are output in presentation order.
//
// When |can_read_without_stalling| is false, preroll should be disabled. This
// is necessary if the decoder cannot guarantee that it can output another
// frame, for example if output buffers are limited or configuration changes
// require the return of all outstanding frames.
//
// The client shall call VideoFrameHandleReleaser::ReleaseVideoFrame() with
// |release_token| when it is finished using |frame|.
OnVideoFrameDecoded@0(VideoFrame frame,
bool can_read_without_stalling,
mojo_base.mojom.UnguessableToken release_token);
// Called when the remote decoder is waiting because of |reason|, e.g. waiting
// for decryption key.
OnWaiting@1(WaitingReason reason);
};
// Interface for handling callbacks from the StableCdmContext interface below.
// Next min method ID: 1
[Stable, Uuid="a1a73e1f-5297-49a2-a4e5-df875a44b61e"]
interface CdmContextEventCallback {
// Sends the event back to the registrar.
EventCallback@0(CdmContextEvent event);
};
// Maps to the media::CdmContext interface for remoting it to another process.
// Next MinVersion: 5
// Next min method ID: 7
[Stable, Uuid="33c7a00e-2970-41b3-8c7b-f1074a539740"]
interface StableCdmContext {
// Proxies to media::CdmContext::GetChromeOsCdmContext()->GetHwKeyData.
[MinVersion=1]
GetHwKeyData@0(DecryptConfig decrypt_config, array<uint8> hw_identifier) =>
(DecryptStatus status, array<uint8> key_data);
// Registers an interface for receiving event callbacks. This maps to
// media::CdmContext::RegisterEventCB.
[MinVersion=1]
RegisterEventCallback@1(pending_remote<CdmContextEventCallback> callback);
// Proxies to media::CdmContext::GetChromeOsCdmContext()->GetHwConfigData.
[MinVersion=1]
GetHwConfigData@2() => (bool success, array<uint8> config_data);
// Proxies to media::CdmContext::GetChromeOsCdmContext()->
// GetScreenResolutions.
[MinVersion=1]
GetScreenResolutions@3() => (array<gfx.mojom.Size> resolutions);
// Proxies to
// media::CdmContext::GetChromeOsCdmContext()->AllocateSecureBuffer.
[MinVersion=2]
AllocateSecureBuffer@4(uint32 size) => (handle<platform>? secure_buffer);
// Proxies to
// media::CdmContext::GetChromeOsCdmContext()->ParseEncryptedSliceHeader.
[MinVersion=3]
ParseEncryptedSliceHeader@5(uint64 secure_handle, uint32 offset,
array<uint8> stream_data)
=> (bool success, array<uint8> slice_header);
// Proxies to
// media::CdmContext::GetDecryptor()->Decrypt for video data.
[MinVersion=4]
DecryptVideoBuffer@6(DecoderBuffer buffer, array<uint8> bytes)
=> (DecryptStatus status, DecoderBuffer? decoder_buffer,
array<uint8> bytes);
};
// Based on |media.mojom.VideoDecoder|.
// Next min method ID: 5
// Next min version: 2
[Stable, Uuid="85611470-3e87-43a9-ac75-a11a63e76415"]
interface StableVideoDecoder {
// Returns a list of supported configs as well as the decoder ID for the
// decoder which supports them. It is expected that Initialize() will fail
// for any config that does not match an entry in this list.
//
// May be called before Construct().
[Sync]
GetSupportedConfigs@0() =>
(array<SupportedVideoDecoderConfig> supported_configs,
VideoDecoderType decoder_type);
// Initialize the decoder. This must be called before any method other than
// GetSupportedConfigs().
// StableVideoDecoder may hold onto references to VideoFrames sent to the
// client. However, it shall not re-use those frames until the client calls
// ReleaseVideoFrame() on |video_frame_handle_releaser|. The
// StableVideoDecoder may, however, release those references at any time.
// Therefore, VideoFrames sent to the client shall contain resources whose
// lifetime is independent of the StableVideoDecoder's lifetime, e.g., file
// descriptors.
Construct@1(
pending_associated_remote<VideoDecoderClient> client,
pending_remote<MediaLog> media_log,
pending_receiver<VideoFrameHandleReleaser> video_frame_handle_releaser,
handle<data_pipe_consumer> decoder_buffer_pipe,
ColorSpace target_color_space);
// Configure (or reconfigure) the decoder. This must be called before decoding
// any frames, and must not be called while there are pending Initialize(),
// Decode(), or Reset() requests.
//
// |cdm_context| is required for the first Initialize() call that sets up
// encryption and is ignored on subsequent calls.
//
// |needs_transcryption| tells the client whether it needs to do transcryption
// for encrypted content before sending it to the decoder.
//
// TODO(b/195769334): consider passing |cdm_context| in Construct() instead of
// Initialize().
Initialize@2(VideoDecoderConfig config, bool low_delay,
pending_remote<StableCdmContext>? cdm_context)
=> (Status status,
bool needs_bitstream_conversion,
int32 max_decode_requests,
VideoDecoderType decoder_type,
[MinVersion=1] bool needs_transcryption);
// Request decoding of exactly one frame or an EOS buffer. This must not be
// called while there are pending Initialize(), Reset(), or Decode(EOS)
// requests.
Decode@3(DecoderBuffer buffer) => (Status status);
// Reset the decoder. All ongoing Decode() requests must be completed or
// aborted before executing the callback. This must not be called while there
// is a pending Initialize() request.
Reset@4() => ();
};
// Only Chrome-for-Linux and ash-chrome should host the implementation of a
// StableVideoDecoderFactory.
[EnableIf=is_linux_or_chromeos_ash]
const sandbox.mojom.Sandbox kStableVideoDecoderFactoryServiceSandbox
= sandbox.mojom.Sandbox.kHardwareVideoDecoding;
[EnableIfNot=is_linux_or_chromeos_ash]
const sandbox.mojom.Sandbox kStableVideoDecoderFactoryServiceSandbox
= sandbox.mojom.Sandbox.kNoSandbox;
// A disconnection of this interface can be interpreted as the
// StableVideoDecoder implementation created by
// StableVideoDecoderFactory.CreateStableVideoDecoder() having been destroyed
// (or never bound in the first place).
//
// This interface is intended to be implemented by the browser process and used
// by the video decoder processes.
[Stable, Uuid="b2211aaa-78e9-4326-8c85-a7ab15b32032"]
interface StableVideoDecoderTracker {};
// A StableVideoDecoderFactory allows the browser process to bind a
// StableVideoDecoder on behalf of some client which can be, e.g., the
// lacros-chrome browser process or a renderer process in ash-chrome.
// Next min method ID: 1
// Next min version: 2
[Stable, Uuid="d6047fd9-fffb-4e37-ad9b-383a1c9e1d2d"]
interface StableVideoDecoderFactory {
// Creates a StableVideoDecoder and should be called by the browser process.
// If |tracker| is provided, the caller can handle its disconnection in order
// to know when the StableVideoDecoder implementation is destroyed. Note that
// |tracker| may get disconnected without ever creating a StableVideoDecoder
// implementation instance, e.g., if an error occurs that prevents |receiver|
// from being bound to an implementation.
CreateStableVideoDecoder@0(
pending_receiver<StableVideoDecoder> receiver,
[MinVersion=1] pending_remote<StableVideoDecoderTracker>? tracker);
};
// A StableVideoDecoderFactoryProcess is intended to be hosted in a utility
// process in either ash-chrome or Chrome-for-linux. The client is expected to
// be the browser process of ash-chrome or Chrome-for-linux. The intended usage
// is as follows:
//
// 1) The browser process of ash-chrome or Chrome-for-linux receives a request
// to bind a pending_receiver<StableVideoDecoderFactory>.
//
// 2) That browser process starts a utility process to bind a
// pending_receiver<StableVideoDecoderFactoryProcess>. It then uses this
// connection to call InitializeStableVideoDecoderFactory() with the
// pending_receiver<StableVideoDecoderFactory> from (1).
[ServiceSandbox=kStableVideoDecoderFactoryServiceSandbox,
EnableIf=is_linux_or_chromeos_ash]
interface StableVideoDecoderFactoryProcess {
// Initializes a StableVideoDecoderFactory using |gpu_feature_info| to
// restrict the supported video decode configurations.
InitializeStableVideoDecoderFactory(
gpu.mojom.GpuFeatureInfo gpu_feature_info,
pending_receiver<StableVideoDecoderFactory> receiver);
};