Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(99)

Side by Side Diff: media/remoting/remoting_source_impl.h

Issue 2457563002: Media Remoting: Add remoting control logic for encrypted contents. (Closed)
Patch Set: Bug fix. Created 4 years, 1 month ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 // Copyright 2016 The Chromium Authors. All rights reserved. 1 // Copyright 2016 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #ifndef MEDIA_REMOTING_REMOTING_CONTROLLER_H_ 5 #ifndef MEDIA_REMOTING_REMOTING_SOURCE_IMPL_H_
6 #define MEDIA_REMOTING_REMOTING_CONTROLLER_H_ 6 #define MEDIA_REMOTING_REMOTING_SOURCE_IMPL_H_
7 7
8 #include <vector>
8 #include "base/callback.h" 9 #include "base/callback.h"
9 #include "base/memory/weak_ptr.h" 10 #include "base/memory/weak_ptr.h"
10 #include "media/base/media_observer.h" 11 #include "base/threading/thread_checker.h"
11 #include "media/mojo/interfaces/remoting.mojom.h" 12 #include "media/mojo/interfaces/remoting.mojom.h"
12 #include "mojo/public/cpp/bindings/binding.h" 13 #include "mojo/public/cpp/bindings/binding.h"
13 14
14 namespace base {
15 class SingleThreadTaskRunner;
16 }
17
18 // This class does the following:
19 // 1) Sends/Receives messages from/to Remoter;
20 // 2) Monitors player events as a MediaObserver;
21 // 3) May trigger the switch of the media renderer between local playback
22 // and remoting.
23 //
24 namespace media { 15 namespace media {
25 16
26 namespace remoting { 17 namespace remoting {
27 class RpcBroker; 18 class RpcBroker;
28 } 19 }
29 20
30 class RemotingController final : public MediaObserver, 21 // State transition diagram:
31 public mojom::RemotingSource { 22 //
23 // .--> SESSION_UNAVAILABLE
24 // | | ^
25 // | V |
26 // | SESSION_CAN_START
27 // | |
28 // | V
29 // | .---SESSION_STARTING --.
30 // | | | |
31 // | | V |
32 // | | SESSION_STARTED----|
33 // | | | |
34 // | | V |
35 // | '-> SESSION_STOPPING |
36 // '-----' | |
37 // V V
38 // SESSION_PERMANENTLY_STOPPED
39
40 enum RemotingSessionState {
41 // Remoting sink is not available. Can't start remoting.
42 SESSION_UNAVAILABLE,
43 // Remoting sink is available, Can start remoting.
44 SESSION_CAN_START,
45 // Starting a remoting session.
46 SESSION_STARTING,
47 // Remoting session is successively started.
48 SESSION_STARTED,
49 // Stopping the session.
50 SESSION_STOPPING,
51 // Remoting session is permanently stopped. This state indicates that the
52 // video stack cannot continue operation. For example, if a remoting session
53 // involving CDM content was stopped, there is no way to continue playback
54 // because the CDM is required but is no longer available.
55 SESSION_PERMANENTLY_STOPPED,
56 };
57
58 // Maintains a single remoting session for multiple clients. The session will
59 // start remoting when receiving the first request. Once remoting is started,
60 // it will be stopped when any of the following happens:
61 // 1) Receives the request from any client to stop remoting.
62 // 2) Remote sink is gone.
63 // 3) Any client requests to permanently terminate the session.
64 // 4) All clients are destroyed.
65 //
66 // This class is ref-counted because, in some cases, an instance will have
67 // shared ownership between RemotingRendererController and
68 // RemotingCdmController.
69 class RemotingSourceImpl final
70 : public mojom::RemotingSource,
71 public base::RefCountedThreadSafe<RemotingSourceImpl> {
32 public: 72 public:
33 RemotingController(mojom::RemotingSourceRequest source_request, 73 class Client {
74 public:
75 // Get notified whether the remoting session is successively started.
76 virtual void OnStarted(bool success) = 0;
77 // Get notified when session state changes.
78 virtual void OnSessionStateChanged() = 0;
79 };
80
81 RemotingSourceImpl(mojom::RemotingSourceRequest source_request,
34 mojom::RemoterPtr remoter); 82 mojom::RemoterPtr remoter);
35 ~RemotingController() override; 83
84 // Get the current session state.
85 RemotingSessionState state() const {
86 DCHECK(thread_checker_.CalledOnValidThread());
87 return state_;
88 }
89
90 // RemotingSource implementations.
91 void OnSinkAvailable() override;
92 void OnSinkGone() override;
93 void OnStarted() override;
94 void OnStartFailed(mojom::RemotingStartFailReason reason) override;
95 void OnMessageFromSink(const std::vector<uint8_t>& message) override;
96 void OnStopped(mojom::RemotingStopReason reason) override;
36 97
37 using DataPipeStartCallback = 98 using DataPipeStartCallback =
38 base::Callback<void(mojom::RemotingDataStreamSenderPtrInfo audio, 99 base::Callback<void(mojom::RemotingDataStreamSenderPtrInfo audio,
39 mojom::RemotingDataStreamSenderPtrInfo video, 100 mojom::RemotingDataStreamSenderPtrInfo video,
40 mojo::ScopedDataPipeProducerHandle audio_handle, 101 mojo::ScopedDataPipeProducerHandle audio_handle,
41 mojo::ScopedDataPipeProducerHandle video_handle)>; 102 mojo::ScopedDataPipeProducerHandle video_handle)>;
42 void StartDataPipe(std::unique_ptr<mojo::DataPipe> audio_data_pipe, 103 void StartDataPipe(std::unique_ptr<mojo::DataPipe> audio_data_pipe,
43 std::unique_ptr<mojo::DataPipe> video_data_pipe, 104 std::unique_ptr<mojo::DataPipe> video_data_pipe,
44 const DataPipeStartCallback& done_callback); 105 const DataPipeStartCallback& done_callback);
45 106
46 // RemotingSource implementations. 107 // Requests to start remoting. Will try start a remoting session if not
47 void OnSinkAvailable() override; 108 // started yet. |client| will get informed whether the session is
48 void OnSinkGone() override; 109 // successifully started throught OnStarted().
49 void OnStarted() override; 110 void StartRemoting(Client* client);
50 void OnStartFailed(mojom::RemotingStartFailReason reason) override;
51 void OnMessageFromSink(const std::vector<uint8_t>& message) override;
52 void OnStopped(mojom::RemotingStopReason reason) override;
53 111
54 // MediaObserver implementations. 112 // Requests to stop the current remoting session if started. When the session
55 // This is called when the video element or its ancestor enters full screen. 113 // is stopping, all clients will get notified.
56 // We currently use this as an indicator for immersive playback. May add other 114 void StopRemoting(Client* client);
57 // criteria (e.g. the actual display width/height of the video element) in
58 // future.
59 void OnEnteredFullscreen() override;
60 void OnExitedFullscreen() override;
61 void OnSetCdm(CdmContext* cdm_context) override;
62 void OnMetadataChanged(const PipelineMetadata& metadata) override;
63 115
64 using SwitchRendererCallback = base::Callback<void()>; 116 // Permanently terminates the current remoting session.
65 void SetSwitchRendererCallback(const SwitchRendererCallback& cb); 117 void Shutdown();
66 118
67 // Tells which renderer should be used. 119 // Add/remove a client to/from |clients_|.
68 bool is_remoting() const { 120 // Note: Clients can only added/removed through these methods.
69 DCHECK(task_runner_->BelongsToCurrentThread()); 121 // Remoting session will be stopped if all clients are gone.
70 return is_remoting_; 122 void AddClient(Client* client);
71 } 123 void RemoveClient(Client* client);
72
73 base::WeakPtr<RemotingController> GetWeakPtr() {
74 return weak_factory_.GetWeakPtr();
75 }
76 124
77 base::WeakPtr<remoting::RpcBroker> GetRpcBroker() const; 125 base::WeakPtr<remoting::RpcBroker> GetRpcBroker() const;
miu 2016/11/05 04:05:16 WeakPtrs are not necessary. Just return a raw poin
xjz 2016/11/07 19:03:55 Done.
78 126
79 private: 127 private:
80 bool IsVideoCodecSupported(); 128 friend class base::RefCountedThreadSafe<RemotingSourceImpl>;
81 bool IsAudioCodecSupported(); 129 ~RemotingSourceImpl() override;
82 130
83 // Helper to decide whether to enter or leave Remoting mode. 131 // Updates the current session state and notifies all the clients if state
84 bool ShouldBeRemoting(); 132 // changes.
85 133 void UpdateAndNotifyState(RemotingSessionState state);
86 // Determines whether to enter or leave Remoting mode and switches if
87 // necessary.
88 void UpdateAndMaybeSwitch();
89 134
90 // Callback from RpcBroker when sending message to remote sink. 135 // Callback from RpcBroker when sending message to remote sink.
91 void OnSendMessageToSink(std::unique_ptr<std::vector<uint8_t>> message); 136 void OnSendMessageToSink(std::unique_ptr<std::vector<uint8_t>> message);
92 137
93 // Handle incomging and outgoing RPC message. 138 // Handle incomging and outgoing RPC message.
94 std::unique_ptr<remoting::RpcBroker> rpc_broker_; 139 std::unique_ptr<remoting::RpcBroker> rpc_broker_;
miu 2016/11/05 04:05:16 Don't use a pointer to a heap-allocated object her
xjz 2016/11/07 19:03:55 Done.
95 140
96 // Indicates if this media element or its ancestor enters full screen. 141 const mojo::Binding<mojom::RemotingSource> binding_;
97 bool is_fullscreen_ = false; 142 const mojom::RemoterPtr remoter_;
98 143
99 // Indicates the remoting sink availablity. 144 // The current state.
100 bool is_sink_available_ = false; 145 RemotingSessionState state_ = RemotingSessionState::SESSION_UNAVAILABLE;
101 146
102 // Indicates if remoting is started. 147 // Clients are added/removed to/from this list by calling Add/RemoveClient().
103 bool is_remoting_ = false; 148 // All the clients are not belong to this class. They are supposed to call
149 // RemoveClient() before they are gone.
150 std::vector<Client*> clients_;
104 151
105 // Indicates whether audio or video is encrypted. 152 // This is used to check all the methods are called on the current thread in
106 bool is_encrypted_ = false; 153 // debug builds.
107 154 base::ThreadChecker thread_checker_;
108 // Current audio/video config.
109 VideoDecoderConfig video_decoder_config_;
110 AudioDecoderConfig audio_decoder_config_;
111 bool has_audio_ = false;
112 bool has_video_ = false;
113
114 // The callback to switch the media renderer.
115 SwitchRendererCallback switch_renderer_cb_;
116
117 mojo::Binding<mojom::RemotingSource> binding_;
118 mojom::RemoterPtr remoter_;
119
120 // TODO(xjz): Add a media thread task runner for the received RPC messages for
121 // remoting media renderer in the up-coming change.
122 const scoped_refptr<base::SingleThreadTaskRunner> task_runner_;
123
124 base::WeakPtrFactory<RemotingController> weak_factory_;
125
126 DISALLOW_COPY_AND_ASSIGN(RemotingController);
127 }; 155 };
128 156
129 } // namespace media 157 } // namespace media
130 158
131 #endif // MEDIA_REMOTING_REMOTING_CONTROLLER_H_ 159 #endif // MEDIA_REMOTING_REMOTING_SOURCE_IMPL_H_
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698