123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194 |
- // Copyright (c) 2012 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_DECRYPTING_DEMUXER_STREAM_H_
- #define MEDIA_FILTERS_DECRYPTING_DEMUXER_STREAM_H_
- #include "base/callback.h"
- #include "base/memory/raw_ptr.h"
- #include "base/memory/ref_counted.h"
- #include "base/memory/weak_ptr.h"
- #include "base/sequence_checker.h"
- #include "media/base/audio_decoder_config.h"
- #include "media/base/callback_registry.h"
- #include "media/base/cdm_context.h"
- #include "media/base/decryptor.h"
- #include "media/base/demuxer_stream.h"
- #include "media/base/pipeline_status.h"
- #include "media/base/video_decoder_config.h"
- #include "media/base/waiting.h"
- #include "third_party/abseil-cpp/absl/types/optional.h"
- namespace base {
- class SequencedTaskRunner;
- }
- namespace media {
- class CdmContext;
- class DecoderBuffer;
- class MediaLog;
- // Decryptor-based DemuxerStream implementation that converts a potentially
- // encrypted demuxer stream to a clear demuxer stream.
- // All public APIs and callbacks are trampolined to the |task_runner_| so
- // that no locks are required for thread safety.
- class MEDIA_EXPORT DecryptingDemuxerStream : public DemuxerStream {
- public:
- DecryptingDemuxerStream(
- const scoped_refptr<base::SequencedTaskRunner>& task_runner,
- MediaLog* media_log,
- const WaitingCB& waiting_cb);
- DecryptingDemuxerStream(const DecryptingDemuxerStream&) = delete;
- DecryptingDemuxerStream& operator=(const DecryptingDemuxerStream&) = delete;
- // Cancels all pending operations immediately and fires all pending callbacks.
- ~DecryptingDemuxerStream() override;
- // |stream| must be encrypted and |cdm_context| must be non-null.
- void Initialize(DemuxerStream* stream,
- CdmContext* cdm_context,
- PipelineStatusCallback status_cb);
- // Cancels all pending operations and fires all pending callbacks. If in
- // kPendingDemuxerRead or kPendingDecrypt state, waits for the pending
- // operation to finish before satisfying |closure|. Sets the state to
- // kUninitialized if |this| hasn't been initialized, or to kIdle otherwise.
- void Reset(base::OnceClosure closure);
- // Returns the name of this class for logging purpose.
- std::string GetDisplayName() const;
- // DemuxerStream implementation.
- void Read(ReadCB read_cb) override;
- AudioDecoderConfig audio_decoder_config() override;
- VideoDecoderConfig video_decoder_config() override;
- Type type() const override;
- StreamLiveness liveness() const override;
- void EnableBitstreamConverter() override;
- bool SupportsConfigChanges() override;
- // Returns whether the stream has clear lead.
- bool HasClearLead() const;
- private:
- // See this link for a detailed state diagram: http://shortn/_1nXgoVIrps
- // Each line has a number that corresponds to an action, status or function
- // that results in a state change. These actions, etc are all listed below.
- // NOTE: invoking Reset() will cause a transition from any state except
- // kUninitialized to the kIdle state.
- //
- // +----------------+ +---------------------------------+
- // | kUninitialized | | Any State Except kUninitialized |
- // +----------------+ +---------------------------------+
- // | |
- // 0 7
- // v v
- // +-------+ +-------+
- // | kIdle |<-------+-+ | kIdle |
- // +-------+ | | +-------+
- // | | |
- // 1 4 5
- // v | |
- // +---------------------+ | |
- // | kPendingDemuxerRead |-+ |
- // +---------------------+ |
- // | |
- // 2 |
- // v |
- // +-----------------+ |
- // +->| kPendingDecrypt |-----+
- // | +-----------------+
- // | |
- // 6 3
- // | v
- // | +----------------+
- // +---| kWaitingForKey |
- // +----------------+
- //
- // 1) Read()
- // 2) Has encrypted buffer
- // 3) kNoKey
- // 4) kConfigChanged, kAborted, has clear buffer or end of stream
- // 5) kSuccess or kAborted
- // 6) OnKeyAdded()
- // 7) Reset()
- enum State {
- kUninitialized = 0,
- kIdle,
- kPendingDemuxerRead,
- kPendingDecrypt,
- kWaitingForKey
- };
- // Callback for DemuxerStream::Read().
- void OnBufferReadFromDemuxerStream(DemuxerStream::Status status,
- scoped_refptr<DecoderBuffer> buffer);
- void DecryptPendingBuffer();
- // Callback for Decryptor::Decrypt().
- void OnBufferDecrypted(Decryptor::Status status,
- scoped_refptr<DecoderBuffer> decrypted_buffer);
- // Callback for the CDM to notify |this|.
- void OnCdmContextEvent(CdmContext::Event event);
- // Resets decoder and calls |reset_cb_|.
- void DoReset();
- // Returns Decryptor::StreamType converted from |stream_type_|.
- Decryptor::StreamType GetDecryptorStreamType() const;
- // Creates and initializes either |audio_config_| or |video_config_| based on
- // |demuxer_stream_|.
- void InitializeDecoderConfig();
- // Completes traces for various pending states.
- void CompletePendingDecrypt(Decryptor::Status status);
- void CompleteWaitingForDecryptionKey();
- void LogMetadata();
- scoped_refptr<base::SequencedTaskRunner> task_runner_;
- SEQUENCE_CHECKER(sequence_checker_);
- const raw_ptr<MediaLog> media_log_;
- WaitingCB waiting_cb_;
- State state_ = kUninitialized;
- PipelineStatusCallback init_cb_;
- ReadCB read_cb_;
- base::OnceClosure reset_cb_;
- // Pointer to the input demuxer stream that will feed us encrypted buffers.
- raw_ptr<DemuxerStream> demuxer_stream_ = nullptr;
- AudioDecoderConfig audio_config_;
- VideoDecoderConfig video_config_;
- raw_ptr<Decryptor> decryptor_ = nullptr;
- absl::optional<bool> has_clear_lead_;
- // The buffer returned by the demuxer that needs to be decrypted.
- scoped_refptr<media::DecoderBuffer> pending_buffer_to_decrypt_;
- // Indicates the situation where new key is added during pending decryption
- // (in other words, this variable can only be set in state kPendingDecrypt).
- // If this variable is true and kNoKey is returned then we need to try
- // decrypting again in case the newly added key is the correct decryption key.
- bool key_added_while_decrypt_pending_ = false;
- // To keep the CdmContext event callback registered.
- std::unique_ptr<CallbackRegistration> event_cb_registration_;
- base::WeakPtrFactory<DecryptingDemuxerStream> weak_factory_{this};
- };
- } // namespace media
- #endif // MEDIA_FILTERS_DECRYPTING_DEMUXER_STREAM_H_
|