1 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2 /* vim:set ts=2 sw=2 sts=2 et cindent: */
3 /* This Source Code Form is subject to the terms of the Mozilla Public
4  * License, v. 2.0. If a copy of the MPL was not distributed with this
5  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
6 
7 #if !defined(MFTEncoder_h_)
8 #  define MFTEncoder_h_
9 
10 #  include <functional>
11 #  include "mozilla/RefPtr.h"
12 #  include "nsISupportsImpl.h"
13 #  include "nsDeque.h"
14 #  include "WMF.h"
15 
16 namespace mozilla {
17 
18 class MFTEncoder final {
19  public:
20   NS_INLINE_DECL_THREADSAFE_REFCOUNTING(MFTEncoder)
21 
22   HRESULT Create(const GUID& aSubtype);
23   HRESULT Destroy();
24   HRESULT SetMediaTypes(IMFMediaType* aInputType, IMFMediaType* aOutputType);
25   HRESULT SetModes(UINT32 aBitsPerSec);
26   HRESULT SetBitrate(UINT32 aBitsPerSec);
27 
28   HRESULT CreateInputSample(RefPtr<IMFSample>* aSample, size_t aSize);
29   HRESULT PushInput(RefPtr<IMFSample>&& aInput);
30   HRESULT TakeOutput(nsTArray<RefPtr<IMFSample>>& aOutput);
31   HRESULT Drain(nsTArray<RefPtr<IMFSample>>& aOutput);
32 
33   HRESULT GetMPEGSequenceHeader(nsTArray<UINT8>& aHeader);
34 
35   static nsCString GetFriendlyName(const GUID& aSubtype);
36 
37   struct Info final {
38     GUID mSubtype;
39     nsCString mName;
40   };
41 
42  private:
~MFTEncoder()43   ~MFTEncoder() { Destroy(); };
44 
45   static nsTArray<Info>& Infos();
46   static nsTArray<Info> Enumerate();
47   static Maybe<Info> GetInfo(const GUID& aSubtype);
48 
49   already_AddRefed<IMFActivate> CreateFactory(const GUID& aSubtype);
50   HRESULT EnableAsync();
51   HRESULT GetStreamIDs();
52   GUID MatchInputSubtype(IMFMediaType* aInputType);
53   HRESULT SendMFTMessage(MFT_MESSAGE_TYPE aMsg, ULONG_PTR aData);
54 
55   HRESULT ProcessEvents();
56   HRESULT ProcessInput();
57   HRESULT ProcessOutput();
58 
59   RefPtr<IMFTransform> mEncoder;
60   // For MFT object creation. See
61   // https://docs.microsoft.com/en-us/windows/win32/medfound/activation-objects
62   RefPtr<IMFActivate> mFactory;
63   // For encoder configuration. See
64   // https://docs.microsoft.com/en-us/windows/win32/directshow/encoder-api
65   RefPtr<ICodecAPI> mConfig;
66   // For async MFT events. See
67   // https://docs.microsoft.com/en-us/windows/win32/medfound/asynchronous-mfts#events
68   RefPtr<IMFMediaEventGenerator> mEventSource;
69 
70   DWORD mInputStreamID;
71   DWORD mOutputStreamID;
72   MFT_INPUT_STREAM_INFO mInputStreamInfo;
73   MFT_OUTPUT_STREAM_INFO mOutputStreamInfo;
74   bool mOutputStreamProvidesSample;
75 
76   size_t mNumNeedInput;
77   enum class DrainState { DRAINED, DRAINABLE, DRAINING };
78   DrainState mDrainState = DrainState::DRAINABLE;
79 
80   nsRefPtrDeque<IMFSample> mPendingInputs;
81   nsTArray<RefPtr<IMFSample>> mOutputs;
82 };
83 
84 }  // namespace mozilla
85 
86 #endif
87