New issue
Advanced search Search tips

Issue 867872 link

Starred by 1 user

Issue metadata

Status: Fixed
Owner:
Closed: Aug 22
Cc:
Components:
EstimatedDays: ----
NextAction: ----
OS: ----
Pri: 3
Type: Bug



Sign in to add a comment

Playback can end twice when disabling track

Project Member Reported by wdzierza...@opera.com, Jul 26

Issue description

Chrome Version: 70.0.3502.0

OS: All


In PipelineIntegrationTest.TrackStatusChangesAfterPipelineEnded, if enough time passes between disabling and enabling the audio track, the pipeline ends twice.

Specifically, for 100% reproduction you can add:

diff --git a/media/test/pipeline_integration_test.cc b/media/test/pipeline_integration_test.cc
index 74cd7eb1ef6..de5e05d9444 100644
--- a/media/test/pipeline_integration_test.cc
+++ b/media/test/pipeline_integration_test.cc
@@ -960,6 +960,12 @@ TEST_F(PipelineIntegrationTest, TrackStatusChangesAfterPipelineEnded) {
   std::vector<MediaTrack::Id> track_ids;
   // Disable audio track.
   OnEnabledAudioTracksChanged(track_ids);
+
+  base::RunLoop().Run();
+
   // Re-enable audio track.
   track_ids.push_back("2");
   OnEnabledAudioTracksChanged(track_ids);

And then the outcome of the test is:

[26908:775:0725/165416.267752:127772396573406:FATAL:pipeline_impl.cc(534)] Check failed: !renderer_ended_. 
0   libbase.dylib                       0x0000000109414a7e base::debug::StackTrace::StackTrace(unsigned long) + 174
1   libbase.dylib                       0x0000000109414b3d base::debug::StackTrace::StackTrace(unsigned long) + 29
2   libbase.dylib                       0x0000000108ff19dc base::debug::StackTrace::StackTrace() + 28
3   libbase.dylib                       0x000000010906cddc logging::LogMessage::~LogMessage() + 460
4   libbase.dylib                       0x000000010906ab45 logging::LogMessage::~LogMessage() + 21
5   libmedia.dylib                      0x000000010a412b77 media::PipelineImpl::RendererWrapper::OnEnded() + 871
6   libmedia.dylib                      0x000000010a7f18a2 media::RendererImpl::RunEndedCallbackIfNeeded() + 450
7   libmedia.dylib                      0x000000010a7f16b2 media::RendererImpl::OnRendererEnded(media::DemuxerStream::Type) + 1218
8   libmedia.dylib                      0x000000010a7f2f0f media::RendererImpl::RendererClientInternal::OnEnded() + 31
9   libmedia.dylib                      0x000000010a7c7d6f media::AudioRendererImpl::OnPlaybackEnded() + 399
10  libmedia.dylib                      0x000000010a7cf1df void base::internal::FunctorTraits<void (media::AudioRendererImpl::*)(), void>::Invoke<void (media::AudioRendererImpl::*)(), base::WeakPtr<media::AudioRendererImpl> const&>(void (media::AudioRendererImpl::*)(), base::WeakPtr<media::AudioRendererImpl> const&&&) + 127
11  libmedia.dylib                      0x000000010a7cf15a void base::internal::InvokeHelper<true, void>::MakeItSo<void (media::AudioRendererImpl::* const&)(), base::WeakPtr<media::AudioRendererImpl> const&>(void (media::AudioRendererImpl::* const&&&)(), base::WeakPtr<media::AudioRendererImpl> const&&&) + 90
12  libmedia.dylib                      0x000000010a7cf0f0 void base::internal::Invoker<base::internal::BindState<void (media::AudioRendererImpl::*)(), base::WeakPtr<media::AudioRendererImpl> >, void ()>::RunImpl<void (media::AudioRendererImpl::* const&)(), std::__1::tuple<base::WeakPtr<media::AudioRendererImpl> > const&, 0ul>(void (media::AudioRendererImpl::* const&&&)(), std::__1::tuple<base::WeakPtr<media::AudioRendererImpl> > const&&&, std::__1::integer_sequence<unsigned long, 0ul>) + 80
13  libmedia.dylib                      0x000000010a7cf08c base::internal::Invoker<base::internal::BindState<void (media::AudioRendererImpl::*)(), base::WeakPtr<media::AudioRendererImpl> >, void ()>::Run(base::internal::BindStateBase*) + 44
14  libbase.dylib                       0x0000000108f97e3c base::OnceCallback<void ()>::Run() && + 92
15  libbase.dylib                       0x0000000108ff3599 base::debug::TaskAnnotator::RunTask(char const*, base::PendingTask*) + 1033
16  libbase.dylib                       0x00000001090c6b1d base::MessageLoop::RunTask(base::PendingTask*) + 877

I wonder if this could happen in real-world usage.

In the original test, the flow is as shown in "TrackStatusChangesAfterPipelineEnded chr.pdf". The buffering change to HAVE_ENOUGH luckily arrives while another track change is pending, and it's effectively ignored.

The test is flaky if the Demuxer implementation (not FFmpegDemuxer) takes some time to process OnEnabledAudioTracksChanged() and does it asynchronously -- and that's how I noticed the problem. When it fails, it's because the flow is like "TrackStatusChangesAfterPipelineEnded gone bad.pdf". Notice how the buffering change gets to be processed before the renderer learns about the track change.

I'm not sure how to proceed with this. Assuming the various buffering state transitions are correct, I could make the test more robust wrt timing by doing what the browser does: WebMediaPlayerImpl::OnEnded() sets the playback rate to 0.0, thus stopping the audio renderer callback and preventing the second OnRendererEnded(). I believe adding pipeline_->SetPlaybackRate(0) to PipelineIntegrationTestBase::OnEnded() mirrors this behavior. However, it causes PipelineIntegrationTest.SeekWhilePlaying to stall, I have yet to figure out why.
 
TrackStatusChangesAfterPipelineEnded chr.pdf
3.5 KB Download
TrackStatusChangesAfterPipelineEnded gone bad.pdf
3.7 KB Download
Owner: tmathmeyer@chromium.org
Status: Started (was: Untriaged)
Project Member

Comment 3 by bugdroid1@chromium.org, Aug 22

The following revision refers to this bug:
  https://chromium.googlesource.com/chromium/src.git/+/df03a5bf1fb0159e9f1e8464f8b136a9a2cd650a

commit df03a5bf1fb0159e9f1e8464f8b136a9a2cd650a
Author: Ted Meyer <tmathmeyer@chromium.org>
Date: Wed Aug 22 06:43:15 2018

Prevent multiple 'on_ended' calls due to track switches

If a track switch happens after the renderers are in a
fully ended state, we should make sure that an extra
ended event isn't fired.

Bug:  867872 
Change-Id: I0685b46aafa76ccec57d5de7ddde4919c08c866e
Reviewed-on: https://chromium-review.googlesource.com/1153144
Commit-Queue: Ted Meyer <tmathmeyer@chromium.org>
Reviewed-by: Dale Curtis <dalecurtis@chromium.org>
Cr-Commit-Position: refs/heads/master@{#584968}
[modify] https://crrev.com/df03a5bf1fb0159e9f1e8464f8b136a9a2cd650a/media/renderers/renderer_impl.cc

Status: Fixed (was: Started)

Sign in to add a comment