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