summaryrefslogtreecommitdiff
path: root/chromium/media
diff options
context:
space:
mode:
Diffstat (limited to 'chromium/media')
-rw-r--r--chromium/media/audio/audio_input_device.cc10
-rw-r--r--chromium/media/audio/audio_input_device.h3
-rw-r--r--chromium/media/audio/audio_output_device.cc22
-rw-r--r--chromium/media/audio/audio_output_device.h4
-rw-r--r--chromium/media/blink/video_frame_compositor.cc43
-rw-r--r--chromium/media/blink/video_frame_compositor.h32
-rw-r--r--chromium/media/blink/video_frame_compositor_unittest.cc37
-rw-r--r--chromium/media/blink/watch_time_reporter_unittest.cc7
-rw-r--r--chromium/media/blink/webmediaplayer_impl.cc52
-rw-r--r--chromium/media/blink/webmediaplayer_impl.h8
-rw-r--r--chromium/media/midi/midi_manager_mac.cc3
-rw-r--r--chromium/media/mojo/interfaces/watch_time_recorder.mojom7
-rw-r--r--chromium/media/mojo/services/watch_time_recorder.cc7
-rw-r--r--chromium/media/mojo/services/watch_time_recorder_unittest.cc14
14 files changed, 123 insertions, 126 deletions
diff --git a/chromium/media/audio/audio_input_device.cc b/chromium/media/audio/audio_input_device.cc
index 290102d4b7f..9b8ccfa6bcf 100644
--- a/chromium/media/audio/audio_input_device.cc
+++ b/chromium/media/audio/audio_input_device.cc
@@ -104,6 +104,14 @@ AudioInputDevice::AudioInputDevice(
void AudioInputDevice::Initialize(const AudioParameters& params,
CaptureCallback* callback,
int session_id) {
+ task_runner()->PostTask(
+ FROM_HERE, base::BindOnce(&AudioInputDevice::InitializeOnIOThread, this,
+ params, callback, session_id));
+}
+
+void AudioInputDevice::InitializeOnIOThread(const AudioParameters& params,
+ CaptureCallback* callback,
+ int session_id) {
DCHECK(params.IsValid());
DCHECK(!callback_);
DCHECK_EQ(0, session_id_);
@@ -113,7 +121,6 @@ void AudioInputDevice::Initialize(const AudioParameters& params,
}
void AudioInputDevice::Start() {
- DCHECK(callback_) << "Initialize hasn't been called";
DVLOG(1) << "Start()";
task_runner()->PostTask(
FROM_HERE, base::BindOnce(&AudioInputDevice::StartUpOnIOThread, this));
@@ -275,6 +282,7 @@ AudioInputDevice::~AudioInputDevice() {
void AudioInputDevice::StartUpOnIOThread() {
DCHECK(task_runner()->BelongsToCurrentThread());
+ DCHECK(callback_) << "Initialize hasn't been called";
// Make sure we don't call Start() more than once.
if (state_ != IDLE)
diff --git a/chromium/media/audio/audio_input_device.h b/chromium/media/audio/audio_input_device.h
index 20c906cc5ce..9e99b70b5fd 100644
--- a/chromium/media/audio/audio_input_device.h
+++ b/chromium/media/audio/audio_input_device.h
@@ -124,6 +124,9 @@ class MEDIA_EXPORT AudioInputDevice : public AudioCapturerSource,
// The following methods are tasks posted on the IO thread that needs to
// be executed on that thread. They interact with AudioInputMessageFilter and
// sends IPC messages on that thread.
+ void InitializeOnIOThread(const AudioParameters& params,
+ CaptureCallback* callback,
+ int session_id);
void StartUpOnIOThread();
void ShutDownOnIOThread();
void SetVolumeOnIOThread(double volume);
diff --git a/chromium/media/audio/audio_output_device.cc b/chromium/media/audio/audio_output_device.cc
index 336f040c650..3789f45a7e5 100644
--- a/chromium/media/audio/audio_output_device.cc
+++ b/chromium/media/audio/audio_output_device.cc
@@ -88,6 +88,13 @@ AudioOutputDevice::AudioOutputDevice(
void AudioOutputDevice::Initialize(const AudioParameters& params,
RenderCallback* callback) {
+ task_runner()->PostTask(
+ FROM_HERE, base::BindOnce(&AudioOutputDevice::InitializeOnIOThread, this,
+ params, callback));
+}
+
+void AudioOutputDevice::InitializeOnIOThread(const AudioParameters& params,
+ RenderCallback* callback) {
DCHECK(!callback_) << "Calling Initialize() twice?";
DCHECK(params.IsValid());
audio_parameters_ = params;
@@ -114,10 +121,8 @@ void AudioOutputDevice::RequestDeviceAuthorization() {
}
void AudioOutputDevice::Start() {
- DCHECK(callback_) << "Initialize hasn't been called";
- task_runner()->PostTask(FROM_HERE,
- base::Bind(&AudioOutputDevice::CreateStreamOnIOThread, this,
- audio_parameters_));
+ task_runner()->PostTask(
+ FROM_HERE, base::Bind(&AudioOutputDevice::CreateStreamOnIOThread, this));
}
void AudioOutputDevice::Stop() {
@@ -196,8 +201,9 @@ void AudioOutputDevice::RequestDeviceAuthorizationOnIOThread() {
}
}
-void AudioOutputDevice::CreateStreamOnIOThread(const AudioParameters& params) {
+void AudioOutputDevice::CreateStreamOnIOThread() {
DCHECK(task_runner()->BelongsToCurrentThread());
+ DCHECK(callback_) << "Initialize hasn't been called";
switch (state_) {
case IPC_CLOSED:
if (callback_)
@@ -208,7 +214,7 @@ void AudioOutputDevice::CreateStreamOnIOThread(const AudioParameters& params) {
if (did_receive_auth_.IsSignaled() && device_id_.empty() &&
security_origin_.unique()) {
state_ = CREATING_STREAM;
- ipc_->CreateStream(this, params);
+ ipc_->CreateStream(this, audio_parameters_);
} else {
RequestDeviceAuthorizationOnIOThread();
start_on_authorized_ = true;
@@ -221,7 +227,7 @@ void AudioOutputDevice::CreateStreamOnIOThread(const AudioParameters& params) {
case AUTHORIZED:
state_ = CREATING_STREAM;
- ipc_->CreateStream(this, params);
+ ipc_->CreateStream(this, audio_parameters_);
start_on_authorized_ = false;
break;
@@ -371,7 +377,7 @@ void AudioOutputDevice::OnDeviceAuthorized(
did_receive_auth_.Signal();
}
if (start_on_authorized_)
- CreateStreamOnIOThread(audio_parameters_);
+ CreateStreamOnIOThread();
} else {
// Closing IPC forces a Signal(), so no clients are locked waiting
// indefinitely after this method returns.
diff --git a/chromium/media/audio/audio_output_device.h b/chromium/media/audio/audio_output_device.h
index 47d16f8abf2..c6755a8ec6c 100644
--- a/chromium/media/audio/audio_output_device.h
+++ b/chromium/media/audio/audio_output_device.h
@@ -145,7 +145,9 @@ class MEDIA_EXPORT AudioOutputDevice : public AudioRendererSink,
// be executed on that thread. They use AudioOutputIPC to send IPC messages
// upon state changes.
void RequestDeviceAuthorizationOnIOThread();
- void CreateStreamOnIOThread(const AudioParameters& params);
+ void InitializeOnIOThread(const AudioParameters& params,
+ RenderCallback* callback);
+ void CreateStreamOnIOThread();
void PlayOnIOThread();
void PauseOnIOThread();
void ShutDownOnIOThread();
diff --git a/chromium/media/blink/video_frame_compositor.cc b/chromium/media/blink/video_frame_compositor.cc
index 8d162fc30c6..7abdf0999d8 100644
--- a/chromium/media/blink/video_frame_compositor.cc
+++ b/chromium/media/blink/video_frame_compositor.cc
@@ -134,6 +134,18 @@ scoped_refptr<VideoFrame> VideoFrameCompositor::GetCurrentFrame() {
return current_frame_;
}
+scoped_refptr<VideoFrame> VideoFrameCompositor::GetCurrentFrameOnAnyThread() {
+ base::AutoLock lock(current_frame_lock_);
+ return current_frame_;
+}
+
+void VideoFrameCompositor::SetCurrentFrame(
+ const scoped_refptr<VideoFrame>& frame) {
+ DCHECK(task_runner_->BelongsToCurrentThread());
+ base::AutoLock lock(current_frame_lock_);
+ current_frame_ = frame;
+}
+
void VideoFrameCompositor::PutCurrentFrame() {
DCHECK(task_runner_->BelongsToCurrentThread());
rendered_last_frame_ = true;
@@ -147,7 +159,7 @@ bool VideoFrameCompositor::UpdateCurrentFrame(base::TimeTicks deadline_min,
bool VideoFrameCompositor::HasCurrentFrame() {
DCHECK(task_runner_->BelongsToCurrentThread());
- return static_cast<bool>(current_frame_);
+ return static_cast<bool>(GetCurrentFrame());
}
void VideoFrameCompositor::Start(RenderCallback* callback) {
@@ -192,12 +204,11 @@ void VideoFrameCompositor::PaintSingleFrame(
}
}
-scoped_refptr<VideoFrame>
-VideoFrameCompositor::GetCurrentFrameAndUpdateIfStale() {
+void VideoFrameCompositor::UpdateCurrentFrameIfStale() {
DCHECK(task_runner_->BelongsToCurrentThread());
if (IsClientSinkAvailable() || !rendering_ || !is_background_rendering_)
- return current_frame_;
+ return;
DCHECK(!last_background_render_.is_null());
@@ -206,24 +217,12 @@ VideoFrameCompositor::GetCurrentFrameAndUpdateIfStale() {
// Cap updates to 250Hz which should be more than enough for everyone.
if (interval < base::TimeDelta::FromMilliseconds(4))
- return current_frame_;
+ return;
// Update the interval based on the time between calls and call background
// render which will give this information to the client.
last_interval_ = interval;
BackgroundRender();
-
- return current_frame_;
-}
-
-base::TimeDelta VideoFrameCompositor::GetCurrentFrameTimestamp() const {
- // When the VFC is stopped, |callback_| is cleared; this synchronously
- // prevents CallRender() from invoking ProcessNewFrame(), and so
- // |current_frame_| won't change again until after Start(). (Assuming that
- // PaintSingleFrame() is not also called while stopped.)
- if (!current_frame_)
- return base::TimeDelta();
- return current_frame_->timestamp();
}
void VideoFrameCompositor::SetOnNewProcessedFrameCallback(
@@ -237,8 +236,8 @@ bool VideoFrameCompositor::ProcessNewFrame(
bool repaint_duplicate_frame) {
DCHECK(task_runner_->BelongsToCurrentThread());
- if (frame && current_frame_ && !repaint_duplicate_frame &&
- frame->unique_id() == current_frame_->unique_id()) {
+ if (frame && GetCurrentFrame() && !repaint_duplicate_frame &&
+ frame->unique_id() == GetCurrentFrame()->unique_id()) {
return false;
}
@@ -246,7 +245,7 @@ bool VideoFrameCompositor::ProcessNewFrame(
// subsequent PutCurrentFrame() call it will mark it as rendered.
rendered_last_frame_ = false;
- current_frame_ = frame;
+ SetCurrentFrame(frame);
if (!new_processed_frame_cb_.is_null())
base::ResetAndReturn(&new_processed_frame_cb_).Run(base::TimeTicks::Now());
@@ -276,14 +275,14 @@ bool VideoFrameCompositor::CallRender(base::TimeTicks deadline_min,
if (!callback_) {
// Even if we no longer have a callback, return true if we have a frame
// which |client_| hasn't seen before.
- return !rendered_last_frame_ && current_frame_;
+ return !rendered_last_frame_ && GetCurrentFrame();
}
DCHECK(rendering_);
// If the previous frame was never rendered and we're not in background
// rendering mode (nor have just exited it), let the client know.
- if (!rendered_last_frame_ && current_frame_ && !background_rendering &&
+ if (!rendered_last_frame_ && GetCurrentFrame() && !background_rendering &&
!is_background_rendering_) {
callback_->OnFrameDropped();
}
diff --git a/chromium/media/blink/video_frame_compositor.h b/chromium/media/blink/video_frame_compositor.h
index 3a50d71aae0..46f66513d72 100644
--- a/chromium/media/blink/video_frame_compositor.h
+++ b/chromium/media/blink/video_frame_compositor.h
@@ -92,6 +92,12 @@ class MEDIA_BLINK_EXPORT VideoFrameCompositor : public VideoRendererSink,
scoped_refptr<VideoFrame> GetCurrentFrame() override;
void PutCurrentFrame() override;
+ // Returns |current_frame_|, without offering a guarantee as to how recently
+ // it was updated. In certain applications, one might need to periodically
+ // call UpdateCurrentFrameIfStale on |task_runner_| to drive the updates.
+ // Can be called from any thread.
+ scoped_refptr<VideoFrame> GetCurrentFrameOnAnyThread();
+
// VideoRendererSink implementation. These methods must be called from the
// same thread (typically the media thread).
void Start(RenderCallback* callback) override;
@@ -99,24 +105,18 @@ class MEDIA_BLINK_EXPORT VideoFrameCompositor : public VideoRendererSink,
void PaintSingleFrame(const scoped_refptr<VideoFrame>& frame,
bool repaint_duplicate_frame = false) override;
- // Returns |current_frame_| if |client_| is set. If no |client_| is set,
- // |is_background_rendering_| is true, and |callback_| is set, it requests a
- // new frame from |callback_|, using the elapsed time between calls to this
- // function as the render interval; defaulting to 16.6ms if no prior calls
- // have been made. A cap of 250Hz (4ms) is in place to prevent clients from
- // accidentally (or intentionally) spamming the rendering pipeline.
+ // If |client_| is not set, |callback_| is set, and |is_background_rendering_|
+ // is true, it requests a new frame from |callback_|. Uses the elapsed time
+ // between calls to this function as the render interval, defaulting to 16.6ms
+ // if no prior calls have been made. A cap of 250Hz (4ms) is in place to
+ // prevent clients from accidentally (or intentionally) spamming the rendering
+ // pipeline.
//
// This method is primarily to facilitate canvas and WebGL based applications
// where the <video> tag is invisible (possibly not even in the DOM) and thus
// does not receive a |client_|. In this case, frame acquisition is driven by
// the frequency of canvas or WebGL paints requested via JavaScript.
- scoped_refptr<VideoFrame> GetCurrentFrameAndUpdateIfStale();
-
- // Returns the timestamp of the current (possibly stale) frame, or
- // base::TimeDelta() if there is no current frame. This method may be called
- // from the media thread as long as the VFC is stopped. (Assuming that
- // PaintSingleFrame() is not also called while stopped.)
- base::TimeDelta GetCurrentFrameTimestamp() const;
+ void UpdateCurrentFrameIfStale();
// Sets the callback to be run when the new frame has been processed. The
// callback is only run once and then reset.
@@ -156,6 +156,8 @@ class MEDIA_BLINK_EXPORT VideoFrameCompositor : public VideoRendererSink,
bool ProcessNewFrame(const scoped_refptr<VideoFrame>& frame,
bool repaint_duplicate_frame);
+ void SetCurrentFrame(const scoped_refptr<VideoFrame>& frame);
+
// Called by |background_rendering_timer_| when enough time elapses where we
// haven't seen a Render() call.
void BackgroundRender();
@@ -193,8 +195,8 @@ class MEDIA_BLINK_EXPORT VideoFrameCompositor : public VideoRendererSink,
base::TimeTicks last_background_render_;
OnNewProcessedFrameCB new_processed_frame_cb_;
- // These values are set on the compositor thread, but also read on the media
- // thread when the VFC is stopped.
+ // Set on the compositor thread, but also read on the media thread.
+ base::Lock current_frame_lock_;
scoped_refptr<VideoFrame> current_frame_;
// These values are updated and read from the media and compositor threads.
diff --git a/chromium/media/blink/video_frame_compositor_unittest.cc b/chromium/media/blink/video_frame_compositor_unittest.cc
index 7f72e237db1..4e3d4748e47 100644
--- a/chromium/media/blink/video_frame_compositor_unittest.cc
+++ b/chromium/media/blink/video_frame_compositor_unittest.cc
@@ -246,33 +246,21 @@ TEST_P(VideoFrameCompositorTest,
StopVideoRendererSink(true);
}
-TEST_P(VideoFrameCompositorTest, GetCurrentFrameAndUpdateIfStale) {
+TEST_P(VideoFrameCompositorTest, UpdateCurrentFrameIfStale) {
scoped_refptr<VideoFrame> opaque_frame_1 = CreateOpaqueFrame();
scoped_refptr<VideoFrame> opaque_frame_2 = CreateOpaqueFrame();
compositor_->set_background_rendering_for_testing(true);
- // |current_frame_| should be null at this point since we don't have a client
- // or a callback.
- ASSERT_FALSE(compositor()->GetCurrentFrameAndUpdateIfStale());
-
// Starting the video renderer should return a single frame.
EXPECT_CALL(*this, Render(_, _, true)).WillOnce(Return(opaque_frame_1));
StartVideoRendererSink();
+ EXPECT_EQ(opaque_frame_1, compositor()->GetCurrentFrame());
// Since we have a client, this call should not call background render, even
// if a lot of time has elapsed between calls.
tick_clock_->Advance(base::TimeDelta::FromSeconds(1));
- ASSERT_EQ(opaque_frame_1, compositor()->GetCurrentFrameAndUpdateIfStale());
-
- // An update current frame call should stop background rendering.
- EXPECT_CALL(*this, Render(_, _, false)).WillOnce(Return(opaque_frame_2));
- EXPECT_TRUE(
- compositor()->UpdateCurrentFrame(base::TimeTicks(), base::TimeTicks()));
-
- // This call should still not call background render.
- ASSERT_EQ(opaque_frame_2, compositor()->GetCurrentFrameAndUpdateIfStale());
-
- testing::Mock::VerifyAndClearExpectations(this);
+ EXPECT_CALL(*this, Render(_, _, _)).Times(0);
+ compositor()->UpdateCurrentFrameIfStale();
if (IsSurfaceLayerForVideoEnabled()) {
compositor()->set_submitter_for_test(nullptr);
@@ -281,25 +269,24 @@ TEST_P(VideoFrameCompositorTest, GetCurrentFrameAndUpdateIfStale) {
compositor()->SetVideoFrameProviderClient(nullptr);
}
- // This call should still not call background render, because we aren't in the
- // background rendering state yet.
- ASSERT_EQ(opaque_frame_2, compositor()->GetCurrentFrameAndUpdateIfStale());
-
- // Wait for background rendering to tick again.
+ // Wait for background rendering to tick.
base::RunLoop run_loop;
EXPECT_CALL(*this, Render(_, _, true))
.WillOnce(
- DoAll(RunClosure(run_loop.QuitClosure()), Return(opaque_frame_1)))
- .WillOnce(Return(opaque_frame_2));
+ DoAll(RunClosure(run_loop.QuitClosure()), Return(opaque_frame_2)));
run_loop.Run();
// This call should still not call background render, because not enough time
// has elapsed since the last background render call.
- ASSERT_EQ(opaque_frame_1, compositor()->GetCurrentFrameAndUpdateIfStale());
+ EXPECT_CALL(*this, Render(_, _, true)).Times(0);
+ compositor()->UpdateCurrentFrameIfStale();
+ EXPECT_EQ(opaque_frame_2, compositor()->GetCurrentFrame());
// Advancing the tick clock should allow a new frame to be requested.
tick_clock_->Advance(base::TimeDelta::FromMilliseconds(10));
- ASSERT_EQ(opaque_frame_2, compositor()->GetCurrentFrameAndUpdateIfStale());
+ EXPECT_CALL(*this, Render(_, _, true)).WillOnce(Return(opaque_frame_1));
+ compositor()->UpdateCurrentFrameIfStale();
+ EXPECT_EQ(opaque_frame_1, compositor()->GetCurrentFrame());
// Background rendering should tick another render callback.
StopVideoRendererSink(false);
diff --git a/chromium/media/blink/watch_time_reporter_unittest.cc b/chromium/media/blink/watch_time_reporter_unittest.cc
index 4f46e59a649..62e749d4bee 100644
--- a/chromium/media/blink/watch_time_reporter_unittest.cc
+++ b/chromium/media/blink/watch_time_reporter_unittest.cc
@@ -167,9 +167,10 @@ class WatchTimeReporterTest : public testing::TestWithParam<bool>,
EXPECT_WATCH_TIME_FINALIZED();
wtr_.reset(new WatchTimeReporter(
- mojom::PlaybackProperties::New(
- kUnknownAudioCodec, kUnknownVideoCodec, has_audio, has_video_,
- is_mse, is_encrypted, false, initial_video_size, url::Origin()),
+ mojom::PlaybackProperties::New(kUnknownAudioCodec, kUnknownVideoCodec,
+ has_audio, has_video_, is_mse,
+ is_encrypted, false, initial_video_size,
+ url::Origin(), true /* is_top_frame */),
base::Bind(&WatchTimeReporterTest::GetCurrentMediaTime,
base::Unretained(this)),
this));
diff --git a/chromium/media/blink/webmediaplayer_impl.cc b/chromium/media/blink/webmediaplayer_impl.cc
index 0c496c4f78c..5ee29f7682d 100644
--- a/chromium/media/blink/webmediaplayer_impl.cc
+++ b/chromium/media/blink/webmediaplayer_impl.cc
@@ -2206,48 +2206,23 @@ blink::WebAudioSourceProvider* WebMediaPlayerImpl::GetAudioSourceProvider() {
return audio_source_provider_.get();
}
-static void GetCurrentFrameAndSignal(VideoFrameCompositor* compositor,
- scoped_refptr<VideoFrame>* video_frame_out,
- base::WaitableEvent* event) {
- TRACE_EVENT0("media", "GetCurrentFrameAndSignal");
- *video_frame_out = compositor->GetCurrentFrameAndUpdateIfStale();
- event->Signal();
-}
-
scoped_refptr<VideoFrame> WebMediaPlayerImpl::GetCurrentFrameFromCompositor()
const {
DCHECK(main_task_runner_->BelongsToCurrentThread());
TRACE_EVENT0("media", "WebMediaPlayerImpl::GetCurrentFrameFromCompositor");
- // Needed when the |main_task_runner_| and |vfc_task_runner_| are the
- // same to avoid deadlock in the Wait() below.
- if (vfc_task_runner_->BelongsToCurrentThread()) {
- scoped_refptr<VideoFrame> video_frame =
- compositor_->GetCurrentFrameAndUpdateIfStale();
- if (!video_frame) {
- return nullptr;
- }
- last_uploaded_frame_size_ = video_frame->natural_size();
- last_uploaded_frame_timestamp_ = video_frame->timestamp();
- return video_frame;
- }
+ // Can be null.
+ scoped_refptr<VideoFrame> video_frame =
+ compositor_->GetCurrentFrameOnAnyThread();
- // Use a posted task and waitable event instead of a lock otherwise
- // WebGL/Canvas can see different content than what the compositor is seeing.
- scoped_refptr<VideoFrame> video_frame;
- base::WaitableEvent event(base::WaitableEvent::ResetPolicy::AUTOMATIC,
- base::WaitableEvent::InitialState::NOT_SIGNALED);
+ // base::Unretained is safe here because |compositor_| is destroyed on
+ // |vfc_task_runner_|. The destruction is queued from |this|' destructor,
+ // which also runs on |main_task_runner_|, which makes it impossible for
+ // UpdateCurrentFrameIfStale() to be queued after |compositor_|'s dtor.
vfc_task_runner_->PostTask(
- FROM_HERE,
- base::Bind(&GetCurrentFrameAndSignal, base::Unretained(compositor_.get()),
- &video_frame, &event));
- event.Wait();
+ FROM_HERE, base::Bind(&VideoFrameCompositor::UpdateCurrentFrameIfStale,
+ base::Unretained(compositor_.get())));
- if (!video_frame) {
- return nullptr;
- }
- last_uploaded_frame_size_ = video_frame->natural_size();
- last_uploaded_frame_timestamp_ = video_frame->timestamp();
return video_frame;
}
@@ -2567,6 +2542,12 @@ void WebMediaPlayerImpl::CreateWatchTimeReporter() {
if (!HasVideo() && !HasAudio())
return;
+ // URL is used for UKM reporting. Privacy requires we only report origin of
+ // the top frame. |is_top_frame| signals how to interpret the origin.
+ // TODO(crbug.com/787209): Stop getting origin from the renderer.
+ bool is_top_frame = frame_ == frame_->Top();
+ url::Origin top_origin(frame_->Top()->GetSecurityOrigin());
+
// Create the watch time reporter and synchronize its initial state.
watch_time_reporter_.reset(new WatchTimeReporter(
mojom::PlaybackProperties::New(
@@ -2574,8 +2555,7 @@ void WebMediaPlayerImpl::CreateWatchTimeReporter() {
pipeline_metadata_.video_decoder_config.codec(),
pipeline_metadata_.has_audio, pipeline_metadata_.has_video,
!!chunk_demuxer_, is_encrypted_, embedded_media_experience_enabled_,
- pipeline_metadata_.natural_size,
- url::Origin(frame_->GetSecurityOrigin())),
+ pipeline_metadata_.natural_size, top_origin, is_top_frame),
base::BindRepeating(&WebMediaPlayerImpl::GetCurrentTimeInternal,
base::Unretained(this)),
watch_time_recorder_provider_));
diff --git a/chromium/media/blink/webmediaplayer_impl.h b/chromium/media/blink/webmediaplayer_impl.h
index 56c5cf472d5..6f5e997ed4e 100644
--- a/chromium/media/blink/webmediaplayer_impl.h
+++ b/chromium/media/blink/webmediaplayer_impl.h
@@ -350,8 +350,9 @@ class MEDIA_BLINK_EXPORT WebMediaPlayerImpl
void SetNetworkState(blink::WebMediaPlayer::NetworkState state);
void SetReadyState(blink::WebMediaPlayer::ReadyState state);
- // Returns the current video frame from |compositor_|. Blocks until the
- // compositor can return the frame.
+ // Returns the current video frame from |compositor_|, and asks the compositor
+ // to update its frame if it is stale.
+ // Can return a nullptr.
scoped_refptr<VideoFrame> GetCurrentFrameFromCompositor() const;
// Called when the demuxer encounters encrypted streams.
@@ -800,9 +801,6 @@ class MEDIA_BLINK_EXPORT WebMediaPlayerImpl
// Whether the use of a surface layer instead of a video layer is enabled.
bool surface_layer_for_video_enabled_ = false;
- mutable gfx::Size last_uploaded_frame_size_;
- mutable base::TimeDelta last_uploaded_frame_timestamp_;
-
base::CancelableCallback<void(base::TimeTicks)> frame_time_report_cb_;
bool initial_video_height_recorded_ = false;
diff --git a/chromium/media/midi/midi_manager_mac.cc b/chromium/media/midi/midi_manager_mac.cc
index ecdf16cc7df..75b373a1daa 100644
--- a/chromium/media/midi/midi_manager_mac.cc
+++ b/chromium/media/midi/midi_manager_mac.cc
@@ -241,10 +241,11 @@ void MidiManagerMac::ReceiveMidiNotify(const MIDINotification* message) {
// On kMIDIMsgObjectRemoved, the entry will be ignored because it
// will not be found in the pool.
if (!info.id.empty()) {
+ size_t index = it - sources_.begin();
sources_.push_back(endpoint);
AddInputPort(info);
MIDIPortConnectSource(midi_input_, endpoint,
- reinterpret_cast<void*>(it - sources_.begin()));
+ reinterpret_cast<void*>(index));
}
} else {
SetInputPortState(it - sources_.begin(), PortState::OPENED);
diff --git a/chromium/media/mojo/interfaces/watch_time_recorder.mojom b/chromium/media/mojo/interfaces/watch_time_recorder.mojom
index fb162233ec9..1e3492ecd84 100644
--- a/chromium/media/mojo/interfaces/watch_time_recorder.mojom
+++ b/chromium/media/mojo/interfaces/watch_time_recorder.mojom
@@ -20,7 +20,12 @@ struct PlaybackProperties {
bool is_eme;
bool is_embedded_media_experience; // Playback from 'Downloads' on Android.
gfx.mojom.Size natural_size; // Size of video frame; (0, 0) if audio only.
- url.mojom.Origin origin;
+
+ // For privacy, only record the top origin. "Untrusted" signals that this
+ // value comes from the renderer and should not be used for security checks.
+ // TODO(crbug.com/787209): Stop getting origin from the renderer.
+ url.mojom.Origin untrusted_top_origin;
+ bool is_top_frame; // False for any inner/iframe playbacks.
};
// Interface by which the WatchTimeReporter reports watch time. This is used to
diff --git a/chromium/media/mojo/services/watch_time_recorder.cc b/chromium/media/mojo/services/watch_time_recorder.cc
index f4f6d9eedfc..ed60fc41c95 100644
--- a/chromium/media/mojo/services/watch_time_recorder.cc
+++ b/chromium/media/mojo/services/watch_time_recorder.cc
@@ -173,9 +173,14 @@ void WatchTimeRecorder::RecordUkmPlaybackData() {
}
const int32_t source_id = ukm_recorder->GetNewSourceID();
- ukm_recorder->UpdateSourceURL(source_id, properties_->origin.GetURL());
+
+ // TODO(crbug.com/787209): Stop getting origin from the renderer.
+ ukm_recorder->UpdateSourceURL(source_id,
+ properties_->untrusted_top_origin.GetURL());
ukm::builders::Media_BasicPlayback builder(source_id);
+ builder.SetIsTopFrame(properties_->is_top_frame);
+
bool recorded_all_metric = false;
for (auto& kv : aggregate_watch_time_info_) {
if (kv.first == WatchTimeKey::kAudioAll ||
diff --git a/chromium/media/mojo/services/watch_time_recorder_unittest.cc b/chromium/media/mojo/services/watch_time_recorder_unittest.cc
index 3535bec3e3a..025c936e34a 100644
--- a/chromium/media/mojo/services/watch_time_recorder_unittest.cc
+++ b/chromium/media/mojo/services/watch_time_recorder_unittest.cc
@@ -55,10 +55,10 @@ class WatchTimeRecorderTest : public testing::Test {
bool is_mse,
bool is_encrypted) {
provider_->AcquireWatchTimeRecorder(
- mojom::PlaybackProperties::New(kUnknownAudioCodec, kUnknownVideoCodec,
- has_audio, has_video, is_mse,
- is_encrypted, false, gfx::Size(800, 600),
- url::Origin(GURL(kTestOrigin))),
+ mojom::PlaybackProperties::New(
+ kUnknownAudioCodec, kUnknownVideoCodec, has_audio, has_video,
+ is_mse, is_encrypted, false, gfx::Size(800, 600),
+ url::Origin(GURL(kTestOrigin)), true /* is_top_frame */),
mojo::MakeRequest(&wtr_));
}
@@ -246,7 +246,7 @@ TEST_F(WatchTimeRecorderTest, TestRebufferingMetrics) {
TEST_F(WatchTimeRecorderTest, BasicUkmAudioVideo) {
mojom::PlaybackPropertiesPtr properties = mojom::PlaybackProperties::New(
kCodecAAC, kCodecH264, true, true, false, false, false,
- gfx::Size(800, 600), url::Origin(GURL(kTestOrigin)));
+ gfx::Size(800, 600), url::Origin(GURL(kTestOrigin)), true);
provider_->AcquireWatchTimeRecorder(properties.Clone(),
mojo::MakeRequest(&wtr_));
@@ -287,7 +287,7 @@ TEST_F(WatchTimeRecorderTest, BasicUkmAudioVideo) {
TEST_F(WatchTimeRecorderTest, BasicUkmAudioVideoWithExtras) {
mojom::PlaybackPropertiesPtr properties = mojom::PlaybackProperties::New(
kCodecOpus, kCodecVP9, true, true, true, true, false, gfx::Size(800, 600),
- url::Origin(GURL(kTestOrigin)));
+ url::Origin(GURL(kTestOrigin)), true);
provider_->AcquireWatchTimeRecorder(properties.Clone(),
mojo::MakeRequest(&wtr_));
@@ -354,7 +354,7 @@ TEST_F(WatchTimeRecorderTest, BasicUkmAudioVideoWithExtras) {
TEST_F(WatchTimeRecorderTest, BasicUkmAudioVideoBackground) {
mojom::PlaybackPropertiesPtr properties = mojom::PlaybackProperties::New(
kCodecAAC, kCodecH264, true, true, false, false, false,
- gfx::Size(800, 600), url::Origin(GURL(kTestOrigin)));
+ gfx::Size(800, 600), url::Origin(GURL(kTestOrigin)), true);
provider_->AcquireWatchTimeRecorder(properties.Clone(),
mojo::MakeRequest(&wtr_));