1
    2
    3
    4
    5
    6
    7
    8
    9
   10
   11
   12
   13
   14
   15
   16
   17
   18
   19
   20
   21
   22
   23
   24
   25
   26
   27
   28
   29
   30
   31
   32
   33
   34
   35
   36
   37
   38
   39
   40
   41
   42
   43
   44
   45
   46
   47
   48
   49
   50
   51
   52
   53
   54
   55
   56
   57
   58
   59
   60
   61
   62
   63
   64
   65
   66
   67
   68
   69
   70
   71
   72
   73
   74
   75
   76
   77
   78
   79
   80
   81
   82
   83
   84
   85
   86
   87
   88
   89
   90
   91
   92
   93
   94
   95
   96
   97
   98
   99
  100
  101
  102
  103
  104
  105
  106
  107
  108
  109
  110
  111
  112
  113
  114
  115
  116
  117
  118
  119
  120
  121
  122
  123
  124
  125
  126
  127
  128
  129
  130
  131
  132
  133
  134
  135
  136
  137
  138
  139
  140
  141
  142
  143
  144
  145
  146
  147
  148
  149
  150
  151
  152
  153
  154
  155
  156
  157
  158
  159
  160
  161
  162
  163
  164
  165
  166
  167
  168
  169
  170
  171
  172
  173
  174
  175
  176
  177
  178

media / mojo / mojom / video_decoder.mojom [blame]

// Copyright 2016 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.mojom;

import "gpu/ipc/common/sync_token.mojom";
import "media/mojo/mojom/media_log.mojom";
import "media/mojo/mojom/media_types.mojom";
import "mojo/public/mojom/base/unguessable_token.mojom";
import "ui/gfx/geometry/mojom/geometry.mojom";
import "ui/gfx/mojom/color_space.mojom";

// Serializable rule for matching VideoDecoderConfigs.
struct SupportedVideoDecoderConfig {
  // Range of VideoCodecProfiles to match, inclusive.
  VideoCodecProfile profile_min;
  VideoCodecProfile profile_max;

  // Range of coded sizes to match, inclusive in each dimension.
  gfx.mojom.Size coded_size_min;
  gfx.mojom.Size coded_size_max;

  // Match configs that have encryption configured.
  bool allow_encrypted;

  // Do not match configs that do not have encryption configured. This is used
  // on Android when the internal software decoder is preferred over the
  // platform decoder (eg. when the platform decoder is a software decoder).
  bool require_encrypted;
};

// Identifies a CommandBufferStub. MediaGpuChannelManager is responsible
// for minting |channel_token| values.
struct CommandBufferId {
  mojo_base.mojom.UnguessableToken channel_token;
  int32 route_id;
};

[Native]
struct OverlayInfo;

// Interface for releasing remote VideoFrames. It is separated from VideoDecoder
// so that VideoFrames can outlive their VideoDecoder.
interface VideoFrameHandleReleaser {
  // Signals that the VideoFrame identified by |release_token| should be
  // released. |release_sync_token| indicates the last use of the VideoFrame
  // (in a GPU command buffer) by the client. If the VideoDecoder outputs frames
  // that have a callback for releasing mailboxes (i.e.,
  // VideoFrame::HasReleaseMailboxCB() returns true), the |release_sync_token|
  // is required but may be empty, and in that case, implementations should let
  // the about-to-be-released VideoFrame retain whatever SyncToken it has. For
  // other frames, it's assumed that the frame can be released immediately upon
  // calling ReleaseVideoFrame() and |release_sync_token| does not need to be
  // supplied (and should be ignored by implementations if supplied).
  ReleaseVideoFrame(mojo_base.mojom.UnguessableToken release_token,
                    gpu.mojom.SyncToken? release_sync_token);
};

