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

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

Issue 2969093002: Make rendering of MediaStreams reflect changes to its set of tracks. (Closed)
Patch Set: rebase Created 3 years, 5 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
« no previous file with comments | « content/renderer/media/webmediaplayer_ms.h ('k') | content/shell/test_runner/mock_web_user_media_client.cc » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: content/renderer/media/webmediaplayer_ms.cc
diff --git a/content/renderer/media/webmediaplayer_ms.cc b/content/renderer/media/webmediaplayer_ms.cc
index 87ab3a76d4a1cf3a8955c03bcba9ae0d386eed61..e9c0723231b4665afebf03e9c7f84eca6dfa432e 100644
--- a/content/renderer/media/webmediaplayer_ms.cc
+++ b/content/renderer/media/webmediaplayer_ms.cc
@@ -20,6 +20,8 @@
#include "content/public/renderer/media_stream_audio_renderer.h"
#include "content/public/renderer/media_stream_renderer_factory.h"
#include "content/public/renderer/media_stream_video_renderer.h"
+#include "content/renderer/media/media_stream_audio_track.h"
+#include "content/renderer/media/media_stream_video_track.h"
#include "content/renderer/media/web_media_element_source_utils.h"
#include "content/renderer/media/webmediaplayer_ms_compositor.h"
#include "content/renderer/media/webrtc_logging.h"
@@ -39,6 +41,14 @@
#include "third_party/WebKit/public/platform/WebSize.h"
#include "third_party/WebKit/public/web/WebLocalFrame.h"
+namespace {
+enum class RendererReloadAction {
+ KEEP_RENDERER,
+ REMOVE_RENDERER,
+ NEW_RENDERER
+};
+} // namespace
+
namespace content {
// FrameDeliverer is responsible for delivering frames received on
@@ -191,6 +201,12 @@ WebMediaPlayerMS::~WebMediaPlayerMS() {
DVLOG(1) << __func__;
DCHECK(thread_checker_.CalledOnValidThread());
+ if (!web_stream_.IsNull()) {
+ MediaStream* native_stream = MediaStream::GetMediaStream(web_stream_);
+ if (native_stream)
+ native_stream->RemoveObserver(this);
+ }
+
// Destruct compositor resources in the proper order.
get_client()->SetWebLayer(nullptr);
if (video_weblayer_)
@@ -224,24 +240,29 @@ void WebMediaPlayerMS::Load(LoadType load_type,
// TODO(acolwell): Change this to DCHECK_EQ(load_type, LoadTypeMediaStream)
// once Blink-side changes land.
DCHECK_NE(load_type, kLoadTypeMediaSource);
- blink::WebMediaStream web_stream =
- GetWebMediaStreamFromWebMediaPlayerSource(source);
+ web_stream_ = GetWebMediaStreamFromWebMediaPlayerSource(source);
+ if (!web_stream_.IsNull()) {
+ MediaStream* native_stream = MediaStream::GetMediaStream(web_stream_);
+ if (native_stream)
+ native_stream->AddObserver(this);
+ }
compositor_ = new WebMediaPlayerMSCompositor(
- compositor_task_runner_, io_task_runner_, web_stream, AsWeakPtr());
+ compositor_task_runner_, io_task_runner_, web_stream_, AsWeakPtr());
SetNetworkState(WebMediaPlayer::kNetworkStateLoading);
SetReadyState(WebMediaPlayer::kReadyStateHaveNothing);
std::string stream_id =
- web_stream.IsNull() ? std::string() : web_stream.Id().Utf8();
+ web_stream_.IsNull() ? std::string() : web_stream_.Id().Utf8();
media_log_->AddEvent(media_log_->CreateLoadEvent(stream_id));
frame_deliverer_.reset(new WebMediaPlayerMS::FrameDeliverer(
AsWeakPtr(),
base::Bind(&WebMediaPlayerMSCompositor::EnqueueFrame, compositor_)));
video_frame_provider_ = renderer_factory_->GetVideoRenderer(
- web_stream, media::BindToCurrentLoop(base::Bind(
- &WebMediaPlayerMS::OnSourceError, AsWeakPtr())),
+ web_stream_,
+ media::BindToCurrentLoop(
+ base::Bind(&WebMediaPlayerMS::OnSourceError, AsWeakPtr())),
frame_deliverer_->GetRepaintCallback(), io_task_runner_,
media_task_runner_, worker_task_runner_, gpu_factories_);
@@ -258,7 +279,7 @@ void WebMediaPlayerMS::Load(LoadType load_type,
}
audio_renderer_ = renderer_factory_->GetAudioRenderer(
- web_stream, routing_id, initial_audio_output_device_id_,
+ web_stream_, routing_id, initial_audio_output_device_id_,
initial_security_origin_);
if (!audio_renderer_)
@@ -272,10 +293,27 @@ void WebMediaPlayerMS::Load(LoadType load_type,
if (audio_renderer_) {
audio_renderer_->SetVolume(volume_);
audio_renderer_->Start();
+
+ // Store the ID of audio track being played in |current_video_track_id_|
+ blink::WebVector<blink::WebMediaStreamTrack> audio_tracks;
+ if (!web_stream_.IsNull()) {
+ web_stream_.AudioTracks(audio_tracks);
+ DCHECK_GT(audio_tracks.size(), 0U);
+ current_audio_track_id_ = audio_tracks[0].Id();
+ }
}
- if (video_frame_provider_)
+
+ if (video_frame_provider_) {
video_frame_provider_->Start();
+ // Store the ID of video track being played in |current_video_track_id_|
+ if (!web_stream_.IsNull()) {
+ blink::WebVector<blink::WebMediaStreamTrack> video_tracks;
+ web_stream_.VideoTracks(video_tracks);
+ DCHECK_GT(video_tracks.size(), 0U);
+ current_video_track_id_ = video_tracks[0].Id();
+ }
+ }
// When associated with an <audio> element, we don't want to wait for the
// first video fram to become available as we do for <video> elements
// (<audio> elements can also be assigned video tracks).
@@ -288,6 +326,113 @@ void WebMediaPlayerMS::Load(LoadType load_type,
}
}
+void WebMediaPlayerMS::TrackAdded(const blink::WebMediaStreamTrack& track) {
+ Reload();
+}
+
+void WebMediaPlayerMS::TrackRemoved(const blink::WebMediaStreamTrack& track) {
+ Reload();
+}
+
+void WebMediaPlayerMS::Reload() {
+ DCHECK(thread_checker_.CalledOnValidThread());
+ if (web_stream_.IsNull())
+ return;
+
+ ReloadVideo();
+ ReloadAudio();
+}
+
+void WebMediaPlayerMS::ReloadVideo() {
+ DCHECK(thread_checker_.CalledOnValidThread());
+ DCHECK(!web_stream_.IsNull());
+ blink::WebVector<blink::WebMediaStreamTrack> video_tracks;
+ // VideoTracks() is a getter.
+ web_stream_.VideoTracks(video_tracks);
+
+ RendererReloadAction renderer_action = RendererReloadAction::KEEP_RENDERER;
+ if (video_tracks.IsEmpty()) {
+ if (video_frame_provider_)
+ renderer_action = RendererReloadAction::REMOVE_RENDERER;
+ current_video_track_id_ = blink::WebString();
+ } else if (video_tracks[0].Id() != current_video_track_id_) {
+ renderer_action = RendererReloadAction::NEW_RENDERER;
+ current_video_track_id_ = video_tracks[0].Id();
+ }
+
+ switch (renderer_action) {
+ case RendererReloadAction::NEW_RENDERER:
+ if (video_frame_provider_)
+ video_frame_provider_->Stop();
+
+ video_frame_provider_ = renderer_factory_->GetVideoRenderer(
+ web_stream_,
+ media::BindToCurrentLoop(
+ base::Bind(&WebMediaPlayerMS::OnSourceError, AsWeakPtr())),
+ frame_deliverer_->GetRepaintCallback(), io_task_runner_,
+ media_task_runner_, worker_task_runner_, gpu_factories_);
+ DCHECK(video_frame_provider_);
+ video_frame_provider_->Start();
+ break;
+
+ case RendererReloadAction::REMOVE_RENDERER:
+ video_frame_provider_->Stop();
+ video_frame_provider_ = nullptr;
+ break;
+
+ default:
+ return;
+ }
+
+ DCHECK_NE(renderer_action, RendererReloadAction::KEEP_RENDERER);
+ if (!paused_)
+ delegate_->DidPlayerSizeChange(delegate_id_, NaturalSize());
+}
+
+void WebMediaPlayerMS::ReloadAudio() {
+ DCHECK(thread_checker_.CalledOnValidThread());
+ DCHECK(!web_stream_.IsNull());
+ RenderFrame* const frame = RenderFrame::FromWebFrame(frame_);
+ if (!frame)
+ return;
+
+ blink::WebVector<blink::WebMediaStreamTrack> audio_tracks;
+ // AudioTracks() is a getter.
+ web_stream_.AudioTracks(audio_tracks);
+
+ RendererReloadAction renderer_action = RendererReloadAction::KEEP_RENDERER;
+ if (audio_tracks.IsEmpty()) {
+ if (audio_renderer_)
+ renderer_action = RendererReloadAction::REMOVE_RENDERER;
+ current_audio_track_id_ = blink::WebString();
+ } else if (audio_tracks[0].Id() != current_video_track_id_) {
+ renderer_action = RendererReloadAction::NEW_RENDERER;
+ current_audio_track_id_ = audio_tracks[0].Id();
+ }
+
+ switch (renderer_action) {
+ case RendererReloadAction::NEW_RENDERER:
+ if (audio_renderer_)
+ audio_renderer_->Stop();
+
+ audio_renderer_ = renderer_factory_->GetAudioRenderer(
+ web_stream_, frame->GetRoutingID(), initial_audio_output_device_id_,
+ initial_security_origin_);
+ audio_renderer_->SetVolume(volume_);
+ audio_renderer_->Start();
+ audio_renderer_->Play();
+ break;
+
+ case RendererReloadAction::REMOVE_RENDERER:
+ audio_renderer_->Stop();
+ audio_renderer_ = nullptr;
+ break;
+
+ default:
+ break;
+ }
+}
+
void WebMediaPlayerMS::Play() {
DVLOG(1) << __func__;
DCHECK(thread_checker_.CalledOnValidThread());
@@ -394,6 +539,9 @@ bool WebMediaPlayerMS::HasAudio() const {
blink::WebSize WebMediaPlayerMS::NaturalSize() const {
DCHECK(thread_checker_.CalledOnValidThread());
+ if (!video_frame_provider_)
+ return blink::WebSize();
+
if (video_rotation_ == media::VIDEO_ROTATION_90 ||
video_rotation_ == media::VideoRotation::VIDEO_ROTATION_270) {
const gfx::Size& current_size = compositor_->GetCurrentSize();
« no previous file with comments | « content/renderer/media/webmediaplayer_ms.h ('k') | content/shell/test_runner/mock_web_user_media_client.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698