blob: 70daafaad52f5e2f5c28fd1678f2cdbdf9d6ee92 [file] [log] [blame]
Andreas Huberbe06d262009-08-14 14:37:10 -07001/*
2 * Copyright (C) 2009 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17#ifndef OMX_CODEC_H_
18
19#define OMX_CODEC_H_
20
Jamie Gennis58a36ad2010-10-07 14:08:38 -070021#include <android/native_window.h>
Andreas Huberbe06d262009-08-14 14:37:10 -070022#include <media/IOMX.h>
23#include <media/stagefright/MediaBuffer.h>
24#include <media/stagefright/MediaSource.h>
25#include <utils/threads.h>
26
27namespace android {
28
29class MemoryDealer;
30struct OMXCodecObserver;
James Dong81c929a2010-07-01 15:02:14 -070031struct CodecProfileLevel;
Andreas Huberbe06d262009-08-14 14:37:10 -070032
33struct OMXCodec : public MediaSource,
34 public MediaBufferObserver {
Andreas Hubere13526a2009-10-22 10:43:34 -070035 enum CreationFlags {
Andreas Huber4c19bf92010-09-08 14:32:20 -070036 kPreferSoftwareCodecs = 1,
Andreas Huber5a40e392010-10-18 09:57:42 -070037 kIgnoreCodecSpecificData = 2,
38
39 // The client wants to access the output buffer's video
40 // data for example for thumbnail extraction.
41 kClientNeedsFramebuffer = 4,
James Dong170a9292010-10-22 17:28:15 -070042
43 // Request for software or hardware codecs. If request
44 // can not be fullfilled, Create() returns NULL.
45 kSoftwareCodecsOnly = 8,
46 kHardwareCodecsOnly = 16,
James Dong05c2fd52010-11-02 13:20:11 -070047
48 // Store meta data in video buffers
49 kStoreMetaDataInVideoBuffers = 32,
James Dong5f3ab062011-01-25 16:31:28 -080050
51 // Only submit one input buffer at one time.
52 kOnlySubmitOneInputBufferAtOneTime = 64,
Glenn Kastenb8763f62011-01-28 12:37:51 -080053
54 // Enable GRALLOC_USAGE_PROTECTED for output buffers from native window
55 kEnableGrallocUsageProtected = 128,
Andreas Hubere13526a2009-10-22 10:43:34 -070056 };
Andreas Huber91eb0352009-12-07 09:43:00 -080057 static sp<MediaSource> Create(
Andreas Huberbe06d262009-08-14 14:37:10 -070058 const sp<IOMX> &omx,
59 const sp<MetaData> &meta, bool createEncoder,
Andreas Hubere6c40962009-09-10 14:13:30 -070060 const sp<MediaSource> &source,
Andreas Hubere13526a2009-10-22 10:43:34 -070061 const char *matchComponentName = NULL,
Jamie Gennis58a36ad2010-10-07 14:08:38 -070062 uint32_t flags = 0,
63 const sp<ANativeWindow> &nativeWindow = NULL);
Andreas Hubere6c40962009-09-10 14:13:30 -070064
65 static void setComponentRole(
66 const sp<IOMX> &omx, IOMX::node_id node, bool isEncoder,
67 const char *mime);
Andreas Huberbe06d262009-08-14 14:37:10 -070068
69 virtual status_t start(MetaData *params = NULL);
70 virtual status_t stop();
71
72 virtual sp<MetaData> getFormat();
73
74 virtual status_t read(
75 MediaBuffer **buffer, const ReadOptions *options = NULL);
76
Andreas Huber1f24b302010-06-10 11:12:39 -070077 virtual status_t pause();
78
Andreas Huberbe06d262009-08-14 14:37:10 -070079 // from MediaBufferObserver
80 virtual void signalBufferReturned(MediaBuffer *buffer);
81
82protected:
83 virtual ~OMXCodec();
84
85private:
James Dong681e89c2011-01-10 08:55:02 -080086
87 // Make sure mLock is accessible to OMXCodecObserver
88 friend class OMXCodecObserver;
89
90 // Call this with mLock hold
91 void on_message(const omx_message &msg);
92
Andreas Huberbe06d262009-08-14 14:37:10 -070093 enum State {
94 DEAD,
95 LOADED,
96 LOADED_TO_IDLE,
97 IDLE_TO_EXECUTING,
98 EXECUTING,
99 EXECUTING_TO_IDLE,
100 IDLE_TO_LOADED,
101 RECONFIGURING,
102 ERROR
103 };
104
105 enum {
106 kPortIndexInput = 0,
107 kPortIndexOutput = 1
108 };
109
110 enum PortStatus {
111 ENABLED,
112 DISABLING,
113 DISABLED,
114 ENABLING,
115 SHUTTING_DOWN,
116 };
117
118 enum Quirks {
Andreas Hubera4357ad2010-04-02 12:49:54 -0700119 kNeedsFlushBeforeDisable = 1,
120 kWantsNALFragments = 2,
121 kRequiresLoadedToIdleAfterAllocation = 4,
122 kRequiresAllocateBufferOnInputPorts = 8,
123 kRequiresFlushCompleteEmulation = 16,
124 kRequiresAllocateBufferOnOutputPorts = 32,
125 kRequiresFlushBeforeShutdown = 64,
126 kDefersOutputBufferAllocation = 128,
127 kDecoderLiesAboutNumberOfChannels = 256,
128 kInputBufferSizesAreBogus = 512,
129 kSupportsMultipleFramesPerInputBuffer = 1024,
James Dong4f501f02010-06-07 14:41:41 -0700130 kAvoidMemcopyInputRecordingFrames = 2048,
James Dong90862e22010-08-26 19:12:59 -0700131 kRequiresLargerEncoderOutputBuffer = 4096,
Andreas Huber1e194162010-10-06 16:43:57 -0700132 kOutputBuffersAreUnreadable = 8192,
Andreas Huberbe06d262009-08-14 14:37:10 -0700133 };
134
Andreas Huberbbbcf652010-12-07 14:25:54 -0800135 enum BufferStatus {
136 OWNED_BY_US,
137 OWNED_BY_COMPONENT,
138 OWNED_BY_NATIVE_WINDOW,
139 OWNED_BY_CLIENT,
140 };
141
Andreas Huberbe06d262009-08-14 14:37:10 -0700142 struct BufferInfo {
143 IOMX::buffer_id mBuffer;
Andreas Huberbbbcf652010-12-07 14:25:54 -0800144 BufferStatus mStatus;
Andreas Huberbe06d262009-08-14 14:37:10 -0700145 sp<IMemory> mMem;
Andreas Huberc712b9f2010-01-20 15:05:46 -0800146 size_t mSize;
147 void *mData;
Andreas Huberbe06d262009-08-14 14:37:10 -0700148 MediaBuffer *mMediaBuffer;
149 };
150
151 struct CodecSpecificData {
152 size_t mSize;
153 uint8_t mData[1];
154 };
155
156 sp<IOMX> mOMX;
Andreas Huberf1fe0642010-01-15 15:28:19 -0800157 bool mOMXLivesLocally;
Andreas Huberbe06d262009-08-14 14:37:10 -0700158 IOMX::node_id mNode;
Andreas Huberbe06d262009-08-14 14:37:10 -0700159 uint32_t mQuirks;
160 bool mIsEncoder;
161 char *mMIME;
162 char *mComponentName;
163 sp<MetaData> mOutputFormat;
164 sp<MediaSource> mSource;
165 Vector<CodecSpecificData *> mCodecSpecificData;
166 size_t mCodecSpecificDataIndex;
167
Andreas Huber5c0a9132009-08-20 11:16:40 -0700168 sp<MemoryDealer> mDealer[2];
Andreas Huberbe06d262009-08-14 14:37:10 -0700169
170 State mState;
171 Vector<BufferInfo> mPortBuffers[2];
172 PortStatus mPortStatus[2];
Andreas Huber42978e52009-08-27 10:08:39 -0700173 bool mInitialBufferSubmit;
Andreas Huberbe06d262009-08-14 14:37:10 -0700174 bool mSignalledEOS;
Andreas Huberd7d22eb2010-02-23 13:45:33 -0800175 status_t mFinalStatus;
Andreas Huberbe06d262009-08-14 14:37:10 -0700176 bool mNoMoreOutputData;
Andreas Hubercfd55572009-10-09 14:11:28 -0700177 bool mOutputPortSettingsHaveChanged;
Andreas Huberbe06d262009-08-14 14:37:10 -0700178 int64_t mSeekTimeUs;
Andreas Huber6624c9f2010-07-20 15:04:28 -0700179 ReadOptions::SeekMode mSeekMode;
180 int64_t mTargetTimeUs;
Andreas Huberb9289832011-02-08 13:10:25 -0800181 bool mOutputPortSettingsChangedPending;
Andreas Huberbe06d262009-08-14 14:37:10 -0700182
Andreas Hubera4357ad2010-04-02 12:49:54 -0700183 MediaBuffer *mLeftOverBuffer;
184
Andreas Huberbe06d262009-08-14 14:37:10 -0700185 Mutex mLock;
186 Condition mAsyncCompletion;
187
Andreas Huber1f24b302010-06-10 11:12:39 -0700188 bool mPaused;
189
Jamie Gennis58a36ad2010-10-07 14:08:38 -0700190 sp<ANativeWindow> mNativeWindow;
191
192 // The index in each of the mPortBuffers arrays of the buffer that will be
193 // submitted to OMX next. This only applies when using buffers from a
194 // native window.
195 size_t mNextNativeBufferIndex[2];
196
Andreas Huberbe06d262009-08-14 14:37:10 -0700197 // A list of indices into mPortStatus[kPortIndexOutput] filled with data.
198 List<size_t> mFilledBuffers;
199 Condition mBufferFilled;
200
James Dong05c2fd52010-11-02 13:20:11 -0700201 bool mIsMetaDataStoredInVideoBuffers;
James Dong5f3ab062011-01-25 16:31:28 -0800202 bool mOnlySubmitOneBufferAtOneTime;
Glenn Kastenb8763f62011-01-28 12:37:51 -0800203 bool mEnableGrallocUsageProtected;
James Dong05c2fd52010-11-02 13:20:11 -0700204
Andreas Huberbe06d262009-08-14 14:37:10 -0700205 OMXCodec(const sp<IOMX> &omx, IOMX::node_id node, uint32_t quirks,
206 bool isEncoder, const char *mime, const char *componentName,
Jamie Gennis58a36ad2010-10-07 14:08:38 -0700207 const sp<MediaSource> &source,
208 const sp<ANativeWindow> &nativeWindow);
Andreas Huberbe06d262009-08-14 14:37:10 -0700209
210 void addCodecSpecificData(const void *data, size_t size);
211 void clearCodecSpecificData();
212
Andreas Huber4c483422009-09-02 16:05:36 -0700213 void setComponentRole();
214
James Dong17299ab2010-05-14 15:45:22 -0700215 void setAMRFormat(bool isWAMR, int32_t bitRate);
216 void setAACFormat(int32_t numChannels, int32_t sampleRate, int32_t bitRate);
Andreas Huber4b3913a2011-05-11 14:13:42 -0700217 void setG711Format(int32_t numChannels);
Andreas Huberbe06d262009-08-14 14:37:10 -0700218
219 status_t setVideoPortFormatType(
220 OMX_U32 portIndex,
221 OMX_VIDEO_CODINGTYPE compressionFormat,
222 OMX_COLOR_FORMATTYPE colorFormat);
223
224 void setVideoInputFormat(
James Dong1244eab2010-06-08 11:58:53 -0700225 const char *mime, const sp<MetaData>& meta);
Andreas Huberbe06d262009-08-14 14:37:10 -0700226
James Dongc0ab2a62010-06-29 16:29:19 -0700227 status_t setupBitRate(int32_t bitRate);
228 status_t setupErrorCorrectionParameters();
229 status_t setupH263EncoderParameters(const sp<MetaData>& meta);
James Dong1244eab2010-06-08 11:58:53 -0700230 status_t setupMPEG4EncoderParameters(const sp<MetaData>& meta);
231 status_t setupAVCEncoderParameters(const sp<MetaData>& meta);
James Dongafd97e82010-08-03 17:19:23 -0700232 status_t findTargetColorFormat(
233 const sp<MetaData>& meta, OMX_COLOR_FORMATTYPE *colorFormat);
234
235 status_t isColorFormatSupported(
236 OMX_COLOR_FORMATTYPE colorFormat, int portIndex);
Andreas Huberb482ce82009-10-29 12:02:48 -0700237
James Dong81c929a2010-07-01 15:02:14 -0700238 // If profile/level is set in the meta data, its value in the meta
239 // data will be used; otherwise, the default value will be used.
240 status_t getVideoProfileLevel(const sp<MetaData>& meta,
241 const CodecProfileLevel& defaultProfileLevel,
242 CodecProfileLevel& profileLevel);
243
Andreas Huber2a09c7e2010-03-16 11:44:07 -0700244 status_t setVideoOutputFormat(
Andreas Huberbe06d262009-08-14 14:37:10 -0700245 const char *mime, OMX_U32 width, OMX_U32 height);
246
247 void setImageOutputFormat(
248 OMX_COLOR_FORMATTYPE format, OMX_U32 width, OMX_U32 height);
249
Andreas Huber5c0a9132009-08-20 11:16:40 -0700250 void setJPEGInputFormat(
251 OMX_U32 width, OMX_U32 height, OMX_U32 compressedSize);
252
Andreas Huberda050cf22009-09-02 14:01:43 -0700253 void setMinBufferSize(OMX_U32 portIndex, OMX_U32 size);
254
255 void setRawAudioFormat(
256 OMX_U32 portIndex, int32_t sampleRate, int32_t numChannels);
257
Andreas Huberbe06d262009-08-14 14:37:10 -0700258 status_t allocateBuffers();
259 status_t allocateBuffersOnPort(OMX_U32 portIndex);
Jamie Gennis58a36ad2010-10-07 14:08:38 -0700260 status_t allocateOutputBuffersFromNativeWindow();
261
262 status_t queueBufferToNativeWindow(BufferInfo *info);
263 status_t cancelBufferToNativeWindow(BufferInfo *info);
264 BufferInfo* dequeueBufferFromNativeWindow();
Andreas Huberbe06d262009-08-14 14:37:10 -0700265
266 status_t freeBuffersOnPort(
267 OMX_U32 portIndex, bool onlyThoseWeOwn = false);
268
Jamie Gennisf0c5c1e2010-11-01 16:04:31 -0700269 status_t freeBuffer(OMX_U32 portIndex, size_t bufIndex);
270
Andreas Huberbbbcf652010-12-07 14:25:54 -0800271 bool drainInputBuffer(IOMX::buffer_id buffer);
Andreas Huberbe06d262009-08-14 14:37:10 -0700272 void fillOutputBuffer(IOMX::buffer_id buffer);
Andreas Huberbbbcf652010-12-07 14:25:54 -0800273 bool drainInputBuffer(BufferInfo *info);
Andreas Huberbe06d262009-08-14 14:37:10 -0700274 void fillOutputBuffer(BufferInfo *info);
275
276 void drainInputBuffers();
277 void fillOutputBuffers();
278
Andreas Huber404cc412009-08-25 14:26:05 -0700279 // Returns true iff a flush was initiated and a completion event is
280 // upcoming, false otherwise (A flush was not necessary as we own all
281 // the buffers on that port).
282 // This method will ONLY ever return false for a component with quirk
283 // "kRequiresFlushCompleteEmulation".
284 bool flushPortAsync(OMX_U32 portIndex);
285
Andreas Huberbe06d262009-08-14 14:37:10 -0700286 void disablePortAsync(OMX_U32 portIndex);
287 void enablePortAsync(OMX_U32 portIndex);
288
289 static size_t countBuffersWeOwn(const Vector<BufferInfo> &buffers);
290 static bool isIntermediateState(State state);
291
292 void onEvent(OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2);
293 void onCmdComplete(OMX_COMMANDTYPE cmd, OMX_U32 data);
294 void onStateChange(OMX_STATETYPE newState);
295 void onPortSettingsChanged(OMX_U32 portIndex);
296
297 void setState(State newState);
298
299 status_t init();
300 void initOutputFormat(const sp<MetaData> &inputFormat);
Jamie Gennis58a36ad2010-10-07 14:08:38 -0700301 status_t initNativeWindow();
Andreas Huberbe06d262009-08-14 14:37:10 -0700302
303 void dumpPortStatus(OMX_U32 portIndex);
304
Andreas Huber4c19bf92010-09-08 14:32:20 -0700305 status_t configureCodec(const sp<MetaData> &meta, uint32_t flags);
Andreas Huber2a09c7e2010-03-16 11:44:07 -0700306
Andreas Huber1e194162010-10-06 16:43:57 -0700307 static uint32_t getComponentQuirks(
308 const char *componentName, bool isEncoder);
Andreas Hubere13526a2009-10-22 10:43:34 -0700309
310 static void findMatchingCodecs(
311 const char *mime,
312 bool createEncoder, const char *matchComponentName,
313 uint32_t flags,
314 Vector<String8> *matchingCodecs);
315
James Dong31b9375f2010-11-10 21:11:41 -0800316 void restorePatchedDataPointer(BufferInfo *info);
317
Andreas Huber5e9dc942011-01-21 14:32:31 -0800318 status_t applyRotation();
319
Andreas Huberbe06d262009-08-14 14:37:10 -0700320 OMXCodec(const OMXCodec &);
321 OMXCodec &operator=(const OMXCodec &);
322};
323
Andreas Hubere6c40962009-09-10 14:13:30 -0700324struct CodecProfileLevel {
325 OMX_U32 mProfile;
326 OMX_U32 mLevel;
327};
328
329struct CodecCapabilities {
330 String8 mComponentName;
331 Vector<CodecProfileLevel> mProfileLevels;
James Dongd7810892010-11-11 00:33:05 -0800332 Vector<OMX_U32> mColorFormats;
Andreas Hubere6c40962009-09-10 14:13:30 -0700333};
334
335// Return a vector of componentNames with supported profile/level pairs
336// supporting the given mime type, if queryDecoders==true, returns components
337// that decode content of the given type, otherwise returns components
338// that encode content of the given type.
339// profile and level indications only make sense for h.263, mpeg4 and avc
340// video.
341// The profile/level values correspond to
342// OMX_VIDEO_H263PROFILETYPE, OMX_VIDEO_MPEG4PROFILETYPE,
343// OMX_VIDEO_AVCPROFILETYPE, OMX_VIDEO_H263LEVELTYPE, OMX_VIDEO_MPEG4LEVELTYPE
344// and OMX_VIDEO_AVCLEVELTYPE respectively.
345
346status_t QueryCodecs(
347 const sp<IOMX> &omx,
348 const char *mimeType, bool queryDecoders,
349 Vector<CodecCapabilities> *results);
350
Andreas Huberbe06d262009-08-14 14:37:10 -0700351} // namespace android
352
353#endif // OMX_CODEC_H_