// A Mojo equivalent of media::VideoDecoder. In practice, this is used for
// hardware decode offloading; in this case the client is a <video> tag running
// in a renderer, and the implementation is running in the GPU process.
interface VideoDecoder {
  // 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() =>
      (array<SupportedVideoDecoderConfig> supported_configs,
       VideoDecoderType decoder_type);

  // Initialize the decoder. This must be called before any method other than
  // GetSupportedConfigs().
  //
  // |client| provides asynchronous client methods to the VideoDecoder, such
  // as delivery of decoded VideoFrame outputs.
  //
  // When a VideoFrame is delivered to |client|, the VideoDecoder may continue
  // to retain a reference to the VideoFrame. In this case a |release_token| is
  // included. The client shall use |video_frame_handle_releaser| to signal
  // that the retained VideoFrame should be released (even after the
  // VideoDecoder is torn down). This enables ordinary VideoFrames in the client
  // process to depend on resources held by the service, without significantly
  // complicating VideoFrame serialization.
  //
  // |decoder_buffer_pipe| is used to transfer the encoded data for each
  // DecoderBuffer.
  //
  // |command_buffer_id|, when present, identifies a CommandBufferStub that
  // the VideoDecoder can use for GL operations. Implementations that require GL
  // will fail Initialize() if |command_buffer_id| is not provided.
  //
  // |implementation| selects the underlying VideoDecoder implementation.  Not
  // all implementations are supported.  Initialize() will fail if
  // |implementation| is not supported.
  //
  // TODO(sandersd): Rename to Initialize() if/when
  // media::VideoDecoder::Initialize() is renamed to Configure().
  Construct(
      pending_associated_remote<VideoDecoderClient> client,
      pending_remote<MediaLog> media_log,
      pending_receiver<VideoFrameHandleReleaser> video_frame_handle_releaser,
      handle<data_pipe_consumer> decoder_buffer_pipe,
      CommandBufferId? command_buffer_id,
      gfx.mojom.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.
  //
  // If |low_delay| is true, the decoder must output frames as soon as possible;
  // in particular, it must not wait for another Decode() request, except as
  // required for frame reordering. Implementations must fail initialization if
  // they cannot satisfy this requirement.
  //
  // On completion, the callback also includes |needs_bitstream_conversion|,
  // indicating whether decode buffers need bitstream conversion, and
  // |max_decode_requests|, the maximum number of concurrent Decode() requests
  // the implementation supports.
  //
  // |cdm_id| must refer to a valid CDM if |config.is_encrypted()|.  It is not
  // used for unencrypted streams.
  Initialize(VideoDecoderConfig config, bool low_delay,
             mojo_base.mojom.UnguessableToken? cdm_id)
      => (DecoderStatus status,
          bool needs_bitstream_conversion,
          int32 max_decode_requests,
          VideoDecoderType decoder_type);

  // 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.
  //
  // Implementations must eventually execute the callback, even if Decode() is
  // not called again. It is not required that the decode status match the
  // actual result of decoding the buffer, only that decode errors are
  // eventually reported (such as at EOS).
  //
  // If |buffer| is an EOS buffer, implementations must execute all other
  // pending Decode() callbacks and output all pending frames before executing
  // the Decode(EOS) callback. (That is, they must flush.)
  Decode(DecoderBuffer buffer) => (DecoderStatus 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() => ();

  // Inform the decoder that new OverlayInfo is available.
  OnOverlayInfoChanged(OverlayInfo overlay_info);
};

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.
  //
  // If |release_token| is provided, the client shall call
  // VideoFrameHandleReleaser::Release() when it is finished using |frame|.
  OnVideoFrameDecoded(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(WaitingReason reason);

  // Request to be notified when the current OverlayInfo changes. This results
  // in at least one call to OnOverlayInfoChanged() for the initial OverlayInfo.
  // |restart_for_transitions| sets whether the decoder should be restarted on
  // overlay transitions instead of receiving a call to OnOverlayInfoChanged().
  RequestOverlayInfo(bool restart_for_transitions);
};