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

Side by Side Diff: media/renderers/video_renderer_impl.cc

Issue 1878783002: Cache effective frame count. Make expired frame count useful. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Clarify comment. Created 4 years, 8 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/renderers/video_renderer_impl.h ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2013 The Chromium Authors. All rights reserved. 1 // Copyright 2013 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/renderers/video_renderer_impl.h" 5 #include "media/renderers/video_renderer_impl.h"
6 6
7 #include <utility> 7 #include <utility>
8 8
9 #include "base/bind.h" 9 #include "base/bind.h"
10 #include "base/callback.h" 10 #include "base/callback.h"
(...skipping 183 matching lines...) Expand 10 before | Expand all | Expand 10 after
194 // 194 //
195 // We use the inverse of |render_first_frame_and_stop_| as a proxy for the 195 // We use the inverse of |render_first_frame_and_stop_| as a proxy for the
196 // value of |time_progressing_| here since we can't access it from the 196 // value of |time_progressing_| here since we can't access it from the
197 // compositor thread. If we're here (in Render()) the sink must have been 197 // compositor thread. If we're here (in Render()) the sink must have been
198 // started -- but if it was started only to render the first frame and stop, 198 // started -- but if it was started only to render the first frame and stop,
199 // then |time_progressing_| is likely false. If we're still in Render() when 199 // then |time_progressing_| is likely false. If we're still in Render() when
200 // |render_first_frame_and_stop_| is false, then |time_progressing_| is true. 200 // |render_first_frame_and_stop_| is false, then |time_progressing_| is true.
201 // If |time_progressing_| is actually true when |render_first_frame_and_stop_| 201 // If |time_progressing_| is actually true when |render_first_frame_and_stop_|
202 // is also true, then the ended callback will be harmlessly delayed until 202 // is also true, then the ended callback will be harmlessly delayed until
203 // MaybeStopSinkAfterFirstPaint() runs and the next Render() call comes in. 203 // MaybeStopSinkAfterFirstPaint() runs and the next Render() call comes in.
204 const size_t effective_frames = 204 MaybeFireEndedCallback_Locked(!render_first_frame_and_stop_);
205 MaybeFireEndedCallback_Locked(!render_first_frame_and_stop_);
206 if (buffering_state_ == BUFFERING_HAVE_ENOUGH && !received_end_of_stream_ && 205 if (buffering_state_ == BUFFERING_HAVE_ENOUGH && !received_end_of_stream_ &&
207 !effective_frames && (!background_rendering || 206 !algorithm_->effective_frames_queued() &&
208 (!frames_decoded_ && was_background_rendering_))) { 207 (!background_rendering ||
208 (!frames_decoded_ && was_background_rendering_))) {
209 // Do not set |buffering_state_| here as the lock in FrameReady() may be 209 // Do not set |buffering_state_| here as the lock in FrameReady() may be
210 // held already and it fire the state changes in the wrong order. 210 // held already and it fire the state changes in the wrong order.
211 task_runner_->PostTask( 211 task_runner_->PostTask(
212 FROM_HERE, base::Bind(&VideoRendererImpl::TransitionToHaveNothing, 212 FROM_HERE, base::Bind(&VideoRendererImpl::TransitionToHaveNothing,
213 weak_factory_.GetWeakPtr())); 213 weak_factory_.GetWeakPtr()));
214 } 214 }
215 215
216 // We don't count dropped frames in the background to avoid skewing the count 216 // We don't count dropped frames in the background to avoid skewing the count
217 // and impacting JavaScript visible metrics used by web developers. 217 // and impacting JavaScript visible metrics used by web developers.
218 // 218 //
(...skipping 113 matching lines...) Expand 10 before | Expand all | Expand 10 after
332 if (sequence_token != sequence_token_) 332 if (sequence_token != sequence_token_)
333 return; 333 return;
334 334
335 DCHECK_NE(state_, kUninitialized); 335 DCHECK_NE(state_, kUninitialized);
336 DCHECK_NE(state_, kFlushed); 336 DCHECK_NE(state_, kFlushed);
337 337
338 CHECK(pending_read_); 338 CHECK(pending_read_);
339 pending_read_ = false; 339 pending_read_ = false;
340 340
341 if (status == VideoFrameStream::DECODE_ERROR) { 341 if (status == VideoFrameStream::DECODE_ERROR) {
342 DCHECK(!frame.get()); 342 DCHECK(!frame);
343 PipelineStatus error = PIPELINE_ERROR_DECODE; 343 PipelineStatus error = PIPELINE_ERROR_DECODE;
344 task_runner_->PostTask(FROM_HERE, base::Bind(error_cb_, error)); 344 task_runner_->PostTask(FROM_HERE, base::Bind(error_cb_, error));
345 return; 345 return;
346 } 346 }
347 347
348 // Already-queued VideoFrameStream ReadCB's can fire after various state 348 // Already-queued VideoFrameStream ReadCB's can fire after various state
349 // transitions have happened; in that case just drop those frames 349 // transitions have happened; in that case just drop those frames
350 // immediately. 350 // immediately.
351 if (state_ == kFlushing) 351 if (state_ == kFlushing)
352 return; 352 return;
353 353
354 DCHECK_EQ(state_, kPlaying); 354 DCHECK_EQ(state_, kPlaying);
355 355
356 // Can happen when demuxers are preparing for a new Seek(). 356 // Can happen when demuxers are preparing for a new Seek().
357 if (!frame.get()) { 357 if (!frame) {
358 DCHECK_EQ(status, VideoFrameStream::DEMUXER_READ_ABORTED); 358 DCHECK_EQ(status, VideoFrameStream::DEMUXER_READ_ABORTED);
359 return; 359 return;
360 } 360 }
361 361
362 if (frame->metadata()->IsTrue(VideoFrameMetadata::END_OF_STREAM)) { 362 if (frame->metadata()->IsTrue(VideoFrameMetadata::END_OF_STREAM)) {
363 DCHECK(!received_end_of_stream_); 363 DCHECK(!received_end_of_stream_);
364 received_end_of_stream_ = true; 364 received_end_of_stream_ = true;
365 365
366 // See if we can fire EOS immediately instead of waiting for Render(). 366 // See if we can fire EOS immediately instead of waiting for Render().
367 MaybeFireEndedCallback_Locked(time_progressing_); 367 MaybeFireEndedCallback_Locked(time_progressing_);
(...skipping 200 matching lines...) Expand 10 before | Expand all | Expand 10 after
568 render_first_frame_and_stop_ = false; 568 render_first_frame_and_stop_ = false;
569 } 569 }
570 570
571 bool VideoRendererImpl::HaveReachedBufferingCap() { 571 bool VideoRendererImpl::HaveReachedBufferingCap() {
572 DCHECK(task_runner_->BelongsToCurrentThread()); 572 DCHECK(task_runner_->BelongsToCurrentThread());
573 const size_t kMaxVideoFrames = limits::kMaxVideoFrames; 573 const size_t kMaxVideoFrames = limits::kMaxVideoFrames;
574 574
575 // When the display rate is less than the frame rate, the effective frames 575 // When the display rate is less than the frame rate, the effective frames
576 // queued may be much smaller than the actual number of frames queued. Here 576 // queued may be much smaller than the actual number of frames queued. Here
577 // we ensure that frames_queued() doesn't get excessive. 577 // we ensure that frames_queued() doesn't get excessive.
578 return algorithm_->EffectiveFramesQueued() >= kMaxVideoFrames || 578 return algorithm_->effective_frames_queued() >= kMaxVideoFrames ||
579 algorithm_->frames_queued() >= 3 * kMaxVideoFrames; 579 algorithm_->frames_queued() >= 3 * kMaxVideoFrames;
580 } 580 }
581 581
582 void VideoRendererImpl::StartSink() { 582 void VideoRendererImpl::StartSink() {
583 DCHECK(task_runner_->BelongsToCurrentThread()); 583 DCHECK(task_runner_->BelongsToCurrentThread());
584 DCHECK_GT(algorithm_->frames_queued(), 0u); 584 DCHECK_GT(algorithm_->frames_queued(), 0u);
585 sink_started_ = true; 585 sink_started_ = true;
586 was_background_rendering_ = false; 586 was_background_rendering_ = false;
587 sink_->Start(this); 587 sink_->Start(this);
588 } 588 }
589 589
590 void VideoRendererImpl::StopSink() { 590 void VideoRendererImpl::StopSink() {
591 DCHECK(task_runner_->BelongsToCurrentThread()); 591 DCHECK(task_runner_->BelongsToCurrentThread());
592 sink_->Stop(); 592 sink_->Stop();
593 algorithm_->set_time_stopped(); 593 algorithm_->set_time_stopped();
594 sink_started_ = false; 594 sink_started_ = false;
595 was_background_rendering_ = false; 595 was_background_rendering_ = false;
596 } 596 }
597 597
598 size_t VideoRendererImpl::MaybeFireEndedCallback_Locked(bool time_progressing) { 598 void VideoRendererImpl::MaybeFireEndedCallback_Locked(bool time_progressing) {
599 lock_.AssertAcquired(); 599 lock_.AssertAcquired();
600 600
601 // If there's only one frame in the video or Render() was never called, the 601 // If there's only one frame in the video or Render() was never called, the
602 // algorithm will have one frame linger indefinitely. So in cases where the 602 // algorithm will have one frame linger indefinitely. So in cases where the
603 // frame duration is unknown and we've received EOS, fire it once we get down 603 // frame duration is unknown and we've received EOS, fire it once we get down
604 // to a single frame. 604 // to a single frame.
605 const size_t effective_frames = algorithm_->EffectiveFramesQueued();
606 605
607 // Don't fire ended if we haven't received EOS or have already done so. 606 // Don't fire ended if we haven't received EOS or have already done so.
608 if (!received_end_of_stream_ || rendered_end_of_stream_) 607 if (!received_end_of_stream_ || rendered_end_of_stream_)
609 return effective_frames; 608 return;
610 609
611 // Don't fire ended if time isn't moving and we have frames. 610 // Don't fire ended if time isn't moving and we have frames.
612 if (!time_progressing && algorithm_->frames_queued()) 611 if (!time_progressing && algorithm_->frames_queued())
613 return effective_frames; 612 return;
614 613
615 // Fire ended if we have no more effective frames or only ever had one frame. 614 // Fire ended if we have no more effective frames or only ever had one frame.
616 if (!effective_frames || 615 if (!algorithm_->effective_frames_queued() ||
617 (algorithm_->frames_queued() == 1u && 616 (algorithm_->frames_queued() == 1u &&
618 algorithm_->average_frame_duration() == base::TimeDelta())) { 617 algorithm_->average_frame_duration().is_zero())) {
619 rendered_end_of_stream_ = true; 618 rendered_end_of_stream_ = true;
620 task_runner_->PostTask(FROM_HERE, ended_cb_); 619 task_runner_->PostTask(FROM_HERE, ended_cb_);
621 } 620 }
622
623 return effective_frames;
624 } 621 }
625 622
626 base::TimeTicks VideoRendererImpl::ConvertMediaTimestamp( 623 base::TimeTicks VideoRendererImpl::ConvertMediaTimestamp(
627 base::TimeDelta media_time) { 624 base::TimeDelta media_time) {
628 std::vector<base::TimeDelta> media_times(1, media_time); 625 std::vector<base::TimeDelta> media_times(1, media_time);
629 std::vector<base::TimeTicks> wall_clock_times; 626 std::vector<base::TimeTicks> wall_clock_times;
630 if (!wall_clock_time_cb_.Run(media_times, &wall_clock_times)) 627 if (!wall_clock_time_cb_.Run(media_times, &wall_clock_times))
631 return base::TimeTicks(); 628 return base::TimeTicks();
632 return wall_clock_times[0]; 629 return wall_clock_times[0];
633 } 630 }
634 631
635 base::TimeTicks VideoRendererImpl::GetCurrentMediaTimeAsWallClockTime() { 632 base::TimeTicks VideoRendererImpl::GetCurrentMediaTimeAsWallClockTime() {
636 std::vector<base::TimeTicks> current_time; 633 std::vector<base::TimeTicks> current_time;
637 wall_clock_time_cb_.Run(std::vector<base::TimeDelta>(), &current_time); 634 wall_clock_time_cb_.Run(std::vector<base::TimeDelta>(), &current_time);
638 return current_time[0]; 635 return current_time[0];
639 } 636 }
640 637
641 bool VideoRendererImpl::IsBeforeStartTime(base::TimeDelta timestamp) { 638 bool VideoRendererImpl::IsBeforeStartTime(base::TimeDelta timestamp) {
642 return timestamp + video_frame_stream_->AverageDuration() < start_timestamp_; 639 return timestamp + video_frame_stream_->AverageDuration() < start_timestamp_;
643 } 640 }
644 641
645 } // namespace media 642 } // namespace media
OLDNEW
« no previous file with comments | « media/renderers/video_renderer_impl.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698