summaryrefslogtreecommitdiff
path: root/chromium/media/remoting/stream_provider.h
diff options
context:
space:
mode:
Diffstat (limited to 'chromium/media/remoting/stream_provider.h')
-rw-r--r--chromium/media/remoting/stream_provider.h280
1 files changed, 249 insertions, 31 deletions
diff --git a/chromium/media/remoting/stream_provider.h b/chromium/media/remoting/stream_provider.h
index f6c7802008b..95d2c214279 100644
--- a/chromium/media/remoting/stream_provider.h
+++ b/chromium/media/remoting/stream_provider.h
@@ -5,62 +5,280 @@
#ifndef MEDIA_REMOTING_STREAM_PROVIDER_H_
#define MEDIA_REMOTING_STREAM_PROVIDER_H_
+#include "base/callback_forward.h"
+#include "base/containers/circular_deque.h"
+#include "base/memory/scoped_refptr.h"
#include "base/memory/weak_ptr.h"
+#include "base/sequenced_task_runner_helpers.h"
+#include "base/single_thread_task_runner.h"
#include "media/base/audio_decoder_config.h"
+#include "media/base/demuxer.h"
#include "media/base/demuxer_stream.h"
-#include "media/base/media_resource.h"
#include "media/base/video_decoder_config.h"
-#include "media/remoting/rpc_broker.h"
+#include "media/mojo/mojom/remoting.mojom.h"
+#include "media/remoting/media_remoting_rpc.pb.h"
+#include "mojo/public/cpp/bindings/receiver.h"
+#include "mojo/public/cpp/bindings/remote.h"
+
+namespace base {
+class SingleThreadTaskRunner;
+} // namespace base
namespace media {
+
+class MojoDecoderBufferReader;
+
namespace remoting {
-class MediaStream;
+class ReceiverController;
+class RpcBroker;
// The media stream provider for Media Remoting receiver.
-class StreamProvider final : public MediaResource {
+class StreamProvider final : public Demuxer {
public:
- StreamProvider(RpcBroker* rpc_broker, base::OnceClosure error_callback);
+ StreamProvider(
+ ReceiverController* receiver_controller,
+ const scoped_refptr<base::SingleThreadTaskRunner>& media_task_runner);
- ~StreamProvider() override;
-
- // MediaResource implemenation.
+ // Demuxer implementation.
std::vector<DemuxerStream*> GetAllStreams() override;
+ std::string GetDisplayName() const override;
+ void Initialize(DemuxerHost* host, PipelineStatusCallback status_cb) override;
+ void AbortPendingReads() override;
+ void StartWaitingForSeek(base::TimeDelta seek_time) override;
+ void CancelPendingSeek(base::TimeDelta seek_time) override;
+ void Seek(base::TimeDelta time, PipelineStatusCallback status_cb) override;
+ void Stop() override;
+ base::TimeDelta GetStartTime() const override;
+ base::Time GetTimelineOffset() const override;
+ int64_t GetMemoryUsage() const override;
+ base::Optional<container_names::MediaContainerName> GetContainerForMetrics()
+ const override;
+ void OnEnabledAudioTracksChanged(const std::vector<MediaTrack::Id>& track_ids,
+ base::TimeDelta curr_time,
+ TrackChangeCB change_completed_cb) override;
+ void OnSelectedVideoTrackChanged(const std::vector<MediaTrack::Id>& track_ids,
+ base::TimeDelta curr_time,
+ TrackChangeCB change_completed_cb) override;
- void Initialize(int remote_audio_handle,
- int remote_video_handle,
- base::OnceClosure callback);
- void AppendBuffer(DemuxerStream::Type type,
- scoped_refptr<DecoderBuffer> buffer);
- void FlushUntil(DemuxerStream::Type type, int count);
+ protected:
+ // Deletion is only allowed via Destroy().
+ ~StreamProvider() override;
private:
- // Called when audio/video stream is initialized.
- void AudioStreamInitialized();
- void VideoStreamInitialized();
+ // An implementation of media::DemuxerStream on Media Remoting receiver.
+ // Receives data from mojo data pipe, and returns one frame or/and status when
+ // Read() is called.
+ class MediaStream final : public DemuxerStream,
+ public mojom::RemotingDataStreamReceiver {
+ public:
+ using UniquePtr =
+ std::unique_ptr<MediaStream, std::function<void(MediaStream*)>>;
- // Called when any error occurs.
- void OnError(const std::string& error);
+ // MediaStream should be created on the main thread to be able to get unique
+ // handle ID from |rpc_broker_|.
+ static void CreateOnMainThread(
+ RpcBroker* rpc_broker,
+ Type type,
+ int32_t handle,
+ const scoped_refptr<base::SingleThreadTaskRunner>& media_task_runner,
+ base::OnceCallback<void(MediaStream::UniquePtr)> callback);
- RpcBroker* const rpc_broker_; // Outlives this class.
- std::unique_ptr<MediaStream> video_stream_;
- std::unique_ptr<MediaStream> audio_stream_;
- bool audio_stream_initialized_ = false;
- bool video_stream_initialized_ = false;
+ // In order to destroy members in the right thread, MediaStream has to use
+ // DestructionHelper() to destroy itself.
+ static void DestructionHelper(MediaStream* stream);
- // Set when Initialize() is called, and will run when both video and audio
- // streams are initialized or error occurs.
- base::OnceClosure init_done_callback_;
+ MediaStream(
+ RpcBroker* rpc_broker,
+ Type type,
+ int32_t remote_handle,
+ const scoped_refptr<base::SingleThreadTaskRunner>& media_task_runner);
+
+ // DemuxerStream implementation.
+ void Read(ReadCB read_cb) override;
+ bool IsReadPending() const override;
+ AudioDecoderConfig audio_decoder_config() override;
+ VideoDecoderConfig video_decoder_config() override;
+ DemuxerStream::Type type() const override;
+ Liveness liveness() const override;
+ bool SupportsConfigChanges() override;
+
+ void Initialize(base::OnceClosure init_done_cb);
+
+ mojo::PendingRemote<mojom::RemotingDataStreamReceiver>
+ BindNewPipeAndPassRemote() {
+ return receiver_.BindNewPipeAndPassRemote();
+ }
+
+ private:
+ friend class base::DeleteHelper<MediaStream>; // For using DeleteSoon().
+ // For testing.
+ friend class StreamProviderTest;
+
+ // Prevent from unique_ptr using ~MediaStream() to destroy MediaStream
+ // instances. Use DestructionHelper() as the custom deleter with unique_ptr
+ // to destroy MediaStream instances.
+ ~MediaStream() override;
+
+ void Destroy();
+
+ // Send RPC message on |main_task_runner_|.
+ void SendRpcMessageOnMainThread(std::unique_ptr<pb::RpcMessage> message);
+
+ // mojom::RemotingDataStreamReceiver implementation.
+ void InitializeDataPipe(
+ mojo::ScopedDataPipeConsumerHandle data_pipe) override;
+ void ReceiveFrame(uint32_t count, mojom::DecoderBufferPtr buffer) override;
+ void FlushUntil(uint32_t count) override;
+
+ // RPC messages handlers.
+ void OnReceivedRpc(std::unique_ptr<pb::RpcMessage> message);
+ void OnInitializeCallback(std::unique_ptr<pb::RpcMessage> message);
+ void OnReadUntilCallback(std::unique_ptr<pb::RpcMessage> message);
+
+ // Issues the ReadUntil RPC message when read is pending and buffer is
+ // empty.
+ void SendReadUntil();
+
+ // Run |init_done_callback_| when MojoDecoderBufferReader is created and
+ // received RPC_DS_INITIALIZE_CALLBACK
+ void CompleteInitialize();
+
+ // Append a frame into |buffers_|.
+ void AppendBuffer(uint32_t count, scoped_refptr<DecoderBuffer> buffer);
+
+ // Run and reset the read callback.
+ void CompleteRead(DemuxerStream::Status status);
+
+ // Update the audio/video decoder config. When config changes in the mid
+ // stream, the new config will be stored in |next_audio_decoder_config_|.
+ // Old config will be dropped when all associated frames are consumed.
+ void UpdateAudioConfig(const pb::AudioDecoderConfig& audio_message);
+ void UpdateVideoConfig(const pb::VideoDecoderConfig& video_message);
+
+ // Called when any error occurs.
+ void OnError(const std::string& error);
+
+ scoped_refptr<base::SingleThreadTaskRunner> main_task_runner_;
+ scoped_refptr<base::SingleThreadTaskRunner> media_task_runner_;
+
+ RpcBroker* const rpc_broker_; // Outlives this class.
+ const Type type_;
+ const int remote_handle_;
+ const int rpc_handle_;
+
+ // Set when Initialize() is called.
+ base::OnceClosure init_done_callback_;
- // Run when first error occurs;
- base::OnceClosure error_callback_;
+ // The frame count of the frame to be returned on the next Read call. It
+ // will be increased whenever a frame is read. It will be updated when
+ // FlushUntil() is called.
+ uint32_t current_frame_count_ = 0;
- base::WeakPtrFactory<StreamProvider> weak_factory_{this};
+ // One plus the last frame count received over RTP. Used for continuity
+ // check.
+ uint32_t buffered_frame_count_ = 0;
- DISALLOW_COPY_AND_ASSIGN(StreamProvider);
+ // The total number of frames received from the sender side. It will be used
+ // as the base value for sending ReadUntil() to request more frames and be
+ // updated in OnReadUntilCallback() which would get the message that
+ // contains how many frames are sent.
+ uint32_t total_received_frame_count_ = 0;
+
+ // Indicates whether Audio/VideoDecoderConfig changed and the frames with
+ // the old config are not yet consumed. The new config is stored in the end
+ // of |audio/video_decoder_config_|.
+ bool config_changed_ = false;
+
+ // Indicates whether a ReadUntil RPC message was sent without receiving the
+ // ReadUntilCallback message yet.
+ bool read_until_sent_ = false;
+
+ // Indicates whether RPC_DS_INITIALIZE_CALLBACK received.
+ bool rpc_initialized_ = false;
+
+ // Set when Read() is called. Run only once when read completes.
+ ReadCB read_complete_callback_;
+
+ // The frame data would be sent via Mojo IPC as MojoDecoderBuffer. When a
+ // frame is sent to |this| from host by calling ReceiveFrame(),
+ // |decoder_buffer_reader_| is used to read the frame date from data pipe.
+ std::unique_ptr<MojoDecoderBufferReader> decoder_buffer_reader_;
+
+ base::circular_deque<scoped_refptr<DecoderBuffer>> buffers_;
+
+ // Current audio/video config.
+ AudioDecoderConfig audio_decoder_config_;
+ VideoDecoderConfig video_decoder_config_;
+
+ // Stores the new audio/video config when config changes.
+ AudioDecoderConfig next_audio_decoder_config_;
+ VideoDecoderConfig next_video_decoder_config_;
+
+ mojo::Receiver<mojom::RemotingDataStreamReceiver> receiver_{this};
+
+ base::WeakPtr<MediaStream> media_weak_this_;
+ base::WeakPtrFactory<MediaStream> media_weak_factory_{this};
+ };
+
+ friend std::default_delete<StreamProvider>;
+ friend class base::DeleteHelper<StreamProvider>; // For using DeleteSoon().
+
+ // For testing.
+ friend class StreamProviderTest;
+
+ void Destroy();
+
+ // RPC messages handlers.
+ void OnReceivedRpc(std::unique_ptr<pb::RpcMessage> message);
+ void OnAcquireDemuxer(std::unique_ptr<pb::RpcMessage> message);
+
+ // Called when audio/video stream is created and initialized.
+ void InitializeDataPipe();
+ void OnAudioStreamCreated(MediaStream::UniquePtr stream);
+ void OnVideoStreamCreated(MediaStream::UniquePtr stream);
+ void OnAudioStreamInitialized();
+ void OnVideoStreamInitialized();
+ void CompleteInitialize();
+
+ scoped_refptr<base::SingleThreadTaskRunner> main_task_runner_;
+ scoped_refptr<base::SingleThreadTaskRunner> media_task_runner_;
+ ReceiverController* const receiver_controller_; // Outlives this class
+ RpcBroker* const rpc_broker_; // Outlives this class
+ MediaStream::UniquePtr audio_stream_;
+ MediaStream::UniquePtr video_stream_;
+ bool has_audio_{false};
+ bool has_video_{false};
+ bool audio_stream_initialized_{false};
+ bool video_stream_initialized_{false};
+
+ // Set when Initialize() is called, and will run when both video and audio
+ // streams are initialized or error occurs.
+ PipelineStatusCallback init_done_callback_;
+
+ base::WeakPtr<StreamProvider> media_weak_this_;
+ base::WeakPtrFactory<StreamProvider> media_weak_factory_{this};
};
} // namespace remoting
} // namespace media
+namespace std {
+
+// Specialize std::default_delete to call Destroy().
+template <>
+struct default_delete<media::remoting::StreamProvider> {
+ constexpr default_delete() = default;
+
+ template <typename U,
+ typename = typename std::enable_if<std::is_convertible<
+ U*,
+ media::remoting::StreamProvider*>::value>::type>
+ explicit default_delete(const default_delete<U>& d) {}
+
+ void operator()(media::remoting::StreamProvider* ptr) const;
+};
+
+} // namespace std
+
#endif // MEDIA_REMOTING_STREAM_PROVIDER_H_