1 /*
2  * Copyright (C) 2010 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 A_CODEC_H_
18 
19 #define A_CODEC_H_
20 
21 #include <stdint.h>
22 #include <android/native_window.h>
23 #include <media/IOMX.h>
24 #include <media/stagefright/foundation/AHierarchicalStateMachine.h>
25 #include <media/stagefright/CodecBase.h>
26 #include <media/stagefright/SkipCutBuffer.h>
27 #include <OMX_Audio.h>
28 
29 #define TRACK_BUFFER_TIMING     0
30 
31 namespace android {
32 
33 struct ABuffer;
34 struct MemoryDealer;
35 struct DescribeColorFormatParams;
36 
37 struct ACodec : public AHierarchicalStateMachine, public CodecBase {
38     ACodec();
39 
40     virtual void setNotificationMessage(const sp<AMessage> &msg);
41 
42     void initiateSetup(const sp<AMessage> &msg);
43 
44     virtual void initiateAllocateComponent(const sp<AMessage> &msg);
45     virtual void initiateConfigureComponent(const sp<AMessage> &msg);
46     virtual void initiateCreateInputSurface();
47     virtual void initiateStart();
48     virtual void initiateShutdown(bool keepComponentAllocated = false);
49 
50     virtual void signalFlush();
51     virtual void signalResume();
52 
53     virtual void signalSetParameters(const sp<AMessage> &msg);
54     virtual void signalEndOfInputStream();
55     virtual void signalRequestIDRFrame();
56 
57     // AHierarchicalStateMachine implements the message handling
onMessageReceivedACodec58     virtual void onMessageReceived(const sp<AMessage> &msg) {
59         handleMessage(msg);
60     }
61 
62     struct PortDescription : public CodecBase::PortDescription {
63         size_t countBuffers();
64         IOMX::buffer_id bufferIDAt(size_t index) const;
65         sp<ABuffer> bufferAt(size_t index) const;
66 
67     private:
68         friend struct ACodec;
69 
70         Vector<IOMX::buffer_id> mBufferIDs;
71         Vector<sp<ABuffer> > mBuffers;
72 
73         PortDescription();
74         void addBuffer(IOMX::buffer_id id, const sp<ABuffer> &buffer);
75 
76         DISALLOW_EVIL_CONSTRUCTORS(PortDescription);
77     };
78 
79     static bool isFlexibleColorFormat(
80             const sp<IOMX> &omx, IOMX::node_id node,
81             uint32_t colorFormat, bool usingNativeBuffers, OMX_U32 *flexibleEquivalent);
82 
83     // Returns 0 if configuration is not supported.  NOTE: this is treated by
84     // some OMX components as auto level, and by others as invalid level.
85     static int /* OMX_VIDEO_AVCLEVELTYPE */ getAVCLevelFor(
86             int width, int height, int rate, int bitrate,
87             OMX_VIDEO_AVCPROFILETYPE profile = OMX_VIDEO_AVCProfileBaseline);
88 
89 protected:
90     virtual ~ACodec();
91 
92 private:
93     struct BaseState;
94     struct UninitializedState;
95     struct LoadedState;
96     struct LoadedToIdleState;
97     struct IdleToExecutingState;
98     struct ExecutingState;
99     struct OutputPortSettingsChangedState;
100     struct ExecutingToIdleState;
101     struct IdleToLoadedState;
102     struct FlushingState;
103     struct DeathNotifier;
104 
105     enum {
106         kWhatSetup                   = 'setu',
107         kWhatOMXMessage              = 'omx ',
108         kWhatInputBufferFilled       = 'inpF',
109         kWhatOutputBufferDrained     = 'outD',
110         kWhatShutdown                = 'shut',
111         kWhatFlush                   = 'flus',
112         kWhatResume                  = 'resm',
113         kWhatDrainDeferredMessages   = 'drai',
114         kWhatAllocateComponent       = 'allo',
115         kWhatConfigureComponent      = 'conf',
116         kWhatCreateInputSurface      = 'cisf',
117         kWhatSignalEndOfInputStream  = 'eois',
118         kWhatStart                   = 'star',
119         kWhatRequestIDRFrame         = 'ridr',
120         kWhatSetParameters           = 'setP',
121         kWhatSubmitOutputMetaDataBufferIfEOS = 'subm',
122         kWhatOMXDied                 = 'OMXd',
123         kWhatReleaseCodecInstance    = 'relC',
124     };
125 
126     enum {
127         kPortIndexInput  = 0,
128         kPortIndexOutput = 1
129     };
130 
131     enum {
132         kFlagIsSecure                                 = 1,
133         kFlagPushBlankBuffersToNativeWindowOnShutdown = 2,
134         kFlagIsGrallocUsageProtected                  = 4,
135     };
136 
137     struct BufferInfo {
138         enum Status {
139             OWNED_BY_US,
140             OWNED_BY_COMPONENT,
141             OWNED_BY_UPSTREAM,
142             OWNED_BY_DOWNSTREAM,
143             OWNED_BY_NATIVE_WINDOW,
144         };
145 
146         IOMX::buffer_id mBufferID;
147         Status mStatus;
148         unsigned mDequeuedAt;
149 
150         sp<ABuffer> mData;
151         sp<GraphicBuffer> mGraphicBuffer;
152     };
153 
154 #if TRACK_BUFFER_TIMING
155     struct BufferStats {
156         int64_t mEmptyBufferTimeUs;
157         int64_t mFillBufferDoneTimeUs;
158     };
159 
160     KeyedVector<int64_t, BufferStats> mBufferStats;
161 #endif
162 
163     sp<AMessage> mNotify;
164 
165     sp<UninitializedState> mUninitializedState;
166     sp<LoadedState> mLoadedState;
167     sp<LoadedToIdleState> mLoadedToIdleState;
168     sp<IdleToExecutingState> mIdleToExecutingState;
169     sp<ExecutingState> mExecutingState;
170     sp<OutputPortSettingsChangedState> mOutputPortSettingsChangedState;
171     sp<ExecutingToIdleState> mExecutingToIdleState;
172     sp<IdleToLoadedState> mIdleToLoadedState;
173     sp<FlushingState> mFlushingState;
174     sp<SkipCutBuffer> mSkipCutBuffer;
175 
176     AString mComponentName;
177     uint32_t mFlags;
178     uint32_t mQuirks;
179     sp<IOMX> mOMX;
180     IOMX::node_id mNode;
181     sp<MemoryDealer> mDealer[2];
182 
183     sp<ANativeWindow> mNativeWindow;
184     sp<AMessage> mInputFormat;
185     sp<AMessage> mOutputFormat;
186     sp<AMessage> mBaseOutputFormat;
187 
188     Vector<BufferInfo> mBuffers[2];
189     bool mPortEOS[2];
190     status_t mInputEOSResult;
191 
192     List<sp<AMessage> > mDeferredQueue;
193 
194     bool mSentFormat;
195     bool mIsEncoder;
196     bool mUseMetadataOnEncoderOutput;
197     bool mShutdownInProgress;
198     bool mExplicitShutdown;
199 
200     // If "mKeepComponentAllocated" we only transition back to Loaded state
201     // and do not release the component instance.
202     bool mKeepComponentAllocated;
203 
204     int32_t mEncoderDelay;
205     int32_t mEncoderPadding;
206     int32_t mRotationDegrees;
207 
208     bool mChannelMaskPresent;
209     int32_t mChannelMask;
210     unsigned mDequeueCounter;
211     bool mStoreMetaDataInOutputBuffers;
212     int32_t mMetaDataBuffersToSubmit;
213     size_t mNumUndequeuedBuffers;
214 
215     int64_t mRepeatFrameDelayUs;
216     int64_t mMaxPtsGapUs;
217 
218     int64_t mTimePerFrameUs;
219     int64_t mTimePerCaptureUs;
220 
221     bool mCreateInputBuffersSuspended;
222 
223     bool mTunneled;
224 
225     status_t setCyclicIntraMacroblockRefresh(const sp<AMessage> &msg, int32_t mode);
226     status_t allocateBuffersOnPort(OMX_U32 portIndex);
227     status_t freeBuffersOnPort(OMX_U32 portIndex);
228     status_t freeBuffer(OMX_U32 portIndex, size_t i);
229 
230     status_t configureOutputBuffersFromNativeWindow(
231             OMX_U32 *nBufferCount, OMX_U32 *nBufferSize,
232             OMX_U32 *nMinUndequeuedBuffers);
233     status_t allocateOutputMetaDataBuffers();
234     status_t submitOutputMetaDataBuffer();
235     void signalSubmitOutputMetaDataBufferIfEOS_workaround();
236     status_t allocateOutputBuffersFromNativeWindow();
237     status_t cancelBufferToNativeWindow(BufferInfo *info);
238     status_t freeOutputBuffersNotOwnedByComponent();
239     BufferInfo *dequeueBufferFromNativeWindow();
240 
241     BufferInfo *findBufferByID(
242             uint32_t portIndex, IOMX::buffer_id bufferID,
243             ssize_t *index = NULL);
244 
245     status_t setComponentRole(bool isEncoder, const char *mime);
246     status_t configureCodec(const char *mime, const sp<AMessage> &msg);
247 
248     status_t configureTunneledVideoPlayback(int32_t audioHwSync,
249             const sp<ANativeWindow> &nativeWindow);
250 
251     status_t setVideoPortFormatType(
252             OMX_U32 portIndex,
253             OMX_VIDEO_CODINGTYPE compressionFormat,
254             OMX_COLOR_FORMATTYPE colorFormat,
255             bool usingNativeBuffers = false);
256 
257     status_t setSupportedOutputFormat(bool getLegacyFlexibleFormat);
258 
259     status_t setupVideoDecoder(
260             const char *mime, const sp<AMessage> &msg, bool usingNativeBuffers);
261 
262     status_t setupVideoEncoder(
263             const char *mime, const sp<AMessage> &msg);
264 
265     status_t setVideoFormatOnPort(
266             OMX_U32 portIndex,
267             int32_t width, int32_t height,
268             OMX_VIDEO_CODINGTYPE compressionFormat, float frameRate = -1.0);
269 
270     typedef struct drcParams {
271         int32_t drcCut;
272         int32_t drcBoost;
273         int32_t heavyCompression;
274         int32_t targetRefLevel;
275         int32_t encodedTargetLevel;
276     } drcParams_t;
277 
278     status_t setupAACCodec(
279             bool encoder,
280             int32_t numChannels, int32_t sampleRate, int32_t bitRate,
281             int32_t aacProfile, bool isADTS, int32_t sbrMode,
282             int32_t maxOutputChannelCount, const drcParams_t& drc,
283             int32_t pcmLimiterEnable);
284 
285     status_t setupAC3Codec(bool encoder, int32_t numChannels, int32_t sampleRate);
286 
287     status_t setupEAC3Codec(bool encoder, int32_t numChannels, int32_t sampleRate);
288 
289     status_t selectAudioPortFormat(
290             OMX_U32 portIndex, OMX_AUDIO_CODINGTYPE desiredFormat);
291 
292     status_t setupAMRCodec(bool encoder, bool isWAMR, int32_t bitRate);
293     status_t setupG711Codec(bool encoder, int32_t numChannels);
294 
295     status_t setupFlacCodec(
296             bool encoder, int32_t numChannels, int32_t sampleRate, int32_t compressionLevel);
297 
298     status_t setupRawAudioFormat(
299             OMX_U32 portIndex, int32_t sampleRate, int32_t numChannels);
300 
301     status_t setMinBufferSize(OMX_U32 portIndex, size_t size);
302 
303     status_t setupMPEG4EncoderParameters(const sp<AMessage> &msg);
304     status_t setupH263EncoderParameters(const sp<AMessage> &msg);
305     status_t setupAVCEncoderParameters(const sp<AMessage> &msg);
306     status_t setupHEVCEncoderParameters(const sp<AMessage> &msg);
307     status_t setupVPXEncoderParameters(const sp<AMessage> &msg);
308 
309     status_t verifySupportForProfileAndLevel(int32_t profile, int32_t level);
310 
311     status_t configureBitrate(
312             int32_t bitrate, OMX_VIDEO_CONTROLRATETYPE bitrateMode);
313 
314     status_t setupErrorCorrectionParameters();
315 
316     status_t initNativeWindow();
317 
318     status_t pushBlankBuffersToNativeWindow();
319 
320     // Returns true iff all buffers on the given port have status
321     // OWNED_BY_US or OWNED_BY_NATIVE_WINDOW.
322     bool allYourBuffersAreBelongToUs(OMX_U32 portIndex);
323 
324     bool allYourBuffersAreBelongToUs();
325 
326     void waitUntilAllPossibleNativeWindowBuffersAreReturnedToUs();
327 
328     size_t countBuffersOwnedByComponent(OMX_U32 portIndex) const;
329     size_t countBuffersOwnedByNativeWindow() const;
330 
331     void deferMessage(const sp<AMessage> &msg);
332     void processDeferredMessages();
333 
334     void sendFormatChange(const sp<AMessage> &reply);
335     status_t getPortFormat(OMX_U32 portIndex, sp<AMessage> &notify);
336 
337     void signalError(
338             OMX_ERRORTYPE error = OMX_ErrorUndefined,
339             status_t internalError = UNKNOWN_ERROR);
340 
341     static bool describeDefaultColorFormat(DescribeColorFormatParams &describeParams);
342     static bool describeColorFormat(
343         const sp<IOMX> &omx, IOMX::node_id node,
344         DescribeColorFormatParams &describeParams);
345 
346     status_t requestIDRFrame();
347     status_t setParameters(const sp<AMessage> &params);
348 
349     // Send EOS on input stream.
350     void onSignalEndOfInputStream();
351 
352     DISALLOW_EVIL_CONSTRUCTORS(ACodec);
353 };
354 
355 }  // namespace android
356 
357 #endif  // A_CODEC_H_
358