decoder_selector.h 7.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198
  1. // Copyright 2014 The Chromium Authors. All rights reserved.
  2. // Use of this source code is governed by a BSD-style license that can be
  3. // found in the LICENSE file.
  4. #ifndef MEDIA_FILTERS_DECODER_SELECTOR_H_
  5. #define MEDIA_FILTERS_DECODER_SELECTOR_H_
  6. #include <memory>
  7. #include <vector>
  8. #include "base/callback.h"
  9. #include "base/memory/raw_ptr.h"
  10. #include "base/memory/ref_counted.h"
  11. #include "base/memory/weak_ptr.h"
  12. #include "base/sequence_checker.h"
  13. #include "base/time/time.h"
  14. #include "media/base/demuxer_stream.h"
  15. #include "media/base/pipeline_status.h"
  16. #include "media/base/waiting.h"
  17. #include "media/filters/decoder_stream_traits.h"
  18. namespace base {
  19. class SequencedTaskRunner;
  20. }
  21. namespace media {
  22. class CdmContext;
  23. class DecryptingDemuxerStream;
  24. class MediaLog;
  25. // Enum returned by `DecoderSelector::DecoderPriorityCB` to indicate
  26. // priority of the current decoder.
  27. enum class DecoderPriority {
  28. // `kNormal` indicates that the current decoder should continue through with
  29. // selection in it's current order.
  30. kNormal,
  31. // `kDeprioritized` indicates that the current decoder should only be selected
  32. // if other decoders have failed.
  33. kDeprioritized,
  34. // `kSkipped` indicates that the current decoder should not be used at all.
  35. kSkipped,
  36. };
  37. // DecoderSelector handles construction and initialization of Decoders for a
  38. // DemuxerStream, and maintains the state required for decoder fallback.
  39. // The template parameter |StreamType| is the type of stream we will be
  40. // selecting a decoder for.
  41. template<DemuxerStream::Type StreamType>
  42. class MEDIA_EXPORT DecoderSelector {
  43. public:
  44. typedef DecoderStreamTraits<StreamType> StreamTraits;
  45. typedef typename StreamTraits::DecoderType Decoder;
  46. typedef typename StreamTraits::DecoderConfigType DecoderConfig;
  47. using DecoderOrError = DecoderStatus::Or<std::unique_ptr<Decoder>>;
  48. // Callback to create a list of decoders to select from.
  49. // TODO(xhwang): Use a DecoderFactory to create decoders one by one as needed,
  50. // instead of creating a list of decoders all at once.
  51. using CreateDecodersCB =
  52. base::RepeatingCallback<std::vector<std::unique_ptr<Decoder>>()>;
  53. // Prediate to evaluate whether a decoder should be prioritized,
  54. // deprioritized, or skipped.
  55. using DecoderPriorityCB =
  56. base::RepeatingCallback<DecoderPriority(const DecoderConfig&,
  57. const Decoder&)>;
  58. // Emits the result of a single call to SelectDecoder(). Parameters are
  59. // 1: The initialized Decoder. nullptr if selection failed.
  60. // 2: The initialized DecryptingDemuxerStream, if one was created. This
  61. // happens at most once for a DecoderSelector instance.
  62. // The caller owns the Decoder and DecryptingDemuxerStream.
  63. //
  64. // The caller should call DecryptingDemuxerStream::Reset() before
  65. // calling Decoder::Reset() to release any pending decryption or read.
  66. using SelectDecoderCB =
  67. base::OnceCallback<void(DecoderOrError,
  68. std::unique_ptr<DecryptingDemuxerStream>)>;
  69. DecoderSelector() = delete;
  70. DecoderSelector(scoped_refptr<base::SequencedTaskRunner> task_runner,
  71. CreateDecodersCB create_decoders_cb,
  72. MediaLog* media_log);
  73. DecoderSelector(const DecoderSelector&) = delete;
  74. DecoderSelector& operator=(const DecoderSelector&) = delete;
  75. // Aborts any pending decoder selection.
  76. ~DecoderSelector();
  77. // Initialize with stream parameters. Should be called exactly once.
  78. void Initialize(StreamTraits* traits,
  79. DemuxerStream* stream,
  80. CdmContext* cdm_context,
  81. WaitingCB waiting_cb);
  82. // Selects and initializes a decoder, which will be returned via
  83. // |select_decoder_cb| posted to |task_runner|. In the event that a selected
  84. // decoder fails to decode, |ResumeDecoderSelection| may be used to get
  85. // another one.
  86. //
  87. // When the caller determines that decoder selection has succeeded (eg.
  88. // because the decoder decoded a frame successfully), it should call
  89. // FinalizeDecoderSelection().
  90. //
  91. // |SelectDecoderCB| may be called with an error if no decoders are available.
  92. //
  93. // Must not be called while another selection is pending.
  94. void BeginDecoderSelection(SelectDecoderCB select_decoder_cb,
  95. typename Decoder::OutputCB output_cb);
  96. // When a client was provided with a decoder that fails to decode after
  97. // being successfully initialized, it should request a new decoder via
  98. // this method rather than |SelectDecoder|. This allows the pipeline to
  99. // report the root cause of decoder failure.
  100. void ResumeDecoderSelection(SelectDecoderCB select_decoder_cb,
  101. typename Decoder::OutputCB output_cb,
  102. DecoderStatus&& reinit_cause);
  103. // Signals that decoder selection has been completed (successfully). Future
  104. // calls to SelectDecoder() will select from the full list of decoders.
  105. void FinalizeDecoderSelection();
  106. // Signals that a config change has started being processed.
  107. // Currently only for metric collection.
  108. void NotifyConfigChanged();
  109. // Adds an additional decoder candidate to be considered when selecting a
  110. // decoder. This decoder is inserted ahead of the decoders returned by
  111. // |CreateDecodersCB| to give it priority over the default set, though it
  112. // may be by deprioritized if |DecoderPriorityCB| considers another decoder a
  113. // better candidate. This decoder should be uninitialized.
  114. void PrependDecoder(std::unique_ptr<Decoder> decoder);
  115. // Overrides the default function for evaluation platform decoder priority.
  116. // Useful for writing tests in a platform-agnostic manner.
  117. void OverrideDecoderPriorityCBForTesting(DecoderPriorityCB priority_cb);
  118. private:
  119. void CreateDecoders();
  120. void GetAndInitializeNextDecoder();
  121. void OnDecoderInitializeDone(DecoderStatus status);
  122. void ReturnSelectionError(DecoderStatus error);
  123. void InitializeDecryptingDemuxerStream();
  124. void OnDecryptingDemuxerStreamInitializeDone(PipelineStatus status);
  125. void RunSelectDecoderCB(DecoderOrError decoder_or_error);
  126. void FilterAndSortAvailableDecoders();
  127. void SelectDecoderInternal(SelectDecoderCB select_decoder_cb,
  128. typename Decoder::OutputCB output_cb,
  129. bool needs_new_decoders);
  130. scoped_refptr<base::SequencedTaskRunner> task_runner_;
  131. SEQUENCE_CHECKER(sequence_checker_);
  132. CreateDecodersCB create_decoders_cb_;
  133. DecoderPriorityCB decoder_priority_cb_;
  134. raw_ptr<MediaLog> media_log_;
  135. raw_ptr<StreamTraits> traits_ = nullptr;
  136. raw_ptr<DemuxerStream> stream_ = nullptr;
  137. raw_ptr<CdmContext> cdm_context_ = nullptr;
  138. WaitingCB waiting_cb_;
  139. // Overall decoder selection state.
  140. DecoderConfig config_;
  141. std::vector<std::unique_ptr<Decoder>> decoders_;
  142. // State for a single GetAndInitializeNextDecoder() invocation.
  143. SelectDecoderCB select_decoder_cb_;
  144. typename Decoder::OutputCB output_cb_;
  145. std::unique_ptr<Decoder> decoder_;
  146. std::unique_ptr<DecryptingDemuxerStream> decrypting_demuxer_stream_;
  147. // Metrics.
  148. bool is_platform_decoder_ = false;
  149. bool is_codec_changing_ = false;
  150. bool is_selecting_for_config_change_ = false;
  151. base::TimeTicks decoder_selection_start_;
  152. base::TimeTicks codec_change_start_;
  153. // Used to keep track of the original failure-to-decode reason so that if
  154. // playback fails entirely, we have a root cause to point to, rather than
  155. // failing due to running out of more acceptable decoders.
  156. absl::optional<DecoderStatus> decode_failure_reinit_cause_ = absl::nullopt;
  157. base::WeakPtrFactory<DecoderSelector> weak_this_factory_{this};
  158. };
  159. typedef DecoderSelector<DemuxerStream::VIDEO> VideoDecoderSelector;
  160. typedef DecoderSelector<DemuxerStream::AUDIO> AudioDecoderSelector;
  161. } // namespace media
  162. #endif // MEDIA_FILTERS_DECODER_SELECTOR_H_