1 /* This Source Code Form is subject to the terms of the Mozilla Public
2  * License, v. 2.0. If a copy of the MPL was not distributed with this
3  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
4 
5 #ifndef RemoteDataDecoder_h_
6 #define RemoteDataDecoder_h_
7 
8 #include "AndroidDecoderModule.h"
9 #include "SurfaceTexture.h"
10 #include "TimeUnits.h"
11 #include "mozilla/java/CodecProxyWrappers.h"
12 #include "mozilla/Maybe.h"
13 #include "mozilla/Monitor.h"
14 
15 namespace mozilla {
16 
17 DDLoggedTypeDeclNameAndBase(RemoteDataDecoder, MediaDataDecoder);
18 
19 class RemoteDataDecoder : public MediaDataDecoder,
20                           public DecoderDoctorLifeLogger<RemoteDataDecoder> {
21  public:
22   static already_AddRefed<MediaDataDecoder> CreateAudioDecoder(
23       const CreateDecoderParams& aParams, const nsString& aDrmStubId,
24       CDMProxy* aProxy);
25 
26   static already_AddRefed<MediaDataDecoder> CreateVideoDecoder(
27       const CreateDecoderParams& aParams, const nsString& aDrmStubId,
28       CDMProxy* aProxy);
29 
30   RefPtr<DecodePromise> Decode(MediaRawData* aSample) override;
31   RefPtr<DecodePromise> Drain() override;
32   RefPtr<FlushPromise> Flush() override;
33   RefPtr<ShutdownPromise> Shutdown() override;
GetDescriptionName()34   nsCString GetDescriptionName() const override {
35     return NS_LITERAL_CSTRING("android decoder (remote)");
36   }
37 
38  protected:
~RemoteDataDecoder()39   virtual ~RemoteDataDecoder() {}
40   RemoteDataDecoder(MediaData::Type aType, const nsACString& aMimeType,
41                     java::sdk::MediaFormat::Param aFormat,
42                     const nsString& aDrmStubId, TaskQueue* aTaskQueue);
43 
44   // Methods only called on mTaskQueue.
45   RefPtr<FlushPromise> ProcessFlush();
46   RefPtr<DecodePromise> ProcessDecode(MediaRawData* aSample);
47   RefPtr<ShutdownPromise> ProcessShutdown();
48   void UpdateInputStatus(int64_t aTimestamp, bool aProcessed);
49   void UpdateOutputStatus(RefPtr<MediaData>&& aSample);
50   void ReturnDecodedData();
51   void DrainComplete();
52   void Error(const MediaResult& aError);
AssertOnTaskQueue()53   void AssertOnTaskQueue() const {
54     MOZ_ASSERT(mTaskQueue->IsCurrentThreadIn());
55   }
56 
57   enum class State { DRAINED, DRAINABLE, DRAINING, SHUTDOWN };
SetState(State aState)58   void SetState(State aState) {
59     AssertOnTaskQueue();
60     mState = aState;
61   }
GetState()62   State GetState() const {
63     AssertOnTaskQueue();
64     return mState;
65   }
66 
67   // Whether the sample will be used.
IsUsefulData(const RefPtr<MediaData> & aSample)68   virtual bool IsUsefulData(const RefPtr<MediaData>& aSample) { return true; }
69 
70   MediaData::Type mType;
71 
72   nsAutoCString mMimeType;
73   java::sdk::MediaFormat::GlobalRef mFormat;
74 
75   java::CodecProxy::GlobalRef mJavaDecoder;
76   java::CodecProxy::NativeCallbacks::GlobalRef mJavaCallbacks;
77   nsString mDrmStubId;
78 
79   RefPtr<TaskQueue> mTaskQueue;
80 
81   // Preallocated Java object used as a reusable storage for input buffer
82   // information. Contents must be changed only on mTaskQueue.
83   java::sdk::BufferInfo::GlobalRef mInputBufferInfo;
84 
85   // Session ID attached to samples. It is returned by CodecProxy::Input().
86   // Accessed on mTaskqueue only.
87   int64_t mSession;
88 
89  private:
90   enum class PendingOp { INCREASE, DECREASE, CLEAR };
91   void UpdatePendingInputStatus(PendingOp aOp);
HasPendingInputs()92   size_t HasPendingInputs() {
93     AssertOnTaskQueue();
94     return mNumPendingInputs > 0;
95   }
96 
97   // The following members must only be accessed on mTaskqueue.
98   MozPromiseHolder<DecodePromise> mDecodePromise;
99   MozPromiseHolder<DecodePromise> mDrainPromise;
100   DecodedData mDecodedData;
101   State mState = State::DRAINED;
102   size_t mNumPendingInputs;
103 };
104 
105 }  // namespace mozilla
106 
107 #endif
108