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 33namespace android { 34 35struct ABuffer; 36struct MemoryDealer; 37struct DescribeColorFormatParams; 38 39struct 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 63 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 94protected: 95 virtual ~ACodec(); 96 97private: 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 164 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 291 inline bool storingMetadataInDecodedBuffers() { 292 return mOutputMetadataType >= 0 && !mIsEncoder; 293 } 294 295 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> ¬ify); 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> ¶ms); 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