ACodec.h revision e2b43843fd12783188edd2c54188ea8d26864788
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/MediaDefs.h> 29#include <media/stagefright/SkipCutBuffer.h> 30#include <utils/NativeHandle.h> 31#include <OMX_Audio.h> 32#include <hardware/gralloc.h> 33 34#define TRACK_BUFFER_TIMING 0 35 36namespace android { 37 38struct ABuffer; 39class ACodecBufferChannel; 40class MediaCodecBuffer; 41class MemoryDealer; 42struct DescribeColorFormat2Params; 43struct DataConverter; 44 45// Treble shared memory 46namespace hidl { 47namespace allocator { 48namespace V1_0 { 49struct IAllocator; 50} // V1_0 51} // allocator 52namespace memory { 53namespace V1_0 { 54struct IMemory; 55} // V1_0 56} // memory 57} // hidl 58 59typedef hidl::allocator::V1_0::IAllocator TAllocator; 60typedef hidl::memory::V1_0::IMemory TMemory; 61 62struct ACodec : public AHierarchicalStateMachine, public CodecBase { 63 ACodec(); 64 65 void initiateSetup(const sp<AMessage> &msg); 66 67 virtual std::shared_ptr<BufferChannelBase> getBufferChannel() override; 68 virtual void initiateAllocateComponent(const sp<AMessage> &msg); 69 virtual void initiateConfigureComponent(const sp<AMessage> &msg); 70 virtual void initiateCreateInputSurface(); 71 virtual void initiateSetInputSurface(const sp<PersistentSurface> &surface); 72 virtual void initiateStart(); 73 virtual void initiateShutdown(bool keepComponentAllocated = false); 74 75 virtual status_t queryCapabilities( 76 const AString &name, const AString &mime, bool isEncoder, 77 sp<MediaCodecInfo::Capabilities> *caps); 78 79 virtual status_t setSurface(const sp<Surface> &surface); 80 81 virtual void signalFlush(); 82 virtual void signalResume(); 83 84 virtual void signalSetParameters(const sp<AMessage> &msg); 85 virtual void signalEndOfInputStream(); 86 virtual void signalRequestIDRFrame(); 87 88 // AHierarchicalStateMachine implements the message handling 89 virtual void onMessageReceived(const sp<AMessage> &msg) { 90 handleMessage(msg); 91 } 92 93 // Returns 0 if configuration is not supported. NOTE: this is treated by 94 // some OMX components as auto level, and by others as invalid level. 95 static int /* OMX_VIDEO_AVCLEVELTYPE */ getAVCLevelFor( 96 int width, int height, int rate, int bitrate, 97 OMX_VIDEO_AVCPROFILETYPE profile = OMX_VIDEO_AVCProfileBaseline); 98 99 // Quirk still supported, even though deprecated 100 enum Quirks { 101 kRequiresAllocateBufferOnInputPorts = 1, 102 kRequiresAllocateBufferOnOutputPorts = 2, 103 }; 104 105 static status_t getOMXChannelMapping(size_t numChannels, OMX_AUDIO_CHANNELTYPE map[]); 106 107 // Save the flag. 108 void setTrebleFlag(bool trebleFlag); 109 // Return the saved flag. 110 bool getTrebleFlag() const; 111 112protected: 113 virtual ~ACodec(); 114 115private: 116 struct BaseState; 117 struct UninitializedState; 118 struct LoadedState; 119 struct LoadedToIdleState; 120 struct IdleToExecutingState; 121 struct ExecutingState; 122 struct OutputPortSettingsChangedState; 123 struct ExecutingToIdleState; 124 struct IdleToLoadedState; 125 struct FlushingState; 126 struct DeathNotifier; 127 128 enum { 129 kWhatSetup = 'setu', 130 kWhatOMXMessage = 'omx ', 131 // same as kWhatOMXMessage - but only used with 132 // handleMessage during OMX message-list handling 133 kWhatOMXMessageItem = 'omxI', 134 kWhatOMXMessageList = 'omxL', 135 kWhatInputBufferFilled = 'inpF', 136 kWhatOutputBufferDrained = 'outD', 137 kWhatShutdown = 'shut', 138 kWhatFlush = 'flus', 139 kWhatResume = 'resm', 140 kWhatDrainDeferredMessages = 'drai', 141 kWhatAllocateComponent = 'allo', 142 kWhatConfigureComponent = 'conf', 143 kWhatSetSurface = 'setS', 144 kWhatCreateInputSurface = 'cisf', 145 kWhatSetInputSurface = 'sisf', 146 kWhatSignalEndOfInputStream = 'eois', 147 kWhatStart = 'star', 148 kWhatRequestIDRFrame = 'ridr', 149 kWhatSetParameters = 'setP', 150 kWhatSubmitOutputMetadataBufferIfEOS = 'subm', 151 kWhatOMXDied = 'OMXd', 152 kWhatReleaseCodecInstance = 'relC', 153 }; 154 155 enum { 156 kPortIndexInput = 0, 157 kPortIndexOutput = 1 158 }; 159 160 enum { 161 kFlagIsSecure = 1, 162 kFlagPushBlankBuffersToNativeWindowOnShutdown = 2, 163 kFlagIsGrallocUsageProtected = 4, 164 }; 165 166 enum { 167 kVideoGrallocUsage = (GRALLOC_USAGE_HW_TEXTURE 168 | GRALLOC_USAGE_HW_COMPOSER 169 | GRALLOC_USAGE_EXTERNAL_DISP), 170 }; 171 172 struct BufferInfo { 173 enum Status { 174 OWNED_BY_US, 175 OWNED_BY_COMPONENT, 176 OWNED_BY_UPSTREAM, 177 OWNED_BY_DOWNSTREAM, 178 OWNED_BY_NATIVE_WINDOW, 179 UNRECOGNIZED, // not a tracked buffer 180 }; 181 182 static inline Status getSafeStatus(BufferInfo *info) { 183 return info == NULL ? UNRECOGNIZED : info->mStatus; 184 } 185 186 IOMX::buffer_id mBufferID; 187 Status mStatus; 188 unsigned mDequeuedAt; 189 190 sp<MediaCodecBuffer> mData; // the client's buffer; if not using data conversion, this is 191 // the codec buffer; otherwise, it is allocated separately 192 sp<RefBase> mMemRef; // and a reference to the IMemory, so it does not go away 193 sp<MediaCodecBuffer> mCodecData; // the codec's buffer 194 sp<RefBase> mCodecRef; // and a reference to the IMemory 195 196 sp<GraphicBuffer> mGraphicBuffer; 197 bool mNewGraphicBuffer; 198 int mFenceFd; 199 FrameRenderTracker::Info *mRenderInfo; 200 201 // The following field and 4 methods are used for debugging only 202 bool mIsReadFence; 203 // Store |fenceFd| and set read/write flag. Log error, if there is already a fence stored. 204 void setReadFence(int fenceFd, const char *dbg); 205 void setWriteFence(int fenceFd, const char *dbg); 206 // Log error, if the current fence is not a read/write fence. 207 void checkReadFence(const char *dbg); 208 void checkWriteFence(const char *dbg); 209 }; 210 211 static const char *_asString(BufferInfo::Status s); 212 void dumpBuffers(OMX_U32 portIndex); 213 214 // If |fd| is non-negative, waits for fence with |fd| and logs an error if it fails. Returns 215 // the error code or OK on success. If |fd| is negative, it returns OK 216 status_t waitForFence(int fd, const char *dbg); 217 218#if TRACK_BUFFER_TIMING 219 struct BufferStats { 220 int64_t mEmptyBufferTimeUs; 221 int64_t mFillBufferDoneTimeUs; 222 }; 223 224 KeyedVector<int64_t, BufferStats> mBufferStats; 225#endif 226 227 sp<UninitializedState> mUninitializedState; 228 sp<LoadedState> mLoadedState; 229 sp<LoadedToIdleState> mLoadedToIdleState; 230 sp<IdleToExecutingState> mIdleToExecutingState; 231 sp<ExecutingState> mExecutingState; 232 sp<OutputPortSettingsChangedState> mOutputPortSettingsChangedState; 233 sp<ExecutingToIdleState> mExecutingToIdleState; 234 sp<IdleToLoadedState> mIdleToLoadedState; 235 sp<FlushingState> mFlushingState; 236 sp<SkipCutBuffer> mSkipCutBuffer; 237 int32_t mSampleRate; 238 239 AString mComponentName; 240 uint32_t mFlags; 241 sp<IOMX> mOMX; 242 sp<IOMXNode> mOMXNode; 243 int32_t mNodeGeneration; 244 bool mTrebleFlag; 245 sp<TAllocator> mAllocator[2]; 246 sp<MemoryDealer> mDealer[2]; 247 248 bool mUsingNativeWindow; 249 sp<ANativeWindow> mNativeWindow; 250 int mNativeWindowUsageBits; 251 android_native_rect_t mLastNativeWindowCrop; 252 int32_t mLastNativeWindowDataSpace; 253 sp<AMessage> mConfigFormat; 254 sp<AMessage> mInputFormat; 255 sp<AMessage> mOutputFormat; 256 257 // Initial output format + configuration params that is reused as the base for all subsequent 258 // format updates. This will equal to mOutputFormat until the first actual frame is received. 259 sp<AMessage> mBaseOutputFormat; 260 261 FrameRenderTracker mRenderTracker; // render information for buffers rendered by ACodec 262 Vector<BufferInfo> mBuffers[2]; 263 bool mPortEOS[2]; 264 status_t mInputEOSResult; 265 266 List<sp<AMessage> > mDeferredQueue; 267 268 sp<AMessage> mLastOutputFormat; 269 bool mIsVideo; 270 bool mIsEncoder; 271 bool mFatalError; 272 bool mShutdownInProgress; 273 bool mExplicitShutdown; 274 bool mIsLegacyVP9Decoder; 275 276 // If "mKeepComponentAllocated" we only transition back to Loaded state 277 // and do not release the component instance. 278 bool mKeepComponentAllocated; 279 280 int32_t mEncoderDelay; 281 int32_t mEncoderPadding; 282 int32_t mRotationDegrees; 283 284 bool mChannelMaskPresent; 285 int32_t mChannelMask; 286 unsigned mDequeueCounter; 287 IOMX::PortMode mPortMode[2]; 288 int32_t mMetadataBuffersToSubmit; 289 size_t mNumUndequeuedBuffers; 290 sp<DataConverter> mConverter[2]; 291 292 sp<IGraphicBufferSource> mGraphicBufferSource; 293 int64_t mRepeatFrameDelayUs; 294 int64_t mMaxPtsGapUs; 295 float mMaxFps; 296 int64_t mTimePerFrameUs; 297 int64_t mTimePerCaptureUs; 298 bool mCreateInputBuffersSuspended; 299 300 bool mTunneled; 301 302 OMX_INDEXTYPE mDescribeColorAspectsIndex; 303 OMX_INDEXTYPE mDescribeHDRStaticInfoIndex; 304 305 std::shared_ptr<ACodecBufferChannel> mBufferChannel; 306 307 status_t setCyclicIntraMacroblockRefresh(const sp<AMessage> &msg, int32_t mode); 308 status_t allocateBuffersOnPort(OMX_U32 portIndex); 309 status_t freeBuffersOnPort(OMX_U32 portIndex); 310 status_t freeBuffer(OMX_U32 portIndex, size_t i); 311 312 status_t handleSetSurface(const sp<Surface> &surface); 313 status_t setPortMode(int32_t portIndex, IOMX::PortMode mode); 314 status_t setupNativeWindowSizeFormatAndUsage( 315 ANativeWindow *nativeWindow /* nonnull */, int *finalUsage /* nonnull */, 316 bool reconnect); 317 318 status_t configureOutputBuffersFromNativeWindow( 319 OMX_U32 *nBufferCount, OMX_U32 *nBufferSize, 320 OMX_U32 *nMinUndequeuedBuffers, bool preregister); 321 status_t allocateOutputMetadataBuffers(); 322 status_t submitOutputMetadataBuffer(); 323 void signalSubmitOutputMetadataBufferIfEOS_workaround(); 324 status_t allocateOutputBuffersFromNativeWindow(); 325 status_t cancelBufferToNativeWindow(BufferInfo *info); 326 status_t freeOutputBuffersNotOwnedByComponent(); 327 BufferInfo *dequeueBufferFromNativeWindow(); 328 329 inline bool storingMetadataInDecodedBuffers() { 330 return (mPortMode[kPortIndexOutput] == IOMX::kPortModeDynamicANWBuffer) && !mIsEncoder; 331 } 332 333 inline bool usingSecureBufferOnEncoderOutput() { 334 return (mPortMode[kPortIndexOutput] == IOMX::kPortModePresetSecureBuffer) && mIsEncoder; 335 } 336 337 BufferInfo *findBufferByID( 338 uint32_t portIndex, IOMX::buffer_id bufferID, 339 ssize_t *index = NULL); 340 341 status_t fillBuffer(BufferInfo *info); 342 343 status_t setComponentRole(bool isEncoder, const char *mime); 344 345 status_t configureCodec(const char *mime, const sp<AMessage> &msg); 346 347 status_t configureTunneledVideoPlayback(int32_t audioHwSync, 348 const sp<ANativeWindow> &nativeWindow); 349 350 status_t setVideoPortFormatType( 351 OMX_U32 portIndex, 352 OMX_VIDEO_CODINGTYPE compressionFormat, 353 OMX_COLOR_FORMATTYPE colorFormat, 354 bool usingNativeBuffers = false); 355 356 status_t setSupportedOutputFormat(bool getLegacyFlexibleFormat); 357 358 status_t setupVideoDecoder( 359 const char *mime, const sp<AMessage> &msg, bool usingNativeBuffers, bool haveSwRenderer, 360 sp<AMessage> &outputformat); 361 362 status_t setupVideoEncoder( 363 const char *mime, const sp<AMessage> &msg, 364 sp<AMessage> &outputformat, sp<AMessage> &inputformat); 365 366 status_t setVideoFormatOnPort( 367 OMX_U32 portIndex, 368 int32_t width, int32_t height, 369 OMX_VIDEO_CODINGTYPE compressionFormat, float frameRate = -1.0); 370 371 // sets |portIndex| port buffer numbers to be |bufferNum|. NOTE: Component could reject 372 // this setting if the |bufferNum| is less than the minimum buffer num of the port. 373 status_t setPortBufferNum(OMX_U32 portIndex, int bufferNum); 374 375 // gets index or sets it to 0 on error. Returns error from codec. 376 status_t initDescribeColorAspectsIndex(); 377 378 // sets |params|. If |readBack| is true, it re-gets them afterwards if set succeeded. 379 // returns the codec error. 380 status_t setCodecColorAspects(DescribeColorAspectsParams ¶ms, bool readBack = false); 381 382 // gets |params|; returns the codec error. |param| should not change on error. 383 status_t getCodecColorAspects(DescribeColorAspectsParams ¶ms); 384 385 // gets dataspace guidance from codec and platform. |params| should be set up with the color 386 // aspects to use. If |tryCodec| is true, the codec is queried first. If it succeeds, we 387 // return OK. Otherwise, we fall back to the platform guidance and return the codec error; 388 // though, we return OK if the codec failed with UNSUPPORTED, as codec guidance is optional. 389 status_t getDataSpace( 390 DescribeColorAspectsParams ¶ms, android_dataspace *dataSpace /* nonnull */, 391 bool tryCodec); 392 393 // sets color aspects for the encoder for certain |width/height| based on |configFormat|, and 394 // set resulting color config into |outputFormat|. If |usingNativeWindow| is true, we use 395 // video defaults if config is unspecified. Returns error from the codec. 396 status_t setColorAspectsForVideoDecoder( 397 int32_t width, int32_t height, bool usingNativeWindow, 398 const sp<AMessage> &configFormat, sp<AMessage> &outputFormat); 399 400 // gets color aspects for the encoder for certain |width/height| based on |configFormat|, and 401 // set resulting color config into |outputFormat|. If |dataSpace| is non-null, it requests 402 // dataspace guidance from the codec and platform and sets it into |dataSpace|. Returns the 403 // error from the codec. 404 status_t getColorAspectsAndDataSpaceForVideoDecoder( 405 int32_t width, int32_t height, const sp<AMessage> &configFormat, 406 sp<AMessage> &outputFormat, android_dataspace *dataSpace); 407 408 // sets color aspects for the video encoder assuming bytebuffer mode for certain |configFormat| 409 // and sets resulting color config into |outputFormat|. For mediarecorder, also set dataspace 410 // into |inputFormat|. Returns the error from the codec. 411 status_t setColorAspectsForVideoEncoder( 412 const sp<AMessage> &configFormat, 413 sp<AMessage> &outputFormat, sp<AMessage> &inputFormat); 414 415 // sets color aspects for the video encoder in surface mode. This basically sets the default 416 // video values for unspecified aspects and sets the dataspace to use in the input format. 417 // Also sets the dataspace into |dataSpace|. 418 // Returns any codec errors during this configuration, except for optional steps. 419 status_t setInitialColorAspectsForVideoEncoderSurfaceAndGetDataSpace( 420 android_dataspace *dataSpace /* nonnull */); 421 422 // gets color aspects for the video encoder input port and sets them into the |format|. 423 // Returns any codec errors. 424 status_t getInputColorAspectsForVideoEncoder(sp<AMessage> &format); 425 426 // updates the encoder output format with |aspects| defaulting to |dataSpace| for 427 // unspecified values. 428 void onDataSpaceChanged(android_dataspace dataSpace, const ColorAspects &aspects); 429 430 // gets index or sets it to 0 on error. Returns error from codec. 431 status_t initDescribeHDRStaticInfoIndex(); 432 433 // sets HDR static metadata for the video encoder/decoder based on |configFormat|, and 434 // sets resulting HDRStaticInfo config into |outputFormat|. Returns error from the codec. 435 status_t setHDRStaticInfoForVideoCodec( 436 OMX_U32 portIndex, const sp<AMessage> &configFormat, sp<AMessage> &outputFormat); 437 438 // sets |params|. Returns the codec error. 439 status_t setHDRStaticInfo(const DescribeHDRStaticInfoParams ¶ms); 440 441 // gets |params|. Returns the codec error. 442 status_t getHDRStaticInfo(DescribeHDRStaticInfoParams ¶ms); 443 444 // gets HDR static information for the video encoder/decoder port and sets them into |format|. 445 status_t getHDRStaticInfoForVideoCodec(OMX_U32 portIndex, sp<AMessage> &format); 446 447 typedef struct drcParams { 448 int32_t drcCut; 449 int32_t drcBoost; 450 int32_t heavyCompression; 451 int32_t targetRefLevel; 452 int32_t encodedTargetLevel; 453 } drcParams_t; 454 455 status_t setupAACCodec( 456 bool encoder, 457 int32_t numChannels, int32_t sampleRate, int32_t bitRate, 458 int32_t aacProfile, bool isADTS, int32_t sbrMode, 459 int32_t maxOutputChannelCount, const drcParams_t& drc, 460 int32_t pcmLimiterEnable); 461 462 status_t setupAC3Codec(bool encoder, int32_t numChannels, int32_t sampleRate); 463 464 status_t setupEAC3Codec(bool encoder, int32_t numChannels, int32_t sampleRate); 465 466 status_t selectAudioPortFormat( 467 OMX_U32 portIndex, OMX_AUDIO_CODINGTYPE desiredFormat); 468 469 status_t setupAMRCodec(bool encoder, bool isWAMR, int32_t bitRate); 470 status_t setupG711Codec(bool encoder, int32_t sampleRate, int32_t numChannels); 471 472 status_t setupFlacCodec( 473 bool encoder, int32_t numChannels, int32_t sampleRate, int32_t compressionLevel); 474 475 status_t setupRawAudioFormat( 476 OMX_U32 portIndex, int32_t sampleRate, int32_t numChannels, 477 AudioEncoding encoding = kAudioEncodingPcm16bit); 478 479 status_t setPriority(int32_t priority); 480 status_t setOperatingRate(float rateFloat, bool isVideo); 481 status_t getIntraRefreshPeriod(uint32_t *intraRefreshPeriod); 482 status_t setIntraRefreshPeriod(uint32_t intraRefreshPeriod, bool inConfigure); 483 484 // Configures temporal layering based on |msg|. |inConfigure| shall be true iff this is called 485 // during configure() call. on success the configured layering is set in |outputFormat|. If 486 // |outputFormat| is mOutputFormat, it is copied to trigger an output format changed event. 487 status_t configureTemporalLayers( 488 const sp<AMessage> &msg, bool inConfigure, sp<AMessage> &outputFormat); 489 490 status_t setMinBufferSize(OMX_U32 portIndex, size_t size); 491 492 status_t setupMPEG4EncoderParameters(const sp<AMessage> &msg); 493 status_t setupH263EncoderParameters(const sp<AMessage> &msg); 494 status_t setupAVCEncoderParameters(const sp<AMessage> &msg); 495 status_t setupHEVCEncoderParameters(const sp<AMessage> &msg); 496 status_t setupVPXEncoderParameters(const sp<AMessage> &msg, sp<AMessage> &outputFormat); 497 498 status_t verifySupportForProfileAndLevel(int32_t profile, int32_t level); 499 500 status_t configureBitrate( 501 int32_t bitrate, OMX_VIDEO_CONTROLRATETYPE bitrateMode); 502 503 status_t setupErrorCorrectionParameters(); 504 505 // Returns true iff all buffers on the given port have status 506 // OWNED_BY_US or OWNED_BY_NATIVE_WINDOW. 507 bool allYourBuffersAreBelongToUs(OMX_U32 portIndex); 508 509 bool allYourBuffersAreBelongToUs(); 510 511 void waitUntilAllPossibleNativeWindowBuffersAreReturnedToUs(); 512 513 size_t countBuffersOwnedByComponent(OMX_U32 portIndex) const; 514 size_t countBuffersOwnedByNativeWindow() const; 515 516 void deferMessage(const sp<AMessage> &msg); 517 void processDeferredMessages(); 518 519 void onFrameRendered(int64_t mediaTimeUs, nsecs_t systemNano); 520 // called when we have dequeued a buffer |buf| from the native window to track render info. 521 // |fenceFd| is the dequeue fence, and |info| points to the buffer info where this buffer is 522 // stored. 523 void updateRenderInfoForDequeuedBuffer( 524 ANativeWindowBuffer *buf, int fenceFd, BufferInfo *info); 525 526 // Checks to see if any frames have rendered up until |until|, and to notify client 527 // (MediaCodec) of rendered frames up-until the frame pointed to by |until| or the first 528 // unrendered frame. These frames are removed from the render queue. 529 // If |dropIncomplete| is true, unrendered frames up-until |until| will be dropped from the 530 // queue, allowing all rendered framed up till then to be notified of. 531 // (This will effectively clear the render queue up-until (and including) |until|.) 532 // If |until| is NULL, or is not in the rendered queue, this method will check all frames. 533 void notifyOfRenderedFrames( 534 bool dropIncomplete = false, FrameRenderTracker::Info *until = NULL); 535 536 // Pass |expectedFormat| to print a warning if the format differs from it. 537 // Using sp<> instead of const sp<>& because expectedFormat is likely the current mOutputFormat 538 // which will get updated inside. 539 void onOutputFormatChanged(sp<const AMessage> expectedFormat = NULL); 540 void addKeyFormatChangesToRenderBufferNotification(sp<AMessage> ¬ify); 541 void sendFormatChange(); 542 543 status_t getPortFormat(OMX_U32 portIndex, sp<AMessage> ¬ify); 544 545 void signalError( 546 OMX_ERRORTYPE error = OMX_ErrorUndefined, 547 status_t internalError = UNKNOWN_ERROR); 548 549 status_t requestIDRFrame(); 550 status_t setParameters(const sp<AMessage> ¶ms); 551 552 // Send EOS on input stream. 553 void onSignalEndOfInputStream(); 554 555 DISALLOW_EVIL_CONSTRUCTORS(ACodec); 556}; 557 558} // namespace android 559 560#endif // A_CODEC_H_ 561