diff options
Diffstat (limited to 'chromium/media')
-rw-r--r-- | chromium/media/audio/audio_input_device.cc | 10 | ||||
-rw-r--r-- | chromium/media/audio/audio_input_device.h | 3 | ||||
-rw-r--r-- | chromium/media/audio/audio_output_device.cc | 22 | ||||
-rw-r--r-- | chromium/media/audio/audio_output_device.h | 4 | ||||
-rw-r--r-- | chromium/media/blink/video_frame_compositor.cc | 43 | ||||
-rw-r--r-- | chromium/media/blink/video_frame_compositor.h | 32 | ||||
-rw-r--r-- | chromium/media/blink/video_frame_compositor_unittest.cc | 37 | ||||
-rw-r--r-- | chromium/media/blink/watch_time_reporter_unittest.cc | 7 | ||||
-rw-r--r-- | chromium/media/blink/webmediaplayer_impl.cc | 52 | ||||
-rw-r--r-- | chromium/media/blink/webmediaplayer_impl.h | 8 | ||||
-rw-r--r-- | chromium/media/midi/midi_manager_mac.cc | 3 | ||||
-rw-r--r-- | chromium/media/mojo/interfaces/watch_time_recorder.mojom | 7 | ||||
-rw-r--r-- | chromium/media/mojo/services/watch_time_recorder.cc | 7 | ||||
-rw-r--r-- | chromium/media/mojo/services/watch_time_recorder_unittest.cc | 14 |
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_)); |