summaryrefslogtreecommitdiffstats
path: root/dom/media/platforms/omx/GonkOmxPlatformLayer.h
blob: aaa8c654dbed53a145f2dad4c7063077b67e142c (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
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim:set ts=2 sw=2 sts=2 et cindent: */
/* 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/. */

#if !defined(GonkOmxPlatformLayer_h_)
#define GonkOmxPlatformLayer_h_

#pragma GCC visibility push(default)

#include <bitset>

#include <utils/RefBase.h>
#include <media/stagefright/OMXClient.h>
#include "nsAutoPtr.h"

#include "OMX_Component.h"

#include "OmxPlatformLayer.h"

class nsACString;

namespace android {
class IMemory;
class MemoryDealer;
}

namespace mozilla {

class GonkOmxObserver;
class GonkOmxPlatformLayer;
class GonkTextureClientRecycleHandler;

/*
 * Due to Android's omx node could live in local process (client) or remote
 * process (mediaserver). And there are 3 kinds of buffer in Android OMX.
 *
 * 1.
 * When buffer is in local process, the IOMX::buffer_id is OMX_BUFFERHEADERTYPE
 * pointer actually, it is safe to use it directly.
 *
 * 2.
 * When buffer is in remote process, the OMX_BUFFERHEADERTYPE pointer is 'IN' the
 * remote process. It can't be used in local process, so here it allocates a
 * local OMX_BUFFERHEADERTYPE. The raw/decoded data is in the android shared
 * memory, IMemory.
 *
 * 3.
 * When buffer is in remote process for the display output port. It uses
 * GraphicBuffer to accelerate the decoding and display.
 *
 */
class GonkBufferData : public OmxPromiseLayer::BufferData {
protected:
  virtual ~GonkBufferData() {}

public:
  GonkBufferData(bool aLiveInLocal,
                 GonkOmxPlatformLayer* aLayer);

  BufferID ID() override
  {
    return mId;
  }

  already_AddRefed<MediaData> GetPlatformMediaData() override;

  bool IsLocalBuffer()
  {
    return !!mMirrorBuffer.get();
  }

  void ReleaseBuffer();

  nsresult SetBufferId(android::IOMX::buffer_id aId)
  {
    mId = aId;
    return NS_OK;
  }

  // The mBuffer is in local process. And aId is actually the OMX_BUFFERHEADERTYPE
  // pointer. It doesn't need a mirror buffer.
  nsresult InitLocalBuffer(android::IOMX::buffer_id aId);

  // aMemory is an IPC based memory which will be used as the pBuffer in
  // mBuffer. And the mBuffer will be the mirror OMX_BUFFERHEADERTYPE
  // of the one in the remote process.
  nsresult InitSharedMemory(android::IMemory* aMemory);

  // GraphicBuffer is for video decoding acceleration on output port.
  // Then mBuffer is the mirror OMX_BUFFERHEADERTYPE of the one in the remote
  // process.
  nsresult InitGraphicBuffer(OMX_VIDEO_PORTDEFINITIONTYPE& aDef);

  // Android OMX uses this id to pass the buffer between OMX component and
  // client.
  android::IOMX::buffer_id mId;

  // mMirrorBuffer are used only when the omx node is in mediaserver.
  // Due to IPC problem, the mId is the OMX_BUFFERHEADERTYPE address in mediaserver.
  // It can't mapping to client process, so we need a local OMX_BUFFERHEADERTYPE
  // here to mirror the remote OMX_BUFFERHEADERTYPE in mediaserver.
  nsAutoPtr<OMX_BUFFERHEADERTYPE> mMirrorBuffer;

  // It creates GraphicBuffer and manages TextureClient.
  RefPtr<GonkTextureClientRecycleHandler> mTextureClientRecycleHandler;

  GonkOmxPlatformLayer* mGonkPlatformLayer;
};

class GonkOmxPlatformLayer : public OmxPlatformLayer {
public:
  enum {
    kRequiresAllocateBufferOnInputPorts = 0,
    kRequiresAllocateBufferOnOutputPorts,
    QUIRKS,
  };
  typedef std::bitset<QUIRKS> Quirks;

  struct ComponentInfo {
    const char* mName;
    Quirks mQuirks;
  };

  GonkOmxPlatformLayer(OmxDataDecoder* aDataDecoder,
                       OmxPromiseLayer* aPromiseLayer,
                       TaskQueue* aTaskQueue,
                       layers::ImageContainer* aImageContainer);

  nsresult AllocateOmxBuffer(OMX_DIRTYPE aType, BUFFERLIST* aBufferList) override;

  nsresult ReleaseOmxBuffer(OMX_DIRTYPE aType, BUFFERLIST* aBufferList) override;

  OMX_ERRORTYPE GetState(OMX_STATETYPE* aType) override;

  OMX_ERRORTYPE GetParameter(OMX_INDEXTYPE aParamIndex,
                             OMX_PTR aComponentParameterStructure,
                             OMX_U32 aComponentParameterSize) override;

  OMX_ERRORTYPE SetParameter(OMX_INDEXTYPE nIndex,
                             OMX_PTR aComponentParameterStructure,
                             OMX_U32 aComponentParameterSize) override;

  OMX_ERRORTYPE InitOmxToStateLoaded(const TrackInfo* aInfo) override;

  OMX_ERRORTYPE EmptyThisBuffer(BufferData* aData) override;

  OMX_ERRORTYPE FillThisBuffer(BufferData* aData) override;

  OMX_ERRORTYPE SendCommand(OMX_COMMANDTYPE aCmd,
                            OMX_U32 aParam1,
                            OMX_PTR aCmdData) override;

  nsresult Shutdown() override;

  static bool FindComponents(const nsACString& aMimeType,
                             nsTArray<ComponentInfo>* aComponents = nullptr);

  // Android/QCOM decoder uses its own OMX_VIDEO_CodingVP8 definition in
  // frameworks/native/media/include/openmax/OMX_Video.h, not the one defined
  // in OpenMAX v1.1.2 OMX_VideoExt.h
  OMX_VIDEO_CODINGTYPE CompressionFormat() override;

protected:
  friend GonkBufferData;

  layers::ImageContainer* GetImageContainer();

  const TrackInfo* GetTrackInfo();

  TaskQueue* GetTaskQueue()
  {
    return mTaskQueue;
  }

  nsresult EnableOmxGraphicBufferPort(OMX_PARAM_PORTDEFINITIONTYPE& aDef);

  bool LoadComponent(const ComponentInfo& aComponent);

  friend class GonkOmxObserver;

  RefPtr<TaskQueue> mTaskQueue;

  RefPtr<layers::ImageContainer> mImageContainer;

  // OMX_DirInput is 0, OMX_DirOutput is 1.
  android::sp<android::MemoryDealer> mMemoryDealer[2];

  android::sp<GonkOmxObserver> mOmxObserver;

  android::sp<android::IOMX> mOmx;

  android::IOMX::node_id mNode;

  android::OMXClient mOmxClient;

  Quirks mQuirks;
};

}

#pragma GCC visibility pop

#endif // GonkOmxPlatformLayer_h_