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