• 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/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> &notify);
144 
145     status_t setOnFirstTunnelFrameReadyNotification(const sp<AMessage> &notify);
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> &notify);
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> &notify);
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> &params);
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> &params);
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