chromium/media/mojo/mojom/remoting.mojom

// 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 "media/mojo/mojom/media_types.mojom";
import "media/mojo/mojom/remoting_common.mojom";
import "ui/gfx/geometry/mojom/geometry.mojom";

interface RemoterFactory {
  // Create a new Remoter associated with the given RemotingSource and bind it
  // to the given interface receiver. The RemotingSource will be notified when
  // the Remoter becomes available for use (or becomes unavailable).
  Create(pending_remote<RemotingSource> source,
         pending_receiver<Remoter> remoter);
};

// Interface used by the source to control when media bitstream data is read
// from a data pipe and then sent to the remote endpoint. There is one
// RemotingDataStreamSender per data pipe.
interface RemotingDataStreamSender {
  // Enqueues a frame for transmission to the remote endpoint, with payload to
  // be read from the data pipe. The callback will be invoked once the receiver
  // is ready to read another frame, immediately following the writing of the
  // sent |frame| to the underlying Openscreen sender.
  //
  // Only one such call may be in flight at a time.
  SendFrame(media.mojom.DecoderBuffer frame) => ();

  // Cancels the transmission of all in-flight data to the remote, up to and
  // including the last SendFrame() call; and also discard any data chunks
  // that were consumed from the data pipe for the next frame. This is used to
  // optimize seeking, when it is known that any in-flight data is no longer
  // needed by the remote. There is no guarantee as to how much of the in-flight
  // data will actually reach the remote before the cancellation takes effect.
  CancelInFlightData();
};

// Interface used by the source to start/stop remoting and send data to the
// sink.
interface Remoter {
  // Starts a remoting session (once the sink has been reported to be available;
  // see RemotingSource). Either RemotingSource.OnStarted() or OnStartFailed()
  // will be called to indicate success or failure. Once OnStarted() has been
  // invoked, the source may then make calls to SendMessageToSink() and expect
  // messages from the remote via RemotingSource.OnMessageFromSink().
  Start();

  // Same as `Start()` except that Remoting will start without asking for users'
  // permission.
  StartWithPermissionAlreadyGranted();

  // Starts remoting the media data streams. This is called after Start() to
  // provide data pipes from which the audio/video bitstream data is consumed
  // and then transported to the remote device. RemotingDataStreamSenders are
  // used by the source to control when data should be consumed from the data
  // pipes and sent. One or both pipes (and their corresponding
  // RemotingDataStreamSender interface receivers) must be provided.
  StartDataStreams(handle<data_pipe_consumer>? audio_pipe,
                   handle<data_pipe_consumer>? video_pipe,
                   pending_receiver<RemotingDataStreamSender>? audio_sender,
                   pending_receiver<RemotingDataStreamSender>? video_sender);

  // Stops remoting media. Messages in both directions will be dropped after this
  // point as well as any pending or in-transit media bitstream data.
  Stop(RemotingStopReason reason);

  // Sends |message| to the sink. |message| is a serialized protobuf from
  // src/media/remoting/proto.
  SendMessageToSink(array<uint8> message);

  // Estimates the transmission capacity. Returns the result in
  // bytes per second.
  EstimateTransmissionCapacity() => (double rate);
};

// Interface used for sending notifications back to the local source's control
// logic, and to pass messages from the sink back to the local media pipeline.
interface RemotingSource {
  // Pass the sink's metadata. It is up to the source's control logic to decide
  // whether/when to start remoting.
  OnSinkAvailable(RemotingSinkMetadata metadata);

  // Notifies the source that the sink is no longer available for remoting. This
  // may happen, for example, because the sink has been shut down, or because
  // another source has started remoting.
  OnSinkGone();

  // One of these is called after the source attempts to start remoting. If
  // OnStarted() is called, messages may begin flowing; and this will continue
  // until OnStopped() is called. On the other hand, if OnStartFailed() is
  // called, then no messages are being passed between source and sink and
  // remoting is not taking place.
  OnStarted();
  OnStartFailed(RemotingStartFailReason reason);

  // Passes a |message| from the sink back to the source. The |message| consists
  // of a serialized protobuf from src/media/remoting/proto. This will only be
  // called after OnStarted() and before OnStopped().
  OnMessageFromSink(array<uint8> message);

  // Notifies the source that remoting has terminated. This may or may not be in
  // response to a Remoter.Stop() call, as other events (possibly external) may
  // have caused remoting to end.
  OnStopped(RemotingStopReason reason);
};

// Interface that is implemented by the host of RemotingSink and
// RemotingDataStreamReceiver. Remotee implementation would be implemented in
// the browser process in order to receive serialized RPC messages and frame
// data from the sender.
interface Remotee {
  // Used by RemotingSink to notify Remotee that it is ready for remoting.
  OnRemotingSinkReady(pending_remote<RemotingSink> sink);

  // Used by the RemotingSink to send a serialized RPC message to sender side.
  // |message| is a serialized protobuf from src/media/remoting/proto.
  SendMessageToSource(array<uint8> message);

  // Initialize the data pipe for RemotingDataStreamReceiver to allow Remotee to
  // send frame data to it.
  // Remoting media could be audio-only media, video-only media, or media has
  // both audio and video. So, at least one of audio stream or video stream
  // should be passed.
  StartDataStreams(
      pending_remote<RemotingDataStreamReceiver>? audio_stream,
      pending_remote<RemotingDataStreamReceiver>? video_stream);

  // Used by RemotingSink to notify Remotee that FlushUntil is happening in
  // order to not send NACK for the frames that are ignored. The implementation
  // should also forward the |{audio/video}_frame_count| to FlushUntil() of
  // {audio|video} streams which are RemotingDataStreamReceiver implementations.
  OnFlushUntil(uint32 audio_frame_count, uint32 video_frame_count);

  // Used by RemotingSink to notify Remotee that VideoNaturalSizeChange is
  // happening.
  OnVideoNaturalSizeChange(gfx.mojom.Size size);
};

// Interface that is used to receive messages from the sender.
interface RemotingSink {
  // Used by the Remotee to send a serialized RPC message to the sink.
  // |message| is a serialized protobuf from src/media/remoting/proto.
  OnMessageFromSource(array<uint8> message);
};

// Interface that is implemented by either an audio or a video demuxer stream at
// the receiver side to receive frame data. Passed to a Remotee which will send
// it frame data.
interface RemotingDataStreamReceiver {
  // Used by the Remotee implementation to bind a data pipe to
  // RemotingDataStreamReceiver.
  InitializeDataPipe(handle<data_pipe_consumer> data_pipe);

  // Used by the Remotee implementation to send frame data to
  // RemotingDataStreamReceiver.
  ReceiveFrame(uint32 frame_count, DecoderBuffer buffer);

  // Used by the Remotee implementation to flush frames until the given frame
  // count.
  FlushUntil(uint32 frame_count);
};