#include "content/browser/renderer_host/media/video_capture_controller.h"
#include <stddef.h>
#include <stdint.h>
#include <map>
#include <set>
#include "base/command_line.h"
#include "base/containers/contains.h"
#include "base/functional/bind.h"
#include "base/functional/callback_forward.h"
#include "base/memory/raw_ptr.h"
#include "base/metrics/histogram_functions.h"
#include "base/metrics/histogram_macros.h"
#include "base/not_fatal_until.h"
#include "base/ranges/algorithm.h"
#include "base/token.h"
#include "build/build_config.h"
#include "content/browser/renderer_host/media/media_stream_manager.h"
#include "content/browser/renderer_host/media/video_capture_manager.h"
#include "content/public/browser/browser_thread.h"
#include "content/public/common/content_switches.h"
#include "media/base/video_frame.h"
#include "media/base/video_types.h"
#include "media/capture/mojom/video_capture_types.mojom.h"
#include "media/capture/video/video_capture_buffer_pool.h"
#include "media/capture/video/video_capture_buffer_tracker_factory_impl.h"
#include "media/capture/video/video_capture_device_client.h"
#include "media/capture/video/video_capture_metrics.h"
#include "services/video_effects/public/mojom/video_effects_processor.mojom-forward.h"
#if !BUILDFLAG(IS_ANDROID)
#include "content/browser/compositor/image_transport_factory.h"
#endif
VideoCaptureFormat;
VideoFrame;
VideoFrameMetadata;
namespace content {
namespace {
static int g_device_start_id = …;
static const int kInfiniteRatio = …;
#define UMA_HISTOGRAM_ASPECT_RATIO(name, width, height) …
void CallOnError(media::VideoCaptureError error,
VideoCaptureControllerEventHandler* client,
const VideoCaptureControllerID& id) { … }
void CallOnStarted(VideoCaptureControllerEventHandler* client,
const VideoCaptureControllerID& id) { … }
void CallOnStartedUsingGpuDecode(VideoCaptureControllerEventHandler* client,
const VideoCaptureControllerID& id) { … }
}
struct VideoCaptureController::ControllerClient { … };
VideoCaptureController::BufferContext::BufferContext(
int buffer_context_id,
int buffer_id,
media::VideoFrameConsumerFeedbackObserver* consumer_feedback_observer,
media::mojom::VideoBufferHandlePtr buffer_handle)
: … { … }
VideoCaptureController::BufferContext::~BufferContext() = default;
VideoCaptureController::BufferContext::BufferContext(
VideoCaptureController::BufferContext&& other) = default;
VideoCaptureController::BufferContext& VideoCaptureController::BufferContext::
operator=(BufferContext&& other) = default;
void VideoCaptureController::BufferContext::RecordConsumerUtilization(
const media::VideoCaptureFeedback& feedback) { … }
void VideoCaptureController::BufferContext::IncreaseConsumerCount() { … }
void VideoCaptureController::BufferContext::DecreaseConsumerCount() { … }
media::mojom::VideoBufferHandlePtr
VideoCaptureController::BufferContext::CloneBufferHandle() { … }
VideoCaptureController::VideoCaptureController(
const std::string& device_id,
blink::mojom::MediaStreamType stream_type,
const media::VideoCaptureParams& params,
std::unique_ptr<VideoCaptureDeviceLauncher> device_launcher,
base::RepeatingCallback<void(const std::string&)> emit_log_message_cb)
: … { … }
VideoCaptureController::~VideoCaptureController() = default;
base::WeakPtr<VideoCaptureController>
VideoCaptureController::GetWeakPtrForIOThread() { … }
void VideoCaptureController::AddClient(
const VideoCaptureControllerID& id,
VideoCaptureControllerEventHandler* event_handler,
const media::VideoCaptureSessionId& session_id,
const media::VideoCaptureParams& params,
std::optional<url::Origin> origin) { … }
base::UnguessableToken VideoCaptureController::RemoveClient(
const VideoCaptureControllerID& id,
VideoCaptureControllerEventHandler* event_handler) { … }
void VideoCaptureController::PauseClient(
const VideoCaptureControllerID& id,
VideoCaptureControllerEventHandler* event_handler) { … }
bool VideoCaptureController::ResumeClient(
const VideoCaptureControllerID& id,
VideoCaptureControllerEventHandler* event_handler) { … }
size_t VideoCaptureController::GetClientCount() const { … }
bool VideoCaptureController::HasActiveClient() const { … }
bool VideoCaptureController::HasPausedClient() const { … }
void VideoCaptureController::StopSession(
const base::UnguessableToken& session_id) { … }
void VideoCaptureController::ReturnBuffer(
const VideoCaptureControllerID& id,
VideoCaptureControllerEventHandler* event_handler,
int buffer_id,
const media::VideoCaptureFeedback& feedback) { … }
const std::optional<media::VideoCaptureFormat>
VideoCaptureController::GetVideoCaptureFormat() const { … }
const std::optional<url::Origin> VideoCaptureController::GetFirstClientOrigin()
const { … }
void VideoCaptureController::OnCaptureConfigurationChanged() { … }
void VideoCaptureController::OnNewBuffer(
int32_t buffer_id,
media::mojom::VideoBufferHandlePtr buffer_handle) { … }
void VideoCaptureController::OnFrameReadyInBuffer(
media::ReadyFrameInBuffer frame) { … }
ReadyBuffer VideoCaptureController::MakeReadyBufferAndSetContextFeedbackId(
int buffer_id,
int frame_feedback_id,
media::mojom::VideoFrameInfoPtr frame_info,
BufferContext** out_buffer_context) { … }
void VideoCaptureController::MakeClientUseBufferContext(
BufferContext* frame_context,
ControllerClient* client) { … }
void VideoCaptureController::OnBufferRetired(int buffer_id) { … }
void VideoCaptureController::OnError(media::VideoCaptureError error) { … }
void VideoCaptureController::OnFrameDropped(
media::VideoCaptureFrameDropReason reason) { … }
void VideoCaptureController::OnNewSubCaptureTargetVersion(
uint32_t sub_capture_target_version) { … }
void VideoCaptureController::OnFrameWithEmptyRegionCapture() { … }
void VideoCaptureController::OnLog(const std::string& message) { … }
void VideoCaptureController::OnStarted() { … }
void VideoCaptureController::OnStartedUsingGpuDecode() { … }
void VideoCaptureController::OnStopped() { … }
void VideoCaptureController::OnDeviceLaunched(
std::unique_ptr<LaunchedVideoCaptureDevice> device) { … }
void VideoCaptureController::OnDeviceLaunchFailed(
media::VideoCaptureError error) { … }
void VideoCaptureController::OnDeviceLaunchAborted() { … }
void VideoCaptureController::OnDeviceConnectionLost() { … }
void VideoCaptureController::CreateAndStartDeviceAsync(
const media::VideoCaptureParams& params,
VideoCaptureDeviceLaunchObserver* observer,
base::OnceClosure done_cb,
mojo::PendingRemote<video_effects::mojom::VideoEffectsProcessor>
video_effects_processor) { … }
void VideoCaptureController::ReleaseDeviceAsync(base::OnceClosure done_cb) { … }
bool VideoCaptureController::IsDeviceAlive() const { … }
void VideoCaptureController::GetPhotoState(
media::VideoCaptureDevice::GetPhotoStateCallback callback) const { … }
void VideoCaptureController::SetPhotoOptions(
media::mojom::PhotoSettingsPtr settings,
media::VideoCaptureDevice::SetPhotoOptionsCallback callback) { … }
void VideoCaptureController::TakePhoto(
media::VideoCaptureDevice::TakePhotoCallback callback) { … }
void VideoCaptureController::MaybeSuspend() { … }
void VideoCaptureController::Resume() { … }
void VideoCaptureController::ApplySubCaptureTarget(
media::mojom::SubCaptureTargetType type,
const base::Token& target,
uint32_t sub_capture_target_version,
base::OnceCallback<void(media::mojom::ApplySubCaptureTargetResult)>
callback) { … }
void VideoCaptureController::RequestRefreshFrame() { … }
void VideoCaptureController::SetDesktopCaptureWindowIdAsync(
gfx::NativeViewId window_id,
base::OnceClosure done_cb) { … }
VideoCaptureController::ControllerClient* VideoCaptureController::FindClient(
const VideoCaptureControllerID& id,
VideoCaptureControllerEventHandler* handler,
const ControllerClients& clients) { … }
VideoCaptureController::ControllerClient* VideoCaptureController::FindClient(
const base::UnguessableToken& session_id,
const ControllerClients& clients) { … }
std::vector<VideoCaptureController::BufferContext>::iterator
VideoCaptureController::FindBufferContextFromBufferContextId(
int buffer_context_id) { … }
std::vector<VideoCaptureController::BufferContext>::iterator
VideoCaptureController::FindUnretiredBufferContextFromBufferId(int buffer_id) { … }
void VideoCaptureController::OnClientFinishedConsumingBuffer(
ControllerClient* client,
int buffer_context_id,
const media::VideoCaptureFeedback& feedback) { … }
void VideoCaptureController::ReleaseBufferContext(
const std::vector<BufferContext>::iterator& buffer_context_iter) { … }
void VideoCaptureController::PerformForClientsWithOpenSession(
EventHandlerAction action) { … }
void VideoCaptureController::EmitLogMessage(const std::string& message,
int verbose_log_level) { … }
}