summaryrefslogtreecommitdiffstats
path: root/dom/media/platforms/android/MediaCodecDataDecoder.h
blob: 0db6407bfb6769a6a5b60ccf12f93cf840bcfba6 (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
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
/* 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 MediaCodecDataDecoder_h_
#define MediaCodecDataDecoder_h_

#include "AndroidDecoderModule.h"

#include "MediaCodec.h"
#include "SurfaceTexture.h"
#include "TimeUnits.h"
#include "mozilla/Monitor.h"
#include "mozilla/Maybe.h"

#include <deque>

namespace mozilla {

typedef std::deque<RefPtr<MediaRawData>> SampleQueue;

class MediaCodecDataDecoder : public MediaDataDecoder {
public:
  static MediaDataDecoder* CreateAudioDecoder(const AudioInfo& aConfig,
                                              java::sdk::MediaFormat::Param aFormat,
                                              MediaDataDecoderCallback* aCallback);

  static MediaDataDecoder* CreateVideoDecoder(const VideoInfo& aConfig,
                                              java::sdk::MediaFormat::Param aFormat,
                                              MediaDataDecoderCallback* aCallback,
                                              layers::ImageContainer* aImageContainer);

  virtual ~MediaCodecDataDecoder();

  RefPtr<MediaDataDecoder::InitPromise> Init() override;
  void Flush() override;
  void Drain() override;
  void Shutdown() override;
  void Input(MediaRawData* aSample) override;
  const char* GetDescriptionName() const override
  {
    return "Android MediaCodec decoder";
  }

protected:
  enum class ModuleState : uint8_t {
    kDecoding = 0,
    kFlushing,
    kDrainQueue,
    kDrainDecoder,
    kDrainWaitEOS,
    kStopping,
    kShutdown
  };

  friend class AndroidDecoderModule;

  MediaCodecDataDecoder(MediaData::Type aType,
                        const nsACString& aMimeType,
                        java::sdk::MediaFormat::Param aFormat,
                        MediaDataDecoderCallback* aCallback);

  static const char* ModuleStateStr(ModuleState aState);

  virtual nsresult InitDecoder(java::sdk::Surface::Param aSurface);

  virtual nsresult Output(java::sdk::BufferInfo::Param aInfo, void* aBuffer,
      java::sdk::MediaFormat::Param aFormat, const media::TimeUnit& aDuration)
  {
    return NS_OK;
  }

  virtual nsresult PostOutput(java::sdk::BufferInfo::Param aInfo,
      java::sdk::MediaFormat::Param aFormat, const media::TimeUnit& aDuration)
  {
    return NS_OK;
  }

  virtual void Cleanup() {};

  nsresult ResetInputBuffers();
  nsresult ResetOutputBuffers();

  nsresult GetInputBuffer(JNIEnv* env, int index, jni::Object::LocalRef* buffer);
  bool WaitForInput();
  already_AddRefed<MediaRawData> PeekNextSample();
  nsresult QueueSample(const MediaRawData* aSample);
  nsresult QueueEOS();
  void HandleEOS(int32_t aOutputStatus);
  Maybe<media::TimeUnit> GetOutputDuration();
  nsresult ProcessOutput(java::sdk::BufferInfo::Param aInfo,
                         java::sdk::MediaFormat::Param aFormat,
                         int32_t aStatus);
  // Sets decoder state and returns whether the new state has become effective.
  bool SetState(ModuleState aState);
  void DecoderLoop();

  virtual void ClearQueue();

  MediaData::Type mType;

  nsAutoCString mMimeType;
  java::sdk::MediaFormat::GlobalRef mFormat;

  MediaDataDecoderCallback* mCallback;

  java::sdk::MediaCodec::GlobalRef mDecoder;

  jni::ObjectArray::GlobalRef mInputBuffers;
  jni::ObjectArray::GlobalRef mOutputBuffers;

  nsCOMPtr<nsIThread> mThread;

  // Only these members are protected by mMonitor.
  Monitor mMonitor;

  ModuleState mState;

  SampleQueue mQueue;
  // Durations are stored in microseconds.
  std::deque<media::TimeUnit> mDurations;
};

} // namespace mozilla

#endif