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

Side by Side Diff: services/media/factory_service/media_sink_impl.cc

Issue 1822333002: Motown: wholesale clang-format (Closed) Base URL: https://github.com/domokit/mojo.git@master
Patch Set: dalesat Created 4 years, 9 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
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 #include "base/logging.h" 5 #include "base/logging.h"
6 #include "mojo/services/media/common/cpp/linear_transform.h" 6 #include "mojo/services/media/common/cpp/linear_transform.h"
7 #include "mojo/services/media/common/cpp/local_time.h" 7 #include "mojo/services/media/common/cpp/local_time.h"
8 #include "services/media/factory_service/media_sink_impl.h" 8 #include "services/media/factory_service/media_sink_impl.h"
9 #include "services/media/framework/conversion_pipeline_builder.h" 9 #include "services/media/framework/conversion_pipeline_builder.h"
10 #include "services/media/framework_mojo/mojo_type_conversions.h" 10 #include "services/media/framework_mojo/mojo_type_conversions.h"
11 11
12 namespace mojo { 12 namespace mojo {
13 namespace media { 13 namespace media {
14 14
15 // static 15 // static
16 std::shared_ptr<MediaSinkImpl> MediaSinkImpl::Create( 16 std::shared_ptr<MediaSinkImpl> MediaSinkImpl::Create(
17 const String& destination_url, 17 const String& destination_url,
18 MediaTypePtr media_type, 18 MediaTypePtr media_type,
19 InterfaceRequest<MediaSink> request, 19 InterfaceRequest<MediaSink> request,
20 MediaFactoryService* owner) { 20 MediaFactoryService* owner) {
21 return std::shared_ptr<MediaSinkImpl>(new MediaSinkImpl( 21 return std::shared_ptr<MediaSinkImpl>(new MediaSinkImpl(
22 destination_url, 22 destination_url, media_type.Pass(), request.Pass(), owner));
23 media_type.Pass(),
24 request.Pass(),
25 owner));
26 } 23 }
27 24
28 MediaSinkImpl::MediaSinkImpl( 25 MediaSinkImpl::MediaSinkImpl(const String& destination_url,
29 const String& destination_url, 26 MediaTypePtr media_type,
30 MediaTypePtr media_type, 27 InterfaceRequest<MediaSink> request,
31 InterfaceRequest<MediaSink> request, 28 MediaFactoryService* owner)
32 MediaFactoryService* owner)
33 : MediaFactoryService::Product(owner), 29 : MediaFactoryService::Product(owner),
34 binding_(this, request.Pass()), 30 binding_(this, request.Pass()),
35 consumer_(MojoConsumer::Create()), 31 consumer_(MojoConsumer::Create()),
36 producer_(MojoProducer::Create()) { 32 producer_(MojoProducer::Create()) {
37 DCHECK(destination_url); 33 DCHECK(destination_url);
38 DCHECK(media_type); 34 DCHECK(media_type);
39 35
40 // Go away when the client is no longer connected. 36 // Go away when the client is no longer connected.
41 binding_.set_connection_error_handler([this]() { 37 binding_.set_connection_error_handler([this]() { ReleaseFromOwner(); });
42 ReleaseFromOwner();
43 });
44 38
45 // TODO(dalesat): Support file and network urls. 39 // TODO(dalesat): Support file and network urls.
46 // TODO(dalesat): Support mojo services in a reasonable way. 40 // TODO(dalesat): Support mojo services in a reasonable way.
47 41
48 PartRef consumer_ref = graph_.Add(consumer_); 42 PartRef consumer_ref = graph_.Add(consumer_);
49 PartRef producer_ref = graph_.Add(producer_); 43 PartRef producer_ref = graph_.Add(producer_);
50 44
51 consumer_->SetPrimeRequestedCallback( 45 consumer_->SetPrimeRequestedCallback(
52 [this](const MediaConsumer::PrimeCallback& callback) { 46 [this](const MediaConsumer::PrimeCallback& callback) {
53 ready_.When([this, callback]() { 47 ready_.When([this, callback]() {
54 DCHECK(producer_); 48 DCHECK(producer_);
55 producer_->PrimeConnection(callback); 49 producer_->PrimeConnection(callback);
56 }); 50 });
57 }); 51 });
58 consumer_->SetFlushRequestedCallback( 52 consumer_->SetFlushRequestedCallback(
59 [this, consumer_ref](const MediaConsumer::FlushCallback& callback) { 53 [this, consumer_ref](const MediaConsumer::FlushCallback& callback) {
60 ready_.When([this, consumer_ref, callback]() { 54 ready_.When([this, consumer_ref, callback]() {
61 DCHECK(producer_); 55 DCHECK(producer_);
62 graph_.FlushOutput(consumer_ref.output()); 56 graph_.FlushOutput(consumer_ref.output());
63 producer_->FlushConnection(callback); 57 producer_->FlushConnection(callback);
64 flushed_ = true; 58 flushed_ = true;
65 }); 59 });
66 }); 60 });
67 61
68 producer_->SetStatusCallback( 62 producer_->SetStatusCallback([this](MediaState state) {
69 [this](MediaState state) { 63 producer_state_ = state;
70 producer_state_ = state; 64 StatusUpdated();
71 StatusUpdated(); 65 if (state == MediaState::ENDED) {
72 if (state == MediaState::ENDED) { 66 Pause();
73 Pause(); 67 }
74 } 68 });
75 });
76 69
77 if (destination_url != "mojo:audio_server") { 70 if (destination_url != "mojo:audio_server") {
78 LOG(ERROR) << "mojo:audio_server is the only supported destination"; 71 LOG(ERROR) << "mojo:audio_server is the only supported destination";
79 if (binding_.is_bound()) { 72 if (binding_.is_bound()) {
80 binding_.Close(); 73 binding_.Close();
81 } 74 }
82 return; 75 return;
83 } 76 }
84 77
85 // TODO(dalesat): Once we have c++14, get rid of this shared pointer hack. 78 // TODO(dalesat): Once we have c++14, get rid of this shared pointer hack.
86 std::shared_ptr<StreamType> 79 std::shared_ptr<StreamType> captured_stream_type(
87 captured_stream_type(Convert(media_type).release()); 80 Convert(media_type).release());
88 81
89 // An AudioTrackController knows how to talk to an audio track, interrogating 82 // An AudioTrackController knows how to talk to an audio track, interrogating
90 // it for supported stream types and configuring it for the chosen stream 83 // it for supported stream types and configuring it for the chosen stream
91 // type. 84 // type.
92 controller_.reset(new AudioTrackController(destination_url, app())); 85 controller_.reset(new AudioTrackController(destination_url, app()));
93 86
94 controller_->GetSupportedMediaTypes( 87 controller_->GetSupportedMediaTypes([this, consumer_ref, producer_ref,
95 [this, consumer_ref, producer_ref, captured_stream_type] 88 captured_stream_type](
96 (std::unique_ptr<std::vector<std::unique_ptr<StreamTypeSet>>> 89 std::unique_ptr<std::vector<std::unique_ptr<StreamTypeSet>>>
97 supported_stream_types) { 90 supported_stream_types) {
98 std::unique_ptr<StreamType> producer_stream_type; 91 std::unique_ptr<StreamType> producer_stream_type;
99 92
100 // Add transforms to the pipeline to convert from stream_type to a 93 // Add transforms to the pipeline to convert from stream_type to a
101 // type supported by the track. 94 // type supported by the track.
102 OutputRef out = consumer_ref.output(); 95 OutputRef out = consumer_ref.output();
103 bool result = BuildConversionPipeline( 96 bool result =
104 *captured_stream_type, 97 BuildConversionPipeline(*captured_stream_type, *supported_stream_types,
105 *supported_stream_types, 98 &graph_, &out, &producer_stream_type);
106 &graph_, 99 if (!result) {
107 &out, 100 // Failed to build conversion pipeline.
108 &producer_stream_type); 101 producer_state_ = MediaState::FAULT;
109 if (!result) { 102 StatusUpdated();
110 // Failed to build conversion pipeline. 103 return;
111 producer_state_ = MediaState::FAULT; 104 }
112 StatusUpdated();
113 return;
114 }
115 105
116 graph_.ConnectOutputToPart(out, producer_ref); 106 graph_.ConnectOutputToPart(out, producer_ref);
117 107
118 switch (producer_stream_type->scheme()) { 108 switch (producer_stream_type->scheme()) {
119 case StreamType::Scheme::kLpcm: 109 case StreamType::Scheme::kLpcm:
120 frames_per_second_ = 110 frames_per_second_ = producer_stream_type->lpcm()->frames_per_second();
121 producer_stream_type->lpcm()->frames_per_second(); 111 break;
122 break; 112 case StreamType::Scheme::kCompressedAudio:
123 case StreamType::Scheme::kCompressedAudio: 113 frames_per_second_ =
124 frames_per_second_ = 114 producer_stream_type->compressed_audio()->frames_per_second();
125 producer_stream_type->compressed_audio()->frames_per_second(); 115 break;
126 break; 116 default:
127 default: 117 // Unsupported producer stream type.
128 // Unsupported producer stream type. 118 producer_state_ = MediaState::FAULT;
129 producer_state_ = MediaState::FAULT; 119 StatusUpdated();
130 StatusUpdated(); 120 return;
131 return; 121 }
132 }
133 122
134 controller_->Configure( 123 controller_->Configure(
135 std::move(producer_stream_type), 124 std::move(producer_stream_type),
136 [this] 125 [this](MediaConsumerPtr consumer, RateControlPtr rate_control) {
137 (MediaConsumerPtr consumer, RateControlPtr rate_control) { 126 DCHECK(consumer);
138 DCHECK(consumer); 127 DCHECK(rate_control);
139 DCHECK(rate_control); 128 rate_control_ = rate_control.Pass();
140 rate_control_ = rate_control.Pass(); 129 producer_->Connect(consumer.Pass(), [this]() {
141 producer_->Connect(consumer.Pass(), [this]() { 130 graph_.Prepare();
142 graph_.Prepare(); 131 ready_.Occur();
143 ready_.Occur(); 132 MaybeSetRate();
144 MaybeSetRate(); 133 });
145 }); 134 });
146 }); 135 });
147 });
148 } 136 }
149 137
150 MediaSinkImpl::~MediaSinkImpl() {} 138 MediaSinkImpl::~MediaSinkImpl() {}
151 139
152 void MediaSinkImpl::GetClockDisposition( 140 void MediaSinkImpl::GetClockDisposition(
153 const GetClockDispositionCallback& callback) { 141 const GetClockDispositionCallback& callback) {
154 callback.Run(ClockDisposition::PREFER_MASTER); 142 callback.Run(ClockDisposition::PREFER_MASTER);
155 // TODO(dalesat): Varies by destination type. 143 // TODO(dalesat): Varies by destination type.
156 } 144 }
157 145
158 void MediaSinkImpl::GetMasterClock(InterfaceRequest<Clock> master_clock) { 146 void MediaSinkImpl::GetMasterClock(InterfaceRequest<Clock> master_clock) {
159 // TODO(dalesat): Produce master clock as appropriate. 147 // TODO(dalesat): Produce master clock as appropriate.
160 } 148 }
161 149
162 void MediaSinkImpl::SetMasterClock(InterfaceHandle<Clock> master_clock) { 150 void MediaSinkImpl::SetMasterClock(InterfaceHandle<Clock> master_clock) {
163 // TODO(dalesat): Accept master clock and arrange for synchronization. 151 // TODO(dalesat): Accept master clock and arrange for synchronization.
164 } 152 }
165 153
166 void MediaSinkImpl::GetConsumer(InterfaceRequest<MediaConsumer> consumer) { 154 void MediaSinkImpl::GetConsumer(InterfaceRequest<MediaConsumer> consumer) {
167 consumer_->AddBinding(consumer.Pass()); 155 consumer_->AddBinding(consumer.Pass());
168 } 156 }
169 157
170 void MediaSinkImpl::GetStatus( 158 void MediaSinkImpl::GetStatus(uint64_t version_last_seen,
171 uint64_t version_last_seen, 159 const GetStatusCallback& callback) {
172 const GetStatusCallback& callback) {
173 if (version_last_seen < status_version_) { 160 if (version_last_seen < status_version_) {
174 RunStatusCallback(callback); 161 RunStatusCallback(callback);
175 } else { 162 } else {
176 pending_status_requests_.push_back(callback); 163 pending_status_requests_.push_back(callback);
177 } 164 }
178 } 165 }
179 166
180 void MediaSinkImpl::Play() { 167 void MediaSinkImpl::Play() {
181 target_rate_ = 1.0; 168 target_rate_ = 1.0;
182 MaybeSetRate(); 169 MaybeSetRate();
183 } 170 }
184 171
185 void MediaSinkImpl::Pause() { 172 void MediaSinkImpl::Pause() {
186 target_rate_ = 0.0; 173 target_rate_ = 0.0;
187 MaybeSetRate(); 174 MaybeSetRate();
188 } 175 }
189 176
190 void MediaSinkImpl::StatusUpdated() { 177 void MediaSinkImpl::StatusUpdated() {
191 ++status_version_; 178 ++status_version_;
192 while (!pending_status_requests_.empty()) { 179 while (!pending_status_requests_.empty()) {
193 RunStatusCallback(pending_status_requests_.front()); 180 RunStatusCallback(pending_status_requests_.front());
194 pending_status_requests_.pop_front(); 181 pending_status_requests_.pop_front();
195 } 182 }
196 } 183 }
197 184
198 void MediaSinkImpl::RunStatusCallback(const GetStatusCallback& callback) const { 185 void MediaSinkImpl::RunStatusCallback(const GetStatusCallback& callback) const {
199 MediaSinkStatusPtr status = MediaSinkStatus::New(); 186 MediaSinkStatusPtr status = MediaSinkStatus::New();
200 status->state = (producer_state_ == MediaState::PAUSED && rate_ != 0.0) ? 187 status->state = (producer_state_ == MediaState::PAUSED && rate_ != 0.0)
201 MediaState::PLAYING : 188 ? MediaState::PLAYING
202 producer_state_; 189 : producer_state_;
203 status->timeline_transform = status_transform_.Clone(); 190 status->timeline_transform = status_transform_.Clone();
204 callback.Run(status_version_, status.Pass()); 191 callback.Run(status_version_, status.Pass());
205 } 192 }
206 193
207 void MediaSinkImpl::MaybeSetRate() { 194 void MediaSinkImpl::MaybeSetRate() {
208 if (producer_state_ < MediaState::PAUSED || rate_ == target_rate_) { 195 if (producer_state_ < MediaState::PAUSED || rate_ == target_rate_) {
209 return; 196 return;
210 } 197 }
211 198
212 DCHECK(rate_control_); 199 DCHECK(rate_control_);
213 200
214 // Desired rate in frames per second. 201 // Desired rate in frames per second.
215 LinearTransform::Ratio rate_frames_per_second( 202 LinearTransform::Ratio rate_frames_per_second(
216 static_cast<uint32_t>(frames_per_second_ * target_rate_), 1); 203 static_cast<uint32_t>(frames_per_second_ * target_rate_), 1);
217 204
218 // Local time rate in seconds_per_tick. 205 // Local time rate in seconds_per_tick.
219 LinearTransform::Ratio local_seconds_per_tick( 206 LinearTransform::Ratio local_seconds_per_tick(LocalDuration::period::num,
220 LocalDuration::period::num, 207 LocalDuration::period::den);
221 LocalDuration::period::den);
222 208
223 // Desired rate in frames per local tick. 209 // Desired rate in frames per local tick.
224 LinearTransform::Ratio rate_frames_per_tick; 210 LinearTransform::Ratio rate_frames_per_tick;
225 bool success = 211 bool success = LinearTransform::Ratio::Compose(
226 LinearTransform::Ratio::Compose( 212 local_seconds_per_tick, rate_frames_per_second, &rate_frames_per_tick);
227 local_seconds_per_tick,
228 rate_frames_per_second,
229 &rate_frames_per_tick);
230 DCHECK(success) 213 DCHECK(success)
231 << "LinearTransform::Ratio::Compose reports loss of precision"; 214 << "LinearTransform::Ratio::Compose reports loss of precision";
232 215
233 // TODO(dalesat): start_local_time should be supplied via the mojo interface. 216 // TODO(dalesat): start_local_time should be supplied via the mojo interface.
234 // For now, it's hard-coded to be 30ms in the future. 217 // For now, it's hard-coded to be 30ms in the future.
235 // The local time when we want the rate to change. 218 // The local time when we want the rate to change.
236 int64_t start_local_time = 219 int64_t start_local_time =
237 (LocalClock::now().time_since_epoch() + std::chrono::milliseconds(30)). 220 (LocalClock::now().time_since_epoch() + std::chrono::milliseconds(30))
238 count(); 221 .count();
239 222
240 // The media time corresponding to start_local_time. 223 // The media time corresponding to start_local_time.
241 int64_t start_media_time; 224 int64_t start_media_time;
242 if (flushed_ && 225 if (flushed_ && producer_->GetFirstPtsSinceFlush() != Packet::kUnknownPts) {
243 producer_->GetFirstPtsSinceFlush() != Packet::kUnknownPts) {
244 // We're getting started initially or after a flush/prime, so the media 226 // We're getting started initially or after a flush/prime, so the media
245 // time corresponding to start_local_time should be the PTS of 227 // time corresponding to start_local_time should be the PTS of
246 // the first packet. 228 // the first packet.
247 start_media_time = producer_->GetFirstPtsSinceFlush(); 229 start_media_time = producer_->GetFirstPtsSinceFlush();
248 } else { 230 } else {
249 // We're resuming, so the media time corresponding to start_local_time can 231 // We're resuming, so the media time corresponding to start_local_time can
250 // be calculated using the existing transform. 232 // be calculated using the existing transform.
251 success = 233 success =
252 transform_.DoForwardTransform(start_local_time, &start_media_time); 234 transform_.DoForwardTransform(start_local_time, &start_media_time);
253 DCHECK(success) 235 DCHECK(success)
(...skipping 11 matching lines...) Expand all
265 rate_quad->reference_offset = start_media_time; 247 rate_quad->reference_offset = start_media_time;
266 rate_quad->target_offset = start_local_time; 248 rate_quad->target_offset = start_local_time;
267 rate_quad->reference_delta = rate_frames_per_tick.numerator; 249 rate_quad->reference_delta = rate_frames_per_tick.numerator;
268 rate_quad->target_delta = rate_frames_per_tick.denominator; 250 rate_quad->target_delta = rate_frames_per_tick.denominator;
269 251
270 rate_control_->SetCurrentQuad(rate_quad.Pass()); 252 rate_control_->SetCurrentQuad(rate_quad.Pass());
271 253
272 // Get the frame rate in frames per local tick. 254 // Get the frame rate in frames per local tick.
273 LinearTransform::Ratio frame_rate_frames_per_second(frames_per_second_, 1); 255 LinearTransform::Ratio frame_rate_frames_per_second(frames_per_second_, 1);
274 LinearTransform::Ratio frame_rate_frames_per_tick; 256 LinearTransform::Ratio frame_rate_frames_per_tick;
275 success = LinearTransform::Ratio::Compose( 257 success = LinearTransform::Ratio::Compose(local_seconds_per_tick,
276 local_seconds_per_tick, 258 frame_rate_frames_per_second,
277 frame_rate_frames_per_second, 259 &frame_rate_frames_per_tick);
278 &frame_rate_frames_per_tick);
279 DCHECK(success) 260 DCHECK(success)
280 << "LinearTransform::Ratio::Compose reports loss of precision"; 261 << "LinearTransform::Ratio::Compose reports loss of precision";
281 262
282 // Create a LinearTransform to translate from presentation units to 263 // Create a LinearTransform to translate from presentation units to
283 // local duration units. 264 // local duration units.
284 LinearTransform local_to_presentation(0, frame_rate_frames_per_tick, 0); 265 LinearTransform local_to_presentation(0, frame_rate_frames_per_tick, 0);
285 266
286 status_transform_ = TimelineTransform::New(); 267 status_transform_ = TimelineTransform::New();
287 status_transform_->quad = TimelineQuad::New(); 268 status_transform_->quad = TimelineQuad::New();
288 269
289 // Translate the current transform quad so the presentation time units 270 // Translate the current transform quad so the presentation time units
290 // are the same as the local time units. 271 // are the same as the local time units.
291 success = local_to_presentation.DoReverseTransform( 272 success = local_to_presentation.DoReverseTransform(
292 start_media_time, 273 start_media_time, &status_transform_->quad->reference_offset);
293 &status_transform_->quad->reference_offset);
294 DCHECK(success) 274 DCHECK(success)
295 << "LinearTransform::DoReverseTransform reports loss of precision"; 275 << "LinearTransform::DoReverseTransform reports loss of precision";
296 status_transform_->quad->target_offset = start_local_time; 276 status_transform_->quad->target_offset = start_local_time;
297 int64_t presentation_delta; 277 int64_t presentation_delta;
298 success = local_to_presentation.DoReverseTransform( 278 success = local_to_presentation.DoReverseTransform(
299 static_cast<int64_t>(rate_frames_per_tick.numerator), 279 static_cast<int64_t>(rate_frames_per_tick.numerator),
300 &presentation_delta); 280 &presentation_delta);
301 DCHECK(success) 281 DCHECK(success)
302 << "LinearTransform::DoReverseTransform reports loss of precision"; 282 << "LinearTransform::DoReverseTransform reports loss of precision";
303 status_transform_->quad->reference_delta = 283 status_transform_->quad->reference_delta =
304 static_cast<int32_t>(presentation_delta); 284 static_cast<int32_t>(presentation_delta);
305 status_transform_->quad->target_delta = rate_frames_per_tick.denominator; 285 status_transform_->quad->target_delta = rate_frames_per_tick.denominator;
306 LinearTransform::Ratio::Reduce( 286 LinearTransform::Ratio::Reduce(&status_transform_->quad->reference_delta,
307 &status_transform_->quad->reference_delta, 287 &status_transform_->quad->target_delta);
308 &status_transform_->quad->target_delta);
309 288
310 rate_ = target_rate_; 289 rate_ = target_rate_;
311 StatusUpdated(); 290 StatusUpdated();
312 } 291 }
313 292
314 } // namespace media 293 } // namespace media
315 } // namespace mojo 294 } // namespace mojo
OLDNEW
« no previous file with comments | « services/media/factory_service/media_sink_impl.h ('k') | services/media/factory_service/media_source_impl.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698