| OLD | NEW |
| 1 // Copyright 2015 The Chromium Authors. All rights reserved. | 1 // Copyright 2015 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 <memory> | 5 #include <memory> |
| 6 | 6 |
| 7 #include "mojo/public/c/system/main.h" | 7 #include "mojo/public/c/system/main.h" |
| 8 #include "mojo/public/cpp/application/application_impl_base.h" | 8 #include "mojo/public/cpp/application/application_impl_base.h" |
| 9 #include "mojo/public/cpp/application/connect.h" | 9 #include "mojo/public/cpp/application/connect.h" |
| 10 #include "mojo/public/cpp/application/run_application.h" | 10 #include "mojo/public/cpp/application/run_application.h" |
| 11 #include "mojo/public/cpp/system/data_pipe.h" | 11 #include "mojo/public/cpp/system/data_pipe.h" |
| 12 #include "mojo/public/cpp/system/wait.h" | 12 #include "mojo/public/cpp/system/wait.h" |
| 13 #include "mojo/public/cpp/utility/run_loop.h" | 13 #include "mojo/public/cpp/utility/run_loop.h" |
| 14 #include "mojo/services/media/audio/interfaces/audio_server.mojom.h" | 14 #include "mojo/services/media/audio/interfaces/audio_server.mojom.h" |
| 15 #include "mojo/services/media/audio/interfaces/audio_track.mojom.h" | 15 #include "mojo/services/media/audio/interfaces/audio_track.mojom.h" |
| 16 #include "mojo/services/media/common/cpp/circular_buffer_media_pipe_adapter.h" | 16 #include "mojo/services/media/common/cpp/circular_buffer_media_pipe_adapter.h" |
| 17 #include "mojo/services/media/common/cpp/linear_transform.h" | 17 #include "mojo/services/media/common/cpp/linear_transform.h" |
| 18 #include "mojo/services/media/common/cpp/local_time.h" | 18 #include "mojo/services/media/common/cpp/local_time.h" |
| 19 #include "mojo/services/media/core/interfaces/media_renderer.mojom.h" |
| 19 #include "mojo/services/network/interfaces/network_service.mojom.h" | 20 #include "mojo/services/network/interfaces/network_service.mojom.h" |
| 20 #include "mojo/services/network/interfaces/url_loader.mojom.h" | 21 #include "mojo/services/network/interfaces/url_loader.mojom.h" |
| 21 | 22 |
| 22 #define PACKED __attribute__((packed)) | 23 #define PACKED __attribute__((packed)) |
| 23 | 24 |
| 24 static inline constexpr uint32_t make_fourcc(uint8_t a, uint8_t b, | 25 static inline constexpr uint32_t make_fourcc(uint8_t a, uint8_t b, |
| 25 uint8_t c, uint8_t d) { | 26 uint8_t c, uint8_t d) { |
| 26 return (static_cast<uint32_t>(a) << 24) | | 27 return (static_cast<uint32_t>(a) << 24) | |
| 27 (static_cast<uint32_t>(b) << 16) | | 28 (static_cast<uint32_t>(b) << 16) | |
| 28 (static_cast<uint32_t>(c) << 8) | | 29 (static_cast<uint32_t>(c) << 8) | |
| (...skipping 90 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 119 | 120 |
| 120 MOJO_DCHECK(wav_info_.frame_size); | 121 MOJO_DCHECK(wav_info_.frame_size); |
| 121 MOJO_DCHECK(frames < | 122 MOJO_DCHECK(frames < |
| 122 std::numeric_limits<uint32_t>::max() / wav_info_.frame_size); | 123 std::numeric_limits<uint32_t>::max() / wav_info_.frame_size); |
| 123 | 124 |
| 124 return frames * wav_info_.frame_size; | 125 return frames * wav_info_.frame_size; |
| 125 } | 126 } |
| 126 | 127 |
| 127 AudioServerPtr audio_server_; | 128 AudioServerPtr audio_server_; |
| 128 AudioTrackPtr audio_track_; | 129 AudioTrackPtr audio_track_; |
| 130 MediaRendererPtr media_renderer_; |
| 129 AudioPipePtr audio_pipe_; | 131 AudioPipePtr audio_pipe_; |
| 130 TimelineConsumerPtr timeline_consumer_; | 132 TimelineConsumerPtr timeline_consumer_; |
| 131 AudioPacket audio_packet_; | 133 AudioPacket audio_packet_; |
| 132 PacketCbk playout_complete_cbk_; | 134 PacketCbk playout_complete_cbk_; |
| 133 NetworkServicePtr network_service_; | 135 NetworkServicePtr network_service_; |
| 134 URLLoaderPtr url_loader_; | 136 URLLoaderPtr url_loader_; |
| 135 ScopedDataPipeConsumerHandle payload_; | 137 ScopedDataPipeConsumerHandle payload_; |
| 136 uint32_t payload_len_; | 138 uint32_t payload_len_; |
| 137 RIFFChunkHeader riff_hdr_; | 139 RIFFChunkHeader riff_hdr_; |
| 138 WAVHeader wav_info_; | 140 WAVHeader wav_info_; |
| (...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 190 MOJO_DCHECK(audio_pipe_); | 192 MOJO_DCHECK(audio_pipe_); |
| 191 audio_pipe_->CancelMediaPacket(&audio_packet_); | 193 audio_pipe_->CancelMediaPacket(&audio_packet_); |
| 192 } | 194 } |
| 193 | 195 |
| 194 payload_.reset(); | 196 payload_.reset(); |
| 195 url_loader_.reset(); | 197 url_loader_.reset(); |
| 196 network_service_.reset(); | 198 network_service_.reset(); |
| 197 audio_pipe_.reset(); | 199 audio_pipe_.reset(); |
| 198 timeline_consumer_.reset(); | 200 timeline_consumer_.reset(); |
| 199 audio_track_.reset(); | 201 audio_track_.reset(); |
| 202 media_renderer_.reset(); |
| 200 audio_server_.reset(); | 203 audio_server_.reset(); |
| 201 } | 204 } |
| 202 | 205 |
| 203 bool PlayWAVApp::BlockingRead(void* buf, uint32_t op_len) { | 206 bool PlayWAVApp::BlockingRead(void* buf, uint32_t op_len) { |
| 204 MojoResult res; | 207 MojoResult res; |
| 205 uint32_t amt; | 208 uint32_t amt; |
| 206 | 209 |
| 207 while (true) { | 210 while (true) { |
| 208 amt = op_len; | 211 amt = op_len; |
| 209 res = ReadDataRaw(payload_.get(), buf, &amt, | 212 res = ReadDataRaw(payload_.get(), buf, &amt, |
| (...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 244 } | 247 } |
| 245 | 248 |
| 246 MOJO_LOG(INFO) << "Preparing to play..."; | 249 MOJO_LOG(INFO) << "Preparing to play..."; |
| 247 MOJO_LOG(INFO) << "File : " << TEST_FILE; | 250 MOJO_LOG(INFO) << "File : " << TEST_FILE; |
| 248 MOJO_LOG(INFO) << "Rate : " << wav_info_.frame_rate; | 251 MOJO_LOG(INFO) << "Rate : " << wav_info_.frame_rate; |
| 249 MOJO_LOG(INFO) << "Chan : " << wav_info_.channel_count; | 252 MOJO_LOG(INFO) << "Chan : " << wav_info_.channel_count; |
| 250 MOJO_LOG(INFO) << "BPS : " << wav_info_.bits_per_sample; | 253 MOJO_LOG(INFO) << "BPS : " << wav_info_.bits_per_sample; |
| 251 | 254 |
| 252 // Create the audio sink we will use to play this WAV file and start to | 255 // Create the audio sink we will use to play this WAV file and start to |
| 253 // configure it. | 256 // configure it. |
| 254 audio_server_->CreateTrack(GetProxy(&audio_track_)); | 257 audio_server_->CreateTrack( |
| 258 GetProxy(&audio_track_), GetProxy(&media_renderer_)); |
| 255 | 259 |
| 256 // TODO(johngro): when there is some better diagnostic information made | 260 // TODO(johngro): when there is some better diagnostic information made |
| 257 // available to us, make sure that we log it so we have some way to proceed | 261 // available to us, make sure that we log it so we have some way to proceed |
| 258 // with debugging. | 262 // with debugging. |
| 259 audio_track_.set_connection_error_handler([this]() { | 263 audio_track_.set_connection_error_handler([this]() { |
| 260 OnConnectionError("audio_track"); | 264 OnConnectionError("audio_track"); |
| 261 }); | 265 }); |
| 262 | 266 media_renderer_.set_connection_error_handler([this]() { |
| 263 LinearTransform::Ratio audio_rate(wav_info_.frame_rate, 1); | 267 OnConnectionError("media_renderer"); |
| 264 LinearTransform::Ratio local_rate(LocalDuration::period::num, | 268 }); |
| 265 LocalDuration::period::den); | |
| 266 LinearTransform::Ratio tmp; | |
| 267 bool success = LinearTransform::Ratio::Compose(audio_rate, local_rate, &tmp); | |
| 268 MOJO_DCHECK(success); | |
| 269 | |
| 270 AudioTrackConfigurationPtr cfg; | |
| 271 cfg = AudioTrackConfiguration::New(); | |
| 272 cfg->audio_frame_ratio = tmp.numerator; | |
| 273 cfg->media_time_ratio = tmp.denominator; | |
| 274 | 269 |
| 275 AudioMediaTypeDetailsPtr pcm_cfg = AudioMediaTypeDetails::New(); | 270 AudioMediaTypeDetailsPtr pcm_cfg = AudioMediaTypeDetails::New(); |
| 276 pcm_cfg->sample_format = (wav_info_.bits_per_sample == 8) | 271 pcm_cfg->sample_format = (wav_info_.bits_per_sample == 8) |
| 277 ? AudioSampleFormat::UNSIGNED_8 | 272 ? AudioSampleFormat::UNSIGNED_8 |
| 278 : AudioSampleFormat::SIGNED_16; | 273 : AudioSampleFormat::SIGNED_16; |
| 279 pcm_cfg->channels = wav_info_.channel_count; | 274 pcm_cfg->channels = wav_info_.channel_count; |
| 280 pcm_cfg->frames_per_second = wav_info_.frame_rate; | 275 pcm_cfg->frames_per_second = wav_info_.frame_rate; |
| 281 | 276 |
| 282 cfg->media_type = MediaType::New(); | 277 MediaTypePtr media_type = MediaType::New(); |
| 283 cfg->media_type->medium = MediaTypeMedium::AUDIO; | 278 media_type->medium = MediaTypeMedium::AUDIO; |
| 284 cfg->media_type->details = MediaTypeDetails::New(); | 279 media_type->details = MediaTypeDetails::New(); |
| 285 cfg->media_type->details->set_audio(pcm_cfg.Pass()); | 280 media_type->details->set_audio(pcm_cfg.Pass()); |
| 286 cfg->media_type->encoding = MediaType::kAudioEncodingLpcm; | 281 media_type->encoding = MediaType::kAudioEncodingLpcm; |
| 287 | 282 |
| 288 // Configure the track based on the WAV header information. | 283 // Configure the track based on the WAV header information. |
| 284 media_renderer_->SetMediaType(media_type.Pass()); |
| 289 MediaConsumerPtr media_pipe; | 285 MediaConsumerPtr media_pipe; |
| 290 audio_track_->Configure(cfg.Pass(), GetProxy(&media_pipe)); | 286 media_renderer_->GetConsumer(GetProxy(&media_pipe)); |
| 291 | 287 |
| 292 // Grab the timeline consumer interface for our audio renderer. | 288 // Grab the timeline consumer interface for our audio renderer. |
| 293 MediaTimelineControlSitePtr timeline_control_site; | 289 MediaTimelineControlSitePtr timeline_control_site; |
| 294 audio_track_->GetTimelineControlSite(GetProxy(&timeline_control_site)); | 290 media_renderer_->GetTimelineControlSite(GetProxy(&timeline_control_site)); |
| 295 timeline_control_site->GetTimelineConsumer(GetProxy(&timeline_consumer_)); | 291 timeline_control_site->GetTimelineConsumer(GetProxy(&timeline_consumer_)); |
| 296 timeline_consumer_.set_connection_error_handler( | 292 timeline_consumer_.set_connection_error_handler( |
| 297 [this]() { OnConnectionError("timeline_consumer"); }); | 293 [this]() { OnConnectionError("timeline_consumer"); }); |
| 298 | 294 |
| 299 // Set up our media pipe helper, configure its callback and water marks to | 295 // Set up our media pipe helper, configure its callback and water marks to |
| 300 // kick off the playback process. | 296 // kick off the playback process. |
| 301 audio_pipe_.reset(new CircularBufferMediaPipeAdapter(media_pipe.Pass())); | 297 audio_pipe_.reset(new CircularBufferMediaPipeAdapter(media_pipe.Pass())); |
| 302 audio_pipe_->Init(USecToBytes(BUF_DEPTH_USEC)); | 298 audio_pipe_->Init(USecToBytes(BUF_DEPTH_USEC)); |
| 303 audio_pipe_->SetWatermarks(USecToBytes(BUF_HI_WATER_USEC), | 299 audio_pipe_->SetWatermarks(USecToBytes(BUF_HI_WATER_USEC), |
| 304 USecToBytes(BUF_LO_WATER_USEC)); | 300 USecToBytes(BUF_LO_WATER_USEC)); |
| (...skipping 247 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 552 | 548 |
| 553 } // namespace examples | 549 } // namespace examples |
| 554 } // namespace audio | 550 } // namespace audio |
| 555 } // namespace media | 551 } // namespace media |
| 556 } // namespace mojo | 552 } // namespace mojo |
| 557 | 553 |
| 558 MojoResult MojoMain(MojoHandle app_request) { | 554 MojoResult MojoMain(MojoHandle app_request) { |
| 559 mojo::media::audio::examples::PlayWAVApp play_wav_app; | 555 mojo::media::audio::examples::PlayWAVApp play_wav_app; |
| 560 return mojo::RunApplication(app_request, &play_wav_app); | 556 return mojo::RunApplication(app_request, &play_wav_app); |
| 561 } | 557 } |
| OLD | NEW |