• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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/hardware/MetadataBufferType.h>
24 #include <media/IOMX.h>
25 #include <media/stagefright/foundation/AHierarchicalStateMachine.h>
26 #include <media/stagefright/CodecBase.h>
27 #include <media/stagefright/FrameRenderTracker.h>
28 #include <media/stagefright/SkipCutBuffer.h>
29 #include <OMX_Audio.h>
30 
31 #define TRACK_BUFFER_TIMING     0
32 
33 namespace android {
34 
35 struct ABuffer;
36 struct MemoryDealer;
37 struct DescribeColorFormatParams;
38 
39 struct ACodec : public AHierarchicalStateMachine, public CodecBase {
40     ACodec();
41 
42     virtual void setNotificationMessage(const sp<AMessage> &msg);
43 
44     void initiateSetup(const sp<AMessage> &msg);
45 
46     virtual void initiateAllocateComponent(const sp<AMessage> &msg);
47     virtual void initiateConfigureComponent(const sp<AMessage> &msg);
48     virtual void initiateCreateInputSurface();
49     virtual void initiateSetInputSurface(const sp<PersistentSurface> &surface);
50     virtual void initiateStart();
51     virtual void initiateShutdown(bool keepComponentAllocated = false);
52 
53     virtual status_t setSurface(const sp<Surface> &surface);
54 
55     virtual void signalFlush();
56     virtual void signalResume();
57 
58     virtual void signalSetParameters(const sp<AMessage> &msg);
59     virtual void signalEndOfInputStream();
60     virtual void signalRequestIDRFrame();
61 
62     // AHierarchicalStateMachine implements the message handling
onMessageReceivedACodec63     virtual void onMessageReceived(const sp<AMessage> &msg) {
64         handleMessage(msg);
65     }
66 
67     struct PortDescription : public CodecBase::PortDescription {
68         size_t countBuffers();
69         IOMX::buffer_id bufferIDAt(size_t index) const;
70         sp<ABuffer> bufferAt(size_t index) const;
71 
72     private:
73         friend struct ACodec;
74 
75         Vector<IOMX::buffer_id> mBufferIDs;
76         Vector<sp<ABuffer> > mBuffers;
77 
78         PortDescription();
79         void addBuffer(IOMX::buffer_id id, const sp<ABuffer> &buffer);
80 
81         DISALLOW_EVIL_CONSTRUCTORS(PortDescription);
82     };
83 
84     static bool isFlexibleColorFormat(
85             const sp<IOMX> &omx, IOMX::node_id node,
86             uint32_t colorFormat, bool usingNativeBuffers, OMX_U32 *flexibleEquivalent);
87 
88     // Returns 0 if configuration is not supported.  NOTE: this is treated by
89     // some OMX components as auto level, and by others as invalid level.
90     static int /* OMX_VIDEO_AVCLEVELTYPE */ getAVCLevelFor(
91             int width, int height, int rate, int bitrate,
92             OMX_VIDEO_AVCPROFILETYPE profile = OMX_VIDEO_AVCProfileBaseline);
93 
94 protected:
95     virtual ~ACodec();
96 
97 private:
98     struct BaseState;
99     struct UninitializedState;
100     struct LoadedState;
101     struct LoadedToIdleState;
102     struct IdleToExecutingState;
103     struct ExecutingState;
104     struct OutputPortSettingsChangedState;
105     struct ExecutingToIdleState;
106     struct IdleToLoadedState;
107     struct FlushingState;
108     struct DeathNotifier;
109 
110     enum {
111         kWhatSetup                   = 'setu',
112         kWhatOMXMessage              = 'omx ',
113         // same as kWhatOMXMessage - but only used with
114         // handleMessage during OMX message-list handling
115         kWhatOMXMessageItem          = 'omxI',
116         kWhatOMXMessageList          = 'omxL',
117         kWhatInputBufferFilled       = 'inpF',
118         kWhatOutputBufferDrained     = 'outD',
119         kWhatShutdown                = 'shut',
120         kWhatFlush                   = 'flus',
121         kWhatResume                  = 'resm',
122         kWhatDrainDeferredMessages   = 'drai',
123         kWhatAllocateComponent       = 'allo',
124         kWhatConfigureComponent      = 'conf',
125         kWhatSetSurface              = 'setS',
126         kWhatCreateInputSurface      = 'cisf',
127         kWhatSetInputSurface         = 'sisf',
128         kWhatSignalEndOfInputStream  = 'eois',
129         kWhatStart                   = 'star',
130         kWhatRequestIDRFrame         = 'ridr',
131         kWhatSetParameters           = 'setP',
132         kWhatSubmitOutputMetadataBufferIfEOS = 'subm',
133         kWhatOMXDied                 = 'OMXd',
134         kWhatReleaseCodecInstance    = 'relC',
135     };
136 
137     enum {
138         kPortIndexInput  = 0,
139         kPortIndexOutput = 1
140     };
141 
142     enum {
143         kFlagIsSecure                                 = 1,
144         kFlagPushBlankBuffersToNativeWindowOnShutdown = 2,
145         kFlagIsGrallocUsageProtected                  = 4,
146     };
147 
148     enum {
149         kVideoGrallocUsage = (GRALLOC_USAGE_HW_TEXTURE
150                             | GRALLOC_USAGE_HW_COMPOSER
151                             | GRALLOC_USAGE_EXTERNAL_DISP),
152     };
153 
154     struct BufferInfo {
155         enum Status {
156             OWNED_BY_US,
157             OWNED_BY_COMPONENT,
158             OWNED_BY_UPSTREAM,
159             OWNED_BY_DOWNSTREAM,
160             OWNED_BY_NATIVE_WINDOW,
161             UNRECOGNIZED,            // not a tracked buffer
162         };
163 
getSafeStatusACodec::BufferInfo164         static inline Status getSafeStatus(BufferInfo *info) {
165             return info == NULL ? UNRECOGNIZED : info->mStatus;
166         }
167 
168         IOMX::buffer_id mBufferID;
169         Status mStatus;
170         unsigned mDequeuedAt;
171 
172         sp<ABuffer> mData;
173         sp<GraphicBuffer> mGraphicBuffer;
174         int mFenceFd;
175         FrameRenderTracker::Info *mRenderInfo;
176 
177         // The following field and 4 methods are used for debugging only
178         bool mIsReadFence;
179         // Store |fenceFd| and set read/write flag. Log error, if there is already a fence stored.
180         void setReadFence(int fenceFd, const char *dbg);
181         void setWriteFence(int fenceFd, const char *dbg);
182         // Log error, if the current fence is not a read/write fence.
183         void checkReadFence(const char *dbg);
184         void checkWriteFence(const char *dbg);
185     };
186 
187     static const char *_asString(BufferInfo::Status s);
188     void dumpBuffers(OMX_U32 portIndex);
189 
190     // If |fd| is non-negative, waits for fence with |fd| and logs an error if it fails. Returns
191     // the error code or OK on success. If |fd| is negative, it returns OK
192     status_t waitForFence(int fd, const char *dbg);
193 
194 #if TRACK_BUFFER_TIMING
195     struct BufferStats {
196         int64_t mEmptyBufferTimeUs;
197         int64_t mFillBufferDoneTimeUs;
198     };
199 
200     KeyedVector<int64_t, BufferStats> mBufferStats;
201 #endif
202 
203     sp<AMessage> mNotify;
204 
205     sp<UninitializedState> mUninitializedState;
206     sp<LoadedState> mLoadedState;
207     sp<LoadedToIdleState> mLoadedToIdleState;
208     sp<IdleToExecutingState> mIdleToExecutingState;
209     sp<ExecutingState> mExecutingState;
210     sp<OutputPortSettingsChangedState> mOutputPortSettingsChangedState;
211     sp<ExecutingToIdleState> mExecutingToIdleState;
212     sp<IdleToLoadedState> mIdleToLoadedState;
213     sp<FlushingState> mFlushingState;
214     sp<SkipCutBuffer> mSkipCutBuffer;
215 
216     AString mComponentName;
217     uint32_t mFlags;
218     uint32_t mQuirks;
219     sp<IOMX> mOMX;
220     IOMX::node_id mNode;
221     sp<MemoryDealer> mDealer[2];
222 
223     sp<ANativeWindow> mNativeWindow;
224     int mNativeWindowUsageBits;
225     sp<AMessage> mInputFormat;
226     sp<AMessage> mOutputFormat;
227     sp<AMessage> mBaseOutputFormat;
228 
229     FrameRenderTracker mRenderTracker; // render information for buffers rendered by ACodec
230     Vector<BufferInfo> mBuffers[2];
231     bool mPortEOS[2];
232     status_t mInputEOSResult;
233 
234     List<sp<AMessage> > mDeferredQueue;
235 
236     bool mSentFormat;
237     bool mIsVideo;
238     bool mIsEncoder;
239     bool mFatalError;
240     bool mShutdownInProgress;
241     bool mExplicitShutdown;
242 
243     // If "mKeepComponentAllocated" we only transition back to Loaded state
244     // and do not release the component instance.
245     bool mKeepComponentAllocated;
246 
247     int32_t mEncoderDelay;
248     int32_t mEncoderPadding;
249     int32_t mRotationDegrees;
250 
251     bool mChannelMaskPresent;
252     int32_t mChannelMask;
253     unsigned mDequeueCounter;
254     MetadataBufferType mInputMetadataType;
255     MetadataBufferType mOutputMetadataType;
256     bool mLegacyAdaptiveExperiment;
257     int32_t mMetadataBuffersToSubmit;
258     size_t mNumUndequeuedBuffers;
259 
260     int64_t mRepeatFrameDelayUs;
261     int64_t mMaxPtsGapUs;
262     float mMaxFps;
263 
264     int64_t mTimePerFrameUs;
265     int64_t mTimePerCaptureUs;
266 
267     bool mCreateInputBuffersSuspended;
268 
269     bool mTunneled;
270 
271     status_t setCyclicIntraMacroblockRefresh(const sp<AMessage> &msg, int32_t mode);
272     status_t allocateBuffersOnPort(OMX_U32 portIndex);
273     status_t freeBuffersOnPort(OMX_U32 portIndex);
274     status_t freeBuffer(OMX_U32 portIndex, size_t i);
275 
276     status_t handleSetSurface(const sp<Surface> &surface);
277     status_t setupNativeWindowSizeFormatAndUsage(
278             ANativeWindow *nativeWindow /* nonnull */, int *finalUsage /* nonnull */);
279 
280     status_t configureOutputBuffersFromNativeWindow(
281             OMX_U32 *nBufferCount, OMX_U32 *nBufferSize,
282             OMX_U32 *nMinUndequeuedBuffers);
283     status_t allocateOutputMetadataBuffers();
284     status_t submitOutputMetadataBuffer();
285     void signalSubmitOutputMetadataBufferIfEOS_workaround();
286     status_t allocateOutputBuffersFromNativeWindow();
287     status_t cancelBufferToNativeWindow(BufferInfo *info);
288     status_t freeOutputBuffersNotOwnedByComponent();
289     BufferInfo *dequeueBufferFromNativeWindow();
290 
storingMetadataInDecodedBuffersACodec291     inline bool storingMetadataInDecodedBuffers() {
292         return mOutputMetadataType >= 0 && !mIsEncoder;
293     }
294 
usingMetadataOnEncoderOutputACodec295     inline bool usingMetadataOnEncoderOutput() {
296         return mOutputMetadataType >= 0 && mIsEncoder;
297     }
298 
299     BufferInfo *findBufferByID(
300             uint32_t portIndex, IOMX::buffer_id bufferID,
301             ssize_t *index = NULL);
302 
303     status_t setComponentRole(bool isEncoder, const char *mime);
304     status_t configureCodec(const char *mime, const sp<AMessage> &msg);
305 
306     status_t configureTunneledVideoPlayback(int32_t audioHwSync,
307             const sp<ANativeWindow> &nativeWindow);
308 
309     status_t setVideoPortFormatType(
310             OMX_U32 portIndex,
311             OMX_VIDEO_CODINGTYPE compressionFormat,
312             OMX_COLOR_FORMATTYPE colorFormat,
313             bool usingNativeBuffers = false);
314 
315     status_t setSupportedOutputFormat(bool getLegacyFlexibleFormat);
316 
317     status_t setupVideoDecoder(
318             const char *mime, const sp<AMessage> &msg, bool usingNativeBuffers);
319 
320     status_t setupVideoEncoder(
321             const char *mime, const sp<AMessage> &msg);
322 
323     status_t setVideoFormatOnPort(
324             OMX_U32 portIndex,
325             int32_t width, int32_t height,
326             OMX_VIDEO_CODINGTYPE compressionFormat, float frameRate = -1.0);
327 
328     typedef struct drcParams {
329         int32_t drcCut;
330         int32_t drcBoost;
331         int32_t heavyCompression;
332         int32_t targetRefLevel;
333         int32_t encodedTargetLevel;
334     } drcParams_t;
335 
336     status_t setupAACCodec(
337             bool encoder,
338             int32_t numChannels, int32_t sampleRate, int32_t bitRate,
339             int32_t aacProfile, bool isADTS, int32_t sbrMode,
340             int32_t maxOutputChannelCount, const drcParams_t& drc,
341             int32_t pcmLimiterEnable);
342 
343     status_t setupAC3Codec(bool encoder, int32_t numChannels, int32_t sampleRate);
344 
345     status_t setupEAC3Codec(bool encoder, int32_t numChannels, int32_t sampleRate);
346 
347     status_t selectAudioPortFormat(
348             OMX_U32 portIndex, OMX_AUDIO_CODINGTYPE desiredFormat);
349 
350     status_t setupAMRCodec(bool encoder, bool isWAMR, int32_t bitRate);
351     status_t setupG711Codec(bool encoder, int32_t sampleRate, int32_t numChannels);
352 
353     status_t setupFlacCodec(
354             bool encoder, int32_t numChannels, int32_t sampleRate, int32_t compressionLevel);
355 
356     status_t setupRawAudioFormat(
357             OMX_U32 portIndex, int32_t sampleRate, int32_t numChannels);
358 
359     status_t setPriority(int32_t priority);
360     status_t setOperatingRate(float rateFloat, bool isVideo);
361 
362     status_t setMinBufferSize(OMX_U32 portIndex, size_t size);
363 
364     status_t setupMPEG4EncoderParameters(const sp<AMessage> &msg);
365     status_t setupH263EncoderParameters(const sp<AMessage> &msg);
366     status_t setupAVCEncoderParameters(const sp<AMessage> &msg);
367     status_t setupHEVCEncoderParameters(const sp<AMessage> &msg);
368     status_t setupVPXEncoderParameters(const sp<AMessage> &msg);
369 
370     status_t verifySupportForProfileAndLevel(int32_t profile, int32_t level);
371 
372     status_t configureBitrate(
373             int32_t bitrate, OMX_VIDEO_CONTROLRATETYPE bitrateMode);
374 
375     status_t setupErrorCorrectionParameters();
376 
377     status_t initNativeWindow();
378 
379     // Returns true iff all buffers on the given port have status
380     // OWNED_BY_US or OWNED_BY_NATIVE_WINDOW.
381     bool allYourBuffersAreBelongToUs(OMX_U32 portIndex);
382 
383     bool allYourBuffersAreBelongToUs();
384 
385     void waitUntilAllPossibleNativeWindowBuffersAreReturnedToUs();
386 
387     size_t countBuffersOwnedByComponent(OMX_U32 portIndex) const;
388     size_t countBuffersOwnedByNativeWindow() const;
389 
390     void deferMessage(const sp<AMessage> &msg);
391     void processDeferredMessages();
392 
393     void onFrameRendered(int64_t mediaTimeUs, nsecs_t systemNano);
394     // called when we have dequeued a buffer |buf| from the native window to track render info.
395     // |fenceFd| is the dequeue fence, and |info| points to the buffer info where this buffer is
396     // stored.
397     void updateRenderInfoForDequeuedBuffer(
398             ANativeWindowBuffer *buf, int fenceFd, BufferInfo *info);
399 
400     // Checks to see if any frames have rendered up until |until|, and to notify client
401     // (MediaCodec) of rendered frames up-until the frame pointed to by |until| or the first
402     // unrendered frame. These frames are removed from the render queue.
403     // If |dropIncomplete| is true, unrendered frames up-until |until| will be dropped from the
404     // queue, allowing all rendered framed up till then to be notified of.
405     // (This will effectively clear the render queue up-until (and including) |until|.)
406     // If |until| is NULL, or is not in the rendered queue, this method will check all frames.
407     void notifyOfRenderedFrames(
408             bool dropIncomplete = false, FrameRenderTracker::Info *until = NULL);
409 
410     void sendFormatChange(const sp<AMessage> &reply);
411     status_t getPortFormat(OMX_U32 portIndex, sp<AMessage> &notify);
412 
413     void signalError(
414             OMX_ERRORTYPE error = OMX_ErrorUndefined,
415             status_t internalError = UNKNOWN_ERROR);
416 
417     static bool describeDefaultColorFormat(DescribeColorFormatParams &describeParams);
418     static bool describeColorFormat(
419         const sp<IOMX> &omx, IOMX::node_id node,
420         DescribeColorFormatParams &describeParams);
421 
422     status_t requestIDRFrame();
423     status_t setParameters(const sp<AMessage> &params);
424 
425     // Send EOS on input stream.
426     void onSignalEndOfInputStream();
427 
428     DISALLOW_EVIL_CONSTRUCTORS(ACodec);
429 };
430 
431 }  // namespace android
432 
433 #endif  // A_CODEC_H_
434