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

Side by Side Diff: media/remoting/remote_stream_provider.cc

Issue 2692593002: Media Remoting: End to end integration tests. (Closed)
Patch Set: Created 3 years, 10 months 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
(Empty)
1 // Copyright 2017 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #include "media/remoting/remote_stream_provider.h"
6
7 #include "base/bind.h"
8 #include "base/callback.h"
9 #include "base/callback_helpers.h"
10 #include "media/base/decoder_buffer.h"
11 #include "media/base/video_rotation.h"
12 #include "media/remoting/proto_enum_utils.h"
13 #include "media/remoting/proto_utils.h"
14
15 namespace media {
16 namespace remoting {
17
18 namespace {
19 // The number of frames requested in each ReadUntil RPC message.
20 constexpr int kNumFramesInEachReadUntil = 10;
21 }
22
23 RemoteMediaStream::RemoteMediaStream(RpcBroker* rpc_broker,
24 Type type,
25 int remote_handle)
26 : rpc_broker_(rpc_broker),
27 type_(type),
28 remote_handle_(remote_handle),
29 rpc_handle_(rpc_broker_->GetUniqueHandle()),
30 weak_factory_(this) {
31 DCHECK(remote_handle_ != RpcBroker::kInvalidHandle);
32 rpc_broker_->RegisterMessageReceiverCallback(
33 rpc_handle_, base::Bind(&RemoteMediaStream::OnReceivedRpc,
34 weak_factory_.GetWeakPtr()));
35 }
36
37 RemoteMediaStream::~RemoteMediaStream() {
38 rpc_broker_->UnregisterMessageReceiverCallback(rpc_handle_);
39 }
40
41 void RemoteMediaStream::Initialize(const base::Closure& init_done_cb) {
42 DCHECK(init_done_callback_.is_null());
43 DCHECK(!init_done_cb.is_null());
44 init_done_callback_ = init_done_cb;
45
46 DVLOG(3) << __func__ << "Issues RpcMessage::RPC_DS_INITIALIZE with "
47 << "remote_handle=" << remote_handle_
48 << " rpc_handle=" << rpc_handle_;
49 std::unique_ptr<pb::RpcMessage> rpc(new pb::RpcMessage());
50 rpc->set_handle(remote_handle_);
51 rpc->set_proc(pb::RpcMessage::RPC_DS_INITIALIZE);
52 rpc->set_integer_value(rpc_handle_);
53 rpc_broker_->SendMessageToRemote(std::move(rpc));
54 }
55
56 void RemoteMediaStream::OnReceivedRpc(std::unique_ptr<pb::RpcMessage> message) {
57 DCHECK(message->handle() == rpc_handle_);
58
59 switch (message->proc()) {
60 case pb::RpcMessage::RPC_DS_INITIALIZE_CALLBACK:
61 OnInitializeCallback(std::move(message));
62 break;
63 case pb::RpcMessage::RPC_DS_READUNTIL_CALLBACK:
64 OnReadUntilCallback(std::move(message));
65 break;
66 default:
67 VLOG(3) << __func__ << "Unknow RPC message.";
68 }
69 }
70
71 void RemoteMediaStream::OnInitializeCallback(
72 std::unique_ptr<pb::RpcMessage> message) {
73 DVLOG(3) << __func__ << "Receives RPC_DS_INITIALIZE_CALLBACK message.";
74 const pb::DemuxerStreamInitializeCallback callback_message =
75 message->demuxerstream_initializecb_rpc();
76 DCHECK(callback_message.type() == type_);
miu 2017/03/29 01:39:14 These four DCHECKs() should be if-statements inste
xjz 2017/03/30 23:21:31 Done.
77 DCHECK(audio_decoder_config_.empty());
78 DCHECK(video_decoder_config_.empty());
79 DCHECK(!init_done_callback_.is_null());
80
81 if (type_ == DemuxerStream::AUDIO &&
82 callback_message.has_audio_decoder_config()) {
83 const pb::AudioDecoderConfig audio_message =
84 callback_message.audio_decoder_config();
85 UpdateConfig(&audio_message, nullptr);
86 } else if (type_ == DemuxerStream::VIDEO &&
87 callback_message.has_video_decoder_config()) {
88 const pb::VideoDecoderConfig video_message =
89 callback_message.video_decoder_config();
90 UpdateConfig(nullptr, &video_message);
91 } else {
92 NOTREACHED();
miu 2017/03/29 01:39:14 Replace with something like: SendInitializeRpcF
xjz 2017/03/30 23:21:31 Done.
93 }
94 base::ResetAndReturn(&init_done_callback_).Run();
95 }
96
97 void RemoteMediaStream::OnReadUntilCallback(
98 std::unique_ptr<pb::RpcMessage> message) {
99 DVLOG(3) << __func__ << ": Receives RPC_DS_READUNTIL_CALLBACK message.";
100 DCHECK(read_until_sent_);
miu 2017/03/29 01:39:14 DCHECK() --> if () ...and rather than me point al
xjz 2017/03/30 23:21:31 Done.
101 read_until_sent_ = false;
102 const pb::DemuxerStreamReadUntilCallback callback_message =
103 message->demuxerstream_readuntilcb_rpc();
104 last_read_until_count_ = callback_message.count();
105 if (ToDemuxerStreamStatus(callback_message.status()) == kConfigChanged) {
106 if (callback_message.has_audio_decoder_config()) {
107 const pb::AudioDecoderConfig audio_message =
108 callback_message.audio_decoder_config();
109 UpdateConfig(&audio_message, nullptr);
110 }
111 if (callback_message.has_video_decoder_config()) {
112 const pb::VideoDecoderConfig video_message =
113 callback_message.video_decoder_config();
114 UpdateConfig(nullptr, &video_message);
115 }
116 config_changed_ = true;
117 if (buffers_.empty() && !read_complete_callback_.is_null())
118 CompleteRead(DemuxerStream::kConfigChanged);
119 return;
120 }
121 if (buffers_.empty() && !read_complete_callback_.is_null())
122 SendReadUntil();
123 }
124
125 void RemoteMediaStream::UpdateConfig(
126 const pb::AudioDecoderConfig* audio_message,
127 const pb::VideoDecoderConfig* video_message) {
128 if (type_ == AUDIO) {
129 DCHECK(audio_message && !video_message);
130 AudioDecoderConfig audio_config;
131 ConvertProtoToAudioDecoderConfig(*audio_message, &audio_config);
132 DCHECK(audio_config.IsValidConfig());
133 audio_decoder_config_.push_back(audio_config);
134 } else if (type_ == VIDEO) {
135 DCHECK(video_message && !audio_message);
136 VideoDecoderConfig video_config;
137 ConvertProtoToVideoDecoderConfig(*video_message, &video_config);
138 DCHECK(video_config.IsValidConfig());
139 video_decoder_config_.push_back(video_config);
140 } else {
141 VLOG(1) << __func__ << ": Only supports video or audio stream.";
142 }
143 }
144
145 void RemoteMediaStream::SendReadUntil() {
146 if (read_until_sent_)
147 return;
148 DVLOG(3) << "Issues RPC_DS_READUNTIL RPC message to remote_handle_="
149 << remote_handle_ << " with callback handle=" << rpc_handle_
150 << " count=" << last_read_until_count_;
151
152 std::unique_ptr<pb::RpcMessage> rpc(new pb::RpcMessage());
153 rpc->set_handle(remote_handle_);
154 rpc->set_proc(pb::RpcMessage::RPC_DS_READUNTIL);
155 auto* message = rpc->mutable_demuxerstream_readuntil_rpc();
156 last_read_until_count_ += kNumFramesInEachReadUntil;
157 message->set_count(last_read_until_count_);
158 message->set_callback_handle(rpc_handle_);
159 rpc_broker_->SendMessageToRemote(std::move(rpc));
160 read_until_sent_ = true;
161 }
162
163 void RemoteMediaStream::FlushUntil(int count) {
164 while (!buffers_.empty()) {
165 buffers_.pop_front();
166 }
167
168 last_read_until_count_ = count;
169 if (!read_complete_callback_.is_null())
170 CompleteRead(DemuxerStream::kAborted);
171 read_until_sent_ = false;
172 }
173
174 void RemoteMediaStream::Read(const ReadCB& read_cb) {
175 DVLOG(3) << __func__;
176 DCHECK(read_complete_callback_.is_null());
177 read_complete_callback_ = read_cb;
178 if (buffers_.empty() && config_changed_) {
179 CompleteRead(DemuxerStream::kConfigChanged);
180 return;
181 }
182
183 // Wait for more data.
184 if (buffers_.empty()) {
185 SendReadUntil();
186 return;
187 }
188
189 CompleteRead(DemuxerStream::kOk);
190 }
191
192 void RemoteMediaStream::CompleteRead(DemuxerStream::Status status) {
193 DVLOG(3) << __func__ << ": " << status;
194 switch (status) {
195 case DemuxerStream::kConfigChanged:
196 if (type_ == AUDIO) {
197 DCHECK(audio_decoder_config_.size() == 2);
miu 2017/03/29 01:39:14 This is weird. Looks like we create a whole deque
xjz 2017/03/30 23:21:31 Done.
198 audio_decoder_config_.pop_front();
199 } else {
200 DCHECK(video_decoder_config_.size() == 2);
201 video_decoder_config_.pop_front();
202 }
203 config_changed_ = false;
204 base::ResetAndReturn(&read_complete_callback_).Run(status, nullptr);
205 return;
206 case DemuxerStream::kAborted:
207 base::ResetAndReturn(&read_complete_callback_).Run(status, nullptr);
208 return;
209 case DemuxerStream::kOk:
210 DCHECK(!buffers_.empty());
211 scoped_refptr<DecoderBuffer> frame_data = buffers_.front();
212 buffers_.pop_front();
213 base::ResetAndReturn(&read_complete_callback_).Run(status, frame_data);
214 return;
215 }
216 }
217
218 AudioDecoderConfig RemoteMediaStream::audio_decoder_config() {
219 DVLOG(3) << __func__;
220 DCHECK(type_ == DemuxerStream::AUDIO);
221 DCHECK(!audio_decoder_config_.empty());
222 return audio_decoder_config_.front();
223 }
224
225 VideoDecoderConfig RemoteMediaStream::video_decoder_config() {
226 DVLOG(3) << __func__;
227 DCHECK(type_ == DemuxerStream::VIDEO);
228 DCHECK(!video_decoder_config_.empty());
229 return video_decoder_config_.front();
230 }
231
232 DemuxerStream::Type RemoteMediaStream::type() const {
233 return type_;
234 }
235
236 bool RemoteMediaStream::SupportsConfigChanges() {
237 return true;
238 }
239
240 VideoRotation RemoteMediaStream::video_rotation() {
241 return VideoRotation::VIDEO_ROTATION_0;
242 }
243
244 bool RemoteMediaStream::enabled() const {
245 return true;
246 }
247
248 void RemoteMediaStream::AppendBuffer(scoped_refptr<DecoderBuffer> buffer) {
249 DVLOG(3) << __func__;
250 buffers_.push_back(buffer);
251 if (!read_complete_callback_.is_null())
252 CompleteRead(DemuxerStream::kOk);
253 }
254
255 RemoteStreamProvider::RemoteStreamProvider(RpcBroker* rpc_broker)
256 : rpc_broker_(rpc_broker), weak_factory_(this) {}
257
258 RemoteStreamProvider::~RemoteStreamProvider() {}
259
260 void RemoteStreamProvider::Initialize(int remote_audio_handle,
261 int remote_video_handle,
262 const base::Closure& callback) {
263 DVLOG(3) << __func__ << ": remote_audio_handle=" << remote_audio_handle
264 << " remote_video_handle=" << remote_video_handle;
265 DCHECK(init_done_callback_.is_null());
266 DCHECK(remote_audio_handle != RpcBroker::kInvalidHandle ||
267 remote_video_handle != RpcBroker::kInvalidHandle);
268
269 init_done_callback_ = callback;
270 if (remote_audio_handle != RpcBroker::kInvalidHandle) {
271 audio_stream_.reset(new RemoteMediaStream(rpc_broker_, DemuxerStream::AUDIO,
272 remote_audio_handle));
273 audio_stream_->Initialize(
274 base::Bind(&RemoteStreamProvider::AudioStreamInitialized,
275 weak_factory_.GetWeakPtr()));
276 }
277 if (remote_video_handle != RpcBroker::kInvalidHandle) {
278 video_stream_.reset(new RemoteMediaStream(rpc_broker_, DemuxerStream::VIDEO,
279 remote_video_handle));
280 video_stream_->Initialize(
281 base::Bind(&RemoteStreamProvider::VideoStreamInitialized,
282 weak_factory_.GetWeakPtr()));
283 }
284 }
285
286 void RemoteStreamProvider::AudioStreamInitialized() {
287 DCHECK(!init_done_callback_.is_null());
288 audio_stream_initialized_ = true;
289 if (video_stream_initialized_ || !video_stream_)
290 base::ResetAndReturn(&init_done_callback_).Run();
291 }
292
293 void RemoteStreamProvider::VideoStreamInitialized() {
294 DCHECK(!init_done_callback_.is_null());
295 video_stream_initialized_ = true;
296 if (audio_stream_initialized_ || !audio_stream_)
297 base::ResetAndReturn(&init_done_callback_).Run();
298 }
299
300 DemuxerStream* RemoteStreamProvider::GetStream(DemuxerStream::Type type) {
301 if (type == DemuxerStream::AUDIO)
302 return audio_stream_.get();
303 else if (type == DemuxerStream::VIDEO)
304 return video_stream_.get();
305 else
306 VLOG(1) << __func__ << ": Only supports video or audio stream.";
307 return nullptr;
308 }
309
310 void RemoteStreamProvider::AppendBuffer(DemuxerStream::Type type,
311 scoped_refptr<DecoderBuffer> buffer) {
312 if (type == DemuxerStream::AUDIO)
313 audio_stream_->AppendBuffer(buffer);
314 else if (type == DemuxerStream::VIDEO)
315 video_stream_->AppendBuffer(buffer);
316 else
317 VLOG(1) << __func__ << ": Only supports video or audio stream.";
318 }
319
320 void RemoteStreamProvider::FlushUntil(DemuxerStream::Type type, int count) {
321 DVLOG(3) << __func__ << ": type=" << type << " count=" << count;
322 if (type == DemuxerStream::AUDIO)
323 audio_stream_->FlushUntil(count);
324 else if (type == DemuxerStream::VIDEO)
325 video_stream_->FlushUntil(count);
326 else
327 VLOG(1) << __func__ << ": Only supports video or audio stream.";
328 }
329
330 } // namespace remoting
331 } // namespace media
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698