• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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> &notify);
136 
137     status_t setOnFirstTunnelFrameReadyNotification(const sp<AMessage> &notify);
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> &notify);
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> &notify);
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> &params);
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> &params);
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