media_foundation_stream_wrapper.h 6.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187
  1. // Copyright 2019 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_RENDERERS_WIN_MEDIA_FOUNDATION_STREAM_WRAPPER_H_
  5. #define MEDIA_RENDERERS_WIN_MEDIA_FOUNDATION_STREAM_WRAPPER_H_
  6. #include <mfapi.h>
  7. #include <mfidl.h>
  8. #include <wrl.h>
  9. #include <memory>
  10. #include <queue>
  11. #include "base/memory/raw_ptr.h"
  12. #include "base/memory/scoped_refptr.h"
  13. #include "base/memory/weak_ptr.h"
  14. #include "base/synchronization/lock.h"
  15. #include "base/task/sequenced_task_runner.h"
  16. #include "media/base/decoder_buffer.h"
  17. #include "media/base/demuxer_stream.h"
  18. #include "media/base/media_log.h"
  19. namespace media {
  20. namespace {
  21. struct MediaFoundationSubsampleEntry {
  22. MediaFoundationSubsampleEntry(SubsampleEntry entry)
  23. : clear_bytes(entry.clear_bytes), cipher_bytes(entry.cypher_bytes) {}
  24. MediaFoundationSubsampleEntry() = default;
  25. DWORD clear_bytes = 0;
  26. DWORD cipher_bytes = 0;
  27. };
  28. } // namespace
  29. // IMFMediaStream implementation
  30. // (https://msdn.microsoft.com/en-us/windows/desktop/ms697561) based on the
  31. // given |demuxer_stream|.
  32. //
  33. class MediaFoundationStreamWrapper
  34. : public Microsoft::WRL::RuntimeClass<
  35. Microsoft::WRL::RuntimeClassFlags<
  36. Microsoft::WRL::RuntimeClassType::ClassicCom>,
  37. IMFMediaStream> {
  38. public:
  39. MediaFoundationStreamWrapper();
  40. ~MediaFoundationStreamWrapper() override;
  41. static HRESULT Create(int stream_id,
  42. IMFMediaSource* parent_source,
  43. DemuxerStream* demuxer_stream,
  44. std::unique_ptr<MediaLog> media_log,
  45. scoped_refptr<base::SequencedTaskRunner> task_runner,
  46. MediaFoundationStreamWrapper** stream_out);
  47. HRESULT RuntimeClassInitialize(int stream_id,
  48. IMFMediaSource* parent_source,
  49. DemuxerStream* demuxer_stream,
  50. std::unique_ptr<MediaLog> media_log);
  51. void SetTaskRunner(scoped_refptr<base::SequencedTaskRunner> task_runner);
  52. void DetachParent();
  53. void DetachDemuxerStream();
  54. bool HasEnded() const;
  55. // The following methods can be invoked by media stack thread or MF threadpool
  56. // thread via MediaFoundationSourceWrapper::Start().
  57. void SetSelected(bool selected);
  58. bool IsSelected();
  59. bool IsEnabled();
  60. void SetEnabled(bool enabled);
  61. void SetFlushed(bool flushed);
  62. // TODO: revisting inheritance and potentially replacing it with composition.
  63. // The stream is encrypted or not.
  64. virtual bool IsEncrypted() const = 0;
  65. // Let derived class to adjust the IMFSample if necessary.
  66. virtual HRESULT TransformSample(Microsoft::WRL::ComPtr<IMFSample>& sample);
  67. // Allow derived class to tell us if we can send MEStreamFormatChanged to MF.
  68. virtual bool AreFormatChangesEnabled();
  69. HRESULT QueueStartedEvent(const PROPVARIANT* start_position);
  70. HRESULT QueueSeekedEvent(const PROPVARIANT* start_position);
  71. HRESULT QueueStoppedEvent();
  72. HRESULT QueuePausedEvent();
  73. HRESULT QueueFormatChangedEvent();
  74. DemuxerStream::Type StreamType() const;
  75. void ProcessRequestsIfPossible();
  76. void OnDemuxerStreamRead(DemuxerStream::Status status,
  77. scoped_refptr<DecoderBuffer> buffer);
  78. // IMFMediaStream implementation - it is in general running in MF threadpool
  79. // thread.
  80. IFACEMETHODIMP GetMediaSource(IMFMediaSource** media_source_out) override;
  81. IFACEMETHODIMP GetStreamDescriptor(
  82. IMFStreamDescriptor** stream_descriptor_out) override;
  83. IFACEMETHODIMP RequestSample(IUnknown* token) override;
  84. // IMFMediaEventGenerator implementation - IMFMediaStream derives from
  85. // IMFMediaEventGenerator.
  86. IFACEMETHODIMP GetEvent(DWORD flags, IMFMediaEvent** event_out) override;
  87. IFACEMETHODIMP BeginGetEvent(IMFAsyncCallback* callback,
  88. IUnknown* state) override;
  89. IFACEMETHODIMP EndGetEvent(IMFAsyncResult* result,
  90. IMFMediaEvent** event_out) override;
  91. IFACEMETHODIMP QueueEvent(MediaEventType type,
  92. REFGUID extended_type,
  93. HRESULT status,
  94. const PROPVARIANT* value) override;
  95. GUID GetLastKeyId() const;
  96. protected:
  97. HRESULT GenerateStreamDescriptor();
  98. HRESULT GenerateSampleFromDecoderBuffer(DecoderBuffer* buffer,
  99. IMFSample** sample_out);
  100. HRESULT ServiceSampleRequest(IUnknown* token, DecoderBuffer* buffer)
  101. EXCLUSIVE_LOCKS_REQUIRED(lock_);
  102. // Returns true when a sample request has been serviced.
  103. bool ServicePostFlushSampleRequest();
  104. virtual HRESULT GetMediaType(IMFMediaType** media_type_out) = 0;
  105. void ReportEncryptionType(const scoped_refptr<DecoderBuffer>& buffer);
  106. scoped_refptr<base::SequencedTaskRunner> task_runner_;
  107. enum class State {
  108. kInitialized,
  109. kStarted,
  110. kStopped,
  111. kPaused
  112. } state_ = State::kInitialized;
  113. raw_ptr<DemuxerStream> demuxer_stream_ = nullptr;
  114. DemuxerStream::Type stream_type_ = DemuxerStream::Type::UNKNOWN;
  115. std::unique_ptr<MediaLog> media_log_;
  116. // Need exclusive access to some members between calls from MF threadpool
  117. // thread and calling thread from Chromium media stack.
  118. base::Lock lock_;
  119. // Indicates whether the stream is selected in the MF pipeline.
  120. bool selected_ GUARDED_BY(lock_) = false;
  121. // Indicates whether the stream is enabled in the Chromium media pipeline.
  122. bool enabled_ GUARDED_BY(lock_) = true;
  123. // Indicates whether the Chromium pipeline has flushed the renderer
  124. // (prior to a seek).
  125. // Since SetFlushed() can be invoked by media stack thread or MF threadpool
  126. // thread, |flushed_| and |post_flush_buffers_| are protected by lock.
  127. bool flushed_ GUARDED_BY(lock_) = false;
  128. int stream_id_;
  129. // |mf_media_event_queue_| is safe to be called on any thread.
  130. Microsoft::WRL::ComPtr<IMFMediaEventQueue> mf_media_event_queue_;
  131. Microsoft::WRL::ComPtr<IMFStreamDescriptor> mf_stream_descriptor_;
  132. // The IMFMediaSource that contains this stream.
  133. Microsoft::WRL::ComPtr<IMFMediaSource> parent_source_ GUARDED_BY(lock_);
  134. // If non-zero, there are pending sample request from MF.
  135. std::queue<Microsoft::WRL::ComPtr<IUnknown>> pending_sample_request_tokens_
  136. GUARDED_BY(lock_);
  137. // If true, there is a pending a read completion from Chromium media stack.
  138. bool pending_stream_read_ = false;
  139. bool stream_ended_ = false;
  140. GUID last_key_id_ = GUID_NULL;
  141. // Save media::DecoderBuffer from OnDemuxerStreamRead call when we are in
  142. // progress of a flush operation.
  143. std::queue<scoped_refptr<DecoderBuffer>> post_flush_buffers_
  144. GUARDED_BY(lock_);
  145. bool encryption_type_reported_ = false;
  146. // NOTE: Weak pointers must be invalidated before all other member variables.
  147. base::WeakPtrFactory<MediaFoundationStreamWrapper> weak_factory_{this};
  148. };
  149. } // namespace media
  150. #endif // MEDIA_RENDERERS_WIN_MEDIA_FOUNDATION_STREAM_WRAPPER_H_