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

Side by Side Diff: media/renderers/audio_renderer_impl.cc

Issue 1955843002: Move Renderer permanent callbacks into RendererClient interface. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: addressed comments Created 4 years, 7 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
« no previous file with comments | « media/renderers/audio_renderer_impl.h ('k') | media/renderers/audio_renderer_impl_unittest.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2012 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 "media/renderers/audio_renderer_impl.h" 5 #include "media/renderers/audio_renderer_impl.h"
6 6
7 #include <math.h> 7 #include <math.h>
8 #include <stddef.h> 8 #include <stddef.h>
9 #include <algorithm> 9 #include <algorithm>
10 #include <utility> 10 #include <utility>
11 11
12 #include "base/bind.h" 12 #include "base/bind.h"
13 #include "base/callback.h" 13 #include "base/callback.h"
14 #include "base/callback_helpers.h" 14 #include "base/callback_helpers.h"
15 #include "base/command_line.h" 15 #include "base/command_line.h"
16 #include "base/logging.h" 16 #include "base/logging.h"
17 #include "base/single_thread_task_runner.h" 17 #include "base/single_thread_task_runner.h"
18 #include "base/time/default_tick_clock.h" 18 #include "base/time/default_tick_clock.h"
19 #include "build/build_config.h" 19 #include "build/build_config.h"
20 #include "media/base/audio_buffer.h" 20 #include "media/base/audio_buffer.h"
21 #include "media/base/audio_buffer_converter.h" 21 #include "media/base/audio_buffer_converter.h"
22 #include "media/base/audio_hardware_config.h" 22 #include "media/base/audio_hardware_config.h"
23 #include "media/base/audio_splicer.h" 23 #include "media/base/audio_splicer.h"
24 #include "media/base/bind_to_current_loop.h" 24 #include "media/base/bind_to_current_loop.h"
25 #include "media/base/demuxer_stream.h" 25 #include "media/base/demuxer_stream.h"
26 #include "media/base/media_log.h" 26 #include "media/base/media_log.h"
27 #include "media/base/media_switches.h" 27 #include "media/base/media_switches.h"
28 #include "media/base/renderer_client.h"
28 #include "media/base/timestamp_constants.h" 29 #include "media/base/timestamp_constants.h"
29 #include "media/filters/audio_clock.h" 30 #include "media/filters/audio_clock.h"
30 #include "media/filters/decrypting_demuxer_stream.h" 31 #include "media/filters/decrypting_demuxer_stream.h"
31 32
32 namespace media { 33 namespace media {
33 34
34 AudioRendererImpl::AudioRendererImpl( 35 AudioRendererImpl::AudioRendererImpl(
35 const scoped_refptr<base::SingleThreadTaskRunner>& task_runner, 36 const scoped_refptr<base::SingleThreadTaskRunner>& task_runner,
36 media::AudioRendererSink* sink, 37 media::AudioRendererSink* sink,
37 ScopedVector<AudioDecoder> decoders, 38 ScopedVector<AudioDecoder> decoders,
38 const AudioHardwareConfig& hardware_config, 39 const AudioHardwareConfig& hardware_config,
39 const scoped_refptr<MediaLog>& media_log) 40 const scoped_refptr<MediaLog>& media_log)
40 : task_runner_(task_runner), 41 : task_runner_(task_runner),
41 expecting_config_changes_(false), 42 expecting_config_changes_(false),
42 sink_(sink), 43 sink_(sink),
43 audio_buffer_stream_( 44 audio_buffer_stream_(
44 new AudioBufferStream(task_runner, std::move(decoders), media_log)), 45 new AudioBufferStream(task_runner, std::move(decoders), media_log)),
45 hardware_config_(hardware_config), 46 hardware_config_(hardware_config),
46 media_log_(media_log), 47 media_log_(media_log),
48 client_(nullptr),
47 tick_clock_(new base::DefaultTickClock()), 49 tick_clock_(new base::DefaultTickClock()),
48 last_audio_memory_usage_(0), 50 last_audio_memory_usage_(0),
49 last_decoded_sample_rate_(0), 51 last_decoded_sample_rate_(0),
50 playback_rate_(0.0), 52 playback_rate_(0.0),
51 state_(kUninitialized), 53 state_(kUninitialized),
52 buffering_state_(BUFFERING_HAVE_NOTHING), 54 buffering_state_(BUFFERING_HAVE_NOTHING),
53 rendering_(false), 55 rendering_(false),
54 sink_playing_(false), 56 sink_playing_(false),
55 pending_read_(false), 57 pending_read_(false),
56 received_end_of_stream_(false), 58 received_end_of_stream_(false),
(...skipping 247 matching lines...) Expand 10 before | Expand all | Expand 10 after
304 base::AutoLock auto_lock(lock_); 306 base::AutoLock auto_lock(lock_);
305 DCHECK(!sink_playing_); 307 DCHECK(!sink_playing_);
306 DCHECK_EQ(state_, kFlushed); 308 DCHECK_EQ(state_, kFlushed);
307 DCHECK_EQ(buffering_state_, BUFFERING_HAVE_NOTHING); 309 DCHECK_EQ(buffering_state_, BUFFERING_HAVE_NOTHING);
308 DCHECK(!pending_read_) << "Pending read must complete before seeking"; 310 DCHECK(!pending_read_) << "Pending read must complete before seeking";
309 311
310 ChangeState_Locked(kPlaying); 312 ChangeState_Locked(kPlaying);
311 AttemptRead_Locked(); 313 AttemptRead_Locked();
312 } 314 }
313 315
314 void AudioRendererImpl::Initialize( 316 void AudioRendererImpl::Initialize(DemuxerStream* stream,
315 DemuxerStream* stream, 317 CdmContext* cdm_context,
316 const PipelineStatusCB& init_cb, 318 RendererClient* client,
317 CdmContext* cdm_context, 319 const PipelineStatusCB& init_cb) {
318 const StatisticsCB& statistics_cb,
319 const BufferingStateCB& buffering_state_cb,
320 const base::Closure& ended_cb,
321 const PipelineStatusCB& error_cb,
322 const base::Closure& waiting_for_decryption_key_cb) {
323 DVLOG(1) << __FUNCTION__; 320 DVLOG(1) << __FUNCTION__;
324 DCHECK(task_runner_->BelongsToCurrentThread()); 321 DCHECK(task_runner_->BelongsToCurrentThread());
322 DCHECK(client);
325 DCHECK(stream); 323 DCHECK(stream);
326 DCHECK_EQ(stream->type(), DemuxerStream::AUDIO); 324 DCHECK_EQ(stream->type(), DemuxerStream::AUDIO);
327 DCHECK(!init_cb.is_null()); 325 DCHECK(!init_cb.is_null());
328 DCHECK(!statistics_cb.is_null());
329 DCHECK(!buffering_state_cb.is_null());
330 DCHECK(!ended_cb.is_null());
331 DCHECK(!error_cb.is_null());
332 DCHECK_EQ(kUninitialized, state_); 326 DCHECK_EQ(kUninitialized, state_);
333 DCHECK(sink_.get()); 327 DCHECK(sink_.get());
334 328
335 state_ = kInitializing; 329 state_ = kInitializing;
330 client_ = client;
336 331
337 // Always post |init_cb_| because |this| could be destroyed if initialization 332 // Always post |init_cb_| because |this| could be destroyed if initialization
338 // failed. 333 // failed.
339 init_cb_ = BindToCurrentLoop(init_cb); 334 init_cb_ = BindToCurrentLoop(init_cb);
340 335
341 buffering_state_cb_ = buffering_state_cb;
342 ended_cb_ = ended_cb;
343 error_cb_ = error_cb;
344 statistics_cb_ = statistics_cb;
345
346 const AudioParameters& hw_params = hardware_config_.GetOutputConfig(); 336 const AudioParameters& hw_params = hardware_config_.GetOutputConfig();
347 expecting_config_changes_ = stream->SupportsConfigChanges(); 337 expecting_config_changes_ = stream->SupportsConfigChanges();
348 if (!expecting_config_changes_ || !hw_params.IsValid() || 338 if (!expecting_config_changes_ || !hw_params.IsValid() ||
349 hw_params.format() == AudioParameters::AUDIO_FAKE) { 339 hw_params.format() == AudioParameters::AUDIO_FAKE) {
350 // The actual buffer size is controlled via the size of the AudioBus 340 // The actual buffer size is controlled via the size of the AudioBus
351 // provided to Render(), so just choose something reasonable here for looks. 341 // provided to Render(), so just choose something reasonable here for looks.
352 int buffer_size = stream->audio_decoder_config().samples_per_second() / 100; 342 int buffer_size = stream->audio_decoder_config().samples_per_second() / 100;
353 audio_parameters_.Reset( 343 audio_parameters_.Reset(
354 AudioParameters::AUDIO_PCM_LOW_LATENCY, 344 AudioParameters::AUDIO_PCM_LOW_LATENCY,
355 stream->audio_decoder_config().channel_layout(), 345 stream->audio_decoder_config().channel_layout(),
(...skipping 68 matching lines...) Expand 10 before | Expand all | Expand 10 after
424 AudioHardwareConfig::GetHighLatencyBufferSize( 414 AudioHardwareConfig::GetHighLatencyBufferSize(
425 sample_rate, preferred_buffer_size)); 415 sample_rate, preferred_buffer_size));
426 } 416 }
427 417
428 audio_clock_.reset( 418 audio_clock_.reset(
429 new AudioClock(base::TimeDelta(), audio_parameters_.sample_rate())); 419 new AudioClock(base::TimeDelta(), audio_parameters_.sample_rate()));
430 420
431 audio_buffer_stream_->Initialize( 421 audio_buffer_stream_->Initialize(
432 stream, base::Bind(&AudioRendererImpl::OnAudioBufferStreamInitialized, 422 stream, base::Bind(&AudioRendererImpl::OnAudioBufferStreamInitialized,
433 weak_factory_.GetWeakPtr()), 423 weak_factory_.GetWeakPtr()),
434 cdm_context, statistics_cb, waiting_for_decryption_key_cb); 424 cdm_context, base::Bind(&AudioRendererImpl::OnStatisticsUpdate,
425 weak_factory_.GetWeakPtr()),
426 base::Bind(&AudioRendererImpl::OnWaitingForDecryptionKey,
427 weak_factory_.GetWeakPtr()));
435 } 428 }
436 429
437 void AudioRendererImpl::OnAudioBufferStreamInitialized(bool success) { 430 void AudioRendererImpl::OnAudioBufferStreamInitialized(bool success) {
438 DVLOG(1) << __FUNCTION__ << ": " << success; 431 DVLOG(1) << __FUNCTION__ << ": " << success;
439 DCHECK(task_runner_->BelongsToCurrentThread()); 432 DCHECK(task_runner_->BelongsToCurrentThread());
440 433
441 base::AutoLock auto_lock(lock_); 434 base::AutoLock auto_lock(lock_);
442 435
443 if (!success) { 436 if (!success) {
444 state_ = kUninitialized; 437 state_ = kUninitialized;
(...skipping 26 matching lines...) Expand all
471 sink_->Start(); 464 sink_->Start();
472 465
473 // Some sinks play on start... 466 // Some sinks play on start...
474 sink_->Pause(); 467 sink_->Pause();
475 } 468 }
476 469
477 DCHECK(!sink_playing_); 470 DCHECK(!sink_playing_);
478 base::ResetAndReturn(&init_cb_).Run(PIPELINE_OK); 471 base::ResetAndReturn(&init_cb_).Run(PIPELINE_OK);
479 } 472 }
480 473
474 void AudioRendererImpl::OnPlaybackError(PipelineStatus error) {
475 DCHECK(task_runner_->BelongsToCurrentThread());
476 client_->OnError(error);
477 }
478
479 void AudioRendererImpl::OnPlaybackEnded() {
480 DCHECK(task_runner_->BelongsToCurrentThread());
481 client_->OnEnded();
482 }
483
484 void AudioRendererImpl::OnStatisticsUpdate(const PipelineStatistics& stats) {
485 DCHECK(task_runner_->BelongsToCurrentThread());
486 client_->OnStatisticsUpdate(stats);
487 }
488
489 void AudioRendererImpl::OnBufferingStateChange(BufferingState state) {
490 DCHECK(task_runner_->BelongsToCurrentThread());
491 client_->OnBufferingStateChange(state);
492 }
493
494 void AudioRendererImpl::OnWaitingForDecryptionKey() {
495 DCHECK(task_runner_->BelongsToCurrentThread());
496 client_->OnWaitingForDecryptionKey();
497 }
498
481 void AudioRendererImpl::SetVolume(float volume) { 499 void AudioRendererImpl::SetVolume(float volume) {
482 DCHECK(task_runner_->BelongsToCurrentThread()); 500 DCHECK(task_runner_->BelongsToCurrentThread());
483 DCHECK(sink_.get()); 501 DCHECK(sink_.get());
484 sink_->SetVolume(volume); 502 sink_->SetVolume(volume);
485 } 503 }
486 504
487 void AudioRendererImpl::DecodedAudioReady( 505 void AudioRendererImpl::DecodedAudioReady(
488 AudioBufferStream::Status status, 506 AudioBufferStream::Status status,
489 const scoped_refptr<AudioBuffer>& buffer) { 507 const scoped_refptr<AudioBuffer>& buffer) {
490 DVLOG(2) << __FUNCTION__ << "(" << status << ")"; 508 DVLOG(2) << __FUNCTION__ << "(" << status << ")";
(...skipping 114 matching lines...) Expand 10 before | Expand all | Expand 10 after
605 623
606 // Store the timestamp of the first packet so we know when to start actual 624 // Store the timestamp of the first packet so we know when to start actual
607 // audio playback. 625 // audio playback.
608 if (first_packet_timestamp_ == kNoTimestamp()) 626 if (first_packet_timestamp_ == kNoTimestamp())
609 first_packet_timestamp_ = buffer->timestamp(); 627 first_packet_timestamp_ = buffer->timestamp();
610 628
611 const size_t memory_usage = algorithm_->GetMemoryUsage(); 629 const size_t memory_usage = algorithm_->GetMemoryUsage();
612 PipelineStatistics stats; 630 PipelineStatistics stats;
613 stats.audio_memory_usage = memory_usage - last_audio_memory_usage_; 631 stats.audio_memory_usage = memory_usage - last_audio_memory_usage_;
614 last_audio_memory_usage_ = memory_usage; 632 last_audio_memory_usage_ = memory_usage;
615 task_runner_->PostTask(FROM_HERE, base::Bind(statistics_cb_, stats)); 633 task_runner_->PostTask(FROM_HERE,
634 base::Bind(&AudioRendererImpl::OnStatisticsUpdate,
635 weak_factory_.GetWeakPtr(), stats));
616 636
617 switch (state_) { 637 switch (state_) {
618 case kUninitialized: 638 case kUninitialized:
619 case kInitializing: 639 case kInitializing:
620 case kFlushing: 640 case kFlushing:
621 NOTREACHED(); 641 NOTREACHED();
622 return false; 642 return false;
623 643
624 case kFlushed: 644 case kFlushed:
625 DCHECK(!pending_read_); 645 DCHECK(!pending_read_);
(...skipping 191 matching lines...) Expand 10 before | Expand all | Expand 10 after
817 837
818 if (CanRead_Locked()) { 838 if (CanRead_Locked()) {
819 task_runner_->PostTask(FROM_HERE, 839 task_runner_->PostTask(FROM_HERE,
820 base::Bind(&AudioRendererImpl::AttemptRead, 840 base::Bind(&AudioRendererImpl::AttemptRead,
821 weak_factory_.GetWeakPtr())); 841 weak_factory_.GetWeakPtr()));
822 } 842 }
823 843
824 if (audio_clock_->front_timestamp() >= ended_timestamp_ && 844 if (audio_clock_->front_timestamp() >= ended_timestamp_ &&
825 !rendered_end_of_stream_) { 845 !rendered_end_of_stream_) {
826 rendered_end_of_stream_ = true; 846 rendered_end_of_stream_ = true;
827 task_runner_->PostTask(FROM_HERE, ended_cb_); 847 task_runner_->PostTask(FROM_HERE,
848 base::Bind(&AudioRendererImpl::OnPlaybackEnded,
849 weak_factory_.GetWeakPtr()));
828 } 850 }
829 } 851 }
830 852
831 DCHECK_LE(frames_written, frames_requested); 853 DCHECK_LE(frames_written, frames_requested);
832 return frames_written; 854 return frames_written;
833 } 855 }
834 856
835 void AudioRendererImpl::OnRenderError() { 857 void AudioRendererImpl::OnRenderError() {
836 MEDIA_LOG(ERROR, media_log_) << "audio render error"; 858 MEDIA_LOG(ERROR, media_log_) << "audio render error";
837 859
838 // Post to |task_runner_| as this is called on the audio callback thread. 860 // Post to |task_runner_| as this is called on the audio callback thread.
839 task_runner_->PostTask(FROM_HERE, 861 task_runner_->PostTask(
840 base::Bind(error_cb_, AUDIO_RENDERER_ERROR)); 862 FROM_HERE, base::Bind(&AudioRendererImpl::OnPlaybackError,
863 weak_factory_.GetWeakPtr(), AUDIO_RENDERER_ERROR));
841 } 864 }
842 865
843 void AudioRendererImpl::HandleAbortedReadOrDecodeError(PipelineStatus status) { 866 void AudioRendererImpl::HandleAbortedReadOrDecodeError(PipelineStatus status) {
844 DCHECK(task_runner_->BelongsToCurrentThread()); 867 DCHECK(task_runner_->BelongsToCurrentThread());
845 lock_.AssertAcquired(); 868 lock_.AssertAcquired();
846 869
847 switch (state_) { 870 switch (state_) {
848 case kUninitialized: 871 case kUninitialized:
849 case kInitializing: 872 case kInitializing:
850 NOTREACHED(); 873 NOTREACHED();
851 return; 874 return;
852 case kFlushing: 875 case kFlushing:
853 ChangeState_Locked(kFlushed); 876 ChangeState_Locked(kFlushed);
854 if (status == PIPELINE_OK) { 877 if (status == PIPELINE_OK) {
855 DoFlush_Locked(); 878 DoFlush_Locked();
856 return; 879 return;
857 } 880 }
858 881
859 MEDIA_LOG(ERROR, media_log_) << "audio error during flushing, status: " 882 MEDIA_LOG(ERROR, media_log_) << "audio error during flushing, status: "
860 << MediaLog::PipelineStatusToString(status); 883 << MediaLog::PipelineStatusToString(status);
861 error_cb_.Run(status); 884 client_->OnError(status);
862 base::ResetAndReturn(&flush_cb_).Run(); 885 base::ResetAndReturn(&flush_cb_).Run();
863 return; 886 return;
864 887
865 case kFlushed: 888 case kFlushed:
866 case kPlaying: 889 case kPlaying:
867 if (status != PIPELINE_OK) { 890 if (status != PIPELINE_OK) {
868 MEDIA_LOG(ERROR, media_log_) 891 MEDIA_LOG(ERROR, media_log_)
869 << "audio error during playing, status: " 892 << "audio error during playing, status: "
870 << MediaLog::PipelineStatusToString(status); 893 << MediaLog::PipelineStatusToString(status);
871 error_cb_.Run(status); 894 client_->OnError(status);
872 } 895 }
873 return; 896 return;
874 } 897 }
875 } 898 }
876 899
877 void AudioRendererImpl::ChangeState_Locked(State new_state) { 900 void AudioRendererImpl::ChangeState_Locked(State new_state) {
878 DVLOG(1) << __FUNCTION__ << " : " << state_ << " -> " << new_state; 901 DVLOG(1) << __FUNCTION__ << " : " << state_ << " -> " << new_state;
879 lock_.AssertAcquired(); 902 lock_.AssertAcquired();
880 state_ = new_state; 903 state_ = new_state;
881 } 904 }
(...skipping 15 matching lines...) Expand all
897 } 920 }
898 921
899 void AudioRendererImpl::SetBufferingState_Locked( 922 void AudioRendererImpl::SetBufferingState_Locked(
900 BufferingState buffering_state) { 923 BufferingState buffering_state) {
901 DVLOG(1) << __FUNCTION__ << " : " << buffering_state_ << " -> " 924 DVLOG(1) << __FUNCTION__ << " : " << buffering_state_ << " -> "
902 << buffering_state; 925 << buffering_state;
903 DCHECK_NE(buffering_state_, buffering_state); 926 DCHECK_NE(buffering_state_, buffering_state);
904 lock_.AssertAcquired(); 927 lock_.AssertAcquired();
905 buffering_state_ = buffering_state; 928 buffering_state_ = buffering_state;
906 929
907 task_runner_->PostTask(FROM_HERE, 930 task_runner_->PostTask(
908 base::Bind(buffering_state_cb_, buffering_state_)); 931 FROM_HERE, base::Bind(&AudioRendererImpl::OnBufferingStateChange,
932 weak_factory_.GetWeakPtr(), buffering_state_));
909 } 933 }
910 934
911 } // namespace media 935 } // namespace media
OLDNEW
« no previous file with comments | « media/renderers/audio_renderer_impl.h ('k') | media/renderers/audio_renderer_impl_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698