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

Unified Diff: content/renderer/media/webmediaplayer_ms.cc

Issue 1265433003: Preliminary change for new rtc rendering algorithm (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Use Compositor Thread to Start/Stop Rendering Created 5 years, 4 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 side-by-side diff with in-line comments
Download patch
Index: content/renderer/media/webmediaplayer_ms.cc
diff --git a/content/renderer/media/webmediaplayer_ms.cc b/content/renderer/media/webmediaplayer_ms.cc
index 80bd723099090ab737278b2bbc21ffd751554805..96aff406716c6b4f2997a14f674d3103e84f58fd 100644
--- a/content/renderer/media/webmediaplayer_ms.cc
+++ b/content/renderer/media/webmediaplayer_ms.cc
@@ -12,6 +12,7 @@
#include "base/metrics/histogram.h"
#include "cc/blink/context_provider_web_context.h"
#include "cc/blink/web_layer_impl.h"
+#include "cc/layers/video_frame_provider_client_impl.h"
#include "cc/layers/video_layer.h"
#include "content/public/renderer/media_stream_audio_renderer.h"
#include "content/public/renderer/media_stream_renderer_factory.h"
@@ -93,7 +94,8 @@ WebMediaPlayerMS::WebMediaPlayerMS(
blink::WebMediaPlayerClient* client,
base::WeakPtr<media::WebMediaPlayerDelegate> delegate,
media::MediaLog* media_log,
- scoped_ptr<MediaStreamRendererFactory> factory)
+ scoped_ptr<MediaStreamRendererFactory> factory,
+ scoped_refptr<base::SingleThreadTaskRunner> compositor_thread)
: frame_(frame),
network_state_(WebMediaPlayer::NetworkStateEmpty),
ready_state_(WebMediaPlayer::ReadyStateHaveNothing),
@@ -108,7 +110,9 @@ WebMediaPlayerMS::WebMediaPlayerMS(
total_frame_count_(0),
dropped_frame_count_(0),
media_log_(media_log),
- renderer_factory_(factory.Pass()) {
+ renderer_factory_(factory.Pass()),
+ compositor_thread_(compositor_thread),
+ wait_event_(false,false) {
DVLOG(1) << "WebMediaPlayerMS::ctor";
media_log_->AddEvent(
media_log_->CreateEvent(media::MediaLogEvent::WEBMEDIAPLAYER_CREATED));
@@ -118,7 +122,20 @@ WebMediaPlayerMS::~WebMediaPlayerMS() {
DVLOG(1) << "WebMediaPlayerMS::dtor";
DCHECK(thread_checker_.CalledOnValidThread());
- SetVideoFrameProviderClient(NULL);
+ // Wait till stop procedure finishes to avoid the case that after
+ // WebMediaPlayerMS is destroyed, VideoFrameProvider is still trying to access
+ // it.
+
+ if (video_frame_provider_client_){
+ compositor_thread_->PostTask(
+ FROM_HERE,
+ base::Bind(
+ &WebMediaPlayerMS::StopVideoFrameProviderAndWakeUpHelper,
+ video_frame_provider_client_,
+ &wait_event_));
+ wait_event_.Wait();
DaleCurtis 2015/08/13 18:06:53 Hmm, this is unfortunate. Typically you'd use Comp
qiangchen 2015/08/14 16:52:50 Done.
+ }
+
GetClient()->setWebLayer(NULL);
if (video_frame_provider_.get())
@@ -187,6 +204,13 @@ void WebMediaPlayerMS::play() {
if (video_frame_provider_.get())
video_frame_provider_->Play();
+ if (video_frame_provider_client_){
+ compositor_thread_->PostTask(
+ FROM_HERE,
+ base::Bind(&WebMediaPlayerMS::StartRenderingHelper,
+ video_frame_provider_client_));
+ }
+
if (audio_renderer_.get())
audio_renderer_->Play();
@@ -206,6 +230,13 @@ void WebMediaPlayerMS::pause() {
if (video_frame_provider_.get())
video_frame_provider_->Pause();
+ if (video_frame_provider_client_){
+ compositor_thread_->PostTask(
+ FROM_HERE,
+ base::Bind(&WebMediaPlayerMS::StopRenderingHelper,
+ video_frame_provider_client_));
+ }
+
if (!paused_) {
if (audio_renderer_.get())
audio_renderer_->Pause();
@@ -449,16 +480,60 @@ void WebMediaPlayerMS::SetVideoFrameProviderClient(
// This is called from both the main renderer thread and the compositor
// thread (when the main thread is blocked).
if (video_frame_provider_client_)
- video_frame_provider_client_->StopUsingProvider();
+ compositor_thread_->PostTask(
+ FROM_HERE,
+ base::Bind(
+ &WebMediaPlayerMS::StopVideoFrameProviderHelper,
+ video_frame_provider_client_));
+
video_frame_provider_client_ = client;
+ if (client && !paused_)
+ compositor_thread_->PostTask(
+ FROM_HERE,
+ base::Bind(&WebMediaPlayerMS::StartRenderingHelper,
+ video_frame_provider_client_));
+}
+
+void WebMediaPlayerMS::StopVideoFrameProviderAndWakeUpHelper(
+ cc::VideoFrameProvider::Client* client,
+ base::WaitableEvent* event) {
+ client->StopUsingProvider();
+ event->Signal();
+}
+
+void WebMediaPlayerMS::StopVideoFrameProviderHelper(
+ cc::VideoFrameProvider::Client* client) {
+ client->StopUsingProvider();
+}
+
+void WebMediaPlayerMS::StartRenderingHelper(
+ cc::VideoFrameProvider::Client* client) {
+ client->StartRendering();
+}
+
+void WebMediaPlayerMS::StopRenderingHelper(
+ cc::VideoFrameProvider::Client* client) {
+ client->StopRendering();
}
bool WebMediaPlayerMS::UpdateCurrentFrame(base::TimeTicks deadline_min,
base::TimeTicks deadline_max) {
+ TRACE_EVENT_BEGIN2("webrtc", "WebMediaPlayerMS::UpdateCurrentFrame",
+ "Actual Render Begin", deadline_min.ToInternalValue(),
+ "Actual Render End", deadline_max.ToInternalValue());
+ last_deadline_max_ = deadline_max;
+
// TODO(dalecurtis): This should make use of the deadline interval to ensure
// the painted frame is correct for the given interval.
- NOTREACHED();
- return false;
+
+ base::TimeTicks render_time;
+ if (!current_frame_->metadata()->GetTimeTicks(
+ media::VideoFrameMetadata::REFERENCE_TIME, &render_time)) {
+ render_time = base::TimeTicks();
+ }
+ TRACE_EVENT_END1("webrtc", "WebMediaPlayerMS::UpdateCurrentFrame",
+ "Ideal Render Instant", render_time.ToInternalValue());
+ return !current_frame_used_;
}
bool WebMediaPlayerMS::HasCurrentFrame() {
@@ -483,6 +558,15 @@ void WebMediaPlayerMS::OnFrameAvailable(
const scoped_refptr<media::VideoFrame>& frame) {
DVLOG(3) << "WebMediaPlayerMS::OnFrameAvailable";
DCHECK(thread_checker_.CalledOnValidThread());
+
+ base::TimeTicks render_time;
+ if (!frame->metadata()->GetTimeTicks(
+ media::VideoFrameMetadata::REFERENCE_TIME, &render_time)) {
+ render_time = base::TimeTicks();
+ }
+ TRACE_EVENT1("webrtc", "WebMediaPlayerMS::OnFrameAvailable",
+ "Ideal Render Instant", render_time.ToInternalValue());
+
++total_frame_count_;
if (!received_first_frame_) {
received_first_frame_ = true;
@@ -508,6 +592,16 @@ void WebMediaPlayerMS::OnFrameAvailable(
if (paused_)
return;
+ if (base::TimeTicks::Now() > last_deadline_max_){
+ // TODO(qiangchen): Theoretically Now is between
+ // [last_deadline_min_ - vsync_duration, last_deadline_min]. If Now is later
+ // than last_deadline_max, it means UpdateCurrentFrame does not get called
+ // for 2 vsyncs. A probable cause is that the video tag is invisible, but we
+ // have to let old frames go (VRA::RemoveExpiredFrames), otherwise frames
+ // will pile up, and when we use up all frame buffers, decoder will be
+ // stuck.
+ }
+
bool size_changed = !current_frame_.get() ||
current_frame_->natural_size() != frame->natural_size();
@@ -522,8 +616,6 @@ void WebMediaPlayerMS::OnFrameAvailable(
if (size_changed)
GetClient()->sizeChanged();
-
- GetClient()->repaint();
}
void WebMediaPlayerMS::RepaintInternal() {
« no previous file with comments | « content/renderer/media/webmediaplayer_ms.h ('k') | content/renderer/media/webrtc/media_stream_remote_video_source.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698