// 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. #ifndef MEDIA_FILTERS_DECODER_SELECTOR_H_ #define MEDIA_FILTERS_DECODER_SELECTOR_H_ #include "base/callback.h" #include "base/macros.h" #include "base/memory/ref_counted.h" #include "base/memory/scoped_vector.h" #include "base/memory/weak_ptr.h" #include "build/build_config.h" #include "media/base/demuxer_stream.h" #include "media/base/pipeline_status.h" #include "media/filters/decoder_stream_traits.h" namespace base { class SingleThreadTaskRunner; } namespace media { class CdmContext; class DecoderBuffer; class DecryptingDemuxerStream; class MediaLog; // DecoderSelector (creates if necessary and) initializes the proper // Decoder for a given DemuxerStream. If the given DemuxerStream is // encrypted, a DecryptingDemuxerStream may also be created. // The template parameter |StreamType| is the type of stream we will be // selecting a decoder for. template class MEDIA_EXPORT DecoderSelector { public: typedef DecoderStreamTraits StreamTraits; typedef typename StreamTraits::DecoderType Decoder; // Indicates completion of Decoder selection. // - First parameter: The initialized Decoder. If it's set to NULL, then // Decoder initialization failed. // - Second parameter: The initialized DecryptingDemuxerStream. If it's not // NULL, then a DecryptingDemuxerStream is created and initialized to do // decryption for the initialized Decoder. // Note: The caller owns selected Decoder and DecryptingDemuxerStream. // The caller should call DecryptingDemuxerStream::Reset() before // calling Decoder::Reset() to release any pending decryption or read. typedef base::Callback< void(scoped_ptr, scoped_ptr)> SelectDecoderCB; // |decoders| contains the Decoders to use when initializing. DecoderSelector( const scoped_refptr& message_loop, ScopedVector decoders, const scoped_refptr& media_log); // Aborts pending Decoder selection and fires |select_decoder_cb| with // NULL and NULL immediately if it's pending. ~DecoderSelector(); // Initializes and selects the first Decoder that can decode the |stream|. // The selected Decoder (and DecryptingDemuxerStream) is returned via // the |select_decoder_cb|. // Notes: // 1. This must not be called again before |select_decoder_cb| is run. // 2. Decoders that fail to initialize will be deleted. Future calls will // select from the decoders following the decoder that was last returned. // 3. |cdm_context| is optional. If |cdm_context| is // null, no CDM will be available to perform decryption. void SelectDecoder(DemuxerStream* stream, CdmContext* cdm_context, const SelectDecoderCB& select_decoder_cb, const typename Decoder::OutputCB& output_cb, const base::Closure& waiting_for_decryption_key_cb); private: #if !defined(OS_ANDROID) void InitializeDecryptingDecoder(); void DecryptingDecoderInitDone(bool success); #endif void InitializeDecryptingDemuxerStream(); void DecryptingDemuxerStreamInitDone(PipelineStatus status); void InitializeDecoder(); void DecoderInitDone(bool success); void ReturnNullDecoder(); scoped_refptr task_runner_; ScopedVector decoders_; scoped_refptr media_log_; DemuxerStream* input_stream_; CdmContext* cdm_context_; SelectDecoderCB select_decoder_cb_; typename Decoder::OutputCB output_cb_; base::Closure waiting_for_decryption_key_cb_; scoped_ptr decoder_; scoped_ptr decrypted_stream_; // NOTE: Weak pointers must be invalidated before all other member variables. base::WeakPtrFactory weak_ptr_factory_; DISALLOW_IMPLICIT_CONSTRUCTORS(DecoderSelector); }; typedef DecoderSelector VideoDecoderSelector; typedef DecoderSelector AudioDecoderSelector; } // namespace media #endif // MEDIA_FILTERS_DECODER_SELECTOR_H_