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
111
112
113
114
115
116
117
118
119
120
121
|
/* 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 DOM_MEDIA_PLATFORMS_ANDROID_ANDROIDDATAENCODER_H_
#define DOM_MEDIA_PLATFORMS_ANDROID_ANDROIDDATAENCODER_H_
#include "MediaData.h"
#include "PlatformEncoderModule.h"
#include "JavaCallbacksSupport.h"
#include "mozilla/Maybe.h"
#include "mozilla/Mutex.h"
namespace mozilla {
class AndroidDataEncoder final : public MediaDataEncoder {
public:
AndroidDataEncoder(const EncoderConfig& aConfig,
const RefPtr<TaskQueue>& aTaskQueue)
: mConfig(aConfig), mTaskQueue(aTaskQueue) {
MOZ_ASSERT(mConfig.mSize.width > 0 && mConfig.mSize.height > 0);
MOZ_ASSERT(mTaskQueue);
}
~AndroidDataEncoder() { MOZ_ASSERT(!mJavaEncoder); }
RefPtr<InitPromise> Init() override;
RefPtr<EncodePromise> Encode(const MediaData* aSample) override;
RefPtr<EncodePromise> Drain() override;
RefPtr<ShutdownPromise> Shutdown() override;
RefPtr<GenericPromise> SetBitrate(uint32_t aBitsPerSec) override;
RefPtr<ReconfigurationPromise> Reconfigure(
const RefPtr<const EncoderConfigurationChangeList>& aConfigurationChanges)
override {
// General reconfiguration interface not implemented right now
return MediaDataEncoder::ReconfigurationPromise::CreateAndReject(
NS_ERROR_DOM_MEDIA_FATAL_ERR, __func__);
};
nsCString GetDescriptionName() const override { return "Android Encoder"_ns; }
private:
class CallbacksSupport final : public JavaCallbacksSupport {
public:
explicit CallbacksSupport(AndroidDataEncoder* aEncoder)
: mMutex("AndroidDataEncoder::CallbacksSupport") {
MutexAutoLock lock(mMutex);
mEncoder = aEncoder;
}
~CallbacksSupport() {
MutexAutoLock lock(mMutex);
mEncoder = nullptr;
}
void HandleInput(int64_t aTimestamp, bool aProcessed) override;
void HandleOutput(java::Sample::Param aSample,
java::SampleBuffer::Param aBuffer) override;
void HandleOutputFormatChanged(
java::sdk::MediaFormat::Param aFormat) override;
void HandleError(const MediaResult& aError) override;
private:
Mutex mMutex;
AndroidDataEncoder* mEncoder MOZ_GUARDED_BY(mMutex);
};
friend class CallbacksSupport;
// Methods only called on mTaskQueue.
RefPtr<InitPromise> ProcessInit();
RefPtr<EncodePromise> ProcessEncode(const RefPtr<const MediaData>& aSample);
RefPtr<EncodePromise> ProcessDrain();
RefPtr<ShutdownPromise> ProcessShutdown();
void ProcessInput();
void ProcessOutput(java::Sample::GlobalRef&& aSample,
java::SampleBuffer::GlobalRef&& aBuffer);
RefPtr<MediaRawData> GetOutputData(java::SampleBuffer::Param aBuffer,
const int32_t aOffset, const int32_t aSize,
const bool aIsKeyFrame);
RefPtr<MediaRawData> GetOutputDataH264(java::SampleBuffer::Param aBuffer,
const int32_t aOffset,
const int32_t aSize,
const bool aIsKeyFrame);
void Error(const MediaResult& aError);
void AssertOnTaskQueue() const {
MOZ_ASSERT(mTaskQueue->IsCurrentThreadIn());
}
EncoderConfig mConfig;
RefPtr<TaskQueue> mTaskQueue;
// Can be accessed on any thread, but only written on during init.
bool mIsHardwareAccelerated = false;
java::CodecProxy::GlobalRef mJavaEncoder;
java::CodecProxy::NativeCallbacks::GlobalRef mJavaCallbacks;
java::sdk::MediaFormat::GlobalRef mFormat;
// Preallocated Java object used as a reusable storage for input buffer
// information. Contents must be changed only on mTaskQueue.
java::sdk::MediaCodec::BufferInfo::GlobalRef mInputBufferInfo;
MozPromiseHolder<EncodePromise> mDrainPromise;
// Accessed on mTaskqueue only.
RefPtr<MediaByteBuffer> mYUVBuffer;
EncodedData mEncodedData;
// SPS/PPS NALUs for realtime usage, avcC otherwise.
RefPtr<MediaByteBuffer> mConfigData;
enum class DrainState { DRAINABLE, DRAINING, DRAINED };
DrainState mDrainState = DrainState::DRAINABLE;
Maybe<MediaResult> mError;
};
} // namespace mozilla
#endif
|