chromium/media/mojo/mojom/stable/stable_video_decoder.mojom

// 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);
};