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

Side by Side Diff: media/base/pipeline_impl.cc

Issue 2616703002: Fix race condition in media Pipeline::GetMediaTime() after seeking. (Closed)
Patch Set: Fix SharedState. Created 3 years, 11 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 (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/base/pipeline_impl.h" 5 #include "media/base/pipeline_impl.h"
6 6
7 #include <algorithm> 7 #include <algorithm>
8 8
9 #include "base/bind.h" 9 #include "base/bind.h"
10 #include "base/bind_helpers.h" 10 #include "base/bind_helpers.h"
(...skipping 940 matching lines...) Expand 10 before | Expand all | Expand 10 after
951 DCHECK(demuxer); 951 DCHECK(demuxer);
952 DCHECK(renderer); 952 DCHECK(renderer);
953 DCHECK(client); 953 DCHECK(client);
954 DCHECK(!seek_cb.is_null()); 954 DCHECK(!seek_cb.is_null());
955 955
956 DCHECK(!client_); 956 DCHECK(!client_);
957 DCHECK(seek_cb_.is_null()); 957 DCHECK(seek_cb_.is_null());
958 client_ = client; 958 client_ = client;
959 seek_cb_ = seek_cb; 959 seek_cb_ = seek_cb;
960 last_media_time_ = base::TimeDelta(); 960 last_media_time_ = base::TimeDelta();
961 pending_seek_time_ = kNoTimestamp;
961 962
962 std::unique_ptr<TextRenderer> text_renderer; 963 std::unique_ptr<TextRenderer> text_renderer;
963 if (base::CommandLine::ForCurrentProcess()->HasSwitch( 964 if (base::CommandLine::ForCurrentProcess()->HasSwitch(
964 switches::kEnableInbandTextTracks)) { 965 switches::kEnableInbandTextTracks)) {
965 text_renderer.reset(new TextRenderer( 966 text_renderer.reset(new TextRenderer(
966 media_task_runner_, 967 media_task_runner_,
967 BindToCurrentLoop(base::Bind(&PipelineImpl::OnAddTextTrack, 968 BindToCurrentLoop(base::Bind(&PipelineImpl::OnAddTextTrack,
968 weak_factory_.GetWeakPtr())))); 969 weak_factory_.GetWeakPtr()))));
969 } 970 }
970 971
(...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after
1032 DCHECK(thread_checker_.CalledOnValidThread()); 1033 DCHECK(thread_checker_.CalledOnValidThread());
1033 DCHECK(!seek_cb.is_null()); 1034 DCHECK(!seek_cb.is_null());
1034 1035
1035 if (!IsRunning()) { 1036 if (!IsRunning()) {
1036 DLOG(ERROR) << "Media pipeline isn't running. Ignoring Seek()."; 1037 DLOG(ERROR) << "Media pipeline isn't running. Ignoring Seek().";
1037 return; 1038 return;
1038 } 1039 }
1039 1040
1040 DCHECK(seek_cb_.is_null()); 1041 DCHECK(seek_cb_.is_null());
1041 seek_cb_ = seek_cb; 1042 seek_cb_ = seek_cb;
1043 pending_seek_time_ = time;
1042 last_media_time_ = base::TimeDelta(); 1044 last_media_time_ = base::TimeDelta();
1043 media_task_runner_->PostTask( 1045 media_task_runner_->PostTask(
1044 FROM_HERE, base::Bind(&RendererWrapper::Seek, 1046 FROM_HERE, base::Bind(&RendererWrapper::Seek,
1045 base::Unretained(renderer_wrapper_.get()), time)); 1047 base::Unretained(renderer_wrapper_.get()), time));
1046 } 1048 }
1047 1049
1048 void PipelineImpl::Suspend(const PipelineStatusCB& suspend_cb) { 1050 void PipelineImpl::Suspend(const PipelineStatusCB& suspend_cb) {
1049 DVLOG(2) << __func__; 1051 DVLOG(2) << __func__;
1050 DCHECK(!suspend_cb.is_null()); 1052 DCHECK(!suspend_cb.is_null());
1051 1053
(...skipping 64 matching lines...) Expand 10 before | Expand all | Expand 10 after
1116 volume_ = volume; 1118 volume_ = volume;
1117 media_task_runner_->PostTask( 1119 media_task_runner_->PostTask(
1118 FROM_HERE, 1120 FROM_HERE,
1119 base::Bind(&RendererWrapper::SetVolume, 1121 base::Bind(&RendererWrapper::SetVolume,
1120 base::Unretained(renderer_wrapper_.get()), volume_)); 1122 base::Unretained(renderer_wrapper_.get()), volume_));
1121 } 1123 }
1122 1124
1123 base::TimeDelta PipelineImpl::GetMediaTime() const { 1125 base::TimeDelta PipelineImpl::GetMediaTime() const {
1124 DCHECK(thread_checker_.CalledOnValidThread()); 1126 DCHECK(thread_checker_.CalledOnValidThread());
1125 1127
1126 base::TimeDelta media_time = renderer_wrapper_->GetMediaTime(); 1128 // Don't trust renderer time during a pending seek. Renderer may return
1129 // pre-seek time which may corrupt |last_media_time_| used for clamping.
1130 base::TimeDelta media_time = pending_seek_time_ == kNoTimestamp
sandersd (OOO until July 31) 2017/01/04 21:10:23 Nit: Swap order.
chcunningham 2017/01/04 21:15:46 Done.
1131 ? renderer_wrapper_->GetMediaTime()
1132 : pending_seek_time_;
1127 1133
1128 // Clamp current media time to the last reported value, this prevents higher 1134 // Clamp current media time to the last reported value, this prevents higher
1129 // level clients from seeing time go backwards based on inaccurate or spurious 1135 // level clients from seeing time go backwards based on inaccurate or spurious
1130 // delay values reported to the AudioClock. 1136 // delay values reported to the AudioClock.
1131 // 1137 //
1132 // It is expected that such events are transient and will be recovered as 1138 // It is expected that such events are transient and will be recovered as
1133 // rendering continues over time. 1139 // rendering continues over time.
1134 if (media_time < last_media_time_) { 1140 if (media_time < last_media_time_) {
1135 DVLOG(2) << __func__ << ": actual=" << media_time 1141 DVLOG(2) << __func__ << ": actual=" << media_time
1136 << " clamped=" << last_media_time_; 1142 << " clamped=" << last_media_time_;
(...skipping 157 matching lines...) Expand 10 before | Expand all | Expand 10 after
1294 1300
1295 DCHECK(client_); 1301 DCHECK(client_);
1296 client_->OnVideoOpacityChange(opaque); 1302 client_->OnVideoOpacityChange(opaque);
1297 } 1303 }
1298 1304
1299 void PipelineImpl::OnSeekDone() { 1305 void PipelineImpl::OnSeekDone() {
1300 DVLOG(3) << __func__; 1306 DVLOG(3) << __func__;
1301 DCHECK(thread_checker_.CalledOnValidThread()); 1307 DCHECK(thread_checker_.CalledOnValidThread());
1302 DCHECK(IsRunning()); 1308 DCHECK(IsRunning());
1303 1309
1310 pending_seek_time_ = kNoTimestamp;
chcunningham 2017/01/04 21:01:37 Should I also be clearing this in PipelineImp::Res
sandersd (OOO until July 31) 2017/01/04 21:10:23 Resume() should also set the seek time, I believe
chcunningham 2017/01/04 21:15:46 Done.
1311
1304 DCHECK(!seek_cb_.is_null()); 1312 DCHECK(!seek_cb_.is_null());
1305 base::ResetAndReturn(&seek_cb_).Run(PIPELINE_OK); 1313 base::ResetAndReturn(&seek_cb_).Run(PIPELINE_OK);
1306 } 1314 }
1307 1315
1308 void PipelineImpl::OnSuspendDone() { 1316 void PipelineImpl::OnSuspendDone() {
1309 DVLOG(3) << __func__; 1317 DVLOG(3) << __func__;
1310 DCHECK(thread_checker_.CalledOnValidThread()); 1318 DCHECK(thread_checker_.CalledOnValidThread());
1311 DCHECK(IsRunning()); 1319 DCHECK(IsRunning());
1312 1320
1313 DCHECK(!suspend_cb_.is_null()); 1321 DCHECK(!suspend_cb_.is_null());
1314 base::ResetAndReturn(&suspend_cb_).Run(PIPELINE_OK); 1322 base::ResetAndReturn(&suspend_cb_).Run(PIPELINE_OK);
1315 } 1323 }
1316 1324
1317 } // namespace media 1325 } // namespace media
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698