1 /* 2 * Copyright 2012, 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 MEDIA_CODEC_H_ 18 19 #define MEDIA_CODEC_H_ 20 21 #include <memory> 22 #include <vector> 23 24 #include <gui/IGraphicBufferProducer.h> 25 #include <media/hardware/CryptoAPI.h> 26 #include <media/MediaCodecInfo.h> 27 #include <media/MediaMetrics.h> 28 #include <media/stagefright/foundation/AHandler.h> 29 #include <media/stagefright/FrameRenderTracker.h> 30 #include <utils/Vector.h> 31 32 class C2Buffer; 33 class C2GraphicBlock; 34 class C2LinearBlock; 35 36 namespace aidl { 37 namespace android { 38 namespace media { 39 class MediaResourceParcel; 40 } // media 41 } // android 42 } // aidl 43 44 namespace android { 45 46 struct ABuffer; 47 struct AMessage; 48 struct AReplyToken; 49 struct AString; 50 struct BatteryChecker; 51 class BufferChannelBase; 52 struct CodecBase; 53 struct CodecParameterDescriptor; 54 class IBatteryStats; 55 struct ICrypto; 56 class MediaCodecBuffer; 57 class IMemory; 58 struct PersistentSurface; 59 class SoftwareRenderer; 60 class Surface; 61 class PlaybackDurationAccumulator; 62 namespace hardware { 63 namespace cas { 64 namespace native { 65 namespace V1_0 { 66 struct IDescrambler; 67 }}}} 68 69 using hardware::cas::native::V1_0::IDescrambler; 70 using aidl::android::media::MediaResourceParcel; 71 72 struct MediaCodec : public AHandler { 73 enum ConfigureFlags { 74 CONFIGURE_FLAG_ENCODE = 1, 75 CONFIGURE_FLAG_USE_BLOCK_MODEL = 2, 76 }; 77 78 enum BufferFlags { 79 BUFFER_FLAG_SYNCFRAME = 1, 80 BUFFER_FLAG_CODECCONFIG = 2, 81 BUFFER_FLAG_EOS = 4, 82 BUFFER_FLAG_PARTIAL_FRAME = 8, 83 BUFFER_FLAG_MUXER_DATA = 16, 84 }; 85 86 enum CVODegree { 87 CVO_DEGREE_0 = 0, 88 CVO_DEGREE_90 = 90, 89 CVO_DEGREE_180 = 180, 90 CVO_DEGREE_270 = 270, 91 }; 92 93 enum { 94 CB_INPUT_AVAILABLE = 1, 95 CB_OUTPUT_AVAILABLE = 2, 96 CB_ERROR = 3, 97 CB_OUTPUT_FORMAT_CHANGED = 4, 98 CB_RESOURCE_RECLAIMED = 5, 99 }; 100 101 static const pid_t kNoPid = -1; 102 static const uid_t kNoUid = -1; 103 104 static sp<MediaCodec> CreateByType( 105 const sp<ALooper> &looper, const AString &mime, bool encoder, status_t *err = NULL, 106 pid_t pid = kNoPid, uid_t uid = kNoUid); 107 108 static sp<MediaCodec> CreateByType( 109 const sp<ALooper> &looper, const AString &mime, bool encoder, status_t *err, 110 pid_t pid, uid_t uid, sp<AMessage> format); 111 112 static sp<MediaCodec> CreateByComponentName( 113 const sp<ALooper> &looper, const AString &name, status_t *err = NULL, 114 pid_t pid = kNoPid, uid_t uid = kNoUid); 115 116 static sp<PersistentSurface> CreatePersistentInputSurface(); 117 118 status_t configure( 119 const sp<AMessage> &format, 120 const sp<Surface> &nativeWindow, 121 const sp<ICrypto> &crypto, 122 uint32_t flags); 123 124 status_t configure( 125 const sp<AMessage> &format, 126 const sp<Surface> &nativeWindow, 127 const sp<ICrypto> &crypto, 128 const sp<IDescrambler> &descrambler, 129 uint32_t flags); 130 131 status_t releaseCrypto(); 132 133 status_t setCallback(const sp<AMessage> &callback); 134 135 status_t setOnFrameRenderedNotification(const sp<AMessage> ¬ify); 136 137 status_t setOnFirstTunnelFrameReadyNotification(const sp<AMessage> ¬ify); 138 139 status_t createInputSurface(sp<IGraphicBufferProducer>* bufferProducer); 140 141 status_t setInputSurface(const sp<PersistentSurface> &surface); 142 143 status_t start(); 144 145 // Returns to a state in which the component remains allocated but 146 // unconfigured. 147 status_t stop(); 148 149 // Resets the codec to the INITIALIZED state. Can be called after an error 150 // has occured to make the codec usable. 151 status_t reset(); 152 153 // Client MUST call release before releasing final reference to this 154 // object. 155 status_t release(); 156 157 status_t releaseAsync(const sp<AMessage> ¬ify); 158 159 status_t flush(); 160 161 status_t queueInputBuffer( 162 size_t index, 163 size_t offset, 164 size_t size, 165 int64_t presentationTimeUs, 166 uint32_t flags, 167 AString *errorDetailMsg = NULL); 168 169 status_t queueSecureInputBuffer( 170 size_t index, 171 size_t offset, 172 const CryptoPlugin::SubSample *subSamples, 173 size_t numSubSamples, 174 const uint8_t key[16], 175 const uint8_t iv[16], 176 CryptoPlugin::Mode mode, 177 const CryptoPlugin::Pattern &pattern, 178 int64_t presentationTimeUs, 179 uint32_t flags, 180 AString *errorDetailMsg = NULL); 181 182 status_t queueBuffer( 183 size_t index, 184 const std::shared_ptr<C2Buffer> &buffer, 185 int64_t presentationTimeUs, 186 uint32_t flags, 187 const sp<AMessage> &tunings, 188 AString *errorDetailMsg = NULL); 189 190 status_t queueEncryptedBuffer( 191 size_t index, 192 const sp<hardware::HidlMemory> &memory, 193 size_t offset, 194 const CryptoPlugin::SubSample *subSamples, 195 size_t numSubSamples, 196 const uint8_t key[16], 197 const uint8_t iv[16], 198 CryptoPlugin::Mode mode, 199 const CryptoPlugin::Pattern &pattern, 200 int64_t presentationTimeUs, 201 uint32_t flags, 202 const sp<AMessage> &tunings, 203 AString *errorDetailMsg = NULL); 204 205 std::shared_ptr<C2Buffer> decrypt( 206 const std::shared_ptr<C2Buffer> &buffer, 207 const CryptoPlugin::SubSample *subSamples, 208 size_t numSubSamples, 209 const uint8_t key[16], 210 const uint8_t iv[16], 211 CryptoPlugin::Mode mode, 212 const CryptoPlugin::Pattern &pattern); 213 214 status_t dequeueInputBuffer(size_t *index, int64_t timeoutUs = 0ll); 215 216 status_t dequeueOutputBuffer( 217 size_t *index, 218 size_t *offset, 219 size_t *size, 220 int64_t *presentationTimeUs, 221 uint32_t *flags, 222 int64_t timeoutUs = 0ll); 223 224 status_t renderOutputBufferAndRelease(size_t index, int64_t timestampNs); 225 status_t renderOutputBufferAndRelease(size_t index); 226 status_t releaseOutputBuffer(size_t index); 227 228 status_t signalEndOfInputStream(); 229 230 status_t getOutputFormat(sp<AMessage> *format) const; 231 status_t getInputFormat(sp<AMessage> *format) const; 232 233 status_t getInputBuffers(Vector<sp<MediaCodecBuffer> > *buffers) const; 234 status_t getOutputBuffers(Vector<sp<MediaCodecBuffer> > *buffers) const; 235 236 status_t getOutputBuffer(size_t index, sp<MediaCodecBuffer> *buffer); 237 status_t getOutputFormat(size_t index, sp<AMessage> *format); 238 status_t getInputBuffer(size_t index, sp<MediaCodecBuffer> *buffer); 239 240 status_t setSurface(const sp<Surface> &nativeWindow); 241 242 status_t requestIDRFrame(); 243 244 // Notification will be posted once there "is something to do", i.e. 245 // an input/output buffer has become available, a format change is 246 // pending, an error is pending. 247 void requestActivityNotification(const sp<AMessage> ¬ify); 248 249 status_t getName(AString *componentName) const; 250 251 status_t getCodecInfo(sp<MediaCodecInfo> *codecInfo) const; 252 253 status_t getMetrics(mediametrics_handle_t &reply); 254 255 status_t setParameters(const sp<AMessage> ¶ms); 256 257 status_t querySupportedVendorParameters(std::vector<std::string> *names); 258 status_t describeParameter(const std::string &name, CodecParameterDescriptor *desc); 259 status_t subscribeToVendorParameters(const std::vector<std::string> &names); 260 status_t unsubscribeFromVendorParameters(const std::vector<std::string> &names); 261 262 // Create a MediaCodec notification message from a list of rendered or dropped render infos 263 // by adding rendered frame information to a base notification message. Returns the number 264 // of frames that were rendered. 265 static size_t CreateFramesRenderedMessage( 266 const std::list<FrameRenderTracker::Info> &done, sp<AMessage> &msg); 267 268 static status_t CanFetchLinearBlock( 269 const std::vector<std::string> &names, bool *isCompatible); 270 271 static std::shared_ptr<C2LinearBlock> FetchLinearBlock( 272 size_t capacity, const std::vector<std::string> &names); 273 274 static status_t CanFetchGraphicBlock( 275 const std::vector<std::string> &names, bool *isCompatible); 276 277 static std::shared_ptr<C2GraphicBlock> FetchGraphicBlock( 278 int32_t width, 279 int32_t height, 280 int32_t format, 281 uint64_t usage, 282 const std::vector<std::string> &names); 283 284 template <typename T> 285 struct WrapperObject : public RefBase { WrapperObjectMediaCodec::WrapperObject286 WrapperObject(const T& v) : value(v) {} WrapperObjectMediaCodec::WrapperObject287 WrapperObject(T&& v) : value(std::move(v)) {} 288 T value; 289 }; 290 291 protected: 292 virtual ~MediaCodec(); 293 virtual void onMessageReceived(const sp<AMessage> &msg); 294 295 private: 296 // used by ResourceManagerClient 297 status_t reclaim(bool force = false); 298 friend struct ResourceManagerClient; 299 300 private: 301 enum State { 302 UNINITIALIZED, 303 INITIALIZING, 304 INITIALIZED, 305 CONFIGURING, 306 CONFIGURED, 307 STARTING, 308 STARTED, 309 FLUSHING, 310 FLUSHED, 311 STOPPING, 312 RELEASING, 313 }; 314 std::string stateString(State state); 315 316 enum { 317 kPortIndexInput = 0, 318 kPortIndexOutput = 1, 319 }; 320 321 enum { 322 kWhatInit = 'init', 323 kWhatConfigure = 'conf', 324 kWhatSetSurface = 'sSur', 325 kWhatCreateInputSurface = 'cisf', 326 kWhatSetInputSurface = 'sisf', 327 kWhatStart = 'strt', 328 kWhatStop = 'stop', 329 kWhatRelease = 'rele', 330 kWhatDequeueInputBuffer = 'deqI', 331 kWhatQueueInputBuffer = 'queI', 332 kWhatDequeueOutputBuffer = 'deqO', 333 kWhatReleaseOutputBuffer = 'relO', 334 kWhatSignalEndOfInputStream = 'eois', 335 kWhatGetBuffers = 'getB', 336 kWhatFlush = 'flus', 337 kWhatGetOutputFormat = 'getO', 338 kWhatGetInputFormat = 'getI', 339 kWhatDequeueInputTimedOut = 'dITO', 340 kWhatDequeueOutputTimedOut = 'dOTO', 341 kWhatCodecNotify = 'codc', 342 kWhatRequestIDRFrame = 'ridr', 343 kWhatRequestActivityNotification = 'racN', 344 kWhatGetName = 'getN', 345 kWhatGetCodecInfo = 'gCoI', 346 kWhatSetParameters = 'setP', 347 kWhatSetCallback = 'setC', 348 kWhatSetNotification = 'setN', 349 kWhatDrmReleaseCrypto = 'rDrm', 350 kWhatCheckBatteryStats = 'chkB', 351 }; 352 353 enum { 354 kFlagUsesSoftwareRenderer = 1, 355 kFlagOutputFormatChanged = 2, 356 kFlagOutputBuffersChanged = 4, 357 kFlagStickyError = 8, 358 kFlagDequeueInputPending = 16, 359 kFlagDequeueOutputPending = 32, 360 kFlagIsSecure = 64, 361 kFlagSawMediaServerDie = 128, 362 kFlagIsEncoder = 256, 363 // 512 skipped 364 kFlagIsAsync = 1024, 365 kFlagIsComponentAllocated = 2048, 366 kFlagPushBlankBuffersOnShutdown = 4096, 367 kFlagUseBlockModel = 8192, 368 }; 369 370 struct BufferInfo { 371 BufferInfo(); 372 373 sp<MediaCodecBuffer> mData; 374 bool mOwnedByClient; 375 }; 376 377 // This type is used to track the tunnel mode video peek state machine: 378 // 379 // DisabledNoBuffer -> EnabledNoBuffer when tunnel-peek = true 380 // DisabledQueued -> EnabledQueued when tunnel-peek = true 381 // DisabledNoBuffer -> DisabledQueued when first frame queued 382 // EnabledNoBuffer -> DisabledNoBuffer when tunnel-peek = false 383 // EnabledQueued -> DisabledQueued when tunnel-peek = false 384 // EnabledNoBuffer -> EnabledQueued when first frame queued 385 // DisabledNoBuffer -> BufferDecoded when kWhatFirstTunnelFrameReady 386 // DisabledQueued -> BufferDecoded when kWhatFirstTunnelFrameReady 387 // EnabledNoBuffer -> BufferDecoded when kWhatFirstTunnelFrameReady 388 // EnabledQueued -> BufferDecoded when kWhatFirstTunnelFrameReady 389 // BufferDecoded -> BufferRendered when kWhatFrameRendered 390 // <all states> -> EnabledNoBuffer when flush 391 // <all states> -> EnabledNoBuffer when stop then configure then start 392 enum struct TunnelPeekState { 393 kDisabledNoBuffer, 394 kEnabledNoBuffer, 395 kDisabledQueued, 396 kEnabledQueued, 397 kBufferDecoded, 398 kBufferRendered, 399 }; 400 401 struct ResourceManagerServiceProxy; 402 403 State mState; 404 uid_t mUid; 405 bool mReleasedByResourceManager; 406 sp<ALooper> mLooper; 407 sp<ALooper> mCodecLooper; 408 sp<CodecBase> mCodec; 409 AString mComponentName; 410 AString mOwnerName; 411 sp<MediaCodecInfo> mCodecInfo; 412 sp<AReplyToken> mReplyID; 413 std::string mLastReplyOrigin; 414 std::vector<sp<AMessage>> mDeferredMessages; 415 uint32_t mFlags; 416 int64_t mPresentationTimeUs = 0; 417 status_t mStickyError; 418 sp<Surface> mSurface; 419 SoftwareRenderer *mSoftRenderer; 420 421 mediametrics_handle_t mMetricsHandle = 0; 422 nsecs_t mLifetimeStartNs = 0; 423 void initMediametrics(); 424 void updateMediametrics(); 425 void flushMediametrics(); 426 void updateEphemeralMediametrics(mediametrics_handle_t item); 427 void updateLowLatency(const sp<AMessage> &msg); 428 constexpr const char *asString(TunnelPeekState state, const char *default_string="?"); 429 void updateTunnelPeek(const sp<AMessage> &msg); 430 void updatePlaybackDuration(const sp<AMessage> &msg); 431 432 sp<AMessage> mOutputFormat; 433 sp<AMessage> mInputFormat; 434 sp<AMessage> mCallback; 435 sp<AMessage> mOnFrameRenderedNotification; 436 sp<AMessage> mAsyncReleaseCompleteNotification; 437 sp<AMessage> mOnFirstTunnelFrameReadyNotification; 438 439 sp<ResourceManagerServiceProxy> mResourceManagerProxy; 440 441 bool mIsVideo; 442 AString mLogSessionId; 443 int32_t mVideoWidth; 444 int32_t mVideoHeight; 445 int32_t mRotationDegrees; 446 int32_t mAllowFrameDroppingBySurface; 447 448 // initial create parameters 449 AString mInitName; 450 451 // configure parameter 452 sp<AMessage> mConfigureMsg; 453 454 // rewrites the format description during configure() for encoding. 455 // format and flags as they exist within configure() 456 // the (possibly) updated format is returned in place. 457 status_t shapeMediaFormat( 458 const sp<AMessage> &format, 459 uint32_t flags); 460 461 // populate the format shaper library with information for this codec encoding 462 // for the indicated media type 463 status_t setupFormatShaper(AString mediaType); 464 465 // Used only to synchronize asynchronous getBufferAndFormat 466 // across all the other (synchronous) buffer state change 467 // operations, such as de/queueIn/OutputBuffer, start and 468 // stop/flush/reset/release. 469 Mutex mBufferLock; 470 471 List<size_t> mAvailPortBuffers[2]; 472 std::vector<BufferInfo> mPortBuffers[2]; 473 474 int32_t mDequeueInputTimeoutGeneration; 475 sp<AReplyToken> mDequeueInputReplyID; 476 477 int32_t mDequeueOutputTimeoutGeneration; 478 sp<AReplyToken> mDequeueOutputReplyID; 479 480 sp<ICrypto> mCrypto; 481 482 int32_t mTunneledInputWidth; 483 int32_t mTunneledInputHeight; 484 bool mTunneled; 485 TunnelPeekState mTunnelPeekState; 486 487 sp<IDescrambler> mDescrambler; 488 489 List<sp<ABuffer> > mCSD; 490 491 sp<AMessage> mActivityNotify; 492 493 bool mHaveInputSurface; 494 bool mHavePendingInputBuffers; 495 bool mCpuBoostRequested; 496 497 std::shared_ptr<BufferChannelBase> mBufferChannel; 498 499 PlaybackDurationAccumulator * mPlaybackDurationAccumulator; 500 bool mIsSurfaceToScreen; 501 502 MediaCodec( 503 const sp<ALooper> &looper, pid_t pid, uid_t uid, 504 std::function<sp<CodecBase>(const AString &, const char *)> getCodecBase = nullptr, 505 std::function<status_t(const AString &, sp<MediaCodecInfo> *)> getCodecInfo = nullptr); 506 507 static sp<CodecBase> GetCodecBase(const AString &name, const char *owner = nullptr); 508 509 static status_t PostAndAwaitResponse( 510 const sp<AMessage> &msg, sp<AMessage> *response); 511 512 void PostReplyWithError(const sp<AMessage> &msg, int32_t err); 513 void PostReplyWithError(const sp<AReplyToken> &replyID, int32_t err); 514 515 status_t init(const AString &name); 516 517 void setState(State newState); 518 void returnBuffersToCodec(bool isReclaim = false); 519 void returnBuffersToCodecOnPort(int32_t portIndex, bool isReclaim = false); 520 size_t updateBuffers(int32_t portIndex, const sp<AMessage> &msg); 521 status_t onQueueInputBuffer(const sp<AMessage> &msg); 522 status_t onReleaseOutputBuffer(const sp<AMessage> &msg); 523 BufferInfo *peekNextPortBuffer(int32_t portIndex); 524 ssize_t dequeuePortBuffer(int32_t portIndex); 525 526 status_t getBufferAndFormat( 527 size_t portIndex, size_t index, 528 sp<MediaCodecBuffer> *buffer, sp<AMessage> *format); 529 530 bool handleDequeueInputBuffer(const sp<AReplyToken> &replyID, bool newRequest = false); 531 bool handleDequeueOutputBuffer(const sp<AReplyToken> &replyID, bool newRequest = false); 532 void cancelPendingDequeueOperations(); 533 534 void extractCSD(const sp<AMessage> &format); 535 status_t queueCSDInputBuffer(size_t bufferIndex); 536 537 status_t handleSetSurface(const sp<Surface> &surface); 538 status_t connectToSurface(const sp<Surface> &surface); 539 status_t disconnectFromSurface(); 540 hasCryptoOrDescramblerMediaCodec541 bool hasCryptoOrDescrambler() { 542 return mCrypto != NULL || mDescrambler != NULL; 543 } 544 545 void postActivityNotificationIfPossible(); 546 547 void onInputBufferAvailable(); 548 void onOutputBufferAvailable(); 549 void onError(status_t err, int32_t actionCode, const char *detail = NULL); 550 void onOutputFormatChanged(); 551 552 status_t onSetParameters(const sp<AMessage> ¶ms); 553 554 status_t amendOutputFormatWithCodecSpecificData(const sp<MediaCodecBuffer> &buffer); 555 void handleOutputFormatChangeIfNeeded(const sp<MediaCodecBuffer> &buffer); 556 bool isExecuting() const; 557 558 uint64_t getGraphicBufferSize(); 559 void requestCpuBoostIfNeeded(); 560 561 bool hasPendingBuffer(int portIndex); 562 bool hasPendingBuffer(); 563 564 void postPendingRepliesAndDeferredMessages(std::string origin, status_t err = OK); 565 void postPendingRepliesAndDeferredMessages(std::string origin, const sp<AMessage> &response); 566 567 /* called to get the last codec error when the sticky flag is set. 568 * if no such codec error is found, returns UNKNOWN_ERROR. 569 */ getStickyErrorMediaCodec570 inline status_t getStickyError() const { 571 return mStickyError != 0 ? mStickyError : UNKNOWN_ERROR; 572 } 573 setStickyErrorMediaCodec574 inline void setStickyError(status_t err) { 575 mFlags |= kFlagStickyError; 576 mStickyError = err; 577 } 578 579 void onReleaseCrypto(const sp<AMessage>& msg); 580 581 // managing time-of-flight aka latency 582 typedef struct { 583 int64_t presentationUs; 584 int64_t startedNs; 585 } BufferFlightTiming_t; 586 std::deque<BufferFlightTiming_t> mBuffersInFlight; 587 Mutex mLatencyLock; 588 int64_t mLatencyUnknown; // buffers for which we couldn't calculate latency 589 590 Mutex mOutputStatsLock; 591 int64_t mBytesEncoded = 0; 592 int64_t mEarliestEncodedPtsUs = INT64_MAX; 593 int64_t mLatestEncodedPtsUs = INT64_MIN; 594 int64_t mFramesEncoded = 0; 595 int64_t mBytesInput = 0; 596 int64_t mFramesInput = 0; 597 598 int64_t mNumLowLatencyEnables; // how many times low latency mode is enabled 599 int64_t mNumLowLatencyDisables; // how many times low latency mode is disabled 600 bool mIsLowLatencyModeOn; // is low latency mode on currently 601 int64_t mIndexOfFirstFrameWhenLowLatencyOn; // index of the first frame queued 602 // when low latency is on 603 int64_t mInputBufferCounter; // number of input buffers queued since last reset/flush 604 605 class ReleaseSurface; 606 std::unique_ptr<ReleaseSurface> mReleaseSurface; 607 608 std::list<sp<AMessage>> mLeftover; 609 status_t handleLeftover(size_t index); 610 611 sp<BatteryChecker> mBatteryChecker; 612 613 void statsBufferSent(int64_t presentationUs, const sp<MediaCodecBuffer> &buffer); 614 void statsBufferReceived(int64_t presentationUs, const sp<MediaCodecBuffer> &buffer); 615 616 enum { 617 // the default shape of our latency histogram buckets 618 // XXX: should these be configurable in some way? 619 kLatencyHistBuckets = 20, 620 kLatencyHistWidth = 2000, 621 kLatencyHistFloor = 2000, 622 623 // how many samples are in the 'recent latency' histogram 624 // 300 frames = 5 sec @ 60fps or ~12 sec @ 24fps 625 kRecentLatencyFrames = 300, 626 627 // how we initialize mRecentSamples 628 kRecentSampleInvalid = -1, 629 }; 630 631 int64_t mRecentSamples[kRecentLatencyFrames]; 632 int mRecentHead; 633 Mutex mRecentLock; 634 635 class Histogram { 636 public: HistogramMediaCodec637 Histogram() : mFloor(0), mWidth(0), mBelow(0), mAbove(0), 638 mMin(INT64_MAX), mMax(INT64_MIN), mSum(0), mCount(0), 639 mBucketCount(0), mBuckets(NULL) {}; ~HistogramMediaCodec640 ~Histogram() { clear(); }; clearMediaCodec641 void clear() { if (mBuckets != NULL) free(mBuckets); mBuckets = NULL; }; 642 bool setup(int nbuckets, int64_t width, int64_t floor = 0); 643 void insert(int64_t sample); getMinMediaCodec644 int64_t getMin() const { return mMin; } getMaxMediaCodec645 int64_t getMax() const { return mMax; } getCountMediaCodec646 int64_t getCount() const { return mCount; } getSumMediaCodec647 int64_t getSum() const { return mSum; } getAvgMediaCodec648 int64_t getAvg() const { return mSum / (mCount == 0 ? 1 : mCount); } 649 std::string emit(); 650 private: 651 int64_t mFloor, mCeiling, mWidth; 652 int64_t mBelow, mAbove; 653 int64_t mMin, mMax, mSum, mCount; 654 655 int mBucketCount; 656 int64_t *mBuckets; 657 }; 658 659 Histogram mLatencyHist; 660 661 std::function<sp<CodecBase>(const AString &, const char *)> mGetCodecBase; 662 std::function<status_t(const AString &, sp<MediaCodecInfo> *)> mGetCodecInfo; 663 friend class MediaTestHelper; 664 665 DISALLOW_EVIL_CONSTRUCTORS(MediaCodec); 666 }; 667 668 } // namespace android 669 670 #endif // MEDIA_CODEC_H_ 671