#ifdef UNSAFE_BUFFERS_BUILD
#pragma allow_unsafe_buffers
#endif
#include "third_party/blink/renderer/modules/mediastream/web_media_player_ms_compositor.h"
#include <stdint.h>
#include <string>
#include <utility>
#include "base/hash/hash.h"
#include "base/metrics/histogram_macros.h"
#include "base/not_fatal_until.h"
#include "base/ranges/algorithm.h"
#include "base/synchronization/waitable_event.h"
#include "base/task/bind_post_task.h"
#include "base/task/sequenced_task_runner.h"
#include "base/task/single_thread_task_runner.h"
#include "base/values.h"
#include "build/build_config.h"
#include "cc/paint/skia_paint_canvas.h"
#include "media/base/media_switches.h"
#include "media/base/video_frame.h"
#include "media/base/video_util.h"
#include "media/renderers/paint_canvas_video_renderer.h"
#include "services/viz/public/cpp/gpu/context_provider_command_buffer.h"
#include "skia/ext/platform_canvas.h"
#include "third_party/blink/public/platform/platform.h"
#include "third_party/blink/public/platform/web_video_frame_submitter.h"
#include "third_party/blink/public/web/modules/mediastream/media_stream_video_source.h"
#include "third_party/blink/public/web/modules/mediastream/web_media_player_ms.h"
#include "third_party/blink/renderer/platform/mediastream/media_stream_component.h"
#include "third_party/blink/renderer/platform/mediastream/media_stream_descriptor.h"
#include "third_party/blink/renderer/platform/scheduler/public/post_cross_thread_task.h"
#include "third_party/blink/renderer/platform/wtf/cross_thread_copier_media.h"
#include "third_party/blink/renderer/platform/wtf/cross_thread_functional.h"
#include "third_party/libyuv/include/libyuv/convert.h"
#include "third_party/libyuv/include/libyuv/planar_functions.h"
#include "third_party/libyuv/include/libyuv/video_common.h"
#include "third_party/skia/include/core/SkSurface.h"
namespace WTF {
CrossThreadCopier<std::optional<T>>;
}
namespace blink {
namespace {
scoped_refptr<media::VideoFrame> CopyFrame(
scoped_refptr<media::VideoFrame> frame,
media::PaintCanvasVideoRenderer* video_renderer) { … }
gfx::Size RotationAdjustedSize(media::VideoRotation rotation,
const gfx::Size& size) { … }
std::string UmaPrefix() { … }
constexpr base::TimeDelta kMaximumVsyncDelayForLowLatencyRenderer = …;
}
WebMediaPlayerMSCompositor::WebMediaPlayerMSCompositor(
scoped_refptr<base::SingleThreadTaskRunner>
video_frame_compositor_task_runner,
scoped_refptr<base::SequencedTaskRunner> video_task_runner,
MediaStreamDescriptor* media_stream_descriptor,
std::unique_ptr<WebVideoFrameSubmitter> submitter,
bool use_surface_layer,
const base::WeakPtr<WebMediaPlayerMS>& player)
: … { … }
WebMediaPlayerMSCompositor::~WebMediaPlayerMSCompositor() { … }
void WebMediaPlayerMSCompositor::InitializeSubmitter() { … }
void WebMediaPlayerMSCompositor::SetIsSurfaceVisible(
bool state,
base::WaitableEvent* done_event) { … }
void WebMediaPlayerMSCompositor::EnableSubmission(
const viz::SurfaceId& id,
media::VideoTransformation transformation,
bool force_submit) { … }
void WebMediaPlayerMSCompositor::SetForceBeginFrames(bool enable) { … }
WebMediaPlayerMSCompositor::Metadata WebMediaPlayerMSCompositor::GetMetadata() { … }
void WebMediaPlayerMSCompositor::SetForceSubmit(bool force_submit) { … }
void WebMediaPlayerMSCompositor::SetIsPageVisible(bool is_visible) { … }
size_t WebMediaPlayerMSCompositor::total_frame_count() { … }
size_t WebMediaPlayerMSCompositor::dropped_frame_count() { … }
void WebMediaPlayerMSCompositor::SetVideoFrameProviderClient(
cc::VideoFrameProvider::Client* client) { … }
void WebMediaPlayerMSCompositor::RecordFrameDecodedStats(
std::optional<base::TimeTicks> frame_received_time,
std::optional<base::TimeDelta> frame_processing_time,
std::optional<uint32_t> frame_rtp_timestamp) { … }
void WebMediaPlayerMSCompositor::SetMetadata() { … }
void WebMediaPlayerMSCompositor::EnqueueFrame(
scoped_refptr<media::VideoFrame> frame,
bool is_copy) { … }
bool WebMediaPlayerMSCompositor::UpdateCurrentFrame(
base::TimeTicks deadline_min,
base::TimeTicks deadline_max) { … }
bool WebMediaPlayerMSCompositor::HasCurrentFrame() { … }
scoped_refptr<media::VideoFrame> WebMediaPlayerMSCompositor::GetCurrentFrame() { … }
void WebMediaPlayerMSCompositor::RecordFrameDisplayedStats(
base::TimeTicks frame_displayed_time) { … }
void WebMediaPlayerMSCompositor::PutCurrentFrame() { … }
base::TimeDelta WebMediaPlayerMSCompositor::GetPreferredRenderInterval() { … }
void WebMediaPlayerMSCompositor::OnContextLost() { … }
void WebMediaPlayerMSCompositor::StartRendering() { … }
void WebMediaPlayerMSCompositor::StopRendering() { … }
bool WebMediaPlayerMSCompositor::MapTimestampsToRenderTimeTicks(
const std::vector<base::TimeDelta>& timestamps,
std::vector<base::TimeTicks>* wall_clock_times) { … }
void WebMediaPlayerMSCompositor::RenderUsingAlgorithm(
base::TimeTicks deadline_min,
base::TimeTicks deadline_max) { … }
void WebMediaPlayerMSCompositor::RenderWithoutAlgorithm(
scoped_refptr<media::VideoFrame> frame,
bool is_copy) { … }
void WebMediaPlayerMSCompositor::RenderWithoutAlgorithmOnCompositor(
scoped_refptr<media::VideoFrame> frame,
bool is_copy) { … }
void WebMediaPlayerMSCompositor::SetCurrentFrame(
scoped_refptr<media::VideoFrame> frame,
bool is_copy,
std::optional<base::TimeTicks> expected_display_time) { … }
void WebMediaPlayerMSCompositor::CheckForFrameChanges(
bool is_first_frame,
bool has_frame_size_changed,
std::optional<media::VideoTransformation> new_frame_transform,
std::optional<bool> new_frame_opacity) { … }
void WebMediaPlayerMSCompositor::StartRenderingInternal() { … }
void WebMediaPlayerMSCompositor::StopRenderingInternal() { … }
void WebMediaPlayerMSCompositor::ReplaceCurrentFrameWithACopy() { … }
void WebMediaPlayerMSCompositor::SetAlgorithmEnabledForTesting(
bool algorithm_enabled) { … }
void WebMediaPlayerMSCompositor::SetOnFramePresentedCallback(
OnNewFramePresentedCB presented_cb) { … }
std::unique_ptr<WebMediaPlayer::VideoFramePresentationMetadata>
WebMediaPlayerMSCompositor::GetLastPresentedFrameMetadata() { … }
}