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

Side by Side Diff: media/filters/video_renderer_base.cc

Issue 9295020: Fix ChunkDemuxer seek deadlock (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: _ Created 8 years, 10 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 | Annotate | Revision Log
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 "base/bind.h" 5 #include "base/bind.h"
6 #include "base/callback.h" 6 #include "base/callback.h"
7 #include "base/threading/platform_thread.h" 7 #include "base/threading/platform_thread.h"
8 #include "media/base/buffers.h" 8 #include "media/base/buffers.h"
9 #include "media/base/filter_host.h" 9 #include "media/base/filter_host.h"
10 #include "media/base/limits.h" 10 #include "media/base/limits.h"
(...skipping 318 matching lines...) Expand 10 before | Expand all | Expand 10 after
329 // frame when this is true. 329 // frame when this is true.
330 frame_available_.Signal(); 330 frame_available_.Signal();
331 if (state_ == kFlushing) { 331 if (state_ == kFlushing) {
332 AttemptFlush_Locked(); 332 AttemptFlush_Locked();
333 } else if (state_ == kError || state_ == kStopped) { 333 } else if (state_ == kError || state_ == kStopped) {
334 DoStopOrError_Locked(); 334 DoStopOrError_Locked();
335 } 335 }
336 } 336 }
337 337
338 void VideoRendererBase::FrameReady(scoped_refptr<VideoFrame> frame) { 338 void VideoRendererBase::FrameReady(scoped_refptr<VideoFrame> frame) {
339 DCHECK(frame);
340
341 base::AutoLock auto_lock(lock_); 339 base::AutoLock auto_lock(lock_);
342 DCHECK_NE(state_, kUninitialized); 340 DCHECK_NE(state_, kUninitialized);
343 DCHECK_NE(state_, kStopped); 341 DCHECK_NE(state_, kStopped);
344 DCHECK_NE(state_, kError); 342 DCHECK_NE(state_, kError);
345 DCHECK_NE(state_, kFlushed); 343 DCHECK_NE(state_, kFlushed);
346 CHECK(pending_read_); 344 CHECK(pending_read_);
347 345
348 pending_read_ = false; 346 pending_read_ = false;
349 347
350 if (state_ == kFlushing) { 348 if (state_ == kFlushing) {
351 AttemptFlush_Locked(); 349 AttemptFlush_Locked();
352 return; 350 return;
353 } 351 }
354 352
355 // Discard frames until we reach our desired seek timestamp. 353 if (frame) {
Ami GONE FROM CHROMIUM 2012/01/27 23:44:58 reverse test & early-return?
acolwell GONE FROM CHROMIUM 2012/01/29 03:00:41 Done.
356 if (state_ == kSeeking && !frame->IsEndOfStream() && 354 // Discard frames until we reach our desired seek timestamp.
357 (frame->GetTimestamp() + frame->GetDuration()) <= seek_timestamp_) { 355 if (state_ == kSeeking && !frame->IsEndOfStream() &&
358 AttemptRead_Locked(); 356 (frame->GetTimestamp() + frame->GetDuration()) <= seek_timestamp_) {
359 return; 357 AttemptRead_Locked();
360 } 358 return;
359 }
361 360
362 // Adjust the incoming frame if its rendering stop time is past the duration 361 // Adjust the incoming frame if its rendering stop time is past the duration
363 // of the video itself. This is typically the last frame of the video and 362 // of the video itself. This is typically the last frame of the video and
364 // occurs if the container specifies a duration that isn't a multiple of the 363 // occurs if the container specifies a duration that isn't a multiple of the
365 // frame rate. Another way for this to happen is for the container to state a 364 // frame rate. Another way for this to happen is for the container to state
366 // smaller duration than the largest packet timestamp. 365 // a smaller duration than the largest packet timestamp.
367 if (!frame->IsEndOfStream()) { 366 if (!frame->IsEndOfStream()) {
368 if (frame->GetTimestamp() > host()->GetDuration()) 367 base::TimeDelta duration = host()->GetDuration();
Ami GONE FROM CHROMIUM 2012/01/27 23:44:58 IMO this is a worsening of readability, since ther
acolwell GONE FROM CHROMIUM 2012/01/29 03:00:41 Done.
369 frame->SetTimestamp(host()->GetDuration()); 368 if (frame->GetTimestamp() > duration)
370 if ((frame->GetTimestamp() + frame->GetDuration()) > host()->GetDuration()) 369 frame->SetTimestamp(duration);
371 frame->SetDuration(host()->GetDuration() - frame->GetTimestamp()); 370 if ((frame->GetTimestamp() + frame->GetDuration()) > duration)
372 } 371 frame->SetDuration(duration - frame->GetTimestamp());
372 }
373 373
374 // This one's a keeper! Place it in the ready queue. 374 // This one's a keeper! Place it in the ready queue.
375 ready_frames_.push_back(frame); 375 ready_frames_.push_back(frame);
376 DCHECK_LE(NumFrames_Locked(), limits::kMaxVideoFrames); 376 DCHECK_LE(NumFrames_Locked(), limits::kMaxVideoFrames);
377 frame_available_.Signal(); 377 frame_available_.Signal();
378 378
379 PipelineStatistics statistics; 379 PipelineStatistics statistics;
380 statistics.video_frames_decoded = 1; 380 statistics.video_frames_decoded = 1;
381 statistics_callback_.Run(statistics); 381 statistics_callback_.Run(statistics);
382 382
383 // Always request more decoded video if we have capacity. This serves two 383 // Always request more decoded video if we have capacity. This serves two
384 // purposes: 384 // purposes:
385 // 1) Prerolling while paused 385 // 1) Prerolling while paused
386 // 2) Keeps decoding going if video rendering thread starts falling behind 386 // 2) Keeps decoding going if video rendering thread starts falling behind
387 if (NumFrames_Locked() < limits::kMaxVideoFrames && !frame->IsEndOfStream()) { 387 if (NumFrames_Locked() < limits::kMaxVideoFrames &&
388 AttemptRead_Locked(); 388 !frame->IsEndOfStream()) {
389 return; 389 AttemptRead_Locked();
390 return;
391 }
390 } 392 }
391 393
392 // If we're at capacity or end of stream while seeking we need to transition 394 // If we're at capacity or end of stream while seeking we need to transition
393 // to prerolled. 395 // to prerolled.
394 if (state_ == kSeeking) { 396 if (state_ == kSeeking) {
395 DCHECK(!current_frame_); 397 DCHECK(!current_frame_);
396 state_ = kPrerolled; 398 state_ = kPrerolled;
397 399
398 // Because we might remain in the prerolled state for an undetermined amount 400 // Because we might remain in the prerolled state for an undetermined amount
399 // of time (i.e., we were not playing before we received a seek), we'll 401 // of time (i.e., we were not playing before we received a seek), we'll
(...skipping 70 matching lines...) Expand 10 before | Expand all | Expand 10 after
470 472
471 int VideoRendererBase::NumFrames_Locked() const { 473 int VideoRendererBase::NumFrames_Locked() const {
472 lock_.AssertAcquired(); 474 lock_.AssertAcquired();
473 int outstanding_frames = 475 int outstanding_frames =
474 (current_frame_ ? 1 : 0) + (last_available_frame_ ? 1 : 0) + 476 (current_frame_ ? 1 : 0) + (last_available_frame_ ? 1 : 0) +
475 (current_frame_ && (current_frame_ == last_available_frame_) ? -1 : 0); 477 (current_frame_ && (current_frame_ == last_available_frame_) ? -1 : 0);
476 return ready_frames_.size() + outstanding_frames; 478 return ready_frames_.size() + outstanding_frames;
477 } 479 }
478 480
479 } // namespace media 481 } // namespace media
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698