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

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

Issue 2616703002: Fix race condition in media Pipeline::GetMediaTime() after seeking. (Closed)
Patch Set: Feedback 2 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
« no previous file with comments | « media/base/pipeline_impl.h ('k') | media/base/pipeline_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/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 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 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 10 matching lines...) Expand all
1062 base::TimeDelta time, 1064 base::TimeDelta time,
1063 const PipelineStatusCB& seek_cb) { 1065 const PipelineStatusCB& seek_cb) {
1064 DVLOG(2) << __func__; 1066 DVLOG(2) << __func__;
1065 DCHECK(thread_checker_.CalledOnValidThread()); 1067 DCHECK(thread_checker_.CalledOnValidThread());
1066 DCHECK(renderer); 1068 DCHECK(renderer);
1067 DCHECK(!seek_cb.is_null()); 1069 DCHECK(!seek_cb.is_null());
1068 1070
1069 DCHECK(IsRunning()); 1071 DCHECK(IsRunning());
1070 DCHECK(seek_cb_.is_null()); 1072 DCHECK(seek_cb_.is_null());
1071 seek_cb_ = seek_cb; 1073 seek_cb_ = seek_cb;
1074 seek_time_ = time;
1072 last_media_time_ = base::TimeDelta(); 1075 last_media_time_ = base::TimeDelta();
1073 1076
1074 media_task_runner_->PostTask( 1077 media_task_runner_->PostTask(
1075 FROM_HERE, base::Bind(&RendererWrapper::Resume, 1078 FROM_HERE, base::Bind(&RendererWrapper::Resume,
1076 base::Unretained(renderer_wrapper_.get()), 1079 base::Unretained(renderer_wrapper_.get()),
1077 base::Passed(&renderer), time)); 1080 base::Passed(&renderer), time));
1078 } 1081 }
1079 1082
1080 bool PipelineImpl::IsRunning() const { 1083 bool PipelineImpl::IsRunning() const {
1081 DCHECK(thread_checker_.CalledOnValidThread()); 1084 DCHECK(thread_checker_.CalledOnValidThread());
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after
1116 volume_ = volume; 1119 volume_ = volume;
1117 media_task_runner_->PostTask( 1120 media_task_runner_->PostTask(
1118 FROM_HERE, 1121 FROM_HERE,
1119 base::Bind(&RendererWrapper::SetVolume, 1122 base::Bind(&RendererWrapper::SetVolume,
1120 base::Unretained(renderer_wrapper_.get()), volume_)); 1123 base::Unretained(renderer_wrapper_.get()), volume_));
1121 } 1124 }
1122 1125
1123 base::TimeDelta PipelineImpl::GetMediaTime() const { 1126 base::TimeDelta PipelineImpl::GetMediaTime() const {
1124 DCHECK(thread_checker_.CalledOnValidThread()); 1127 DCHECK(thread_checker_.CalledOnValidThread());
1125 1128
1129 // Don't trust renderer time during a pending seek. Renderer may return
1130 // pre-seek time which may corrupt |last_media_time_| used for clamping.
1131 if (seek_time_ != kNoTimestamp) {
1132 DVLOG(3) << __func__ << ": (seeking) " << seek_time_.InMilliseconds()
1133 << " ms";
1134 return seek_time_;
1135 }
1136
1126 base::TimeDelta media_time = renderer_wrapper_->GetMediaTime(); 1137 base::TimeDelta media_time = renderer_wrapper_->GetMediaTime();
1127 1138
1128 // Clamp current media time to the last reported value, this prevents higher 1139 // 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 1140 // level clients from seeing time go backwards based on inaccurate or spurious
1130 // delay values reported to the AudioClock. 1141 // delay values reported to the AudioClock.
1131 // 1142 //
1132 // It is expected that such events are transient and will be recovered as 1143 // It is expected that such events are transient and will be recovered as
1133 // rendering continues over time. 1144 // rendering continues over time.
1134 if (media_time < last_media_time_) { 1145 if (media_time < last_media_time_) {
1135 DVLOG(2) << __func__ << ": actual=" << media_time 1146 DVLOG(2) << __func__ << ": actual=" << media_time
(...skipping 158 matching lines...) Expand 10 before | Expand all | Expand 10 after
1294 1305
1295 DCHECK(client_); 1306 DCHECK(client_);
1296 client_->OnVideoOpacityChange(opaque); 1307 client_->OnVideoOpacityChange(opaque);
1297 } 1308 }
1298 1309
1299 void PipelineImpl::OnSeekDone() { 1310 void PipelineImpl::OnSeekDone() {
1300 DVLOG(3) << __func__; 1311 DVLOG(3) << __func__;
1301 DCHECK(thread_checker_.CalledOnValidThread()); 1312 DCHECK(thread_checker_.CalledOnValidThread());
1302 DCHECK(IsRunning()); 1313 DCHECK(IsRunning());
1303 1314
1315 seek_time_ = kNoTimestamp;
1316
1304 DCHECK(!seek_cb_.is_null()); 1317 DCHECK(!seek_cb_.is_null());
1305 base::ResetAndReturn(&seek_cb_).Run(PIPELINE_OK); 1318 base::ResetAndReturn(&seek_cb_).Run(PIPELINE_OK);
1306 } 1319 }
1307 1320
1308 void PipelineImpl::OnSuspendDone() { 1321 void PipelineImpl::OnSuspendDone() {
1309 DVLOG(3) << __func__; 1322 DVLOG(3) << __func__;
1310 DCHECK(thread_checker_.CalledOnValidThread()); 1323 DCHECK(thread_checker_.CalledOnValidThread());
1311 DCHECK(IsRunning()); 1324 DCHECK(IsRunning());
1312 1325
1313 DCHECK(!suspend_cb_.is_null()); 1326 DCHECK(!suspend_cb_.is_null());
1314 base::ResetAndReturn(&suspend_cb_).Run(PIPELINE_OK); 1327 base::ResetAndReturn(&suspend_cb_).Run(PIPELINE_OK);
1315 } 1328 }
1316 1329
1317 } // namespace media 1330 } // namespace media
OLDNEW
« no previous file with comments | « media/base/pipeline_impl.h ('k') | media/base/pipeline_impl_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698