#include "media/base/pipeline_impl.h"
#include <algorithm>
#include <memory>
#include <utility>
#include "base/command_line.h"
#include "base/functional/bind.h"
#include "base/functional/callback.h"
#include "base/functional/callback_helpers.h"
#include "base/location.h"
#include "base/memory/raw_ptr.h"
#include "base/metrics/histogram_functions.h"
#include "base/metrics/histogram_macros.h"
#include "base/strings/string_number_conversions.h"
#include "base/synchronization/lock.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 "build/build_config.h"
#include "media/base/callback_timeout_helpers.h"
#include "media/base/cdm_context.h"
#include "media/base/decoder.h"
#include "media/base/demuxer.h"
#include "media/base/media_log.h"
#include "media/base/media_switches.h"
#include "media/base/renderer.h"
#include "media/base/renderer_client.h"
#include "media/base/serial_runner.h"
#include "media/base/timestamp_constants.h"
#include "media/base/video_decoder_config.h"
#if BUILDFLAG(IS_WIN)
#include "media/base/win/mf_feature_checks.h"
#endif
static const double kDefaultPlaybackRate = …;
static const float kDefaultVolume = …;
namespace media {
namespace {
gfx::Size GetRotatedVideoSize(VideoRotation rotation, gfx::Size natural_size) { … }
void OnCallbackTimeout(const std::string& uma_name,
bool called_on_destruction) { … }
}
class PipelineImpl::RendererWrapper final : public DemuxerHost,
public RendererClient { … };
PipelineImpl::RendererWrapper::RendererWrapper(
scoped_refptr<base::SequencedTaskRunner> media_task_runner,
scoped_refptr<base::SingleThreadTaskRunner> main_task_runner,
MediaLog* media_log)
: … { … }
PipelineImpl::RendererWrapper::~RendererWrapper() { … }
void PipelineImpl::RendererWrapper::Start(
StartType start_type,
Demuxer* demuxer,
std::unique_ptr<Renderer> default_renderer,
base::WeakPtr<PipelineImpl> weak_pipeline) { … }
void PipelineImpl::RendererWrapper::Stop() { … }
void PipelineImpl::RendererWrapper::Seek(base::TimeDelta time) { … }
void PipelineImpl::RendererWrapper::Suspend() { … }
void PipelineImpl::RendererWrapper::Resume(
std::unique_ptr<Renderer> default_renderer,
base::TimeDelta timestamp) { … }
void PipelineImpl::RendererWrapper::SetPlaybackRate(double playback_rate) { … }
void PipelineImpl::RendererWrapper::SetVolume(float volume) { … }
void PipelineImpl::RendererWrapper::SetLatencyHint(
std::optional<base::TimeDelta> latency_hint) { … }
void PipelineImpl::RendererWrapper::SetPreservesPitch(bool preserves_pitch) { … }
void PipelineImpl::RendererWrapper::SetWasPlayedWithUserActivation(
bool was_played_with_user_activation) { … }
base::TimeDelta PipelineImpl::RendererWrapper::GetMediaTime() const { … }
Ranges<base::TimeDelta> PipelineImpl::RendererWrapper::GetBufferedTimeRanges()
const { … }
bool PipelineImpl::RendererWrapper::DidLoadingProgress() { … }
PipelineStatistics PipelineImpl::RendererWrapper::GetStatistics() const { … }
void PipelineImpl::RendererWrapper::SetCdm(CdmContext* cdm_context,
CdmAttachedCB cdm_attached_cb) { … }
void PipelineImpl::RendererWrapper::CreateRendererInternal(
PipelineStatusCallback done_cb) { … }
void PipelineImpl::RendererWrapper::OnBufferedTimeRangesChanged(
const Ranges<base::TimeDelta>& ranges) { … }
void PipelineImpl::RendererWrapper::SetDuration(base::TimeDelta duration) { … }
const char* PipelineImpl::RendererWrapper::GetStateString(State state) { … }
void PipelineImpl::RendererWrapper::OnDemuxerError(PipelineStatus error) { … }
void PipelineImpl::RendererWrapper::OnError(PipelineStatus error) { … }
void PipelineImpl::RendererWrapper::OnFallback(PipelineStatus fallback) { … }
void PipelineImpl::RendererWrapper::OnEnded() { … }
base::TimeDelta PipelineImpl::RendererWrapper::GetCurrentTimestamp() { … }
void PipelineImpl::OnEnabledAudioTracksChanged(
const std::vector<MediaTrack::Id>& enabled_track_ids,
base::OnceClosure change_completed_cb) { … }
void PipelineImpl::RendererWrapper::OnEnabledAudioTracksChanged(
const std::vector<MediaTrack::Id>& enabled_track_ids,
base::OnceClosure change_completed_cb) { … }
void PipelineImpl::OnSelectedVideoTrackChanged(
std::optional<MediaTrack::Id> selected_track_id,
base::OnceClosure change_completed_cb) { … }
void PipelineImpl::RendererWrapper::OnSelectedVideoTrackChanged(
std::optional<MediaTrack::Id> selected_track_id,
base::OnceClosure change_completed_cb) { … }
void PipelineImpl::OnExternalVideoFrameRequest() { … }
void PipelineImpl::RendererWrapper::OnExternalVideoFrameRequest() { … }
void PipelineImpl::RendererWrapper::OnDemuxerCompletedTrackChange(
base::OnceClosure change_completed_cb,
DemuxerStream::Type stream_type,
const std::vector<DemuxerStream*>& streams) { … }
void PipelineImpl::RendererWrapper::OnStatisticsUpdate(
const PipelineStatistics& stats) { … }
void PipelineImpl::RendererWrapper::OnBufferingStateChange(
BufferingState state,
BufferingStateChangeReason reason) { … }
void PipelineImpl::RendererWrapper::OnWaiting(WaitingReason reason) { … }
void PipelineImpl::RendererWrapper::OnVideoNaturalSizeChange(
const gfx::Size& size) { … }
void PipelineImpl::RendererWrapper::OnVideoOpacityChange(bool opaque) { … }
void PipelineImpl::RendererWrapper::OnVideoFrameRateChange(
std::optional<int> fps) { … }
void PipelineImpl::RendererWrapper::OnAudioConfigChange(
const AudioDecoderConfig& config) { … }
void PipelineImpl::RendererWrapper::OnVideoConfigChange(
const VideoDecoderConfig& config) { … }
void PipelineImpl::RendererWrapper::OnPipelineError(PipelineStatus error) { … }
void PipelineImpl::RendererWrapper::OnCdmAttached(CdmAttachedCB cdm_attached_cb,
CdmContext* cdm_context,
bool success) { … }
void PipelineImpl::RendererWrapper::CheckPlaybackEnded() { … }
void PipelineImpl::RendererWrapper::SetState(State next_state) { … }
void PipelineImpl::RendererWrapper::CompleteSeek(base::TimeDelta seek_time,
PipelineStatus status) { … }
void PipelineImpl::RendererWrapper::CompleteSuspend(PipelineStatus status) { … }
void PipelineImpl::RendererWrapper::InitializeDemuxer(
PipelineStatusCallback done_cb) { … }
void PipelineImpl::RendererWrapper::CreateRenderer(
PipelineStatusCallback done_cb) { … }
void PipelineImpl::RendererWrapper::OnRendererCreated(
PipelineStatusCallback done_cb,
std::unique_ptr<Renderer> renderer) { … }
void PipelineImpl::RendererWrapper::InitializeRenderer(
PipelineStatusCallback done_cb) { … }
void PipelineImpl::RendererWrapper::DestroyRenderer() { … }
void PipelineImpl::RendererWrapper::ReportMetadata(StartType start_type) { … }
bool PipelineImpl::RendererWrapper::HasEncryptedStream() { … }
PipelineImpl::PipelineImpl(
scoped_refptr<base::SequencedTaskRunner> media_task_runner,
scoped_refptr<base::SingleThreadTaskRunner> main_task_runner,
CreateRendererCB create_renderer_cb,
MediaLog* media_log)
: … { … }
PipelineImpl::~PipelineImpl() { … }
void PipelineImpl::Start(StartType start_type,
Demuxer* demuxer,
Client* client,
PipelineStatusCallback seek_cb) { … }
void PipelineImpl::Stop() { … }
void PipelineImpl::Seek(base::TimeDelta time, PipelineStatusCallback seek_cb) { … }
void PipelineImpl::Suspend(PipelineStatusCallback suspend_cb) { … }
void PipelineImpl::Resume(base::TimeDelta time,
PipelineStatusCallback seek_cb) { … }
bool PipelineImpl::IsRunning() const { … }
bool PipelineImpl::IsSuspended() const { … }
double PipelineImpl::GetPlaybackRate() const { … }
void PipelineImpl::SetPlaybackRate(double playback_rate) { … }
float PipelineImpl::GetVolume() const { … }
void PipelineImpl::SetVolume(float volume) { … }
void PipelineImpl::SetLatencyHint(std::optional<base::TimeDelta> latency_hint) { … }
void PipelineImpl::SetPreservesPitch(bool preserves_pitch) { … }
void PipelineImpl::SetWasPlayedWithUserActivation(
bool was_played_with_user_activation) { … }
base::TimeDelta PipelineImpl::GetMediaTime() const { … }
Ranges<base::TimeDelta> PipelineImpl::GetBufferedTimeRanges() const { … }
base::TimeDelta PipelineImpl::GetMediaDuration() const { … }
bool PipelineImpl::DidLoadingProgress() { … }
PipelineStatistics PipelineImpl::GetStatistics() const { … }
void PipelineImpl::SetCdm(CdmContext* cdm_context,
CdmAttachedCB cdm_attached_cb) { … }
void PipelineImpl::AsyncCreateRenderer(
std::optional<RendererType> renderer_type,
RendererCreatedCB renderer_created_cb) { … }
void PipelineImpl::OnError(PipelineStatus error) { … }
void PipelineImpl::OnFallback(PipelineStatus status) { … }
void PipelineImpl::OnEnded() { … }
void PipelineImpl::OnMetadata(const PipelineMetadata& metadata) { … }
void PipelineImpl::OnBufferingStateChange(BufferingState state,
BufferingStateChangeReason reason) { … }
void PipelineImpl::OnDurationChange(base::TimeDelta duration) { … }
void PipelineImpl::OnWaiting(WaitingReason reason) { … }
void PipelineImpl::OnVideoNaturalSizeChange(const gfx::Size& size) { … }
void PipelineImpl::OnVideoOpacityChange(bool opaque) { … }
void PipelineImpl::OnVideoFrameRateChange(std::optional<int> fps) { … }
void PipelineImpl::OnAudioConfigChange(const AudioDecoderConfig& config) { … }
void PipelineImpl::OnVideoConfigChange(const VideoDecoderConfig& config) { … }
void PipelineImpl::OnVideoAverageKeyframeDistanceUpdate() { … }
void PipelineImpl::OnAudioPipelineInfoChange(const AudioPipelineInfo& info) { … }
void PipelineImpl::OnVideoPipelineInfoChange(const VideoPipelineInfo& info) { … }
void PipelineImpl::OnSeekDone(bool is_suspended) { … }
void PipelineImpl::OnSuspendDone() { … }
}