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

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

Issue 2492953003: media: Delete renderer/demuxer splicing code. (Closed)
Patch Set: 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 (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/power_monitor/power_monitor.h" 17 #include "base/power_monitor/power_monitor.h"
18 #include "base/single_thread_task_runner.h" 18 #include "base/single_thread_task_runner.h"
19 #include "base/time/default_tick_clock.h" 19 #include "base/time/default_tick_clock.h"
20 #include "build/build_config.h" 20 #include "build/build_config.h"
21 #include "media/base/audio_buffer.h" 21 #include "media/base/audio_buffer.h"
22 #include "media/base/audio_buffer_converter.h" 22 #include "media/base/audio_buffer_converter.h"
23 #include "media/base/audio_latency.h" 23 #include "media/base/audio_latency.h"
24 #include "media/base/audio_splicer.h"
25 #include "media/base/bind_to_current_loop.h" 24 #include "media/base/bind_to_current_loop.h"
26 #include "media/base/demuxer_stream.h" 25 #include "media/base/demuxer_stream.h"
27 #include "media/base/media_log.h" 26 #include "media/base/media_log.h"
28 #include "media/base/media_switches.h" 27 #include "media/base/media_switches.h"
29 #include "media/base/renderer_client.h" 28 #include "media/base/renderer_client.h"
30 #include "media/base/timestamp_constants.h" 29 #include "media/base/timestamp_constants.h"
31 #include "media/filters/audio_clock.h" 30 #include "media/filters/audio_clock.h"
32 #include "media/filters/decrypting_demuxer_stream.h" 31 #include "media/filters/decrypting_demuxer_stream.h"
33 32
34 namespace media { 33 namespace media {
(...skipping 16 matching lines...) Expand all
51 playback_rate_(0.0), 50 playback_rate_(0.0),
52 state_(kUninitialized), 51 state_(kUninitialized),
53 buffering_state_(BUFFERING_HAVE_NOTHING), 52 buffering_state_(BUFFERING_HAVE_NOTHING),
54 rendering_(false), 53 rendering_(false),
55 sink_playing_(false), 54 sink_playing_(false),
56 pending_read_(false), 55 pending_read_(false),
57 received_end_of_stream_(false), 56 received_end_of_stream_(false),
58 rendered_end_of_stream_(false), 57 rendered_end_of_stream_(false),
59 is_suspending_(false), 58 is_suspending_(false),
60 weak_factory_(this) { 59 weak_factory_(this) {
61 audio_buffer_stream_->set_splice_observer(base::Bind(
62 &AudioRendererImpl::OnNewSpliceBuffer, weak_factory_.GetWeakPtr()));
63 audio_buffer_stream_->set_config_change_observer(base::Bind( 60 audio_buffer_stream_->set_config_change_observer(base::Bind(
64 &AudioRendererImpl::OnConfigChange, weak_factory_.GetWeakPtr())); 61 &AudioRendererImpl::OnConfigChange, weak_factory_.GetWeakPtr()));
65 62
66 // Tests may not have a power monitor. 63 // Tests may not have a power monitor.
67 base::PowerMonitor* monitor = base::PowerMonitor::Get(); 64 base::PowerMonitor* monitor = base::PowerMonitor::Get();
68 if (!monitor) 65 if (!monitor)
69 return; 66 return;
70 67
71 // PowerObserver's must be added and removed from the same thread, but we 68 // PowerObserver's must be added and removed from the same thread, but we
72 // won't remove the observer until we're destructed on |task_runner_| so we 69 // won't remove the observer until we're destructed on |task_runner_| so we
(...skipping 221 matching lines...) Expand 10 before | Expand all | Expand 10 after
294 DCHECK_EQ(state_, kFlushed); 291 DCHECK_EQ(state_, kFlushed);
295 DCHECK(!flush_cb_.is_null()); 292 DCHECK(!flush_cb_.is_null());
296 293
297 received_end_of_stream_ = false; 294 received_end_of_stream_ = false;
298 rendered_end_of_stream_ = false; 295 rendered_end_of_stream_ = false;
299 296
300 // Flush() may have been called while underflowed/not fully buffered. 297 // Flush() may have been called while underflowed/not fully buffered.
301 if (buffering_state_ != BUFFERING_HAVE_NOTHING) 298 if (buffering_state_ != BUFFERING_HAVE_NOTHING)
302 SetBufferingState_Locked(BUFFERING_HAVE_NOTHING); 299 SetBufferingState_Locked(BUFFERING_HAVE_NOTHING);
303 300
304 splicer_->Reset();
305 if (buffer_converter_) 301 if (buffer_converter_)
306 buffer_converter_->Reset(); 302 buffer_converter_->Reset();
307 algorithm_->FlushBuffers(); 303 algorithm_->FlushBuffers();
308 } 304 }
309 305
310 // Changes in buffering state are always posted. Flush callback must only be 306 // Changes in buffering state are always posted. Flush callback must only be
311 // run after buffering state has been set back to nothing. 307 // run after buffering state has been set back to nothing.
312 task_runner_->PostTask(FROM_HERE, base::ResetAndReturn(&flush_cb_)); 308 task_runner_->PostTask(FROM_HERE, base::ResetAndReturn(&flush_cb_));
313 } 309 }
314 310
(...skipping 144 matching lines...) Expand 10 before | Expand all | Expand 10 after
459 if (!audio_parameters_.IsValid()) { 455 if (!audio_parameters_.IsValid()) {
460 DVLOG(1) << __func__ << ": Invalid audio parameters: " 456 DVLOG(1) << __func__ << ": Invalid audio parameters: "
461 << audio_parameters_.AsHumanReadableString(); 457 << audio_parameters_.AsHumanReadableString();
462 ChangeState_Locked(kUninitialized); 458 ChangeState_Locked(kUninitialized);
463 base::ResetAndReturn(&init_cb_).Run(PIPELINE_ERROR_INITIALIZATION_FAILED); 459 base::ResetAndReturn(&init_cb_).Run(PIPELINE_ERROR_INITIALIZATION_FAILED);
464 return; 460 return;
465 } 461 }
466 462
467 if (expecting_config_changes_) 463 if (expecting_config_changes_)
468 buffer_converter_.reset(new AudioBufferConverter(audio_parameters_)); 464 buffer_converter_.reset(new AudioBufferConverter(audio_parameters_));
469 splicer_.reset(new AudioSplicer(audio_parameters_.sample_rate(), media_log_));
470 465
471 // We're all good! Continue initializing the rest of the audio renderer 466 // We're all good! Continue initializing the rest of the audio renderer
472 // based on the decoder format. 467 // based on the decoder format.
473 algorithm_.reset(new AudioRendererAlgorithm()); 468 algorithm_.reset(new AudioRendererAlgorithm());
474 algorithm_->Initialize(audio_parameters_); 469 algorithm_->Initialize(audio_parameters_);
475 470
476 ChangeState_Locked(kFlushed); 471 ChangeState_Locked(kFlushed);
477 472
478 { 473 {
479 base::AutoUnlock auto_unlock(lock_); 474 base::AutoUnlock auto_unlock(lock_);
(...skipping 74 matching lines...) Expand 10 before | Expand all | Expand 10 after
554 549
555 DCHECK_EQ(status, AudioBufferStream::OK); 550 DCHECK_EQ(status, AudioBufferStream::OK);
556 DCHECK(buffer.get()); 551 DCHECK(buffer.get());
557 552
558 if (state_ == kFlushing) { 553 if (state_ == kFlushing) {
559 ChangeState_Locked(kFlushed); 554 ChangeState_Locked(kFlushed);
560 DoFlush_Locked(); 555 DoFlush_Locked();
561 return; 556 return;
562 } 557 }
563 558
559 bool need_another_buffer = false;
560
564 if (expecting_config_changes_) { 561 if (expecting_config_changes_) {
565 if (last_decoded_sample_rate_ && 562 if (last_decoded_sample_rate_ &&
566 buffer->sample_rate() != last_decoded_sample_rate_) { 563 buffer->sample_rate() != last_decoded_sample_rate_) {
567 DVLOG(1) << __func__ << " Updating audio sample_rate." 564 DVLOG(1) << __func__ << " Updating audio sample_rate."
568 << " ts:" << buffer->timestamp().InMicroseconds() 565 << " ts:" << buffer->timestamp().InMicroseconds()
569 << " old:" << last_decoded_sample_rate_ 566 << " old:" << last_decoded_sample_rate_
570 << " new:" << buffer->sample_rate(); 567 << " new:" << buffer->sample_rate();
571 OnConfigChange(); 568 OnConfigChange();
572 } 569 }
573 last_decoded_sample_rate_ = buffer->sample_rate(); 570 last_decoded_sample_rate_ = buffer->sample_rate();
574 571
575 DCHECK(buffer_converter_); 572 DCHECK(buffer_converter_);
576 buffer_converter_->AddInput(buffer); 573 buffer_converter_->AddInput(buffer);
574
575 if (!buffer_converter_->HasNextBuffer()) {
576 AttemptRead_Locked();
577 return;
578 }
579
577 while (buffer_converter_->HasNextBuffer()) { 580 while (buffer_converter_->HasNextBuffer()) {
578 if (!splicer_->AddInput(buffer_converter_->GetNextBuffer())) { 581 need_another_buffer =
579 HandleAbortedReadOrDecodeError(AUDIO_RENDERER_ERROR_SPLICE_FAILED); 582 HandleDecodedBuffer_Locked(buffer_converter_->GetNextBuffer());
580 return;
581 }
582 } 583 }
583 } else { 584 } else {
584 // TODO(chcunningham, tguilbert): Figure out if we want to support implicit 585 // TODO(chcunningham, tguilbert): Figure out if we want to support implicit
585 // config changes during src=. Doing so requires resampling each individual 586 // config changes during src=. Doing so requires resampling each individual
586 // stream which is inefficient when there are many tags in a page. 587 // stream which is inefficient when there are many tags in a page.
587 // 588 //
588 // Check if the buffer we received matches the expected configuration. 589 // Check if the buffer we received matches the expected configuration.
589 // Note: We explicitly do not check channel layout here to avoid breaking 590 // Note: We explicitly do not check channel layout here to avoid breaking
590 // weird behavior with multichannel wav files: http://crbug.com/600538. 591 // weird behavior with multichannel wav files: http://crbug.com/600538.
591 if (!buffer->end_of_stream() && 592 if (!buffer->end_of_stream() &&
592 (buffer->sample_rate() != audio_parameters_.sample_rate() || 593 (buffer->sample_rate() != audio_parameters_.sample_rate() ||
593 buffer->channel_count() != audio_parameters_.channels())) { 594 buffer->channel_count() != audio_parameters_.channels())) {
594 MEDIA_LOG(ERROR, media_log_) 595 MEDIA_LOG(ERROR, media_log_)
595 << "Unsupported midstream configuration change!" 596 << "Unsupported midstream configuration change!"
596 << " Sample Rate: " << buffer->sample_rate() << " vs " 597 << " Sample Rate: " << buffer->sample_rate() << " vs "
597 << audio_parameters_.sample_rate() 598 << audio_parameters_.sample_rate()
598 << ", Channels: " << buffer->channel_count() << " vs " 599 << ", Channels: " << buffer->channel_count() << " vs "
599 << audio_parameters_.channels(); 600 << audio_parameters_.channels();
600 HandleAbortedReadOrDecodeError(PIPELINE_ERROR_DECODE); 601 HandleAbortedReadOrDecodeError(PIPELINE_ERROR_DECODE);
601 return; 602 return;
602 } 603 }
603 604
604 if (!splicer_->AddInput(buffer)) { 605 need_another_buffer = HandleDecodedBuffer_Locked(buffer);
605 HandleAbortedReadOrDecodeError(AUDIO_RENDERER_ERROR_SPLICE_FAILED);
606 return;
607 }
608 } 606 }
609 607
610 if (!splicer_->HasNextBuffer()) {
611 AttemptRead_Locked();
612 return;
613 }
614
615 bool need_another_buffer = false;
616 while (splicer_->HasNextBuffer())
617 need_another_buffer = HandleSplicerBuffer_Locked(splicer_->GetNextBuffer());
618
619 if (!need_another_buffer && !CanRead_Locked()) 608 if (!need_another_buffer && !CanRead_Locked())
620 return; 609 return;
621 610
622 AttemptRead_Locked(); 611 AttemptRead_Locked();
623 } 612 }
624 613
625 bool AudioRendererImpl::HandleSplicerBuffer_Locked( 614 bool AudioRendererImpl::HandleDecodedBuffer_Locked(
626 const scoped_refptr<AudioBuffer>& buffer) { 615 const scoped_refptr<AudioBuffer>& buffer) {
627 lock_.AssertAcquired(); 616 lock_.AssertAcquired();
628 if (buffer->end_of_stream()) { 617 if (buffer->end_of_stream()) {
629 received_end_of_stream_ = true; 618 received_end_of_stream_ = true;
630 } else { 619 } else {
631 if (state_ == kPlaying) { 620 if (state_ == kPlaying) {
632 if (IsBeforeStartTime(buffer)) 621 if (IsBeforeStartTime(buffer))
633 return true; 622 return true;
634 623
635 // Trim off any additional time before the start timestamp. 624 // Trim off any additional time before the start timestamp.
(...skipping 292 matching lines...) Expand 10 before | Expand all | Expand 10 after
928 return; 917 return;
929 } 918 }
930 } 919 }
931 920
932 void AudioRendererImpl::ChangeState_Locked(State new_state) { 921 void AudioRendererImpl::ChangeState_Locked(State new_state) {
933 DVLOG(1) << __func__ << " : " << state_ << " -> " << new_state; 922 DVLOG(1) << __func__ << " : " << state_ << " -> " << new_state;
934 lock_.AssertAcquired(); 923 lock_.AssertAcquired();
935 state_ = new_state; 924 state_ = new_state;
936 } 925 }
937 926
938 void AudioRendererImpl::OnNewSpliceBuffer(base::TimeDelta splice_timestamp) {
939 DCHECK(task_runner_->BelongsToCurrentThread());
940 splicer_->SetSpliceTimestamp(splice_timestamp);
941 }
942
943 void AudioRendererImpl::OnConfigChange() { 927 void AudioRendererImpl::OnConfigChange() {
944 DCHECK(task_runner_->BelongsToCurrentThread()); 928 DCHECK(task_runner_->BelongsToCurrentThread());
945 DCHECK(expecting_config_changes_); 929 DCHECK(expecting_config_changes_);
946 buffer_converter_->ResetTimestampState(); 930 buffer_converter_->ResetTimestampState();
947 // Drain flushed buffers from the converter so the AudioSplicer receives all
948 // data ahead of any OnNewSpliceBuffer() calls. Since discontinuities should
949 // only appear after config changes, AddInput() should never fail here.
950 while (buffer_converter_->HasNextBuffer())
951 CHECK(splicer_->AddInput(buffer_converter_->GetNextBuffer()));
952 } 931 }
953 932
954 void AudioRendererImpl::SetBufferingState_Locked( 933 void AudioRendererImpl::SetBufferingState_Locked(
955 BufferingState buffering_state) { 934 BufferingState buffering_state) {
956 DVLOG(1) << __func__ << " : " << buffering_state_ << " -> " 935 DVLOG(1) << __func__ << " : " << buffering_state_ << " -> "
957 << buffering_state; 936 << buffering_state;
958 DCHECK_NE(buffering_state_, buffering_state); 937 DCHECK_NE(buffering_state_, buffering_state);
959 lock_.AssertAcquired(); 938 lock_.AssertAcquired();
960 buffering_state_ = buffering_state; 939 buffering_state_ = buffering_state;
961 940
962 task_runner_->PostTask( 941 task_runner_->PostTask(
963 FROM_HERE, base::Bind(&AudioRendererImpl::OnBufferingStateChange, 942 FROM_HERE, base::Bind(&AudioRendererImpl::OnBufferingStateChange,
964 weak_factory_.GetWeakPtr(), buffering_state_)); 943 weak_factory_.GetWeakPtr(), buffering_state_));
965 } 944 }
966 945
967 } // namespace media 946 } // namespace media
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698