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

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

Issue 2621183002: [TO 56] Fix race in media Pipeline::GetMediaTime() after seeking. (Closed)
Patch Set: 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 920 matching lines...) Expand 10 before | Expand all | Expand 10 after
931 DCHECK(demuxer); 931 DCHECK(demuxer);
932 DCHECK(renderer); 932 DCHECK(renderer);
933 DCHECK(client); 933 DCHECK(client);
934 DCHECK(!seek_cb.is_null()); 934 DCHECK(!seek_cb.is_null());
935 935
936 DCHECK(!client_); 936 DCHECK(!client_);
937 DCHECK(seek_cb_.is_null()); 937 DCHECK(seek_cb_.is_null());
938 client_ = client; 938 client_ = client;
939 seek_cb_ = seek_cb; 939 seek_cb_ = seek_cb;
940 last_media_time_ = base::TimeDelta(); 940 last_media_time_ = base::TimeDelta();
941 seek_time_ = kNoTimestamp;
941 942
942 std::unique_ptr<TextRenderer> text_renderer; 943 std::unique_ptr<TextRenderer> text_renderer;
943 if (base::CommandLine::ForCurrentProcess()->HasSwitch( 944 if (base::CommandLine::ForCurrentProcess()->HasSwitch(
944 switches::kEnableInbandTextTracks)) { 945 switches::kEnableInbandTextTracks)) {
945 text_renderer.reset(new TextRenderer( 946 text_renderer.reset(new TextRenderer(
946 media_task_runner_, 947 media_task_runner_,
947 BindToCurrentLoop(base::Bind(&PipelineImpl::OnAddTextTrack, 948 BindToCurrentLoop(base::Bind(&PipelineImpl::OnAddTextTrack,
948 weak_factory_.GetWeakPtr())))); 949 weak_factory_.GetWeakPtr()))));
949 } 950 }
950 951
(...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after
1012 DCHECK(thread_checker_.CalledOnValidThread()); 1013 DCHECK(thread_checker_.CalledOnValidThread());
1013 DCHECK(!seek_cb.is_null()); 1014 DCHECK(!seek_cb.is_null());
1014 1015
1015 if (!IsRunning()) { 1016 if (!IsRunning()) {
1016 DLOG(ERROR) << "Media pipeline isn't running. Ignoring Seek()."; 1017 DLOG(ERROR) << "Media pipeline isn't running. Ignoring Seek().";
1017 return; 1018 return;
1018 } 1019 }
1019 1020
1020 DCHECK(seek_cb_.is_null()); 1021 DCHECK(seek_cb_.is_null());
1021 seek_cb_ = seek_cb; 1022 seek_cb_ = seek_cb;
1023 seek_time_ = time;
1022 last_media_time_ = base::TimeDelta(); 1024 last_media_time_ = base::TimeDelta();
1023 media_task_runner_->PostTask( 1025 media_task_runner_->PostTask(
1024 FROM_HERE, base::Bind(&RendererWrapper::Seek, 1026 FROM_HERE, base::Bind(&RendererWrapper::Seek,
1025 base::Unretained(renderer_wrapper_.get()), time)); 1027 base::Unretained(renderer_wrapper_.get()), time));
1026 } 1028 }
1027 1029
1028 void PipelineImpl::Suspend(const PipelineStatusCB& suspend_cb) { 1030 void PipelineImpl::Suspend(const PipelineStatusCB& suspend_cb) {
1029 DVLOG(2) << __func__; 1031 DVLOG(2) << __func__;
1030 DCHECK(!suspend_cb.is_null()); 1032 DCHECK(!suspend_cb.is_null());
1031 1033
(...skipping 10 matching lines...) Expand all
1042 base::TimeDelta time, 1044 base::TimeDelta time,
1043 const PipelineStatusCB& seek_cb) { 1045 const PipelineStatusCB& seek_cb) {
1044 DVLOG(2) << __func__; 1046 DVLOG(2) << __func__;
1045 DCHECK(thread_checker_.CalledOnValidThread()); 1047 DCHECK(thread_checker_.CalledOnValidThread());
1046 DCHECK(renderer); 1048 DCHECK(renderer);
1047 DCHECK(!seek_cb.is_null()); 1049 DCHECK(!seek_cb.is_null());
1048 1050
1049 DCHECK(IsRunning()); 1051 DCHECK(IsRunning());
1050 DCHECK(seek_cb_.is_null()); 1052 DCHECK(seek_cb_.is_null());
1051 seek_cb_ = seek_cb; 1053 seek_cb_ = seek_cb;
1054 seek_time_ = time;
1052 last_media_time_ = base::TimeDelta(); 1055 last_media_time_ = base::TimeDelta();
1053 1056
1054 media_task_runner_->PostTask( 1057 media_task_runner_->PostTask(
1055 FROM_HERE, base::Bind(&RendererWrapper::Resume, 1058 FROM_HERE, base::Bind(&RendererWrapper::Resume,
1056 base::Unretained(renderer_wrapper_.get()), 1059 base::Unretained(renderer_wrapper_.get()),
1057 base::Passed(&renderer), time)); 1060 base::Passed(&renderer), time));
1058 } 1061 }
1059 1062
1060 bool PipelineImpl::IsRunning() const { 1063 bool PipelineImpl::IsRunning() const {
1061 DCHECK(thread_checker_.CalledOnValidThread()); 1064 DCHECK(thread_checker_.CalledOnValidThread());
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after
1096 volume_ = volume; 1099 volume_ = volume;
1097 media_task_runner_->PostTask( 1100 media_task_runner_->PostTask(
1098 FROM_HERE, 1101 FROM_HERE,
1099 base::Bind(&RendererWrapper::SetVolume, 1102 base::Bind(&RendererWrapper::SetVolume,
1100 base::Unretained(renderer_wrapper_.get()), volume_)); 1103 base::Unretained(renderer_wrapper_.get()), volume_));
1101 } 1104 }
1102 1105
1103 base::TimeDelta PipelineImpl::GetMediaTime() const { 1106 base::TimeDelta PipelineImpl::GetMediaTime() const {
1104 DCHECK(thread_checker_.CalledOnValidThread()); 1107 DCHECK(thread_checker_.CalledOnValidThread());
1105 1108
1109 // Don't trust renderer time during a pending seek. Renderer may return
1110 // pre-seek time which may corrupt |last_media_time_| used for clamping.
1111 if (seek_time_ != kNoTimestamp) {
1112 DVLOG(3) << __func__ << ": (seeking) " << seek_time_.InMilliseconds()
1113 << " ms";
1114 return seek_time_;
1115 }
1116
1106 base::TimeDelta media_time = renderer_wrapper_->GetMediaTime(); 1117 base::TimeDelta media_time = renderer_wrapper_->GetMediaTime();
1107 1118
1108 // Clamp current media time to the last reported value, this prevents higher 1119 // Clamp current media time to the last reported value, this prevents higher
1109 // level clients from seeing time go backwards based on inaccurate or spurious 1120 // level clients from seeing time go backwards based on inaccurate or spurious
1110 // delay values reported to the AudioClock. 1121 // delay values reported to the AudioClock.
1111 // 1122 //
1112 // It is expected that such events are transient and will be recovered as 1123 // It is expected that such events are transient and will be recovered as
1113 // rendering continues over time. 1124 // rendering continues over time.
1114 if (media_time < last_media_time_) { 1125 if (media_time < last_media_time_) {
1115 DVLOG(2) << __func__ << ": actual=" << media_time 1126 DVLOG(2) << __func__ << ": actual=" << media_time
(...skipping 158 matching lines...) Expand 10 before | Expand all | Expand 10 after
1274 1285
1275 DCHECK(client_); 1286 DCHECK(client_);
1276 client_->OnVideoOpacityChange(opaque); 1287 client_->OnVideoOpacityChange(opaque);
1277 } 1288 }
1278 1289
1279 void PipelineImpl::OnSeekDone() { 1290 void PipelineImpl::OnSeekDone() {
1280 DVLOG(3) << __func__; 1291 DVLOG(3) << __func__;
1281 DCHECK(thread_checker_.CalledOnValidThread()); 1292 DCHECK(thread_checker_.CalledOnValidThread());
1282 DCHECK(IsRunning()); 1293 DCHECK(IsRunning());
1283 1294
1295 seek_time_ = kNoTimestamp;
1296
1284 DCHECK(!seek_cb_.is_null()); 1297 DCHECK(!seek_cb_.is_null());
1285 base::ResetAndReturn(&seek_cb_).Run(PIPELINE_OK); 1298 base::ResetAndReturn(&seek_cb_).Run(PIPELINE_OK);
1286 } 1299 }
1287 1300
1288 void PipelineImpl::OnSuspendDone() { 1301 void PipelineImpl::OnSuspendDone() {
1289 DVLOG(3) << __func__; 1302 DVLOG(3) << __func__;
1290 DCHECK(thread_checker_.CalledOnValidThread()); 1303 DCHECK(thread_checker_.CalledOnValidThread());
1291 DCHECK(IsRunning()); 1304 DCHECK(IsRunning());
1292 1305
1293 DCHECK(!suspend_cb_.is_null()); 1306 DCHECK(!suspend_cb_.is_null());
1294 base::ResetAndReturn(&suspend_cb_).Run(PIPELINE_OK); 1307 base::ResetAndReturn(&suspend_cb_).Run(PIPELINE_OK);
1295 } 1308 }
1296 1309
1297 } // namespace media 1310 } // 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