blob: 93b5d24da90761e0e6537e18fe4ae239dea9f13d [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 Huberbe06d262009-08-14 14:37:10 -0700217
218 status_t setVideoPortFormatType(
219 OMX_U32 portIndex,
220 OMX_VIDEO_CODINGTYPE compressionFormat,
221 OMX_COLOR_FORMATTYPE colorFormat);
222
223 void setVideoInputFormat(
James Dong1244eab2010-06-08 11:58:53 -0700224 const char *mime, const sp<MetaData>& meta);
Andreas Huberbe06d262009-08-14 14:37:10 -0700225
James Dongc0ab2a62010-06-29 16:29:19 -0700226 status_t setupBitRate(int32_t bitRate);
227 status_t setupErrorCorrectionParameters();
228 status_t setupH263EncoderParameters(const sp<MetaData>& meta);
James Dong1244eab2010-06-08 11:58:53 -0700229 status_t setupMPEG4EncoderParameters(const sp<MetaData>& meta);
230 status_t setupAVCEncoderParameters(const sp<MetaData>& meta);
James Dongafd97e82010-08-03 17:19:23 -0700231 status_t findTargetColorFormat(
232 const sp<MetaData>& meta, OMX_COLOR_FORMATTYPE *colorFormat);
233
234 status_t isColorFormatSupported(
235 OMX_COLOR_FORMATTYPE colorFormat, int portIndex);
Andreas Huberb482ce82009-10-29 12:02:48 -0700236
James Dong81c929a2010-07-01 15:02:14 -0700237 // If profile/level is set in the meta data, its value in the meta
238 // data will be used; otherwise, the default value will be used.
239 status_t getVideoProfileLevel(const sp<MetaData>& meta,
240 const CodecProfileLevel& defaultProfileLevel,
241 CodecProfileLevel& profileLevel);
242
Andreas Huber2a09c7e2010-03-16 11:44:07 -0700243 status_t setVideoOutputFormat(
Andreas Huberbe06d262009-08-14 14:37:10 -0700244 const char *mime, OMX_U32 width, OMX_U32 height);
245
246 void setImageOutputFormat(
247 OMX_COLOR_FORMATTYPE format, OMX_U32 width, OMX_U32 height);
248
Andreas Huber5c0a9132009-08-20 11:16:40 -0700249 void setJPEGInputFormat(
250 OMX_U32 width, OMX_U32 height, OMX_U32 compressedSize);
251
Andreas Huberda050cf22009-09-02 14:01:43 -0700252 void setMinBufferSize(OMX_U32 portIndex, OMX_U32 size);
253
254 void setRawAudioFormat(
255 OMX_U32 portIndex, int32_t sampleRate, int32_t numChannels);
256
Andreas Huberbe06d262009-08-14 14:37:10 -0700257 status_t allocateBuffers();
258 status_t allocateBuffersOnPort(OMX_U32 portIndex);
Jamie Gennis58a36ad2010-10-07 14:08:38 -0700259 status_t allocateOutputBuffersFromNativeWindow();
260
261 status_t queueBufferToNativeWindow(BufferInfo *info);
262 status_t cancelBufferToNativeWindow(BufferInfo *info);
263 BufferInfo* dequeueBufferFromNativeWindow();
Andreas Huberbe06d262009-08-14 14:37:10 -0700264
265 status_t freeBuffersOnPort(
266 OMX_U32 portIndex, bool onlyThoseWeOwn = false);
267
Jamie Gennisf0c5c1e2010-11-01 16:04:31 -0700268 status_t freeBuffer(OMX_U32 portIndex, size_t bufIndex);
269
Andreas Huberbbbcf652010-12-07 14:25:54 -0800270 bool drainInputBuffer(IOMX::buffer_id buffer);
Andreas Huberbe06d262009-08-14 14:37:10 -0700271 void fillOutputBuffer(IOMX::buffer_id buffer);
Andreas Huberbbbcf652010-12-07 14:25:54 -0800272 bool drainInputBuffer(BufferInfo *info);
Andreas Huberbe06d262009-08-14 14:37:10 -0700273 void fillOutputBuffer(BufferInfo *info);
274
275 void drainInputBuffers();
276 void fillOutputBuffers();
277
Andreas Huber404cc412009-08-25 14:26:05 -0700278 // Returns true iff a flush was initiated and a completion event is
279 // upcoming, false otherwise (A flush was not necessary as we own all
280 // the buffers on that port).
281 // This method will ONLY ever return false for a component with quirk
282 // "kRequiresFlushCompleteEmulation".
283 bool flushPortAsync(OMX_U32 portIndex);
284
Andreas Huberbe06d262009-08-14 14:37:10 -0700285 void disablePortAsync(OMX_U32 portIndex);
286 void enablePortAsync(OMX_U32 portIndex);
287
288 static size_t countBuffersWeOwn(const Vector<BufferInfo> &buffers);
289 static bool isIntermediateState(State state);
290
291 void onEvent(OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2);
292 void onCmdComplete(OMX_COMMANDTYPE cmd, OMX_U32 data);
293 void onStateChange(OMX_STATETYPE newState);
294 void onPortSettingsChanged(OMX_U32 portIndex);
295
296 void setState(State newState);
297
298 status_t init();
299 void initOutputFormat(const sp<MetaData> &inputFormat);
Jamie Gennis58a36ad2010-10-07 14:08:38 -0700300 status_t initNativeWindow();
Andreas Huberbe06d262009-08-14 14:37:10 -0700301
302 void dumpPortStatus(OMX_U32 portIndex);
303
Andreas Huber4c19bf92010-09-08 14:32:20 -0700304 status_t configureCodec(const sp<MetaData> &meta, uint32_t flags);
Andreas Huber2a09c7e2010-03-16 11:44:07 -0700305
Andreas Huber1e194162010-10-06 16:43:57 -0700306 static uint32_t getComponentQuirks(
307 const char *componentName, bool isEncoder);
Andreas Hubere13526a2009-10-22 10:43:34 -0700308
309 static void findMatchingCodecs(
310 const char *mime,
311 bool createEncoder, const char *matchComponentName,
312 uint32_t flags,
313 Vector<String8> *matchingCodecs);
314
James Dong31b9375f2010-11-10 21:11:41 -0800315 void restorePatchedDataPointer(BufferInfo *info);
316
Andreas Huber5e9dc942011-01-21 14:32:31 -0800317 status_t applyRotation();
318
Andreas Huberbe06d262009-08-14 14:37:10 -0700319 OMXCodec(const OMXCodec &);
320 OMXCodec &operator=(const OMXCodec &);
321};
322
Andreas Hubere6c40962009-09-10 14:13:30 -0700323struct CodecProfileLevel {
324 OMX_U32 mProfile;
325 OMX_U32 mLevel;
326};
327
328struct CodecCapabilities {
329 String8 mComponentName;
330 Vector<CodecProfileLevel> mProfileLevels;
James Dongd7810892010-11-11 00:33:05 -0800331 Vector<OMX_U32> mColorFormats;
Andreas Hubere6c40962009-09-10 14:13:30 -0700332};
333
334// Return a vector of componentNames with supported profile/level pairs
335// supporting the given mime type, if queryDecoders==true, returns components
336// that decode content of the given type, otherwise returns components
337// that encode content of the given type.
338// profile and level indications only make sense for h.263, mpeg4 and avc
339// video.
340// The profile/level values correspond to
341// OMX_VIDEO_H263PROFILETYPE, OMX_VIDEO_MPEG4PROFILETYPE,
342// OMX_VIDEO_AVCPROFILETYPE, OMX_VIDEO_H263LEVELTYPE, OMX_VIDEO_MPEG4LEVELTYPE
343// and OMX_VIDEO_AVCLEVELTYPE respectively.
344
345status_t QueryCodecs(
346 const sp<IOMX> &omx,
347 const char *mimeType, bool queryDecoders,
348 Vector<CodecCapabilities> *results);
349
Andreas Huberbe06d262009-08-14 14:37:10 -0700350} // namespace android
351
352#endif // OMX_CODEC_H_