video_frame_provider_client_impl.cc 5.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183
  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
  3. // found in the LICENSE file.
  4. #include "cc/layers/video_frame_provider_client_impl.h"
  5. #include "base/trace_event/trace_event.h"
  6. #include "cc/base/math_util.h"
  7. #include "cc/layers/video_layer_impl.h"
  8. #include "media/base/video_frame.h"
  9. namespace cc {
  10. // static
  11. scoped_refptr<VideoFrameProviderClientImpl>
  12. VideoFrameProviderClientImpl::Create(VideoFrameProvider* provider,
  13. VideoFrameControllerClient* client) {
  14. return base::WrapRefCounted(
  15. new VideoFrameProviderClientImpl(provider, client));
  16. }
  17. VideoFrameProviderClientImpl::VideoFrameProviderClientImpl(
  18. VideoFrameProvider* provider,
  19. VideoFrameControllerClient* client)
  20. : provider_(provider),
  21. client_(client),
  22. active_video_layer_(nullptr),
  23. stopped_(false),
  24. rendering_(false),
  25. needs_put_current_frame_(false) {
  26. // |provider_| may be null if destructed before the layer.
  27. if (provider_) {
  28. // This only happens during a commit on the compositor thread while the main
  29. // thread is blocked. That makes this a thread-safe call to set the video
  30. // frame provider client that does not require a lock. The same is true of
  31. // the call to Stop().
  32. provider_->SetVideoFrameProviderClient(this);
  33. }
  34. }
  35. VideoFrameProviderClientImpl::~VideoFrameProviderClientImpl() {
  36. DCHECK(thread_checker_.CalledOnValidThread());
  37. DCHECK(stopped_);
  38. }
  39. VideoLayerImpl* VideoFrameProviderClientImpl::ActiveVideoLayer() const {
  40. DCHECK(thread_checker_.CalledOnValidThread());
  41. return active_video_layer_;
  42. }
  43. void VideoFrameProviderClientImpl::SetActiveVideoLayer(
  44. VideoLayerImpl* video_layer) {
  45. DCHECK(thread_checker_.CalledOnValidThread());
  46. DCHECK(video_layer);
  47. active_video_layer_ = video_layer;
  48. }
  49. void VideoFrameProviderClientImpl::Stop() {
  50. DCHECK(thread_checker_.CalledOnValidThread());
  51. active_video_layer_ = nullptr;
  52. // It's called when the main thread is blocked, so lock isn't needed.
  53. if (provider_) {
  54. provider_->SetVideoFrameProviderClient(nullptr);
  55. provider_ = nullptr;
  56. }
  57. if (rendering_)
  58. StopRendering();
  59. stopped_ = true;
  60. }
  61. bool VideoFrameProviderClientImpl::Stopped() const {
  62. DCHECK(thread_checker_.CalledOnValidThread());
  63. return stopped_;
  64. }
  65. scoped_refptr<media::VideoFrame>
  66. VideoFrameProviderClientImpl::AcquireLockAndCurrentFrame() {
  67. DCHECK(thread_checker_.CalledOnValidThread());
  68. provider_lock_.Acquire(); // Balanced by call to ReleaseLock().
  69. if (!provider_)
  70. return nullptr;
  71. return provider_->GetCurrentFrame();
  72. }
  73. void VideoFrameProviderClientImpl::PutCurrentFrame() {
  74. DCHECK(thread_checker_.CalledOnValidThread());
  75. provider_->PutCurrentFrame();
  76. needs_put_current_frame_ = false;
  77. }
  78. void VideoFrameProviderClientImpl::ReleaseLock() {
  79. DCHECK(thread_checker_.CalledOnValidThread());
  80. provider_lock_.Release();
  81. }
  82. bool VideoFrameProviderClientImpl::HasCurrentFrame() {
  83. base::AutoLock locker(provider_lock_);
  84. return provider_ && provider_->HasCurrentFrame();
  85. }
  86. void VideoFrameProviderClientImpl::StopUsingProvider() {
  87. {
  88. // Block the provider from shutting down until this client is done
  89. // using the frame.
  90. base::AutoLock locker(provider_lock_);
  91. provider_ = nullptr;
  92. }
  93. if (rendering_)
  94. StopRendering();
  95. }
  96. void VideoFrameProviderClientImpl::StartRendering() {
  97. DCHECK(thread_checker_.CalledOnValidThread());
  98. TRACE_EVENT0("cc", "VideoFrameProviderClientImpl::StartRendering");
  99. DCHECK(!rendering_);
  100. DCHECK(!stopped_);
  101. rendering_ = true;
  102. client_->AddVideoFrameController(this);
  103. }
  104. void VideoFrameProviderClientImpl::StopRendering() {
  105. DCHECK(thread_checker_.CalledOnValidThread());
  106. TRACE_EVENT0("cc", "VideoFrameProviderClientImpl::StopRendering");
  107. DCHECK(rendering_);
  108. DCHECK(!stopped_);
  109. client_->RemoveVideoFrameController(this);
  110. rendering_ = false;
  111. if (active_video_layer_)
  112. active_video_layer_->SetNeedsRedraw();
  113. }
  114. void VideoFrameProviderClientImpl::DidReceiveFrame() {
  115. TRACE_EVENT1("cc",
  116. "VideoFrameProviderClientImpl::DidReceiveFrame",
  117. "active_video_layer",
  118. !!active_video_layer_);
  119. DCHECK(thread_checker_.CalledOnValidThread());
  120. needs_put_current_frame_ = true;
  121. if (active_video_layer_)
  122. active_video_layer_->SetNeedsRedraw();
  123. }
  124. void VideoFrameProviderClientImpl::OnBeginFrame(
  125. const viz::BeginFrameArgs& args) {
  126. DCHECK(thread_checker_.CalledOnValidThread());
  127. DCHECK(rendering_);
  128. DCHECK(!stopped_);
  129. TRACE_EVENT0("cc", "VideoFrameProviderClientImpl::OnBeginFrame");
  130. {
  131. base::AutoLock locker(provider_lock_);
  132. // We use frame_time + interval here because that is the estimated time at
  133. // which a frame returned during this phase will end up being displayed.
  134. if (!provider_ ||
  135. !provider_->UpdateCurrentFrame(args.frame_time + args.interval,
  136. args.frame_time + 2 * args.interval)) {
  137. return;
  138. }
  139. }
  140. // Warning: Do not hold |provider_lock_| while calling this function, it may
  141. // lead to a reentrant call to HasCurrentFrame() above.
  142. DidReceiveFrame();
  143. }
  144. void VideoFrameProviderClientImpl::DidDrawFrame() {
  145. DCHECK(thread_checker_.CalledOnValidThread());
  146. {
  147. base::AutoLock locker(provider_lock_);
  148. if (provider_ && needs_put_current_frame_)
  149. provider_->PutCurrentFrame();
  150. }
  151. needs_put_current_frame_ = false;
  152. }
  153. bool VideoFrameProviderClientImpl::IsDrivingFrameUpdates() const {
  154. // We drive frame updates any time we're rendering, even if we're off-screen.
  155. return rendering_;
  156. }
  157. } // namespace cc