blob: 06ca575fcceb04d64f16429a1cf3def2353c1ebc [file] [log] [blame]
// Copyright 2014 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include <memory>
#include <vector>
#include "base/callback.h"
#include "base/macros.h"
#include "base/memory/ref_counted.h"
#include "base/memory/weak_ptr.h"
#include "base/time/time.h"
#include "media/base/demuxer_stream.h"
#include "media/base/pipeline_status.h"
#include "media/base/waiting.h"
#include "media/filters/decoder_stream_traits.h"
namespace base {
class SingleThreadTaskRunner;
namespace media {
class CdmContext;
class DecryptingDemuxerStream;
class MediaLog;
// DecoderSelector handles construction and initialization of Decoders for a
// DemuxerStream, and maintains the state required for decoder fallback.
// The template parameter |StreamType| is the type of stream we will be
// selecting a decoder for.
template<DemuxerStream::Type StreamType>
class MEDIA_EXPORT DecoderSelector {
typedef DecoderStreamTraits<StreamType> StreamTraits;
typedef typename StreamTraits::DecoderType Decoder;
typedef typename StreamTraits::DecoderConfigType DecoderConfig;
// Callback to create a list of decoders to select from.
// TODO(xhwang): Use a DecoderFactory to create decoders one by one as needed,
// instead of creating a list of decoders all at once.
using CreateDecodersCB =
// Emits the result of a single call to SelectDecoder(). Parameters are
// 1: The initialized Decoder. nullptr if selection failed.
// 2: The initialized DecryptingDemuxerStream, if one was created. This
// happens at most once for a DecoderSelector instance.
// The caller owns the Decoder and DecryptingDemuxerStream.
// The caller should call DecryptingDemuxerStream::Reset() before
// calling Decoder::Reset() to release any pending decryption or read.
using SelectDecoderCB =
DecoderSelector(scoped_refptr<base::SingleThreadTaskRunner> task_runner,
CreateDecodersCB create_decoders_cb,
MediaLog* media_log);
// Aborts any pending decoder selection.
// Initialize with stream parameters. Should be called exactly once.
void Initialize(StreamTraits* traits,
DemuxerStream* stream,
CdmContext* cdm_context,
WaitingCB waiting_cb);
// Selects and initializes a decoder, which will be returned via
// |select_decoder_cb| posted to |task_runner|. Subsequent calls to
// SelectDecoder() will return different decoder instances, until all
// potential decoders have been exhausted.
// When the caller determines that decoder selection has succeeded (eg.
// because the decoder decoded a frame successfully), it should call
// FinalizeDecoderSelection().
// Must not be called while another selection is pending.
void SelectDecoder(SelectDecoderCB select_decoder_cb,
typename Decoder::OutputCB output_cb);
// Signals that decoder selection has been completed (successfully). Future
// calls to SelectDecoder() will select from the full list of decoders.
void FinalizeDecoderSelection();
// Signals that a config change has started being processed.
// Currently only for metric collection.
void NotifyConfigChanged();
void InitializeDecoder();
void OnDecoderInitializeDone(bool success);
void ReturnNullDecoder();
void InitializeDecryptingDemuxerStream();
void OnDecryptingDemuxerStreamInitializeDone(PipelineStatus status);
void RunSelectDecoderCB();
scoped_refptr<base::SingleThreadTaskRunner> task_runner_;
CreateDecodersCB create_decoders_cb_;
MediaLog* media_log_;
StreamTraits* traits_ = nullptr;
DemuxerStream* stream_ = nullptr;
CdmContext* cdm_context_ = nullptr;
WaitingCB waiting_cb_;
// Overall decoder selection state.
DecoderConfig config_;
bool is_selecting_decoders_ = false;
std::vector<std::unique_ptr<Decoder>> decoders_;
// State for a single SelectDecoder() invocation.
SelectDecoderCB select_decoder_cb_;
typename Decoder::OutputCB output_cb_;
std::unique_ptr<Decoder> decoder_;
std::unique_ptr<DecryptingDemuxerStream> decrypting_demuxer_stream_;
// Metrics.
bool is_platform_decoder_ = false;
bool is_codec_changing_ = false;
base::TimeTicks codec_change_start_;
base::WeakPtrFactory<DecoderSelector> weak_this_factory_;
typedef DecoderSelector<DemuxerStream::VIDEO> VideoDecoderSelector;
typedef DecoderSelector<DemuxerStream::AUDIO> AudioDecoderSelector;
} // namespace media