blob: 150eebed7e14cff22d40f7317c6093f9e2da18f7 [file] [log] [blame]
// Copyright 2018 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.
#include <memory>
#include "base/callback.h"
#include "base/component_export.h"
#include "base/containers/queue.h"
#include "base/macros.h"
#include "base/memory/weak_ptr.h"
#include "base/sequence_checker.h"
#include "media/cast/sender/frame_sender.h"
#include "media/mojo/interfaces/remoting.mojom.h"
#include "mojo/public/cpp/bindings/binding.h"
namespace base {
class TickClock;
} // namespace base
namespace media {
class MojoDataPipeReader;
} // namespace media
namespace mirroring {
// RTP sender for a single Cast Remoting RTP stream. The client calls Send() to
// instruct the sender to read from a Mojo data pipe and transmit the data using
// a CastTransport.
: public media::mojom::RemotingDataStreamSender,
public media::cast::FrameSender {
// |transport| is expected to outlive this class.
RemotingSender(scoped_refptr<media::cast::CastEnvironment> cast_environment,
media::cast::CastTransport* transport,
const media::cast::FrameSenderConfig& config,
mojo::ScopedDataPipeConsumerHandle pipe,
media::mojom::RemotingDataStreamSenderRequest request,
base::OnceClosure error_callback);
~RemotingSender() override;
// Friend class for unit tests.
friend class RemotingSenderTest;
// media::mojom::RemotingDataStreamSender implementation. SendFrame() will
// push callbacks onto the back of the input queue, and these may or may not
// be processed at a later time. It depends on whether the data pipe has data
// available or the CastTransport can accept more frames. CancelInFlightData()
// is processed immediately, and will cause all pending operations to discard
// data when they are processed later.
void SendFrame(uint32_t frame_size) override;
void CancelInFlightData() override;
// FrameSender override.
int GetNumberOfFramesInEncoder() const override;
base::TimeDelta GetInFlightMediaDuration() const override;
void OnCancelSendingFrames() override;
// Attempt to run next pending input task, popping the head of the input queue
// as each task succeeds.
void ProcessNextInputTask();
// These are called via callbacks run from the input queue.
// Consumes a frame of |size| from the associated Mojo data pipe.
void ReadFrame(uint32_t size);
// Sends out the frame to the receiver over network.
void TrySendFrame();
// Called when a frame is completely read/discarded from the data pipe.
void OnFrameRead(bool success);
// Called when an input task completes.
void OnInputTaskComplete();
void OnRemotingDataStreamError();
const base::TickClock* clock_;
// Callback that is run to notify when a fatal error occurs.
base::OnceClosure error_callback_;
std::unique_ptr<media::MojoDataPipeReader> data_pipe_reader_;
// Mojo binding for this instance. Implementation at the other end of the
// message pipe uses the RemotingDataStreamSender interface to control when
// this RemotingSender consumes from |pipe_|.
mojo::Binding<media::mojom::RemotingDataStreamSender> binding_;
// The next frame's payload data. Populated by call to OnFrameRead() when
// reading succeeded.
std::string next_frame_data_;
// Queue of pending input operations. |input_queue_discards_remaining_|
// indicates the number of operations where data should be discarded (due to
// CancelInFlightData()).
base::queue<base::RepeatingClosure> input_queue_;
size_t input_queue_discards_remaining_;
// Indicates whether the |data_pipe_reader_| is processing a reading request.
bool is_reading_;
// Set to true if the first frame has not yet been sent, or if a
// CancelInFlightData() operation just completed. This causes TrySendFrame()
// to mark the next frame as the start of a new sequence.
bool flow_restart_pending_;
// NOTE: Weak pointers must be invalidated before all other member variables.
base::WeakPtrFactory<RemotingSender> weak_factory_;
} // namespace mirroring