summaryrefslogtreecommitdiffstats
path: root/dom/media/platforms/android/AndroidDataEncoder.h
blob: ad4e5a8ee96fcb8f1a7cf2ecac02a86a6749a2b4 (plain)
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
/* 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 "TimeUnits.h"

#include "JavaCallbacksSupport.h"

#include "mozilla/Maybe.h"
#include "mozilla/Monitor.h"

namespace mozilla {

class AndroidDataEncoder final : public MediaDataEncoder {
 public:
  using Config = H264Config;

  AndroidDataEncoder(const Config& aConfig, RefPtr<TaskQueue> aTaskQueue)
      : mConfig(aConfig), mTaskQueue(aTaskQueue) {
    MOZ_ASSERT(mConfig.mSize.width > 0 && mConfig.mSize.height > 0);
    MOZ_ASSERT(mTaskQueue);
  }
  RefPtr<InitPromise> Init() override;
  RefPtr<EncodePromise> Encode(const MediaData* aSample) override;
  RefPtr<EncodePromise> Drain() override;
  RefPtr<ShutdownPromise> Shutdown() override;
  RefPtr<GenericPromise> SetBitrate(const Rate aBitsPerSec) override;

  nsCString GetDescriptionName() const override { return "Android Encoder"_ns; }

 private:
  class CallbacksSupport final : public JavaCallbacksSupport {
   public:
    explicit CallbacksSupport(AndroidDataEncoder* aEncoder)
        : mEncoder(aEncoder) {}

    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:
    AndroidDataEncoder* mEncoder;
  };
  friend class CallbacksSupport;

  // Methods only called on mTaskQueue.
  RefPtr<InitPromise> ProcessInit();
  RefPtr<EncodePromise> ProcessEncode(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);
  void Error(const MediaResult& aError);

  void AssertOnTaskQueue() const {
    MOZ_ASSERT(mTaskQueue->IsCurrentThreadIn());
  }

  Config 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::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 { DRAINED, DRAINABLE, DRAINING };
  DrainState mDrainState;

  Maybe<MediaResult> mError;
};

}  // namespace mozilla

#endif