ACodec.cpp revision bb644123966bfa2f44c60710faaafa8fa6f0e920
1/*
2 * Copyright (C) 2010 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 *      http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17//#define LOG_NDEBUG 0
18#define LOG_TAG "ACodec"
19
20#ifdef __LP64__
21#define OMX_ANDROID_COMPILE_AS_32BIT_ON_64BIT_PLATFORMS
22#endif
23
24#include <inttypes.h>
25#include <utils/Trace.h>
26
27#include <gui/Surface.h>
28
29#include <media/stagefright/ACodec.h>
30
31#include <media/stagefright/foundation/avc_utils.h>
32#include <media/stagefright/foundation/hexdump.h>
33#include <media/stagefright/foundation/ABuffer.h>
34#include <media/stagefright/foundation/ADebug.h>
35#include <media/stagefright/foundation/AMessage.h>
36#include <media/stagefright/foundation/AUtils.h>
37
38#include <media/stagefright/BufferProducerWrapper.h>
39#include <media/stagefright/MediaCodec.h>
40#include <media/stagefright/MediaDefs.h>
41#include <media/stagefright/OMXClient.h>
42#include <media/stagefright/PersistentSurface.h>
43#include <media/stagefright/SurfaceUtils.h>
44#include <media/hardware/HardwareAPI.h>
45#include <media/MediaBufferHolder.h>
46#include <media/OMXBuffer.h>
47#include <media/omx/1.0/WOmxNode.h>
48
49#include <hidlmemory/mapping.h>
50
51#include <media/openmax/OMX_AudioExt.h>
52#include <media/openmax/OMX_VideoExt.h>
53#include <media/openmax/OMX_Component.h>
54#include <media/openmax/OMX_IndexExt.h>
55#include <media/openmax/OMX_AsString.h>
56
57#include "include/ACodecBufferChannel.h"
58#include "include/DataConverter.h"
59#include "include/SecureBuffer.h"
60#include "include/SharedMemoryBuffer.h"
61#include <media/stagefright/omx/OMXUtils.h>
62
63namespace android {
64
65using binder::Status;
66
67enum {
68    kMaxIndicesToCheck = 32, // used when enumerating supported formats and profiles
69};
70
71// OMX errors are directly mapped into status_t range if
72// there is no corresponding MediaError status code.
73// Use the statusFromOMXError(int32_t omxError) function.
74//
75// Currently this is a direct map.
76// See frameworks/native/include/media/openmax/OMX_Core.h
77//
78// Vendor OMX errors     from 0x90000000 - 0x9000FFFF
79// Extension OMX errors  from 0x8F000000 - 0x90000000
80// Standard OMX errors   from 0x80001000 - 0x80001024 (0x80001024 current)
81//
82
83// returns true if err is a recognized OMX error code.
84// as OMX error is OMX_S32, this is an int32_t type
85static inline bool isOMXError(int32_t err) {
86    return (ERROR_CODEC_MIN <= err && err <= ERROR_CODEC_MAX);
87}
88
89// converts an OMX error to a status_t
90static inline status_t statusFromOMXError(int32_t omxError) {
91    switch (omxError) {
92    case OMX_ErrorInvalidComponentName:
93    case OMX_ErrorComponentNotFound:
94        return NAME_NOT_FOUND; // can trigger illegal argument error for provided names.
95    default:
96        return isOMXError(omxError) ? omxError : 0; // no translation required
97    }
98}
99
100static inline status_t statusFromBinderStatus(const Status &status) {
101    if (status.isOk()) {
102        return OK;
103    }
104    status_t err;
105    if ((err = status.serviceSpecificErrorCode()) != OK) {
106        return err;
107    }
108    if ((err = status.transactionError()) != OK) {
109        return err;
110    }
111    // Other exception
112    return UNKNOWN_ERROR;
113}
114
115// checks and converts status_t to a non-side-effect status_t
116static inline status_t makeNoSideEffectStatus(status_t err) {
117    switch (err) {
118    // the following errors have side effects and may come
119    // from other code modules. Remap for safety reasons.
120    case INVALID_OPERATION:
121    case DEAD_OBJECT:
122        return UNKNOWN_ERROR;
123    default:
124        return err;
125    }
126}
127
128static OMX_VIDEO_CONTROLRATETYPE getVideoBitrateMode(const sp<AMessage> &msg) {
129    int32_t tmp;
130    if (msg->findInt32("bitrate-mode", &tmp)) {
131        // explicitly translate from MediaCodecInfo.EncoderCapabilities.
132        // BITRATE_MODE_* into OMX bitrate mode.
133        switch (tmp) {
134            //BITRATE_MODE_CQ
135            case 0: return OMX_Video_ControlRateConstantQuality;
136            //BITRATE_MODE_VBR
137            case 1: return OMX_Video_ControlRateVariable;
138            //BITRATE_MODE_CBR
139            case 2: return OMX_Video_ControlRateConstant;
140            default: break;
141        }
142    }
143    return OMX_Video_ControlRateVariable;
144}
145
146static bool findVideoBitrateControlInfo(const sp<AMessage> &msg,
147        OMX_VIDEO_CONTROLRATETYPE *mode, int32_t *bitrate, int32_t *quality) {
148    *mode = getVideoBitrateMode(msg);
149    bool isCQ = (*mode == OMX_Video_ControlRateConstantQuality);
150    return (!isCQ && msg->findInt32("bitrate", bitrate))
151         || (isCQ && msg->findInt32("quality", quality));
152}
153
154struct MessageList : public RefBase {
155    MessageList() {
156    }
157    virtual ~MessageList() {
158    }
159    std::list<sp<AMessage> > &getList() { return mList; }
160private:
161    std::list<sp<AMessage> > mList;
162
163    DISALLOW_EVIL_CONSTRUCTORS(MessageList);
164};
165
166static sp<DataConverter> getCopyConverter() {
167    static pthread_once_t once = PTHREAD_ONCE_INIT; // const-inited
168    static sp<DataConverter> sCopyConverter;        // zero-inited
169    pthread_once(&once, [](){ sCopyConverter = new DataConverter(); });
170    return sCopyConverter;
171}
172
173struct CodecObserver : public BnOMXObserver {
174    CodecObserver() {}
175
176    void setNotificationMessage(const sp<AMessage> &msg) {
177        mNotify = msg;
178    }
179
180    // from IOMXObserver
181    virtual void onMessages(const std::list<omx_message> &messages) {
182        if (messages.empty()) {
183            return;
184        }
185
186        sp<AMessage> notify = mNotify->dup();
187        sp<MessageList> msgList = new MessageList();
188        for (std::list<omx_message>::const_iterator it = messages.cbegin();
189              it != messages.cend(); ++it) {
190            const omx_message &omx_msg = *it;
191
192            sp<AMessage> msg = new AMessage;
193            msg->setInt32("type", omx_msg.type);
194            switch (omx_msg.type) {
195                case omx_message::EVENT:
196                {
197                    msg->setInt32("event", omx_msg.u.event_data.event);
198                    msg->setInt32("data1", omx_msg.u.event_data.data1);
199                    msg->setInt32("data2", omx_msg.u.event_data.data2);
200                    break;
201                }
202
203                case omx_message::EMPTY_BUFFER_DONE:
204                {
205                    msg->setInt32("buffer", omx_msg.u.buffer_data.buffer);
206                    msg->setInt32("fence_fd", omx_msg.fenceFd);
207                    break;
208                }
209
210                case omx_message::FILL_BUFFER_DONE:
211                {
212                    msg->setInt32(
213                            "buffer", omx_msg.u.extended_buffer_data.buffer);
214                    msg->setInt32(
215                            "range_offset",
216                            omx_msg.u.extended_buffer_data.range_offset);
217                    msg->setInt32(
218                            "range_length",
219                            omx_msg.u.extended_buffer_data.range_length);
220                    msg->setInt32(
221                            "flags",
222                            omx_msg.u.extended_buffer_data.flags);
223                    msg->setInt64(
224                            "timestamp",
225                            omx_msg.u.extended_buffer_data.timestamp);
226                    msg->setInt32(
227                            "fence_fd", omx_msg.fenceFd);
228                    break;
229                }
230
231                case omx_message::FRAME_RENDERED:
232                {
233                    msg->setInt64(
234                            "media_time_us", omx_msg.u.render_data.timestamp);
235                    msg->setInt64(
236                            "system_nano", omx_msg.u.render_data.nanoTime);
237                    break;
238                }
239
240                default:
241                    ALOGE("Unrecognized message type: %d", omx_msg.type);
242                    break;
243            }
244            msgList->getList().push_back(msg);
245        }
246        notify->setObject("messages", msgList);
247        notify->post();
248    }
249
250protected:
251    virtual ~CodecObserver() {}
252
253private:
254    sp<AMessage> mNotify;
255
256    DISALLOW_EVIL_CONSTRUCTORS(CodecObserver);
257};
258
259////////////////////////////////////////////////////////////////////////////////
260
261struct ACodec::BaseState : public AState {
262    explicit BaseState(ACodec *codec, const sp<AState> &parentState = NULL);
263
264protected:
265    enum PortMode {
266        KEEP_BUFFERS,
267        RESUBMIT_BUFFERS,
268        FREE_BUFFERS,
269    };
270
271    ACodec *mCodec;
272
273    virtual PortMode getPortMode(OMX_U32 portIndex);
274
275    virtual void stateExited();
276    virtual bool onMessageReceived(const sp<AMessage> &msg);
277
278    virtual bool onOMXEvent(OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2);
279
280    virtual void onOutputBufferDrained(const sp<AMessage> &msg);
281    virtual void onInputBufferFilled(const sp<AMessage> &msg);
282
283    void postFillThisBuffer(BufferInfo *info);
284
285private:
286    // Handles an OMX message. Returns true iff message was handled.
287    bool onOMXMessage(const sp<AMessage> &msg);
288
289    // Handles a list of messages. Returns true iff messages were handled.
290    bool onOMXMessageList(const sp<AMessage> &msg);
291
292    // returns true iff this message is for this component and the component is alive
293    bool checkOMXMessage(const sp<AMessage> &msg);
294
295    bool onOMXEmptyBufferDone(IOMX::buffer_id bufferID, int fenceFd);
296
297    bool onOMXFillBufferDone(
298            IOMX::buffer_id bufferID,
299            size_t rangeOffset, size_t rangeLength,
300            OMX_U32 flags,
301            int64_t timeUs,
302            int fenceFd);
303
304    virtual bool onOMXFrameRendered(int64_t mediaTimeUs, nsecs_t systemNano);
305
306    void getMoreInputDataIfPossible();
307
308    DISALLOW_EVIL_CONSTRUCTORS(BaseState);
309};
310
311////////////////////////////////////////////////////////////////////////////////
312
313struct ACodec::DeathNotifier :
314        public IBinder::DeathRecipient,
315        public ::android::hardware::hidl_death_recipient {
316    explicit DeathNotifier(const sp<AMessage> &notify)
317        : mNotify(notify) {
318    }
319
320    virtual void binderDied(const wp<IBinder> &) {
321        mNotify->post();
322    }
323
324    virtual void serviceDied(
325            uint64_t /* cookie */,
326            const wp<::android::hidl::base::V1_0::IBase>& /* who */) {
327        mNotify->post();
328    }
329
330protected:
331    virtual ~DeathNotifier() {}
332
333private:
334    sp<AMessage> mNotify;
335
336    DISALLOW_EVIL_CONSTRUCTORS(DeathNotifier);
337};
338
339struct ACodec::UninitializedState : public ACodec::BaseState {
340    explicit UninitializedState(ACodec *codec);
341
342protected:
343    virtual bool onMessageReceived(const sp<AMessage> &msg);
344    virtual void stateEntered();
345
346private:
347    void onSetup(const sp<AMessage> &msg);
348    bool onAllocateComponent(const sp<AMessage> &msg);
349
350    sp<DeathNotifier> mDeathNotifier;
351
352    DISALLOW_EVIL_CONSTRUCTORS(UninitializedState);
353};
354
355////////////////////////////////////////////////////////////////////////////////
356
357struct ACodec::LoadedState : public ACodec::BaseState {
358    explicit LoadedState(ACodec *codec);
359
360protected:
361    virtual bool onMessageReceived(const sp<AMessage> &msg);
362    virtual void stateEntered();
363
364private:
365    friend struct ACodec::UninitializedState;
366
367    bool onConfigureComponent(const sp<AMessage> &msg);
368    void onCreateInputSurface(const sp<AMessage> &msg);
369    void onSetInputSurface(const sp<AMessage> &msg);
370    void onStart();
371    void onShutdown(bool keepComponentAllocated);
372
373    status_t setupInputSurface();
374
375    DISALLOW_EVIL_CONSTRUCTORS(LoadedState);
376};
377
378////////////////////////////////////////////////////////////////////////////////
379
380struct ACodec::LoadedToIdleState : public ACodec::BaseState {
381    explicit LoadedToIdleState(ACodec *codec);
382
383protected:
384    virtual bool onMessageReceived(const sp<AMessage> &msg);
385    virtual bool onOMXEvent(OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2);
386    virtual void stateEntered();
387
388private:
389    status_t allocateBuffers();
390
391    DISALLOW_EVIL_CONSTRUCTORS(LoadedToIdleState);
392};
393
394////////////////////////////////////////////////////////////////////////////////
395
396struct ACodec::IdleToExecutingState : public ACodec::BaseState {
397    explicit IdleToExecutingState(ACodec *codec);
398
399protected:
400    virtual bool onMessageReceived(const sp<AMessage> &msg);
401    virtual bool onOMXEvent(OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2);
402    virtual void stateEntered();
403
404private:
405    DISALLOW_EVIL_CONSTRUCTORS(IdleToExecutingState);
406};
407
408////////////////////////////////////////////////////////////////////////////////
409
410struct ACodec::ExecutingState : public ACodec::BaseState {
411    explicit ExecutingState(ACodec *codec);
412
413    void submitRegularOutputBuffers();
414    void submitOutputMetaBuffers();
415    void submitOutputBuffers();
416
417    // Submit output buffers to the decoder, submit input buffers to client
418    // to fill with data.
419    void resume();
420
421    // Returns true iff input and output buffers are in play.
422    bool active() const { return mActive; }
423
424protected:
425    virtual PortMode getPortMode(OMX_U32 portIndex);
426    virtual bool onMessageReceived(const sp<AMessage> &msg);
427    virtual void stateEntered();
428
429    virtual bool onOMXEvent(OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2);
430    virtual bool onOMXFrameRendered(int64_t mediaTimeUs, nsecs_t systemNano);
431
432private:
433    bool mActive;
434
435    DISALLOW_EVIL_CONSTRUCTORS(ExecutingState);
436};
437
438////////////////////////////////////////////////////////////////////////////////
439
440struct ACodec::OutputPortSettingsChangedState : public ACodec::BaseState {
441    explicit OutputPortSettingsChangedState(ACodec *codec);
442
443protected:
444    virtual PortMode getPortMode(OMX_U32 portIndex);
445    virtual bool onMessageReceived(const sp<AMessage> &msg);
446    virtual void stateEntered();
447
448    virtual bool onOMXEvent(OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2);
449    virtual bool onOMXFrameRendered(int64_t mediaTimeUs, nsecs_t systemNano);
450
451private:
452    DISALLOW_EVIL_CONSTRUCTORS(OutputPortSettingsChangedState);
453};
454
455////////////////////////////////////////////////////////////////////////////////
456
457struct ACodec::ExecutingToIdleState : public ACodec::BaseState {
458    explicit ExecutingToIdleState(ACodec *codec);
459
460protected:
461    virtual bool onMessageReceived(const sp<AMessage> &msg);
462    virtual void stateEntered();
463
464    virtual bool onOMXEvent(OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2);
465
466    virtual void onOutputBufferDrained(const sp<AMessage> &msg);
467    virtual void onInputBufferFilled(const sp<AMessage> &msg);
468
469private:
470    void changeStateIfWeOwnAllBuffers();
471
472    bool mComponentNowIdle;
473
474    DISALLOW_EVIL_CONSTRUCTORS(ExecutingToIdleState);
475};
476
477////////////////////////////////////////////////////////////////////////////////
478
479struct ACodec::IdleToLoadedState : public ACodec::BaseState {
480    explicit IdleToLoadedState(ACodec *codec);
481
482protected:
483    virtual bool onMessageReceived(const sp<AMessage> &msg);
484    virtual void stateEntered();
485
486    virtual bool onOMXEvent(OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2);
487
488private:
489    DISALLOW_EVIL_CONSTRUCTORS(IdleToLoadedState);
490};
491
492////////////////////////////////////////////////////////////////////////////////
493
494struct ACodec::FlushingState : public ACodec::BaseState {
495    explicit FlushingState(ACodec *codec);
496
497protected:
498    virtual bool onMessageReceived(const sp<AMessage> &msg);
499    virtual void stateEntered();
500
501    virtual bool onOMXEvent(OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2);
502
503    virtual void onOutputBufferDrained(const sp<AMessage> &msg);
504    virtual void onInputBufferFilled(const sp<AMessage> &msg);
505
506private:
507    bool mFlushComplete[2];
508
509    void changeStateIfWeOwnAllBuffers();
510
511    DISALLOW_EVIL_CONSTRUCTORS(FlushingState);
512};
513
514////////////////////////////////////////////////////////////////////////////////
515
516void ACodec::BufferInfo::setWriteFence(int fenceFd, const char *dbg) {
517    if (mFenceFd >= 0) {
518        ALOGW("OVERWRITE OF %s fence %d by write fence %d in %s",
519                mIsReadFence ? "read" : "write", mFenceFd, fenceFd, dbg);
520    }
521    mFenceFd = fenceFd;
522    mIsReadFence = false;
523}
524
525void ACodec::BufferInfo::setReadFence(int fenceFd, const char *dbg) {
526    if (mFenceFd >= 0) {
527        ALOGW("OVERWRITE OF %s fence %d by read fence %d in %s",
528                mIsReadFence ? "read" : "write", mFenceFd, fenceFd, dbg);
529    }
530    mFenceFd = fenceFd;
531    mIsReadFence = true;
532}
533
534void ACodec::BufferInfo::checkWriteFence(const char *dbg) {
535    if (mFenceFd >= 0 && mIsReadFence) {
536        ALOGD("REUSING read fence %d as write fence in %s", mFenceFd, dbg);
537    }
538}
539
540void ACodec::BufferInfo::checkReadFence(const char *dbg) {
541    if (mFenceFd >= 0 && !mIsReadFence) {
542        ALOGD("REUSING write fence %d as read fence in %s", mFenceFd, dbg);
543    }
544}
545
546////////////////////////////////////////////////////////////////////////////////
547
548ACodec::ACodec()
549    : mSampleRate(0),
550      mNodeGeneration(0),
551      mUsingNativeWindow(false),
552      mNativeWindowUsageBits(0),
553      mLastNativeWindowDataSpace(HAL_DATASPACE_UNKNOWN),
554      mIsVideo(false),
555      mIsEncoder(false),
556      mFatalError(false),
557      mShutdownInProgress(false),
558      mExplicitShutdown(false),
559      mIsLegacyVP9Decoder(false),
560      mEncoderDelay(0),
561      mEncoderPadding(0),
562      mRotationDegrees(0),
563      mChannelMaskPresent(false),
564      mChannelMask(0),
565      mDequeueCounter(0),
566      mMetadataBuffersToSubmit(0),
567      mNumUndequeuedBuffers(0),
568      mRepeatFrameDelayUs(-1ll),
569      mMaxPtsGapUs(-1ll),
570      mMaxFps(-1),
571      mFps(-1.0),
572      mCaptureFps(-1.0),
573      mCreateInputBuffersSuspended(false),
574      mLatency(0),
575      mTunneled(false),
576      mDescribeColorAspectsIndex((OMX_INDEXTYPE)0),
577      mDescribeHDRStaticInfoIndex((OMX_INDEXTYPE)0),
578      mStateGeneration(0),
579      mVendorExtensionsStatus(kExtensionsUnchecked) {
580    memset(&mLastHDRStaticInfo, 0, sizeof(mLastHDRStaticInfo));
581
582    mUninitializedState = new UninitializedState(this);
583    mLoadedState = new LoadedState(this);
584    mLoadedToIdleState = new LoadedToIdleState(this);
585    mIdleToExecutingState = new IdleToExecutingState(this);
586    mExecutingState = new ExecutingState(this);
587
588    mOutputPortSettingsChangedState =
589        new OutputPortSettingsChangedState(this);
590
591    mExecutingToIdleState = new ExecutingToIdleState(this);
592    mIdleToLoadedState = new IdleToLoadedState(this);
593    mFlushingState = new FlushingState(this);
594
595    mPortEOS[kPortIndexInput] = mPortEOS[kPortIndexOutput] = false;
596    mInputEOSResult = OK;
597
598    mPortMode[kPortIndexInput] = IOMX::kPortModePresetByteBuffer;
599    mPortMode[kPortIndexOutput] = IOMX::kPortModePresetByteBuffer;
600
601    memset(&mLastNativeWindowCrop, 0, sizeof(mLastNativeWindowCrop));
602
603    changeState(mUninitializedState);
604}
605
606ACodec::~ACodec() {
607}
608
609void ACodec::initiateSetup(const sp<AMessage> &msg) {
610    msg->setWhat(kWhatSetup);
611    msg->setTarget(this);
612    msg->post();
613}
614
615std::shared_ptr<BufferChannelBase> ACodec::getBufferChannel() {
616    if (!mBufferChannel) {
617        mBufferChannel = std::make_shared<ACodecBufferChannel>(
618                new AMessage(kWhatInputBufferFilled, this),
619                new AMessage(kWhatOutputBufferDrained, this));
620    }
621    return mBufferChannel;
622}
623
624void ACodec::signalSetParameters(const sp<AMessage> &params) {
625    sp<AMessage> msg = new AMessage(kWhatSetParameters, this);
626    msg->setMessage("params", params);
627    msg->post();
628}
629
630void ACodec::initiateAllocateComponent(const sp<AMessage> &msg) {
631    msg->setWhat(kWhatAllocateComponent);
632    msg->setTarget(this);
633    msg->post();
634}
635
636void ACodec::initiateConfigureComponent(const sp<AMessage> &msg) {
637    msg->setWhat(kWhatConfigureComponent);
638    msg->setTarget(this);
639    msg->post();
640}
641
642status_t ACodec::setSurface(const sp<Surface> &surface) {
643    sp<AMessage> msg = new AMessage(kWhatSetSurface, this);
644    msg->setObject("surface", surface);
645
646    sp<AMessage> response;
647    status_t err = msg->postAndAwaitResponse(&response);
648
649    if (err == OK) {
650        (void)response->findInt32("err", &err);
651    }
652    return err;
653}
654
655void ACodec::initiateCreateInputSurface() {
656    (new AMessage(kWhatCreateInputSurface, this))->post();
657}
658
659void ACodec::initiateSetInputSurface(
660        const sp<PersistentSurface> &surface) {
661    sp<AMessage> msg = new AMessage(kWhatSetInputSurface, this);
662    msg->setObject("input-surface", surface);
663    msg->post();
664}
665
666void ACodec::signalEndOfInputStream() {
667    (new AMessage(kWhatSignalEndOfInputStream, this))->post();
668}
669
670void ACodec::initiateStart() {
671    (new AMessage(kWhatStart, this))->post();
672}
673
674void ACodec::signalFlush() {
675    ALOGV("[%s] signalFlush", mComponentName.c_str());
676    (new AMessage(kWhatFlush, this))->post();
677}
678
679void ACodec::signalResume() {
680    (new AMessage(kWhatResume, this))->post();
681}
682
683void ACodec::initiateShutdown(bool keepComponentAllocated) {
684    sp<AMessage> msg = new AMessage(kWhatShutdown, this);
685    msg->setInt32("keepComponentAllocated", keepComponentAllocated);
686    msg->post();
687    if (!keepComponentAllocated) {
688        // ensure shutdown completes in 3 seconds
689        (new AMessage(kWhatReleaseCodecInstance, this))->post(3000000);
690    }
691}
692
693void ACodec::signalRequestIDRFrame() {
694    (new AMessage(kWhatRequestIDRFrame, this))->post();
695}
696
697// *** NOTE: THE FOLLOWING WORKAROUND WILL BE REMOVED ***
698// Some codecs may return input buffers before having them processed.
699// This causes a halt if we already signaled an EOS on the input
700// port.  For now keep submitting an output buffer if there was an
701// EOS on the input port, but not yet on the output port.
702void ACodec::signalSubmitOutputMetadataBufferIfEOS_workaround() {
703    if (mPortEOS[kPortIndexInput] && !mPortEOS[kPortIndexOutput] &&
704            mMetadataBuffersToSubmit > 0) {
705        (new AMessage(kWhatSubmitOutputMetadataBufferIfEOS, this))->post();
706    }
707}
708
709status_t ACodec::handleSetSurface(const sp<Surface> &surface) {
710    // allow keeping unset surface
711    if (surface == NULL) {
712        if (mNativeWindow != NULL) {
713            ALOGW("cannot unset a surface");
714            return INVALID_OPERATION;
715        }
716        return OK;
717    }
718
719    // cannot switch from bytebuffers to surface
720    if (mNativeWindow == NULL) {
721        ALOGW("component was not configured with a surface");
722        return INVALID_OPERATION;
723    }
724
725    ANativeWindow *nativeWindow = surface.get();
726    // if we have not yet started the codec, we can simply set the native window
727    if (mBuffers[kPortIndexInput].size() == 0) {
728        mNativeWindow = surface;
729        return OK;
730    }
731
732    // we do not support changing a tunneled surface after start
733    if (mTunneled) {
734        ALOGW("cannot change tunneled surface");
735        return INVALID_OPERATION;
736    }
737
738    int usageBits = 0;
739    // no need to reconnect as we will not dequeue all buffers
740    status_t err = setupNativeWindowSizeFormatAndUsage(
741            nativeWindow, &usageBits, !storingMetadataInDecodedBuffers());
742    if (err != OK) {
743        return err;
744    }
745
746    int ignoredFlags = kVideoGrallocUsage;
747    // New output surface is not allowed to add new usage flag except ignored ones.
748    if ((usageBits & ~(mNativeWindowUsageBits | ignoredFlags)) != 0) {
749        ALOGW("cannot change usage from %#x to %#x", mNativeWindowUsageBits, usageBits);
750        return BAD_VALUE;
751    }
752
753    // get min undequeued count. We cannot switch to a surface that has a higher
754    // undequeued count than we allocated.
755    int minUndequeuedBuffers = 0;
756    err = nativeWindow->query(
757            nativeWindow, NATIVE_WINDOW_MIN_UNDEQUEUED_BUFFERS,
758            &minUndequeuedBuffers);
759    if (err != 0) {
760        ALOGE("NATIVE_WINDOW_MIN_UNDEQUEUED_BUFFERS query failed: %s (%d)",
761                strerror(-err), -err);
762        return err;
763    }
764    if (minUndequeuedBuffers > (int)mNumUndequeuedBuffers) {
765        ALOGE("new surface holds onto more buffers (%d) than planned for (%zu)",
766                minUndequeuedBuffers, mNumUndequeuedBuffers);
767        return BAD_VALUE;
768    }
769
770    // we cannot change the number of output buffers while OMX is running
771    // set up surface to the same count
772    Vector<BufferInfo> &buffers = mBuffers[kPortIndexOutput];
773    ALOGV("setting up surface for %zu buffers", buffers.size());
774
775    err = native_window_set_buffer_count(nativeWindow, buffers.size());
776    if (err != 0) {
777        ALOGE("native_window_set_buffer_count failed: %s (%d)", strerror(-err),
778                -err);
779        return err;
780    }
781
782    // need to enable allocation when attaching
783    surface->getIGraphicBufferProducer()->allowAllocation(true);
784
785    // for meta data mode, we move dequeud buffers to the new surface.
786    // for non-meta mode, we must move all registered buffers
787    for (size_t i = 0; i < buffers.size(); ++i) {
788        const BufferInfo &info = buffers[i];
789        // skip undequeued buffers for meta data mode
790        if (storingMetadataInDecodedBuffers()
791                && info.mStatus == BufferInfo::OWNED_BY_NATIVE_WINDOW) {
792            ALOGV("skipping buffer");
793            continue;
794        }
795        ALOGV("attaching buffer %p", info.mGraphicBuffer->getNativeBuffer());
796
797        err = surface->attachBuffer(info.mGraphicBuffer->getNativeBuffer());
798        if (err != OK) {
799            ALOGE("failed to attach buffer %p to the new surface: %s (%d)",
800                    info.mGraphicBuffer->getNativeBuffer(),
801                    strerror(-err), -err);
802            return err;
803        }
804    }
805
806    // cancel undequeued buffers to new surface
807    if (!storingMetadataInDecodedBuffers()) {
808        for (size_t i = 0; i < buffers.size(); ++i) {
809            BufferInfo &info = buffers.editItemAt(i);
810            if (info.mStatus == BufferInfo::OWNED_BY_NATIVE_WINDOW) {
811                ALOGV("canceling buffer %p", info.mGraphicBuffer->getNativeBuffer());
812                err = nativeWindow->cancelBuffer(
813                        nativeWindow, info.mGraphicBuffer->getNativeBuffer(), info.mFenceFd);
814                info.mFenceFd = -1;
815                if (err != OK) {
816                    ALOGE("failed to cancel buffer %p to the new surface: %s (%d)",
817                            info.mGraphicBuffer->getNativeBuffer(),
818                            strerror(-err), -err);
819                    return err;
820                }
821            }
822        }
823        // disallow further allocation
824        (void)surface->getIGraphicBufferProducer()->allowAllocation(false);
825    }
826
827    // push blank buffers to previous window if requested
828    if (mFlags & kFlagPushBlankBuffersToNativeWindowOnShutdown) {
829        pushBlankBuffersToNativeWindow(mNativeWindow.get());
830    }
831
832    mNativeWindow = nativeWindow;
833    mNativeWindowUsageBits = usageBits;
834    return OK;
835}
836
837status_t ACodec::setPortMode(int32_t portIndex, IOMX::PortMode mode) {
838    status_t err = mOMXNode->setPortMode(portIndex, mode);
839    if (err != OK) {
840        ALOGE("[%s] setPortMode on %s to %s failed w/ err %d",
841                mComponentName.c_str(),
842                portIndex == kPortIndexInput ? "input" : "output",
843                asString(mode),
844                err);
845        return err;
846    }
847
848    mPortMode[portIndex] = mode;
849    return OK;
850}
851
852status_t ACodec::allocateBuffersOnPort(OMX_U32 portIndex) {
853    CHECK(portIndex == kPortIndexInput || portIndex == kPortIndexOutput);
854
855    CHECK(mAllocator[portIndex] == NULL);
856    CHECK(mBuffers[portIndex].isEmpty());
857
858    status_t err;
859    if (mNativeWindow != NULL && portIndex == kPortIndexOutput) {
860        if (storingMetadataInDecodedBuffers()) {
861            err = allocateOutputMetadataBuffers();
862        } else {
863            err = allocateOutputBuffersFromNativeWindow();
864        }
865    } else {
866        OMX_PARAM_PORTDEFINITIONTYPE def;
867        InitOMXParams(&def);
868        def.nPortIndex = portIndex;
869
870        err = mOMXNode->getParameter(
871                OMX_IndexParamPortDefinition, &def, sizeof(def));
872
873        if (err == OK) {
874            const IOMX::PortMode &mode = mPortMode[portIndex];
875            size_t bufSize = def.nBufferSize;
876            // Always allocate VideoNativeMetadata if using ANWBuffer.
877            // OMX might use gralloc source internally, but we don't share
878            // metadata buffer with OMX, OMX has its own headers.
879            if (mode == IOMX::kPortModeDynamicANWBuffer) {
880                bufSize = sizeof(VideoNativeMetadata);
881            } else if (mode == IOMX::kPortModeDynamicNativeHandle) {
882                bufSize = sizeof(VideoNativeHandleMetadata);
883            }
884
885            size_t conversionBufferSize = 0;
886
887            sp<DataConverter> converter = mConverter[portIndex];
888            if (converter != NULL) {
889                // here we assume sane conversions of max 4:1, so result fits in int32
890                if (portIndex == kPortIndexInput) {
891                    conversionBufferSize = converter->sourceSize(bufSize);
892                } else {
893                    conversionBufferSize = converter->targetSize(bufSize);
894                }
895            }
896
897            size_t alignment = 32; // This is the value currently returned by
898                                   // MemoryDealer::getAllocationAlignment().
899                                   // TODO: Fix this when Treble has
900                                   // MemoryHeap/MemoryDealer.
901
902            ALOGV("[%s] Allocating %u buffers of size %zu (from %u using %s) on %s port",
903                    mComponentName.c_str(),
904                    def.nBufferCountActual, bufSize, def.nBufferSize, asString(mode),
905                    portIndex == kPortIndexInput ? "input" : "output");
906
907            // verify buffer sizes to avoid overflow in align()
908            if (bufSize == 0 || max(bufSize, conversionBufferSize) > kMaxCodecBufferSize) {
909                ALOGE("b/22885421");
910                return NO_MEMORY;
911            }
912
913            // don't modify bufSize as OMX may not expect it to increase after negotiation
914            size_t alignedSize = align(bufSize, alignment);
915            size_t alignedConvSize = align(conversionBufferSize, alignment);
916            if (def.nBufferCountActual > SIZE_MAX / (alignedSize + alignedConvSize)) {
917                ALOGE("b/22885421");
918                return NO_MEMORY;
919            }
920
921            if (mode != IOMX::kPortModePresetSecureBuffer) {
922                mAllocator[portIndex] = TAllocator::getService("ashmem");
923                if (mAllocator[portIndex] == nullptr) {
924                    ALOGE("hidl allocator on port %d is null",
925                            (int)portIndex);
926                    return NO_MEMORY;
927                }
928                // TODO: When Treble has MemoryHeap/MemoryDealer, we should
929                // specify the heap size to be
930                // def.nBufferCountActual * (alignedSize + alignedConvSize).
931            }
932
933            const sp<AMessage> &format =
934                    portIndex == kPortIndexInput ? mInputFormat : mOutputFormat;
935            for (OMX_U32 i = 0; i < def.nBufferCountActual && err == OK; ++i) {
936                hidl_memory hidlMemToken;
937                sp<TMemory> hidlMem;
938                sp<IMemory> mem;
939
940                BufferInfo info;
941                info.mStatus = BufferInfo::OWNED_BY_US;
942                info.mFenceFd = -1;
943                info.mRenderInfo = NULL;
944                info.mGraphicBuffer = NULL;
945                info.mNewGraphicBuffer = false;
946
947                if (mode == IOMX::kPortModePresetSecureBuffer) {
948                    void *ptr = NULL;
949                    sp<NativeHandle> native_handle;
950                    err = mOMXNode->allocateSecureBuffer(
951                            portIndex, bufSize, &info.mBufferID,
952                            &ptr, &native_handle);
953
954                    info.mData = (native_handle == NULL)
955                            ? new SecureBuffer(format, ptr, bufSize)
956                            : new SecureBuffer(format, native_handle, bufSize);
957                    info.mCodecData = info.mData;
958                } else {
959                    bool success;
960                    auto transStatus = mAllocator[portIndex]->allocate(
961                            bufSize,
962                            [&success, &hidlMemToken](
963                                    bool s,
964                                    hidl_memory const& m) {
965                                success = s;
966                                hidlMemToken = m;
967                            });
968
969                    if (!transStatus.isOk()) {
970                        ALOGE("hidl's AshmemAllocator failed at the "
971                                "transport: %s",
972                                transStatus.description().c_str());
973                        return NO_MEMORY;
974                    }
975                    if (!success) {
976                        return NO_MEMORY;
977                    }
978                    hidlMem = mapMemory(hidlMemToken);
979                    if (hidlMem == nullptr) {
980                        return NO_MEMORY;
981                    }
982                    err = mOMXNode->useBuffer(
983                            portIndex, hidlMemToken, &info.mBufferID);
984
985                    if (mode == IOMX::kPortModeDynamicANWBuffer) {
986                        VideoNativeMetadata* metaData = (VideoNativeMetadata*)(
987                                (void*)hidlMem->getPointer());
988                        metaData->nFenceFd = -1;
989                    }
990
991                    info.mCodecData = new SharedMemoryBuffer(
992                            format, hidlMem);
993                    info.mCodecRef = hidlMem;
994
995                    // if we require conversion, allocate conversion buffer for client use;
996                    // otherwise, reuse codec buffer
997                    if (mConverter[portIndex] != NULL) {
998                        CHECK_GT(conversionBufferSize, (size_t)0);
999                        bool success;
1000                        mAllocator[portIndex]->allocate(
1001                                conversionBufferSize,
1002                                [&success, &hidlMemToken](
1003                                        bool s,
1004                                        hidl_memory const& m) {
1005                                    success = s;
1006                                    hidlMemToken = m;
1007                                });
1008                        if (!success) {
1009                            return NO_MEMORY;
1010                        }
1011                        hidlMem = mapMemory(hidlMemToken);
1012                        if (hidlMem == nullptr) {
1013                            return NO_MEMORY;
1014                        }
1015                        info.mData = new SharedMemoryBuffer(format, hidlMem);
1016                        info.mMemRef = hidlMem;
1017                    } else {
1018                        info.mData = info.mCodecData;
1019                        info.mMemRef = info.mCodecRef;
1020                    }
1021                }
1022
1023                mBuffers[portIndex].push(info);
1024            }
1025        }
1026    }
1027
1028    if (err != OK) {
1029        return err;
1030    }
1031
1032    std::vector<ACodecBufferChannel::BufferAndId> array(mBuffers[portIndex].size());
1033    for (size_t i = 0; i < mBuffers[portIndex].size(); ++i) {
1034        array[i] = {mBuffers[portIndex][i].mData, mBuffers[portIndex][i].mBufferID};
1035    }
1036    if (portIndex == kPortIndexInput) {
1037        mBufferChannel->setInputBufferArray(array);
1038    } else if (portIndex == kPortIndexOutput) {
1039        mBufferChannel->setOutputBufferArray(array);
1040    } else {
1041        TRESPASS();
1042    }
1043
1044    return OK;
1045}
1046
1047status_t ACodec::setupNativeWindowSizeFormatAndUsage(
1048        ANativeWindow *nativeWindow /* nonnull */, int *finalUsage /* nonnull */,
1049        bool reconnect) {
1050    OMX_PARAM_PORTDEFINITIONTYPE def;
1051    InitOMXParams(&def);
1052    def.nPortIndex = kPortIndexOutput;
1053
1054    status_t err = mOMXNode->getParameter(
1055            OMX_IndexParamPortDefinition, &def, sizeof(def));
1056
1057    if (err != OK) {
1058        return err;
1059    }
1060
1061    OMX_INDEXTYPE index;
1062    err = mOMXNode->getExtensionIndex(
1063            "OMX.google.android.index.AndroidNativeBufferConsumerUsage",
1064            &index);
1065
1066    if (err != OK) {
1067        // allow failure
1068        err = OK;
1069    } else {
1070        int usageBits = 0;
1071        if (nativeWindow->query(
1072                nativeWindow,
1073                NATIVE_WINDOW_CONSUMER_USAGE_BITS,
1074                &usageBits) == OK) {
1075            OMX_PARAM_U32TYPE params;
1076            InitOMXParams(&params);
1077            params.nPortIndex = kPortIndexOutput;
1078            params.nU32 = (OMX_U32)usageBits;
1079
1080            err = mOMXNode->setParameter(index, &params, sizeof(params));
1081
1082            if (err != OK) {
1083                ALOGE("Fail to set AndroidNativeBufferConsumerUsage: %d", err);
1084                return err;
1085            }
1086        }
1087    }
1088
1089    OMX_U32 usage = 0;
1090    err = mOMXNode->getGraphicBufferUsage(kPortIndexOutput, &usage);
1091    if (err != 0) {
1092        ALOGW("querying usage flags from OMX IL component failed: %d", err);
1093        // XXX: Currently this error is logged, but not fatal.
1094        usage = 0;
1095    }
1096    int omxUsage = usage;
1097
1098    if (mFlags & kFlagIsGrallocUsageProtected) {
1099        usage |= GRALLOC_USAGE_PROTECTED;
1100    }
1101
1102    usage |= kVideoGrallocUsage;
1103    *finalUsage = usage;
1104
1105    memset(&mLastNativeWindowCrop, 0, sizeof(mLastNativeWindowCrop));
1106    mLastNativeWindowDataSpace = HAL_DATASPACE_UNKNOWN;
1107
1108    ALOGV("gralloc usage: %#x(OMX) => %#x(ACodec)", omxUsage, usage);
1109    return setNativeWindowSizeFormatAndUsage(
1110            nativeWindow,
1111            def.format.video.nFrameWidth,
1112            def.format.video.nFrameHeight,
1113            def.format.video.eColorFormat,
1114            mRotationDegrees,
1115            usage,
1116            reconnect);
1117}
1118
1119status_t ACodec::configureOutputBuffersFromNativeWindow(
1120        OMX_U32 *bufferCount, OMX_U32 *bufferSize,
1121        OMX_U32 *minUndequeuedBuffers, bool preregister) {
1122
1123    OMX_PARAM_PORTDEFINITIONTYPE def;
1124    InitOMXParams(&def);
1125    def.nPortIndex = kPortIndexOutput;
1126
1127    status_t err = mOMXNode->getParameter(
1128            OMX_IndexParamPortDefinition, &def, sizeof(def));
1129
1130    if (err == OK) {
1131        err = setupNativeWindowSizeFormatAndUsage(
1132                mNativeWindow.get(), &mNativeWindowUsageBits,
1133                preregister && !mTunneled /* reconnect */);
1134    }
1135    if (err != OK) {
1136        mNativeWindowUsageBits = 0;
1137        return err;
1138    }
1139
1140    // Exits here for tunneled video playback codecs -- i.e. skips native window
1141    // buffer allocation step as this is managed by the tunneled OMX omponent
1142    // itself and explicitly sets def.nBufferCountActual to 0.
1143    if (mTunneled) {
1144        ALOGV("Tunneled Playback: skipping native window buffer allocation.");
1145        def.nBufferCountActual = 0;
1146        err = mOMXNode->setParameter(
1147                OMX_IndexParamPortDefinition, &def, sizeof(def));
1148
1149        *minUndequeuedBuffers = 0;
1150        *bufferCount = 0;
1151        *bufferSize = 0;
1152        return err;
1153    }
1154
1155    *minUndequeuedBuffers = 0;
1156    err = mNativeWindow->query(
1157            mNativeWindow.get(), NATIVE_WINDOW_MIN_UNDEQUEUED_BUFFERS,
1158            (int *)minUndequeuedBuffers);
1159
1160    if (err != 0) {
1161        ALOGE("NATIVE_WINDOW_MIN_UNDEQUEUED_BUFFERS query failed: %s (%d)",
1162                strerror(-err), -err);
1163        return err;
1164    }
1165
1166    // FIXME: assume that surface is controlled by app (native window
1167    // returns the number for the case when surface is not controlled by app)
1168    // FIXME2: This means that minUndeqeueudBufs can be 1 larger than reported
1169    // For now, try to allocate 1 more buffer, but don't fail if unsuccessful
1170
1171    // Use conservative allocation while also trying to reduce starvation
1172    //
1173    // 1. allocate at least nBufferCountMin + minUndequeuedBuffers - that is the
1174    //    minimum needed for the consumer to be able to work
1175    // 2. try to allocate two (2) additional buffers to reduce starvation from
1176    //    the consumer
1177    //    plus an extra buffer to account for incorrect minUndequeuedBufs
1178    for (OMX_U32 extraBuffers = 2 + 1; /* condition inside loop */; extraBuffers--) {
1179        OMX_U32 newBufferCount =
1180            def.nBufferCountMin + *minUndequeuedBuffers + extraBuffers;
1181        def.nBufferCountActual = newBufferCount;
1182        err = mOMXNode->setParameter(
1183                OMX_IndexParamPortDefinition, &def, sizeof(def));
1184
1185        if (err == OK) {
1186            *minUndequeuedBuffers += extraBuffers;
1187            break;
1188        }
1189
1190        ALOGW("[%s] setting nBufferCountActual to %u failed: %d",
1191                mComponentName.c_str(), newBufferCount, err);
1192        /* exit condition */
1193        if (extraBuffers == 0) {
1194            return err;
1195        }
1196    }
1197
1198    err = native_window_set_buffer_count(
1199            mNativeWindow.get(), def.nBufferCountActual);
1200
1201    if (err != 0) {
1202        ALOGE("native_window_set_buffer_count failed: %s (%d)", strerror(-err),
1203                -err);
1204        return err;
1205    }
1206
1207    *bufferCount = def.nBufferCountActual;
1208    *bufferSize =  def.nBufferSize;
1209    return err;
1210}
1211
1212status_t ACodec::allocateOutputBuffersFromNativeWindow() {
1213    // This method only handles the non-metadata mode (or simulating legacy
1214    // mode with metadata, which is transparent to ACodec).
1215    CHECK(!storingMetadataInDecodedBuffers());
1216
1217    OMX_U32 bufferCount, bufferSize, minUndequeuedBuffers;
1218    status_t err = configureOutputBuffersFromNativeWindow(
1219            &bufferCount, &bufferSize, &minUndequeuedBuffers, true /* preregister */);
1220    if (err != 0)
1221        return err;
1222    mNumUndequeuedBuffers = minUndequeuedBuffers;
1223
1224    static_cast<Surface*>(mNativeWindow.get())
1225            ->getIGraphicBufferProducer()->allowAllocation(true);
1226
1227    ALOGV("[%s] Allocating %u buffers from a native window of size %u on "
1228         "output port",
1229         mComponentName.c_str(), bufferCount, bufferSize);
1230
1231    // Dequeue buffers and send them to OMX
1232    for (OMX_U32 i = 0; i < bufferCount; i++) {
1233        ANativeWindowBuffer *buf;
1234        int fenceFd;
1235        err = mNativeWindow->dequeueBuffer(mNativeWindow.get(), &buf, &fenceFd);
1236        if (err != 0) {
1237            ALOGE("dequeueBuffer failed: %s (%d)", strerror(-err), -err);
1238            break;
1239        }
1240
1241        sp<GraphicBuffer> graphicBuffer(GraphicBuffer::from(buf));
1242        BufferInfo info;
1243        info.mStatus = BufferInfo::OWNED_BY_US;
1244        info.mFenceFd = fenceFd;
1245        info.mIsReadFence = false;
1246        info.mRenderInfo = NULL;
1247        info.mGraphicBuffer = graphicBuffer;
1248        info.mNewGraphicBuffer = false;
1249
1250        // TODO: We shouln't need to create MediaCodecBuffer. In metadata mode
1251        //       OMX doesn't use the shared memory buffer, but some code still
1252        //       access info.mData. Create an ABuffer as a placeholder.
1253        info.mData = new MediaCodecBuffer(mOutputFormat, new ABuffer(bufferSize));
1254        info.mCodecData = info.mData;
1255
1256        mBuffers[kPortIndexOutput].push(info);
1257
1258        IOMX::buffer_id bufferId;
1259        err = mOMXNode->useBuffer(kPortIndexOutput, graphicBuffer, &bufferId);
1260        if (err != 0) {
1261            ALOGE("registering GraphicBuffer %u with OMX IL component failed: "
1262                 "%d", i, err);
1263            break;
1264        }
1265
1266        mBuffers[kPortIndexOutput].editItemAt(i).mBufferID = bufferId;
1267
1268        ALOGV("[%s] Registered graphic buffer with ID %u (pointer = %p)",
1269             mComponentName.c_str(),
1270             bufferId, graphicBuffer.get());
1271    }
1272
1273    OMX_U32 cancelStart;
1274    OMX_U32 cancelEnd;
1275
1276    if (err != OK) {
1277        // If an error occurred while dequeuing we need to cancel any buffers
1278        // that were dequeued. Also cancel all if we're in legacy metadata mode.
1279        cancelStart = 0;
1280        cancelEnd = mBuffers[kPortIndexOutput].size();
1281    } else {
1282        // Return the required minimum undequeued buffers to the native window.
1283        cancelStart = bufferCount - minUndequeuedBuffers;
1284        cancelEnd = bufferCount;
1285    }
1286
1287    for (OMX_U32 i = cancelStart; i < cancelEnd; i++) {
1288        BufferInfo *info = &mBuffers[kPortIndexOutput].editItemAt(i);
1289        if (info->mStatus == BufferInfo::OWNED_BY_US) {
1290            status_t error = cancelBufferToNativeWindow(info);
1291            if (err == 0) {
1292                err = error;
1293            }
1294        }
1295    }
1296
1297    static_cast<Surface*>(mNativeWindow.get())
1298            ->getIGraphicBufferProducer()->allowAllocation(false);
1299
1300    return err;
1301}
1302
1303status_t ACodec::allocateOutputMetadataBuffers() {
1304    CHECK(storingMetadataInDecodedBuffers());
1305
1306    OMX_U32 bufferCount, bufferSize, minUndequeuedBuffers;
1307    status_t err = configureOutputBuffersFromNativeWindow(
1308            &bufferCount, &bufferSize, &minUndequeuedBuffers,
1309            false /* preregister */);
1310    if (err != OK)
1311        return err;
1312    mNumUndequeuedBuffers = minUndequeuedBuffers;
1313
1314    ALOGV("[%s] Allocating %u meta buffers on output port",
1315         mComponentName.c_str(), bufferCount);
1316
1317    for (OMX_U32 i = 0; i < bufferCount; i++) {
1318        BufferInfo info;
1319        info.mStatus = BufferInfo::OWNED_BY_NATIVE_WINDOW;
1320        info.mFenceFd = -1;
1321        info.mRenderInfo = NULL;
1322        info.mGraphicBuffer = NULL;
1323        info.mNewGraphicBuffer = false;
1324        info.mDequeuedAt = mDequeueCounter;
1325
1326        info.mData = new MediaCodecBuffer(mOutputFormat, new ABuffer(bufferSize));
1327
1328        // Initialize fence fd to -1 to avoid warning in freeBuffer().
1329        ((VideoNativeMetadata *)info.mData->base())->nFenceFd = -1;
1330
1331        info.mCodecData = info.mData;
1332
1333        err = mOMXNode->useBuffer(kPortIndexOutput, OMXBuffer::sPreset, &info.mBufferID);
1334        mBuffers[kPortIndexOutput].push(info);
1335
1336        ALOGV("[%s] allocated meta buffer with ID %u",
1337                mComponentName.c_str(), info.mBufferID);
1338    }
1339
1340    mMetadataBuffersToSubmit = bufferCount - minUndequeuedBuffers;
1341    return err;
1342}
1343
1344status_t ACodec::submitOutputMetadataBuffer() {
1345    CHECK(storingMetadataInDecodedBuffers());
1346    if (mMetadataBuffersToSubmit == 0)
1347        return OK;
1348
1349    BufferInfo *info = dequeueBufferFromNativeWindow();
1350    if (info == NULL) {
1351        return ERROR_IO;
1352    }
1353
1354    ALOGV("[%s] submitting output meta buffer ID %u for graphic buffer %p",
1355          mComponentName.c_str(), info->mBufferID, info->mGraphicBuffer->handle);
1356
1357    --mMetadataBuffersToSubmit;
1358    info->checkWriteFence("submitOutputMetadataBuffer");
1359    return fillBuffer(info);
1360}
1361
1362status_t ACodec::waitForFence(int fd, const char *dbg ) {
1363    status_t res = OK;
1364    if (fd >= 0) {
1365        sp<Fence> fence = new Fence(fd);
1366        res = fence->wait(IOMX::kFenceTimeoutMs);
1367        ALOGW_IF(res != OK, "FENCE TIMEOUT for %d in %s", fd, dbg);
1368    }
1369    return res;
1370}
1371
1372// static
1373const char *ACodec::_asString(BufferInfo::Status s) {
1374    switch (s) {
1375        case BufferInfo::OWNED_BY_US:            return "OUR";
1376        case BufferInfo::OWNED_BY_COMPONENT:     return "COMPONENT";
1377        case BufferInfo::OWNED_BY_UPSTREAM:      return "UPSTREAM";
1378        case BufferInfo::OWNED_BY_DOWNSTREAM:    return "DOWNSTREAM";
1379        case BufferInfo::OWNED_BY_NATIVE_WINDOW: return "SURFACE";
1380        case BufferInfo::UNRECOGNIZED:           return "UNRECOGNIZED";
1381        default:                                 return "?";
1382    }
1383}
1384
1385void ACodec::dumpBuffers(OMX_U32 portIndex) {
1386    CHECK(portIndex == kPortIndexInput || portIndex == kPortIndexOutput);
1387    ALOGI("[%s] %s port has %zu buffers:", mComponentName.c_str(),
1388            portIndex == kPortIndexInput ? "input" : "output", mBuffers[portIndex].size());
1389    for (size_t i = 0; i < mBuffers[portIndex].size(); ++i) {
1390        const BufferInfo &info = mBuffers[portIndex][i];
1391        ALOGI("  slot %2zu: #%8u %p/%p %s(%d) dequeued:%u",
1392                i, info.mBufferID, info.mGraphicBuffer.get(),
1393                info.mGraphicBuffer == NULL ? NULL : info.mGraphicBuffer->getNativeBuffer(),
1394                _asString(info.mStatus), info.mStatus, info.mDequeuedAt);
1395    }
1396}
1397
1398status_t ACodec::cancelBufferToNativeWindow(BufferInfo *info) {
1399    CHECK_EQ((int)info->mStatus, (int)BufferInfo::OWNED_BY_US);
1400
1401    ALOGV("[%s] Calling cancelBuffer on buffer %u",
1402         mComponentName.c_str(), info->mBufferID);
1403
1404    info->checkWriteFence("cancelBufferToNativeWindow");
1405    int err = mNativeWindow->cancelBuffer(
1406        mNativeWindow.get(), info->mGraphicBuffer.get(), info->mFenceFd);
1407    info->mFenceFd = -1;
1408
1409    ALOGW_IF(err != 0, "[%s] can not return buffer %u to native window",
1410            mComponentName.c_str(), info->mBufferID);
1411    // change ownership even if cancelBuffer fails
1412    info->mStatus = BufferInfo::OWNED_BY_NATIVE_WINDOW;
1413
1414    return err;
1415}
1416
1417void ACodec::updateRenderInfoForDequeuedBuffer(
1418        ANativeWindowBuffer *buf, int fenceFd, BufferInfo *info) {
1419
1420    info->mRenderInfo =
1421        mRenderTracker.updateInfoForDequeuedBuffer(
1422                buf, fenceFd, info - &mBuffers[kPortIndexOutput][0]);
1423
1424    // check for any fences already signaled
1425    notifyOfRenderedFrames(false /* dropIncomplete */, info->mRenderInfo);
1426}
1427
1428void ACodec::onFrameRendered(int64_t mediaTimeUs, nsecs_t systemNano) {
1429    if (mRenderTracker.onFrameRendered(mediaTimeUs, systemNano) != OK) {
1430        mRenderTracker.dumpRenderQueue();
1431    }
1432}
1433
1434void ACodec::notifyOfRenderedFrames(bool dropIncomplete, FrameRenderTracker::Info *until) {
1435    std::list<FrameRenderTracker::Info> done =
1436        mRenderTracker.checkFencesAndGetRenderedFrames(until, dropIncomplete);
1437
1438    // unlink untracked frames
1439    for (std::list<FrameRenderTracker::Info>::const_iterator it = done.cbegin();
1440            it != done.cend(); ++it) {
1441        ssize_t index = it->getIndex();
1442        if (index >= 0 && (size_t)index < mBuffers[kPortIndexOutput].size()) {
1443            mBuffers[kPortIndexOutput].editItemAt(index).mRenderInfo = NULL;
1444        } else if (index >= 0) {
1445            // THIS SHOULD NEVER HAPPEN
1446            ALOGE("invalid index %zd in %zu", index, mBuffers[kPortIndexOutput].size());
1447        }
1448    }
1449
1450    mCallback->onOutputFramesRendered(done);
1451}
1452
1453ACodec::BufferInfo *ACodec::dequeueBufferFromNativeWindow() {
1454    ANativeWindowBuffer *buf;
1455    CHECK(mNativeWindow.get() != NULL);
1456
1457    if (mTunneled) {
1458        ALOGW("dequeueBufferFromNativeWindow() should not be called in tunnel"
1459              " video playback mode mode!");
1460        return NULL;
1461    }
1462
1463    if (mFatalError) {
1464        ALOGW("not dequeuing from native window due to fatal error");
1465        return NULL;
1466    }
1467
1468    int fenceFd = -1;
1469    do {
1470        status_t err = mNativeWindow->dequeueBuffer(mNativeWindow.get(), &buf, &fenceFd);
1471        if (err != 0) {
1472            ALOGE("dequeueBuffer failed: %s(%d).", asString(err), err);
1473            return NULL;
1474        }
1475
1476        bool stale = false;
1477        for (size_t i = mBuffers[kPortIndexOutput].size(); i > 0;) {
1478            i--;
1479            BufferInfo *info = &mBuffers[kPortIndexOutput].editItemAt(i);
1480
1481            if (info->mGraphicBuffer != NULL &&
1482                    info->mGraphicBuffer->handle == buf->handle) {
1483                // Since consumers can attach buffers to BufferQueues, it is possible
1484                // that a known yet stale buffer can return from a surface that we
1485                // once used.  We can simply ignore this as we have already dequeued
1486                // this buffer properly.  NOTE: this does not eliminate all cases,
1487                // e.g. it is possible that we have queued the valid buffer to the
1488                // NW, and a stale copy of the same buffer gets dequeued - which will
1489                // be treated as the valid buffer by ACodec.
1490                if (info->mStatus != BufferInfo::OWNED_BY_NATIVE_WINDOW) {
1491                    ALOGI("dequeued stale buffer %p. discarding", buf);
1492                    stale = true;
1493                    break;
1494                }
1495
1496                ALOGV("dequeued buffer #%u with age %u, graphicBuffer %p",
1497                        (unsigned)(info - &mBuffers[kPortIndexOutput][0]),
1498                        mDequeueCounter - info->mDequeuedAt,
1499                        info->mGraphicBuffer->handle);
1500
1501                info->mStatus = BufferInfo::OWNED_BY_US;
1502                info->setWriteFence(fenceFd, "dequeueBufferFromNativeWindow");
1503                updateRenderInfoForDequeuedBuffer(buf, fenceFd, info);
1504                return info;
1505            }
1506        }
1507
1508        // It is also possible to receive a previously unregistered buffer
1509        // in non-meta mode. These should be treated as stale buffers. The
1510        // same is possible in meta mode, in which case, it will be treated
1511        // as a normal buffer, which is not desirable.
1512        // TODO: fix this.
1513        if (!stale && !storingMetadataInDecodedBuffers()) {
1514            ALOGI("dequeued unrecognized (stale) buffer %p. discarding", buf);
1515            stale = true;
1516        }
1517        if (stale) {
1518            // TODO: detach stale buffer, but there is no API yet to do it.
1519            buf = NULL;
1520        }
1521    } while (buf == NULL);
1522
1523    // get oldest undequeued buffer
1524    BufferInfo *oldest = NULL;
1525    for (size_t i = mBuffers[kPortIndexOutput].size(); i > 0;) {
1526        i--;
1527        BufferInfo *info =
1528            &mBuffers[kPortIndexOutput].editItemAt(i);
1529        if (info->mStatus == BufferInfo::OWNED_BY_NATIVE_WINDOW &&
1530            (oldest == NULL ||
1531             // avoid potential issues from counter rolling over
1532             mDequeueCounter - info->mDequeuedAt >
1533                    mDequeueCounter - oldest->mDequeuedAt)) {
1534            oldest = info;
1535        }
1536    }
1537
1538    // it is impossible dequeue a buffer when there are no buffers with ANW
1539    CHECK(oldest != NULL);
1540    // it is impossible to dequeue an unknown buffer in non-meta mode, as the
1541    // while loop above does not complete
1542    CHECK(storingMetadataInDecodedBuffers());
1543
1544    // discard buffer in LRU info and replace with new buffer
1545    oldest->mGraphicBuffer = GraphicBuffer::from(buf);
1546    oldest->mNewGraphicBuffer = true;
1547    oldest->mStatus = BufferInfo::OWNED_BY_US;
1548    oldest->setWriteFence(fenceFd, "dequeueBufferFromNativeWindow for oldest");
1549    mRenderTracker.untrackFrame(oldest->mRenderInfo);
1550    oldest->mRenderInfo = NULL;
1551
1552    ALOGV("replaced oldest buffer #%u with age %u, graphicBuffer %p",
1553            (unsigned)(oldest - &mBuffers[kPortIndexOutput][0]),
1554            mDequeueCounter - oldest->mDequeuedAt,
1555            oldest->mGraphicBuffer->handle);
1556
1557    updateRenderInfoForDequeuedBuffer(buf, fenceFd, oldest);
1558    return oldest;
1559}
1560
1561status_t ACodec::freeBuffersOnPort(OMX_U32 portIndex) {
1562    if (portIndex == kPortIndexInput) {
1563        mBufferChannel->setInputBufferArray({});
1564    } else {
1565        mBufferChannel->setOutputBufferArray({});
1566    }
1567
1568    status_t err = OK;
1569    for (size_t i = mBuffers[portIndex].size(); i > 0;) {
1570        i--;
1571        status_t err2 = freeBuffer(portIndex, i);
1572        if (err == OK) {
1573            err = err2;
1574        }
1575    }
1576
1577    mAllocator[portIndex].clear();
1578    return err;
1579}
1580
1581status_t ACodec::freeOutputBuffersNotOwnedByComponent() {
1582    status_t err = OK;
1583    for (size_t i = mBuffers[kPortIndexOutput].size(); i > 0;) {
1584        i--;
1585        BufferInfo *info =
1586            &mBuffers[kPortIndexOutput].editItemAt(i);
1587
1588        // At this time some buffers may still be with the component
1589        // or being drained.
1590        if (info->mStatus != BufferInfo::OWNED_BY_COMPONENT &&
1591            info->mStatus != BufferInfo::OWNED_BY_DOWNSTREAM) {
1592            status_t err2 = freeBuffer(kPortIndexOutput, i);
1593            if (err == OK) {
1594                err = err2;
1595            }
1596        }
1597    }
1598
1599    return err;
1600}
1601
1602status_t ACodec::freeBuffer(OMX_U32 portIndex, size_t i) {
1603    BufferInfo *info = &mBuffers[portIndex].editItemAt(i);
1604    status_t err = OK;
1605
1606    // there should not be any fences in the metadata
1607    if (mPortMode[portIndex] == IOMX::kPortModeDynamicANWBuffer && info->mCodecData != NULL
1608            && info->mCodecData->size() >= sizeof(VideoNativeMetadata)) {
1609        int fenceFd = ((VideoNativeMetadata *)info->mCodecData->base())->nFenceFd;
1610        if (fenceFd >= 0) {
1611            ALOGW("unreleased fence (%d) in %s metadata buffer %zu",
1612                    fenceFd, portIndex == kPortIndexInput ? "input" : "output", i);
1613        }
1614    }
1615
1616    switch (info->mStatus) {
1617        case BufferInfo::OWNED_BY_US:
1618            if (portIndex == kPortIndexOutput && mNativeWindow != NULL) {
1619                (void)cancelBufferToNativeWindow(info);
1620            }
1621            // fall through
1622
1623        case BufferInfo::OWNED_BY_NATIVE_WINDOW:
1624            err = mOMXNode->freeBuffer(portIndex, info->mBufferID);
1625            break;
1626
1627        default:
1628            ALOGE("trying to free buffer not owned by us or ANW (%d)", info->mStatus);
1629            err = FAILED_TRANSACTION;
1630            break;
1631    }
1632
1633    if (info->mFenceFd >= 0) {
1634        ::close(info->mFenceFd);
1635    }
1636
1637    if (portIndex == kPortIndexOutput) {
1638        mRenderTracker.untrackFrame(info->mRenderInfo, i);
1639        info->mRenderInfo = NULL;
1640    }
1641
1642    // remove buffer even if mOMXNode->freeBuffer fails
1643    mBuffers[portIndex].removeAt(i);
1644    return err;
1645}
1646
1647ACodec::BufferInfo *ACodec::findBufferByID(
1648        uint32_t portIndex, IOMX::buffer_id bufferID, ssize_t *index) {
1649    for (size_t i = 0; i < mBuffers[portIndex].size(); ++i) {
1650        BufferInfo *info = &mBuffers[portIndex].editItemAt(i);
1651
1652        if (info->mBufferID == bufferID) {
1653            if (index != NULL) {
1654                *index = i;
1655            }
1656            return info;
1657        }
1658    }
1659
1660    ALOGE("Could not find buffer with ID %u", bufferID);
1661    return NULL;
1662}
1663
1664status_t ACodec::fillBuffer(BufferInfo *info) {
1665    status_t err;
1666    // Even in dynamic ANW buffer mode, if the graphic buffer is not changing,
1667    // send sPreset instead of the same graphic buffer, so that OMX server
1668    // side doesn't update the meta. In theory it should make no difference,
1669    // however when the same buffer is parcelled again, a new handle could be
1670    // created on server side, and some decoder doesn't recognize the handle
1671    // even if it's the same buffer.
1672    if (!storingMetadataInDecodedBuffers() || !info->mNewGraphicBuffer) {
1673        err = mOMXNode->fillBuffer(
1674            info->mBufferID, OMXBuffer::sPreset, info->mFenceFd);
1675    } else {
1676        err = mOMXNode->fillBuffer(
1677            info->mBufferID, info->mGraphicBuffer, info->mFenceFd);
1678    }
1679
1680    info->mNewGraphicBuffer = false;
1681    info->mFenceFd = -1;
1682    if (err == OK) {
1683        info->mStatus = BufferInfo::OWNED_BY_COMPONENT;
1684    }
1685    return err;
1686}
1687
1688status_t ACodec::setComponentRole(
1689        bool isEncoder, const char *mime) {
1690    const char *role = GetComponentRole(isEncoder, mime);
1691    if (role == NULL) {
1692        return BAD_VALUE;
1693    }
1694    status_t err = SetComponentRole(mOMXNode, role);
1695    if (err != OK) {
1696        ALOGW("[%s] Failed to set standard component role '%s'.",
1697             mComponentName.c_str(), role);
1698    }
1699    return err;
1700}
1701
1702status_t ACodec::configureCodec(
1703        const char *mime, const sp<AMessage> &msg) {
1704    int32_t encoder;
1705    if (!msg->findInt32("encoder", &encoder)) {
1706        encoder = false;
1707    }
1708
1709    sp<AMessage> inputFormat = new AMessage;
1710    sp<AMessage> outputFormat = new AMessage;
1711    mConfigFormat = msg;
1712
1713    mIsEncoder = encoder;
1714    mIsVideo = !strncasecmp(mime, "video/", 6);
1715
1716    mPortMode[kPortIndexInput] = IOMX::kPortModePresetByteBuffer;
1717    mPortMode[kPortIndexOutput] = IOMX::kPortModePresetByteBuffer;
1718
1719    status_t err = setComponentRole(encoder /* isEncoder */, mime);
1720
1721    if (err != OK) {
1722        return err;
1723    }
1724
1725    OMX_VIDEO_CONTROLRATETYPE bitrateMode;
1726    int32_t bitrate = 0, quality;
1727    // FLAC encoder or video encoder in constant quality mode doesn't need a
1728    // bitrate, other encoders do.
1729    if (encoder) {
1730        if (mIsVideo && !findVideoBitrateControlInfo(
1731                msg, &bitrateMode, &bitrate, &quality)) {
1732            return INVALID_OPERATION;
1733        } else if (!mIsVideo && strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_FLAC)
1734            && !msg->findInt32("bitrate", &bitrate)) {
1735            return INVALID_OPERATION;
1736        }
1737    }
1738
1739    // propagate bitrate to the output so that the muxer has it
1740    if (encoder && msg->findInt32("bitrate", &bitrate)) {
1741        // Technically ISO spec says that 'bitrate' should be 0 for VBR even though it is the
1742        // average bitrate. We've been setting both bitrate and max-bitrate to this same value.
1743        outputFormat->setInt32("bitrate", bitrate);
1744        outputFormat->setInt32("max-bitrate", bitrate);
1745    }
1746
1747    int32_t storeMeta;
1748    if (encoder
1749            && msg->findInt32("android._input-metadata-buffer-type", &storeMeta)
1750            && storeMeta != kMetadataBufferTypeInvalid) {
1751        IOMX::PortMode mode;
1752        if (storeMeta == kMetadataBufferTypeNativeHandleSource) {
1753            mode = IOMX::kPortModeDynamicNativeHandle;
1754        } else if (storeMeta == kMetadataBufferTypeANWBuffer ||
1755                storeMeta == kMetadataBufferTypeGrallocSource) {
1756            mode = IOMX::kPortModeDynamicANWBuffer;
1757        } else {
1758            return BAD_VALUE;
1759        }
1760        err = setPortMode(kPortIndexInput, mode);
1761        if (err != OK) {
1762            return err;
1763        }
1764
1765        uint32_t usageBits;
1766        if (mOMXNode->getParameter(
1767                (OMX_INDEXTYPE)OMX_IndexParamConsumerUsageBits,
1768                &usageBits, sizeof(usageBits)) == OK) {
1769            inputFormat->setInt32(
1770                    "using-sw-read-often", !!(usageBits & GRALLOC_USAGE_SW_READ_OFTEN));
1771        }
1772    }
1773
1774    int32_t prependSPSPPS = 0;
1775    if (encoder
1776            && msg->findInt32("prepend-sps-pps-to-idr-frames", &prependSPSPPS)
1777            && prependSPSPPS != 0) {
1778        OMX_INDEXTYPE index;
1779        err = mOMXNode->getExtensionIndex(
1780                "OMX.google.android.index.prependSPSPPSToIDRFrames", &index);
1781
1782        if (err == OK) {
1783            PrependSPSPPSToIDRFramesParams params;
1784            InitOMXParams(&params);
1785            params.bEnable = OMX_TRUE;
1786
1787            err = mOMXNode->setParameter(index, &params, sizeof(params));
1788        }
1789
1790        if (err != OK) {
1791            ALOGE("Encoder could not be configured to emit SPS/PPS before "
1792                  "IDR frames. (err %d)", err);
1793
1794            return err;
1795        }
1796    }
1797
1798    // Only enable metadata mode on encoder output if encoder can prepend
1799    // sps/pps to idr frames, since in metadata mode the bitstream is in an
1800    // opaque handle, to which we don't have access.
1801    if (encoder && mIsVideo) {
1802        OMX_BOOL enable = (OMX_BOOL) (prependSPSPPS
1803            && msg->findInt32("android._store-metadata-in-buffers-output", &storeMeta)
1804            && storeMeta != 0);
1805        if (mFlags & kFlagIsSecure) {
1806            enable = OMX_TRUE;
1807        }
1808
1809        err = setPortMode(kPortIndexOutput, enable ?
1810                IOMX::kPortModePresetSecureBuffer : IOMX::kPortModePresetByteBuffer);
1811        if (err != OK) {
1812            return err;
1813        }
1814
1815        if (!msg->findInt64(
1816                    "repeat-previous-frame-after",
1817                    &mRepeatFrameDelayUs)) {
1818            mRepeatFrameDelayUs = -1ll;
1819        }
1820
1821        // only allow 32-bit value, since we pass it as U32 to OMX.
1822        if (!msg->findInt64("max-pts-gap-to-encoder", &mMaxPtsGapUs)) {
1823            mMaxPtsGapUs = -1ll;
1824        } else if (mMaxPtsGapUs > INT32_MAX || mMaxPtsGapUs < 0) {
1825            ALOGW("Unsupported value for max pts gap %lld", (long long) mMaxPtsGapUs);
1826            mMaxPtsGapUs = -1ll;
1827        }
1828
1829        if (!msg->findFloat("max-fps-to-encoder", &mMaxFps)) {
1830            mMaxFps = -1;
1831        }
1832
1833        if (!msg->findDouble("time-lapse-fps", &mCaptureFps)) {
1834            mCaptureFps = -1.0;
1835        }
1836
1837        if (!msg->findInt32(
1838                    "create-input-buffers-suspended",
1839                    (int32_t*)&mCreateInputBuffersSuspended)) {
1840            mCreateInputBuffersSuspended = false;
1841        }
1842    }
1843
1844    // NOTE: we only use native window for video decoders
1845    sp<RefBase> obj;
1846    bool haveNativeWindow = msg->findObject("native-window", &obj)
1847            && obj != NULL && mIsVideo && !encoder;
1848    mUsingNativeWindow = haveNativeWindow;
1849    if (mIsVideo && !encoder) {
1850        inputFormat->setInt32("adaptive-playback", false);
1851
1852        int32_t usageProtected;
1853        if (msg->findInt32("protected", &usageProtected) && usageProtected) {
1854            if (!haveNativeWindow) {
1855                ALOGE("protected output buffers must be sent to an ANativeWindow");
1856                return PERMISSION_DENIED;
1857            }
1858            mFlags |= kFlagIsGrallocUsageProtected;
1859            mFlags |= kFlagPushBlankBuffersToNativeWindowOnShutdown;
1860        }
1861    }
1862    if (mFlags & kFlagIsSecure) {
1863        // use native_handles for secure input buffers
1864        err = setPortMode(kPortIndexInput, IOMX::kPortModePresetSecureBuffer);
1865
1866        if (err != OK) {
1867            ALOGI("falling back to non-native_handles");
1868            setPortMode(kPortIndexInput, IOMX::kPortModePresetByteBuffer);
1869            err = OK; // ignore error for now
1870        }
1871    }
1872    if (haveNativeWindow) {
1873        sp<ANativeWindow> nativeWindow =
1874            static_cast<ANativeWindow *>(static_cast<Surface *>(obj.get()));
1875
1876        // START of temporary support for automatic FRC - THIS WILL BE REMOVED
1877        int32_t autoFrc;
1878        if (msg->findInt32("auto-frc", &autoFrc)) {
1879            bool enabled = autoFrc;
1880            OMX_CONFIG_BOOLEANTYPE config;
1881            InitOMXParams(&config);
1882            config.bEnabled = (OMX_BOOL)enabled;
1883            status_t temp = mOMXNode->setConfig(
1884                    (OMX_INDEXTYPE)OMX_IndexConfigAutoFramerateConversion,
1885                    &config, sizeof(config));
1886            if (temp == OK) {
1887                outputFormat->setInt32("auto-frc", enabled);
1888            } else if (enabled) {
1889                ALOGI("codec does not support requested auto-frc (err %d)", temp);
1890            }
1891        }
1892        // END of temporary support for automatic FRC
1893
1894        int32_t tunneled;
1895        if (msg->findInt32("feature-tunneled-playback", &tunneled) &&
1896            tunneled != 0) {
1897            ALOGI("Configuring TUNNELED video playback.");
1898            mTunneled = true;
1899
1900            int32_t audioHwSync = 0;
1901            if (!msg->findInt32("audio-hw-sync", &audioHwSync)) {
1902                ALOGW("No Audio HW Sync provided for video tunnel");
1903            }
1904            err = configureTunneledVideoPlayback(audioHwSync, nativeWindow);
1905            if (err != OK) {
1906                ALOGE("configureTunneledVideoPlayback(%d,%p) failed!",
1907                        audioHwSync, nativeWindow.get());
1908                return err;
1909            }
1910
1911            int32_t maxWidth = 0, maxHeight = 0;
1912            if (msg->findInt32("max-width", &maxWidth) &&
1913                    msg->findInt32("max-height", &maxHeight)) {
1914
1915                err = mOMXNode->prepareForAdaptivePlayback(
1916                        kPortIndexOutput, OMX_TRUE, maxWidth, maxHeight);
1917                if (err != OK) {
1918                    ALOGW("[%s] prepareForAdaptivePlayback failed w/ err %d",
1919                            mComponentName.c_str(), err);
1920                    // allow failure
1921                    err = OK;
1922                } else {
1923                    inputFormat->setInt32("max-width", maxWidth);
1924                    inputFormat->setInt32("max-height", maxHeight);
1925                    inputFormat->setInt32("adaptive-playback", true);
1926                }
1927            }
1928        } else {
1929            ALOGV("Configuring CPU controlled video playback.");
1930            mTunneled = false;
1931
1932            // Explicity reset the sideband handle of the window for
1933            // non-tunneled video in case the window was previously used
1934            // for a tunneled video playback.
1935            err = native_window_set_sideband_stream(nativeWindow.get(), NULL);
1936            if (err != OK) {
1937                ALOGE("set_sideband_stream(NULL) failed! (err %d).", err);
1938                return err;
1939            }
1940
1941            err = setPortMode(kPortIndexOutput, IOMX::kPortModeDynamicANWBuffer);
1942            if (err != OK) {
1943                // if adaptive playback has been requested, try JB fallback
1944                // NOTE: THIS FALLBACK MECHANISM WILL BE REMOVED DUE TO ITS
1945                // LARGE MEMORY REQUIREMENT
1946
1947                // we will not do adaptive playback on software accessed
1948                // surfaces as they never had to respond to changes in the
1949                // crop window, and we don't trust that they will be able to.
1950                int usageBits = 0;
1951                bool canDoAdaptivePlayback;
1952
1953                if (nativeWindow->query(
1954                        nativeWindow.get(),
1955                        NATIVE_WINDOW_CONSUMER_USAGE_BITS,
1956                        &usageBits) != OK) {
1957                    canDoAdaptivePlayback = false;
1958                } else {
1959                    canDoAdaptivePlayback =
1960                        (usageBits &
1961                                (GRALLOC_USAGE_SW_READ_MASK |
1962                                 GRALLOC_USAGE_SW_WRITE_MASK)) == 0;
1963                }
1964
1965                int32_t maxWidth = 0, maxHeight = 0;
1966                if (canDoAdaptivePlayback &&
1967                        msg->findInt32("max-width", &maxWidth) &&
1968                        msg->findInt32("max-height", &maxHeight)) {
1969                    ALOGV("[%s] prepareForAdaptivePlayback(%dx%d)",
1970                            mComponentName.c_str(), maxWidth, maxHeight);
1971
1972                    err = mOMXNode->prepareForAdaptivePlayback(
1973                            kPortIndexOutput, OMX_TRUE, maxWidth, maxHeight);
1974                    ALOGW_IF(err != OK,
1975                            "[%s] prepareForAdaptivePlayback failed w/ err %d",
1976                            mComponentName.c_str(), err);
1977
1978                    if (err == OK) {
1979                        inputFormat->setInt32("max-width", maxWidth);
1980                        inputFormat->setInt32("max-height", maxHeight);
1981                        inputFormat->setInt32("adaptive-playback", true);
1982                    }
1983                }
1984                // allow failure
1985                err = OK;
1986            } else {
1987                ALOGV("[%s] setPortMode on output to %s succeeded",
1988                        mComponentName.c_str(), asString(IOMX::kPortModeDynamicANWBuffer));
1989                CHECK(storingMetadataInDecodedBuffers());
1990                inputFormat->setInt32("adaptive-playback", true);
1991            }
1992
1993            int32_t push;
1994            if (msg->findInt32("push-blank-buffers-on-shutdown", &push)
1995                    && push != 0) {
1996                mFlags |= kFlagPushBlankBuffersToNativeWindowOnShutdown;
1997            }
1998        }
1999
2000        int32_t rotationDegrees;
2001        if (msg->findInt32("rotation-degrees", &rotationDegrees)) {
2002            mRotationDegrees = rotationDegrees;
2003        } else {
2004            mRotationDegrees = 0;
2005        }
2006    }
2007
2008    AudioEncoding pcmEncoding = kAudioEncodingPcm16bit;
2009    (void)msg->findInt32("pcm-encoding", (int32_t*)&pcmEncoding);
2010    // invalid encodings will default to PCM-16bit in setupRawAudioFormat.
2011
2012    if (mIsVideo) {
2013        // determine need for software renderer
2014        bool usingSwRenderer = false;
2015        if (haveNativeWindow && mComponentName.startsWith("OMX.google.")) {
2016            usingSwRenderer = true;
2017            haveNativeWindow = false;
2018            (void)setPortMode(kPortIndexOutput, IOMX::kPortModePresetByteBuffer);
2019        } else if (haveNativeWindow && !storingMetadataInDecodedBuffers()) {
2020            err = setPortMode(kPortIndexOutput, IOMX::kPortModePresetANWBuffer);
2021            if (err != OK) {
2022                return err;
2023            }
2024        }
2025
2026        if (encoder) {
2027            err = setupVideoEncoder(mime, msg, outputFormat, inputFormat);
2028        } else {
2029            err = setupVideoDecoder(mime, msg, haveNativeWindow, usingSwRenderer, outputFormat);
2030        }
2031
2032        if (err != OK) {
2033            return err;
2034        }
2035
2036        if (haveNativeWindow) {
2037            mNativeWindow = static_cast<Surface *>(obj.get());
2038
2039            // fallback for devices that do not handle flex-YUV for native buffers
2040            int32_t requestedColorFormat = OMX_COLOR_FormatUnused;
2041            if (msg->findInt32("color-format", &requestedColorFormat) &&
2042                    requestedColorFormat == OMX_COLOR_FormatYUV420Flexible) {
2043                status_t err = getPortFormat(kPortIndexOutput, outputFormat);
2044                if (err != OK) {
2045                    return err;
2046                }
2047                int32_t colorFormat = OMX_COLOR_FormatUnused;
2048                OMX_U32 flexibleEquivalent = OMX_COLOR_FormatUnused;
2049                if (!outputFormat->findInt32("color-format", &colorFormat)) {
2050                    ALOGE("ouptut port did not have a color format (wrong domain?)");
2051                    return BAD_VALUE;
2052                }
2053                ALOGD("[%s] Requested output format %#x and got %#x.",
2054                        mComponentName.c_str(), requestedColorFormat, colorFormat);
2055                if (!IsFlexibleColorFormat(
2056                        mOMXNode, colorFormat, haveNativeWindow, &flexibleEquivalent)
2057                        || flexibleEquivalent != (OMX_U32)requestedColorFormat) {
2058                    // device did not handle flex-YUV request for native window, fall back
2059                    // to SW renderer
2060                    ALOGI("[%s] Falling back to software renderer", mComponentName.c_str());
2061                    mNativeWindow.clear();
2062                    mNativeWindowUsageBits = 0;
2063                    haveNativeWindow = false;
2064                    usingSwRenderer = true;
2065                    // TODO: implement adaptive-playback support for bytebuffer mode.
2066                    // This is done by SW codecs, but most HW codecs don't support it.
2067                    err = setPortMode(kPortIndexOutput, IOMX::kPortModePresetByteBuffer);
2068                    inputFormat->setInt32("adaptive-playback", false);
2069                    if (mFlags & kFlagIsGrallocUsageProtected) {
2070                        // fallback is not supported for protected playback
2071                        err = PERMISSION_DENIED;
2072                    } else if (err == OK) {
2073                        err = setupVideoDecoder(
2074                                mime, msg, haveNativeWindow, usingSwRenderer, outputFormat);
2075                    }
2076                }
2077            }
2078        }
2079
2080        if (usingSwRenderer) {
2081            outputFormat->setInt32("using-sw-renderer", 1);
2082        }
2083    } else if (!strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_MPEG)) {
2084        int32_t numChannels, sampleRate;
2085        if (!msg->findInt32("channel-count", &numChannels)
2086                || !msg->findInt32("sample-rate", &sampleRate)) {
2087            // Since we did not always check for these, leave them optional
2088            // and have the decoder figure it all out.
2089            err = OK;
2090        } else {
2091            err = setupRawAudioFormat(
2092                    encoder ? kPortIndexInput : kPortIndexOutput,
2093                    sampleRate,
2094                    numChannels);
2095        }
2096    } else if (!strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_AAC)) {
2097        int32_t numChannels, sampleRate;
2098        if (!msg->findInt32("channel-count", &numChannels)
2099                || !msg->findInt32("sample-rate", &sampleRate)) {
2100            err = INVALID_OPERATION;
2101        } else {
2102            int32_t isADTS, aacProfile;
2103            int32_t sbrMode;
2104            int32_t maxOutputChannelCount;
2105            int32_t pcmLimiterEnable;
2106            drcParams_t drc;
2107            if (!msg->findInt32("is-adts", &isADTS)) {
2108                isADTS = 0;
2109            }
2110            if (!msg->findInt32("aac-profile", &aacProfile)) {
2111                aacProfile = OMX_AUDIO_AACObjectNull;
2112            }
2113            if (!msg->findInt32("aac-sbr-mode", &sbrMode)) {
2114                sbrMode = -1;
2115            }
2116
2117            if (!msg->findInt32("aac-max-output-channel_count", &maxOutputChannelCount)) {
2118                maxOutputChannelCount = -1;
2119            }
2120            if (!msg->findInt32("aac-pcm-limiter-enable", &pcmLimiterEnable)) {
2121                // value is unknown
2122                pcmLimiterEnable = -1;
2123            }
2124            if (!msg->findInt32("aac-encoded-target-level", &drc.encodedTargetLevel)) {
2125                // value is unknown
2126                drc.encodedTargetLevel = -1;
2127            }
2128            if (!msg->findInt32("aac-drc-cut-level", &drc.drcCut)) {
2129                // value is unknown
2130                drc.drcCut = -1;
2131            }
2132            if (!msg->findInt32("aac-drc-boost-level", &drc.drcBoost)) {
2133                // value is unknown
2134                drc.drcBoost = -1;
2135            }
2136            if (!msg->findInt32("aac-drc-heavy-compression", &drc.heavyCompression)) {
2137                // value is unknown
2138                drc.heavyCompression = -1;
2139            }
2140            if (!msg->findInt32("aac-target-ref-level", &drc.targetRefLevel)) {
2141                // value is unknown
2142                drc.targetRefLevel = -1;
2143            }
2144
2145            err = setupAACCodec(
2146                    encoder, numChannels, sampleRate, bitrate, aacProfile,
2147                    isADTS != 0, sbrMode, maxOutputChannelCount, drc,
2148                    pcmLimiterEnable);
2149        }
2150    } else if (!strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_AMR_NB)) {
2151        err = setupAMRCodec(encoder, false /* isWAMR */, bitrate);
2152    } else if (!strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_AMR_WB)) {
2153        err = setupAMRCodec(encoder, true /* isWAMR */, bitrate);
2154    } else if (!strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_G711_ALAW)
2155            || !strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_G711_MLAW)) {
2156        // These are PCM-like formats with a fixed sample rate but
2157        // a variable number of channels.
2158
2159        int32_t numChannels;
2160        if (!msg->findInt32("channel-count", &numChannels)) {
2161            err = INVALID_OPERATION;
2162        } else {
2163            int32_t sampleRate;
2164            if (!msg->findInt32("sample-rate", &sampleRate)) {
2165                sampleRate = 8000;
2166            }
2167            err = setupG711Codec(encoder, sampleRate, numChannels);
2168        }
2169    } else if (!strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_FLAC)) {
2170        int32_t numChannels = 0, sampleRate = 0, compressionLevel = -1;
2171        if (encoder &&
2172                (!msg->findInt32("channel-count", &numChannels)
2173                        || !msg->findInt32("sample-rate", &sampleRate))) {
2174            ALOGE("missing channel count or sample rate for FLAC encoder");
2175            err = INVALID_OPERATION;
2176        } else {
2177            if (encoder) {
2178                if (!msg->findInt32(
2179                            "complexity", &compressionLevel) &&
2180                    !msg->findInt32(
2181                            "flac-compression-level", &compressionLevel)) {
2182                    compressionLevel = 5; // default FLAC compression level
2183                } else if (compressionLevel < 0) {
2184                    ALOGW("compression level %d outside [0..8] range, "
2185                          "using 0",
2186                          compressionLevel);
2187                    compressionLevel = 0;
2188                } else if (compressionLevel > 8) {
2189                    ALOGW("compression level %d outside [0..8] range, "
2190                          "using 8",
2191                          compressionLevel);
2192                    compressionLevel = 8;
2193                }
2194            }
2195            err = setupFlacCodec(
2196                    encoder, numChannels, sampleRate, compressionLevel);
2197        }
2198    } else if (!strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_RAW)) {
2199        int32_t numChannels, sampleRate;
2200        if (encoder
2201                || !msg->findInt32("channel-count", &numChannels)
2202                || !msg->findInt32("sample-rate", &sampleRate)) {
2203            err = INVALID_OPERATION;
2204        } else {
2205            err = setupRawAudioFormat(kPortIndexInput, sampleRate, numChannels, pcmEncoding);
2206        }
2207    } else if (!strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_AC3)) {
2208        int32_t numChannels;
2209        int32_t sampleRate;
2210        if (!msg->findInt32("channel-count", &numChannels)
2211                || !msg->findInt32("sample-rate", &sampleRate)) {
2212            err = INVALID_OPERATION;
2213        } else {
2214            err = setupAC3Codec(encoder, numChannels, sampleRate);
2215        }
2216    } else if (!strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_EAC3)) {
2217        int32_t numChannels;
2218        int32_t sampleRate;
2219        if (!msg->findInt32("channel-count", &numChannels)
2220                || !msg->findInt32("sample-rate", &sampleRate)) {
2221            err = INVALID_OPERATION;
2222        } else {
2223            err = setupEAC3Codec(encoder, numChannels, sampleRate);
2224        }
2225    }
2226
2227    if (err != OK) {
2228        return err;
2229    }
2230
2231    if (!msg->findInt32("encoder-delay", &mEncoderDelay)) {
2232        mEncoderDelay = 0;
2233    }
2234
2235    if (!msg->findInt32("encoder-padding", &mEncoderPadding)) {
2236        mEncoderPadding = 0;
2237    }
2238
2239    if (msg->findInt32("channel-mask", &mChannelMask)) {
2240        mChannelMaskPresent = true;
2241    } else {
2242        mChannelMaskPresent = false;
2243    }
2244
2245    int32_t maxInputSize;
2246    if (msg->findInt32("max-input-size", &maxInputSize)) {
2247        err = setMinBufferSize(kPortIndexInput, (size_t)maxInputSize);
2248        err = OK; // ignore error
2249    } else if (!strcmp("OMX.Nvidia.aac.decoder", mComponentName.c_str())) {
2250        err = setMinBufferSize(kPortIndexInput, 8192);  // XXX
2251        err = OK; // ignore error
2252    }
2253
2254    int32_t priority;
2255    if (msg->findInt32("priority", &priority)) {
2256        err = setPriority(priority);
2257        err = OK; // ignore error
2258    }
2259
2260    int32_t rateInt = -1;
2261    float rateFloat = -1;
2262    if (!msg->findFloat("operating-rate", &rateFloat)) {
2263        msg->findInt32("operating-rate", &rateInt);
2264        rateFloat = (float)rateInt;  // 16MHz (FLINTMAX) is OK for upper bound.
2265    }
2266    if (rateFloat > 0) {
2267        err = setOperatingRate(rateFloat, mIsVideo);
2268        err = OK; // ignore errors
2269    }
2270
2271    if (err == OK) {
2272        err = setVendorParameters(msg);
2273        if (err != OK) {
2274            return err;
2275        }
2276    }
2277
2278    // NOTE: both mBaseOutputFormat and mOutputFormat are outputFormat to signal first frame.
2279    mBaseOutputFormat = outputFormat;
2280    mLastOutputFormat.clear();
2281
2282    err = getPortFormat(kPortIndexInput, inputFormat);
2283    if (err == OK) {
2284        err = getPortFormat(kPortIndexOutput, outputFormat);
2285        if (err == OK) {
2286            mInputFormat = inputFormat;
2287            mOutputFormat = outputFormat;
2288        }
2289    }
2290
2291    // create data converters if needed
2292    if (!mIsVideo && err == OK) {
2293        AudioEncoding codecPcmEncoding = kAudioEncodingPcm16bit;
2294        if (encoder) {
2295            (void)mInputFormat->findInt32("pcm-encoding", (int32_t*)&codecPcmEncoding);
2296            mConverter[kPortIndexInput] = AudioConverter::Create(pcmEncoding, codecPcmEncoding);
2297            if (mConverter[kPortIndexInput] != NULL) {
2298                mInputFormat->setInt32("pcm-encoding", pcmEncoding);
2299            }
2300        } else {
2301            (void)mOutputFormat->findInt32("pcm-encoding", (int32_t*)&codecPcmEncoding);
2302            mConverter[kPortIndexOutput] = AudioConverter::Create(codecPcmEncoding, pcmEncoding);
2303            if (mConverter[kPortIndexOutput] != NULL) {
2304                mOutputFormat->setInt32("pcm-encoding", pcmEncoding);
2305            }
2306        }
2307    }
2308
2309    return err;
2310}
2311
2312status_t ACodec::setLatency(uint32_t latency) {
2313    OMX_PARAM_U32TYPE config;
2314    InitOMXParams(&config);
2315    config.nPortIndex = kPortIndexInput;
2316    config.nU32 = (OMX_U32)latency;
2317    status_t err = mOMXNode->setConfig(
2318            (OMX_INDEXTYPE)OMX_IndexConfigLatency,
2319            &config, sizeof(config));
2320    return err;
2321}
2322
2323status_t ACodec::getLatency(uint32_t *latency) {
2324    OMX_PARAM_U32TYPE config;
2325    InitOMXParams(&config);
2326    config.nPortIndex = kPortIndexInput;
2327    status_t err = mOMXNode->getConfig(
2328            (OMX_INDEXTYPE)OMX_IndexConfigLatency,
2329            &config, sizeof(config));
2330    if (err == OK) {
2331        *latency = config.nU32;
2332    }
2333    return err;
2334}
2335
2336status_t ACodec::setPriority(int32_t priority) {
2337    if (priority < 0) {
2338        return BAD_VALUE;
2339    }
2340    OMX_PARAM_U32TYPE config;
2341    InitOMXParams(&config);
2342    config.nU32 = (OMX_U32)priority;
2343    status_t temp = mOMXNode->setConfig(
2344            (OMX_INDEXTYPE)OMX_IndexConfigPriority,
2345            &config, sizeof(config));
2346    if (temp != OK) {
2347        ALOGI("codec does not support config priority (err %d)", temp);
2348    }
2349    return OK;
2350}
2351
2352status_t ACodec::setOperatingRate(float rateFloat, bool isVideo) {
2353    if (rateFloat < 0) {
2354        return BAD_VALUE;
2355    }
2356    OMX_U32 rate;
2357    if (isVideo) {
2358        if (rateFloat > 65535) {
2359            return BAD_VALUE;
2360        }
2361        rate = (OMX_U32)(rateFloat * 65536.0f + 0.5f);
2362    } else {
2363        if (rateFloat > UINT_MAX) {
2364            return BAD_VALUE;
2365        }
2366        rate = (OMX_U32)(rateFloat);
2367    }
2368    OMX_PARAM_U32TYPE config;
2369    InitOMXParams(&config);
2370    config.nU32 = rate;
2371    status_t err = mOMXNode->setConfig(
2372            (OMX_INDEXTYPE)OMX_IndexConfigOperatingRate,
2373            &config, sizeof(config));
2374    if (err != OK) {
2375        ALOGI("codec does not support config operating rate (err %d)", err);
2376    }
2377    return OK;
2378}
2379
2380status_t ACodec::getIntraRefreshPeriod(uint32_t *intraRefreshPeriod) {
2381    OMX_VIDEO_CONFIG_ANDROID_INTRAREFRESHTYPE params;
2382    InitOMXParams(&params);
2383    params.nPortIndex = kPortIndexOutput;
2384    status_t err = mOMXNode->getConfig(
2385            (OMX_INDEXTYPE)OMX_IndexConfigAndroidIntraRefresh, &params, sizeof(params));
2386    if (err == OK) {
2387        *intraRefreshPeriod = params.nRefreshPeriod;
2388        return OK;
2389    }
2390
2391    // Fallback to query through standard OMX index.
2392    OMX_VIDEO_PARAM_INTRAREFRESHTYPE refreshParams;
2393    InitOMXParams(&refreshParams);
2394    refreshParams.nPortIndex = kPortIndexOutput;
2395    refreshParams.eRefreshMode = OMX_VIDEO_IntraRefreshCyclic;
2396    err = mOMXNode->getParameter(
2397            OMX_IndexParamVideoIntraRefresh, &refreshParams, sizeof(refreshParams));
2398    if (err != OK || refreshParams.nCirMBs == 0) {
2399        *intraRefreshPeriod = 0;
2400        return OK;
2401    }
2402
2403    // Calculate period based on width and height
2404    uint32_t width, height;
2405    OMX_PARAM_PORTDEFINITIONTYPE def;
2406    InitOMXParams(&def);
2407    OMX_VIDEO_PORTDEFINITIONTYPE *video_def = &def.format.video;
2408    def.nPortIndex = kPortIndexOutput;
2409    err = mOMXNode->getParameter(
2410            OMX_IndexParamPortDefinition, &def, sizeof(def));
2411    if (err != OK) {
2412        *intraRefreshPeriod = 0;
2413        return err;
2414    }
2415    width = video_def->nFrameWidth;
2416    height = video_def->nFrameHeight;
2417    // Use H.264/AVC MacroBlock size 16x16
2418    *intraRefreshPeriod = divUp((divUp(width, 16u) * divUp(height, 16u)), refreshParams.nCirMBs);
2419
2420    return OK;
2421}
2422
2423status_t ACodec::setIntraRefreshPeriod(uint32_t intraRefreshPeriod, bool inConfigure) {
2424    OMX_VIDEO_CONFIG_ANDROID_INTRAREFRESHTYPE params;
2425    InitOMXParams(&params);
2426    params.nPortIndex = kPortIndexOutput;
2427    params.nRefreshPeriod = intraRefreshPeriod;
2428    status_t err = mOMXNode->setConfig(
2429            (OMX_INDEXTYPE)OMX_IndexConfigAndroidIntraRefresh, &params, sizeof(params));
2430    if (err == OK) {
2431        return OK;
2432    }
2433
2434    // Only in configure state, a component could invoke setParameter.
2435    if (!inConfigure) {
2436        return INVALID_OPERATION;
2437    } else {
2438        ALOGI("[%s] try falling back to Cyclic", mComponentName.c_str());
2439    }
2440
2441    OMX_VIDEO_PARAM_INTRAREFRESHTYPE refreshParams;
2442    InitOMXParams(&refreshParams);
2443    refreshParams.nPortIndex = kPortIndexOutput;
2444    refreshParams.eRefreshMode = OMX_VIDEO_IntraRefreshCyclic;
2445
2446    if (intraRefreshPeriod == 0) {
2447        // 0 means disable intra refresh.
2448        refreshParams.nCirMBs = 0;
2449    } else {
2450        // Calculate macroblocks that need to be intra coded base on width and height
2451        uint32_t width, height;
2452        OMX_PARAM_PORTDEFINITIONTYPE def;
2453        InitOMXParams(&def);
2454        OMX_VIDEO_PORTDEFINITIONTYPE *video_def = &def.format.video;
2455        def.nPortIndex = kPortIndexOutput;
2456        err = mOMXNode->getParameter(
2457                OMX_IndexParamPortDefinition, &def, sizeof(def));
2458        if (err != OK) {
2459            return err;
2460        }
2461        width = video_def->nFrameWidth;
2462        height = video_def->nFrameHeight;
2463        // Use H.264/AVC MacroBlock size 16x16
2464        refreshParams.nCirMBs = divUp((divUp(width, 16u) * divUp(height, 16u)), intraRefreshPeriod);
2465    }
2466
2467    err = mOMXNode->setParameter(
2468            OMX_IndexParamVideoIntraRefresh,
2469            &refreshParams, sizeof(refreshParams));
2470    if (err != OK) {
2471        return err;
2472    }
2473
2474    return OK;
2475}
2476
2477status_t ACodec::configureTemporalLayers(
2478        const sp<AMessage> &msg, bool inConfigure, sp<AMessage> &outputFormat) {
2479    if (!mIsVideo || !mIsEncoder) {
2480        return INVALID_OPERATION;
2481    }
2482
2483    AString tsSchema;
2484    if (!msg->findString("ts-schema", &tsSchema)) {
2485        return OK;
2486    }
2487
2488    unsigned int numLayers = 0;
2489    unsigned int numBLayers = 0;
2490    int tags;
2491    char dummy;
2492    OMX_VIDEO_ANDROID_TEMPORALLAYERINGPATTERNTYPE pattern =
2493        OMX_VIDEO_AndroidTemporalLayeringPatternNone;
2494    if (sscanf(tsSchema.c_str(), "webrtc.vp8.%u-layer%c", &numLayers, &dummy) == 1
2495            && numLayers > 0) {
2496        pattern = OMX_VIDEO_AndroidTemporalLayeringPatternWebRTC;
2497    } else if ((tags = sscanf(tsSchema.c_str(), "android.generic.%u%c%u%c",
2498                    &numLayers, &dummy, &numBLayers, &dummy))
2499            && (tags == 1 || (tags == 3 && dummy == '+'))
2500            && numLayers > 0 && numLayers < UINT32_MAX - numBLayers) {
2501        numLayers += numBLayers;
2502        pattern = OMX_VIDEO_AndroidTemporalLayeringPatternAndroid;
2503    } else {
2504        ALOGI("Ignoring unsupported ts-schema [%s]", tsSchema.c_str());
2505        return BAD_VALUE;
2506    }
2507
2508    OMX_VIDEO_PARAM_ANDROID_TEMPORALLAYERINGTYPE layerParams;
2509    InitOMXParams(&layerParams);
2510    layerParams.nPortIndex = kPortIndexOutput;
2511
2512    status_t err = mOMXNode->getParameter(
2513            (OMX_INDEXTYPE)OMX_IndexParamAndroidVideoTemporalLayering,
2514            &layerParams, sizeof(layerParams));
2515
2516    if (err != OK) {
2517        return err;
2518    } else if (!(layerParams.eSupportedPatterns & pattern)) {
2519        return BAD_VALUE;
2520    }
2521
2522    numLayers = min(numLayers, layerParams.nLayerCountMax);
2523    numBLayers = min(numBLayers, layerParams.nBLayerCountMax);
2524
2525    if (!inConfigure) {
2526        OMX_VIDEO_CONFIG_ANDROID_TEMPORALLAYERINGTYPE layerConfig;
2527        InitOMXParams(&layerConfig);
2528        layerConfig.nPortIndex = kPortIndexOutput;
2529        layerConfig.ePattern = pattern;
2530        layerConfig.nPLayerCountActual = numLayers - numBLayers;
2531        layerConfig.nBLayerCountActual = numBLayers;
2532        layerConfig.bBitrateRatiosSpecified = OMX_FALSE;
2533
2534        err = mOMXNode->setConfig(
2535                (OMX_INDEXTYPE)OMX_IndexConfigAndroidVideoTemporalLayering,
2536                &layerConfig, sizeof(layerConfig));
2537    } else {
2538        layerParams.ePattern = pattern;
2539        layerParams.nPLayerCountActual = numLayers - numBLayers;
2540        layerParams.nBLayerCountActual = numBLayers;
2541        layerParams.bBitrateRatiosSpecified = OMX_FALSE;
2542
2543        err = mOMXNode->setParameter(
2544                (OMX_INDEXTYPE)OMX_IndexParamAndroidVideoTemporalLayering,
2545                &layerParams, sizeof(layerParams));
2546    }
2547
2548    AString configSchema;
2549    if (pattern == OMX_VIDEO_AndroidTemporalLayeringPatternAndroid) {
2550        configSchema = AStringPrintf("android.generic.%u+%u", numLayers - numBLayers, numBLayers);
2551    } else if (pattern == OMX_VIDEO_AndroidTemporalLayeringPatternWebRTC) {
2552        configSchema = AStringPrintf("webrtc.vp8.%u", numLayers);
2553    }
2554
2555    if (err != OK) {
2556        ALOGW("Failed to set temporal layers to %s (requested %s)",
2557                configSchema.c_str(), tsSchema.c_str());
2558        return err;
2559    }
2560
2561    err = mOMXNode->getParameter(
2562            (OMX_INDEXTYPE)OMX_IndexParamAndroidVideoTemporalLayering,
2563            &layerParams, sizeof(layerParams));
2564
2565    if (err == OK) {
2566        ALOGD("Temporal layers requested:%s configured:%s got:%s(%u: P=%u, B=%u)",
2567                tsSchema.c_str(), configSchema.c_str(),
2568                asString(layerParams.ePattern), layerParams.ePattern,
2569                layerParams.nPLayerCountActual, layerParams.nBLayerCountActual);
2570
2571        if (outputFormat.get() == mOutputFormat.get()) {
2572            mOutputFormat = mOutputFormat->dup(); // trigger an output format change event
2573        }
2574        // assume we got what we configured
2575        outputFormat->setString("ts-schema", configSchema);
2576    }
2577    return err;
2578}
2579
2580status_t ACodec::setMinBufferSize(OMX_U32 portIndex, size_t size) {
2581    OMX_PARAM_PORTDEFINITIONTYPE def;
2582    InitOMXParams(&def);
2583    def.nPortIndex = portIndex;
2584
2585    status_t err = mOMXNode->getParameter(
2586            OMX_IndexParamPortDefinition, &def, sizeof(def));
2587
2588    if (err != OK) {
2589        return err;
2590    }
2591
2592    if (def.nBufferSize >= size) {
2593        return OK;
2594    }
2595
2596    def.nBufferSize = size;
2597
2598    err = mOMXNode->setParameter(
2599            OMX_IndexParamPortDefinition, &def, sizeof(def));
2600
2601    if (err != OK) {
2602        return err;
2603    }
2604
2605    err = mOMXNode->getParameter(
2606            OMX_IndexParamPortDefinition, &def, sizeof(def));
2607
2608    if (err != OK) {
2609        return err;
2610    }
2611
2612    if (def.nBufferSize < size) {
2613        ALOGE("failed to set min buffer size to %zu (is still %u)", size, def.nBufferSize);
2614        return FAILED_TRANSACTION;
2615    }
2616
2617    return OK;
2618}
2619
2620status_t ACodec::selectAudioPortFormat(
2621        OMX_U32 portIndex, OMX_AUDIO_CODINGTYPE desiredFormat) {
2622    OMX_AUDIO_PARAM_PORTFORMATTYPE format;
2623    InitOMXParams(&format);
2624
2625    format.nPortIndex = portIndex;
2626    for (OMX_U32 index = 0; index <= kMaxIndicesToCheck; ++index) {
2627        format.nIndex = index;
2628        status_t err = mOMXNode->getParameter(
2629                OMX_IndexParamAudioPortFormat, &format, sizeof(format));
2630
2631        if (err != OK) {
2632            return err;
2633        }
2634
2635        if (format.eEncoding == desiredFormat) {
2636            break;
2637        }
2638
2639        if (index == kMaxIndicesToCheck) {
2640            ALOGW("[%s] stopping checking formats after %u: %s(%x)",
2641                    mComponentName.c_str(), index,
2642                    asString(format.eEncoding), format.eEncoding);
2643            return ERROR_UNSUPPORTED;
2644        }
2645    }
2646
2647    return mOMXNode->setParameter(
2648            OMX_IndexParamAudioPortFormat, &format, sizeof(format));
2649}
2650
2651status_t ACodec::setupAACCodec(
2652        bool encoder, int32_t numChannels, int32_t sampleRate,
2653        int32_t bitRate, int32_t aacProfile, bool isADTS, int32_t sbrMode,
2654        int32_t maxOutputChannelCount, const drcParams_t& drc,
2655        int32_t pcmLimiterEnable) {
2656    if (encoder && isADTS) {
2657        return -EINVAL;
2658    }
2659
2660    status_t err = setupRawAudioFormat(
2661            encoder ? kPortIndexInput : kPortIndexOutput,
2662            sampleRate,
2663            numChannels);
2664
2665    if (err != OK) {
2666        return err;
2667    }
2668
2669    if (encoder) {
2670        err = selectAudioPortFormat(kPortIndexOutput, OMX_AUDIO_CodingAAC);
2671
2672        if (err != OK) {
2673            return err;
2674        }
2675
2676        OMX_PARAM_PORTDEFINITIONTYPE def;
2677        InitOMXParams(&def);
2678        def.nPortIndex = kPortIndexOutput;
2679
2680        err = mOMXNode->getParameter(
2681                OMX_IndexParamPortDefinition, &def, sizeof(def));
2682
2683        if (err != OK) {
2684            return err;
2685        }
2686
2687        def.format.audio.bFlagErrorConcealment = OMX_TRUE;
2688        def.format.audio.eEncoding = OMX_AUDIO_CodingAAC;
2689
2690        err = mOMXNode->setParameter(
2691                OMX_IndexParamPortDefinition, &def, sizeof(def));
2692
2693        if (err != OK) {
2694            return err;
2695        }
2696
2697        OMX_AUDIO_PARAM_AACPROFILETYPE profile;
2698        InitOMXParams(&profile);
2699        profile.nPortIndex = kPortIndexOutput;
2700
2701        err = mOMXNode->getParameter(
2702                OMX_IndexParamAudioAac, &profile, sizeof(profile));
2703
2704        if (err != OK) {
2705            return err;
2706        }
2707
2708        profile.nChannels = numChannels;
2709
2710        profile.eChannelMode =
2711            (numChannels == 1)
2712                ? OMX_AUDIO_ChannelModeMono: OMX_AUDIO_ChannelModeStereo;
2713
2714        profile.nSampleRate = sampleRate;
2715        profile.nBitRate = bitRate;
2716        profile.nAudioBandWidth = 0;
2717        profile.nFrameLength = 0;
2718        profile.nAACtools = OMX_AUDIO_AACToolAll;
2719        profile.nAACERtools = OMX_AUDIO_AACERNone;
2720        profile.eAACProfile = (OMX_AUDIO_AACPROFILETYPE) aacProfile;
2721        profile.eAACStreamFormat = OMX_AUDIO_AACStreamFormatMP4FF;
2722        switch (sbrMode) {
2723        case 0:
2724            // disable sbr
2725            profile.nAACtools &= ~OMX_AUDIO_AACToolAndroidSSBR;
2726            profile.nAACtools &= ~OMX_AUDIO_AACToolAndroidDSBR;
2727            break;
2728        case 1:
2729            // enable single-rate sbr
2730            profile.nAACtools |= OMX_AUDIO_AACToolAndroidSSBR;
2731            profile.nAACtools &= ~OMX_AUDIO_AACToolAndroidDSBR;
2732            break;
2733        case 2:
2734            // enable dual-rate sbr
2735            profile.nAACtools &= ~OMX_AUDIO_AACToolAndroidSSBR;
2736            profile.nAACtools |= OMX_AUDIO_AACToolAndroidDSBR;
2737            break;
2738        case -1:
2739            // enable both modes -> the codec will decide which mode should be used
2740            profile.nAACtools |= OMX_AUDIO_AACToolAndroidSSBR;
2741            profile.nAACtools |= OMX_AUDIO_AACToolAndroidDSBR;
2742            break;
2743        default:
2744            // unsupported sbr mode
2745            return BAD_VALUE;
2746        }
2747
2748
2749        err = mOMXNode->setParameter(
2750                OMX_IndexParamAudioAac, &profile, sizeof(profile));
2751
2752        if (err != OK) {
2753            return err;
2754        }
2755
2756        return err;
2757    }
2758
2759    OMX_AUDIO_PARAM_AACPROFILETYPE profile;
2760    InitOMXParams(&profile);
2761    profile.nPortIndex = kPortIndexInput;
2762
2763    err = mOMXNode->getParameter(
2764            OMX_IndexParamAudioAac, &profile, sizeof(profile));
2765
2766    if (err != OK) {
2767        return err;
2768    }
2769
2770    profile.nChannels = numChannels;
2771    profile.nSampleRate = sampleRate;
2772
2773    profile.eAACStreamFormat =
2774        isADTS
2775            ? OMX_AUDIO_AACStreamFormatMP4ADTS
2776            : OMX_AUDIO_AACStreamFormatMP4FF;
2777
2778    OMX_AUDIO_PARAM_ANDROID_AACPRESENTATIONTYPE presentation;
2779    InitOMXParams(&presentation);
2780    presentation.nMaxOutputChannels = maxOutputChannelCount;
2781    presentation.nDrcCut = drc.drcCut;
2782    presentation.nDrcBoost = drc.drcBoost;
2783    presentation.nHeavyCompression = drc.heavyCompression;
2784    presentation.nTargetReferenceLevel = drc.targetRefLevel;
2785    presentation.nEncodedTargetLevel = drc.encodedTargetLevel;
2786    presentation.nPCMLimiterEnable = pcmLimiterEnable;
2787
2788    status_t res = mOMXNode->setParameter(
2789            OMX_IndexParamAudioAac, &profile, sizeof(profile));
2790    if (res == OK) {
2791        // optional parameters, will not cause configuration failure
2792        mOMXNode->setParameter(
2793                (OMX_INDEXTYPE)OMX_IndexParamAudioAndroidAacPresentation,
2794                &presentation, sizeof(presentation));
2795    } else {
2796        ALOGW("did not set AudioAndroidAacPresentation due to error %d when setting AudioAac", res);
2797    }
2798    mSampleRate = sampleRate;
2799    return res;
2800}
2801
2802status_t ACodec::setupAC3Codec(
2803        bool encoder, int32_t numChannels, int32_t sampleRate) {
2804    status_t err = setupRawAudioFormat(
2805            encoder ? kPortIndexInput : kPortIndexOutput, sampleRate, numChannels);
2806
2807    if (err != OK) {
2808        return err;
2809    }
2810
2811    if (encoder) {
2812        ALOGW("AC3 encoding is not supported.");
2813        return INVALID_OPERATION;
2814    }
2815
2816    OMX_AUDIO_PARAM_ANDROID_AC3TYPE def;
2817    InitOMXParams(&def);
2818    def.nPortIndex = kPortIndexInput;
2819
2820    err = mOMXNode->getParameter(
2821            (OMX_INDEXTYPE)OMX_IndexParamAudioAndroidAc3, &def, sizeof(def));
2822
2823    if (err != OK) {
2824        return err;
2825    }
2826
2827    def.nChannels = numChannels;
2828    def.nSampleRate = sampleRate;
2829
2830    return mOMXNode->setParameter(
2831            (OMX_INDEXTYPE)OMX_IndexParamAudioAndroidAc3, &def, sizeof(def));
2832}
2833
2834status_t ACodec::setupEAC3Codec(
2835        bool encoder, int32_t numChannels, int32_t sampleRate) {
2836    status_t err = setupRawAudioFormat(
2837            encoder ? kPortIndexInput : kPortIndexOutput, sampleRate, numChannels);
2838
2839    if (err != OK) {
2840        return err;
2841    }
2842
2843    if (encoder) {
2844        ALOGW("EAC3 encoding is not supported.");
2845        return INVALID_OPERATION;
2846    }
2847
2848    OMX_AUDIO_PARAM_ANDROID_EAC3TYPE def;
2849    InitOMXParams(&def);
2850    def.nPortIndex = kPortIndexInput;
2851
2852    err = mOMXNode->getParameter(
2853            (OMX_INDEXTYPE)OMX_IndexParamAudioAndroidEac3, &def, sizeof(def));
2854
2855    if (err != OK) {
2856        return err;
2857    }
2858
2859    def.nChannels = numChannels;
2860    def.nSampleRate = sampleRate;
2861
2862    return mOMXNode->setParameter(
2863            (OMX_INDEXTYPE)OMX_IndexParamAudioAndroidEac3, &def, sizeof(def));
2864}
2865
2866static OMX_AUDIO_AMRBANDMODETYPE pickModeFromBitRate(
2867        bool isAMRWB, int32_t bps) {
2868    if (isAMRWB) {
2869        if (bps <= 6600) {
2870            return OMX_AUDIO_AMRBandModeWB0;
2871        } else if (bps <= 8850) {
2872            return OMX_AUDIO_AMRBandModeWB1;
2873        } else if (bps <= 12650) {
2874            return OMX_AUDIO_AMRBandModeWB2;
2875        } else if (bps <= 14250) {
2876            return OMX_AUDIO_AMRBandModeWB3;
2877        } else if (bps <= 15850) {
2878            return OMX_AUDIO_AMRBandModeWB4;
2879        } else if (bps <= 18250) {
2880            return OMX_AUDIO_AMRBandModeWB5;
2881        } else if (bps <= 19850) {
2882            return OMX_AUDIO_AMRBandModeWB6;
2883        } else if (bps <= 23050) {
2884            return OMX_AUDIO_AMRBandModeWB7;
2885        }
2886
2887        // 23850 bps
2888        return OMX_AUDIO_AMRBandModeWB8;
2889    } else {  // AMRNB
2890        if (bps <= 4750) {
2891            return OMX_AUDIO_AMRBandModeNB0;
2892        } else if (bps <= 5150) {
2893            return OMX_AUDIO_AMRBandModeNB1;
2894        } else if (bps <= 5900) {
2895            return OMX_AUDIO_AMRBandModeNB2;
2896        } else if (bps <= 6700) {
2897            return OMX_AUDIO_AMRBandModeNB3;
2898        } else if (bps <= 7400) {
2899            return OMX_AUDIO_AMRBandModeNB4;
2900        } else if (bps <= 7950) {
2901            return OMX_AUDIO_AMRBandModeNB5;
2902        } else if (bps <= 10200) {
2903            return OMX_AUDIO_AMRBandModeNB6;
2904        }
2905
2906        // 12200 bps
2907        return OMX_AUDIO_AMRBandModeNB7;
2908    }
2909}
2910
2911status_t ACodec::setupAMRCodec(bool encoder, bool isWAMR, int32_t bitrate) {
2912    OMX_AUDIO_PARAM_AMRTYPE def;
2913    InitOMXParams(&def);
2914    def.nPortIndex = encoder ? kPortIndexOutput : kPortIndexInput;
2915
2916    status_t err = mOMXNode->getParameter(
2917            OMX_IndexParamAudioAmr, &def, sizeof(def));
2918
2919    if (err != OK) {
2920        return err;
2921    }
2922
2923    def.eAMRFrameFormat = OMX_AUDIO_AMRFrameFormatFSF;
2924    def.eAMRBandMode = pickModeFromBitRate(isWAMR, bitrate);
2925
2926    err = mOMXNode->setParameter(
2927            OMX_IndexParamAudioAmr, &def, sizeof(def));
2928
2929    if (err != OK) {
2930        return err;
2931    }
2932
2933    return setupRawAudioFormat(
2934            encoder ? kPortIndexInput : kPortIndexOutput,
2935            isWAMR ? 16000 : 8000 /* sampleRate */,
2936            1 /* numChannels */);
2937}
2938
2939status_t ACodec::setupG711Codec(bool encoder, int32_t sampleRate, int32_t numChannels) {
2940    if (encoder) {
2941        return INVALID_OPERATION;
2942    }
2943
2944    return setupRawAudioFormat(
2945            kPortIndexInput, sampleRate, numChannels);
2946}
2947
2948status_t ACodec::setupFlacCodec(
2949        bool encoder, int32_t numChannels, int32_t sampleRate, int32_t compressionLevel) {
2950
2951    if (encoder) {
2952        OMX_AUDIO_PARAM_FLACTYPE def;
2953        InitOMXParams(&def);
2954        def.nPortIndex = kPortIndexOutput;
2955
2956        // configure compression level
2957        status_t err = mOMXNode->getParameter(OMX_IndexParamAudioFlac, &def, sizeof(def));
2958        if (err != OK) {
2959            ALOGE("setupFlacCodec(): Error %d getting OMX_IndexParamAudioFlac parameter", err);
2960            return err;
2961        }
2962        def.nCompressionLevel = compressionLevel;
2963        err = mOMXNode->setParameter(OMX_IndexParamAudioFlac, &def, sizeof(def));
2964        if (err != OK) {
2965            ALOGE("setupFlacCodec(): Error %d setting OMX_IndexParamAudioFlac parameter", err);
2966            return err;
2967        }
2968    }
2969
2970    return setupRawAudioFormat(
2971            encoder ? kPortIndexInput : kPortIndexOutput,
2972            sampleRate,
2973            numChannels);
2974}
2975
2976status_t ACodec::setupRawAudioFormat(
2977        OMX_U32 portIndex, int32_t sampleRate, int32_t numChannels, AudioEncoding encoding) {
2978    OMX_PARAM_PORTDEFINITIONTYPE def;
2979    InitOMXParams(&def);
2980    def.nPortIndex = portIndex;
2981
2982    status_t err = mOMXNode->getParameter(
2983            OMX_IndexParamPortDefinition, &def, sizeof(def));
2984
2985    if (err != OK) {
2986        return err;
2987    }
2988
2989    def.format.audio.eEncoding = OMX_AUDIO_CodingPCM;
2990
2991    err = mOMXNode->setParameter(
2992            OMX_IndexParamPortDefinition, &def, sizeof(def));
2993
2994    if (err != OK) {
2995        return err;
2996    }
2997
2998    OMX_AUDIO_PARAM_PCMMODETYPE pcmParams;
2999    InitOMXParams(&pcmParams);
3000    pcmParams.nPortIndex = portIndex;
3001
3002    err = mOMXNode->getParameter(
3003            OMX_IndexParamAudioPcm, &pcmParams, sizeof(pcmParams));
3004
3005    if (err != OK) {
3006        return err;
3007    }
3008
3009    pcmParams.nChannels = numChannels;
3010    switch (encoding) {
3011        case kAudioEncodingPcm8bit:
3012            pcmParams.eNumData = OMX_NumericalDataUnsigned;
3013            pcmParams.nBitPerSample = 8;
3014            break;
3015        case kAudioEncodingPcmFloat:
3016            pcmParams.eNumData = OMX_NumericalDataFloat;
3017            pcmParams.nBitPerSample = 32;
3018            break;
3019        case kAudioEncodingPcm16bit:
3020            pcmParams.eNumData = OMX_NumericalDataSigned;
3021            pcmParams.nBitPerSample = 16;
3022            break;
3023        default:
3024            return BAD_VALUE;
3025    }
3026    pcmParams.bInterleaved = OMX_TRUE;
3027    pcmParams.nSamplingRate = sampleRate;
3028    pcmParams.ePCMMode = OMX_AUDIO_PCMModeLinear;
3029
3030    if (getOMXChannelMapping(numChannels, pcmParams.eChannelMapping) != OK) {
3031        return OMX_ErrorNone;
3032    }
3033
3034    err = mOMXNode->setParameter(
3035            OMX_IndexParamAudioPcm, &pcmParams, sizeof(pcmParams));
3036    // if we could not set up raw format to non-16-bit, try with 16-bit
3037    // NOTE: we will also verify this via readback, in case codec ignores these fields
3038    if (err != OK && encoding != kAudioEncodingPcm16bit) {
3039        pcmParams.eNumData = OMX_NumericalDataSigned;
3040        pcmParams.nBitPerSample = 16;
3041        err = mOMXNode->setParameter(
3042                OMX_IndexParamAudioPcm, &pcmParams, sizeof(pcmParams));
3043    }
3044    return err;
3045}
3046
3047status_t ACodec::configureTunneledVideoPlayback(
3048        int32_t audioHwSync, const sp<ANativeWindow> &nativeWindow) {
3049    native_handle_t* sidebandHandle;
3050
3051    status_t err = mOMXNode->configureVideoTunnelMode(
3052            kPortIndexOutput, OMX_TRUE, audioHwSync, &sidebandHandle);
3053    if (err != OK) {
3054        ALOGE("configureVideoTunnelMode failed! (err %d).", err);
3055        return err;
3056    }
3057
3058    err = native_window_set_sideband_stream(nativeWindow.get(), sidebandHandle);
3059    if (err != OK) {
3060        ALOGE("native_window_set_sideband_stream(%p) failed! (err %d).",
3061                sidebandHandle, err);
3062        return err;
3063    }
3064
3065    return OK;
3066}
3067
3068status_t ACodec::setVideoPortFormatType(
3069        OMX_U32 portIndex,
3070        OMX_VIDEO_CODINGTYPE compressionFormat,
3071        OMX_COLOR_FORMATTYPE colorFormat,
3072        bool usingNativeBuffers) {
3073    OMX_VIDEO_PARAM_PORTFORMATTYPE format;
3074    InitOMXParams(&format);
3075    format.nPortIndex = portIndex;
3076    format.nIndex = 0;
3077    bool found = false;
3078
3079    for (OMX_U32 index = 0; index <= kMaxIndicesToCheck; ++index) {
3080        format.nIndex = index;
3081        status_t err = mOMXNode->getParameter(
3082                OMX_IndexParamVideoPortFormat,
3083                &format, sizeof(format));
3084
3085        if (err != OK) {
3086            return err;
3087        }
3088
3089        // substitute back flexible color format to codec supported format
3090        OMX_U32 flexibleEquivalent;
3091        if (compressionFormat == OMX_VIDEO_CodingUnused
3092                && IsFlexibleColorFormat(
3093                        mOMXNode, format.eColorFormat, usingNativeBuffers, &flexibleEquivalent)
3094                && colorFormat == flexibleEquivalent) {
3095            ALOGI("[%s] using color format %#x in place of %#x",
3096                    mComponentName.c_str(), format.eColorFormat, colorFormat);
3097            colorFormat = format.eColorFormat;
3098        }
3099
3100        // The following assertion is violated by TI's video decoder.
3101        // CHECK_EQ(format.nIndex, index);
3102
3103        if (!strcmp("OMX.TI.Video.encoder", mComponentName.c_str())) {
3104            if (portIndex == kPortIndexInput
3105                    && colorFormat == format.eColorFormat) {
3106                // eCompressionFormat does not seem right.
3107                found = true;
3108                break;
3109            }
3110            if (portIndex == kPortIndexOutput
3111                    && compressionFormat == format.eCompressionFormat) {
3112                // eColorFormat does not seem right.
3113                found = true;
3114                break;
3115            }
3116        }
3117
3118        if (format.eCompressionFormat == compressionFormat
3119            && format.eColorFormat == colorFormat) {
3120            found = true;
3121            break;
3122        }
3123
3124        if (index == kMaxIndicesToCheck) {
3125            ALOGW("[%s] stopping checking formats after %u: %s(%x)/%s(%x)",
3126                    mComponentName.c_str(), index,
3127                    asString(format.eCompressionFormat), format.eCompressionFormat,
3128                    asString(format.eColorFormat), format.eColorFormat);
3129        }
3130    }
3131
3132    if (!found) {
3133        return UNKNOWN_ERROR;
3134    }
3135
3136    status_t err = mOMXNode->setParameter(
3137            OMX_IndexParamVideoPortFormat, &format, sizeof(format));
3138
3139    return err;
3140}
3141
3142// Set optimal output format. OMX component lists output formats in the order
3143// of preference, but this got more complicated since the introduction of flexible
3144// YUV formats. We support a legacy behavior for applications that do not use
3145// surface output, do not specify an output format, but expect a "usable" standard
3146// OMX format. SW readable and standard formats must be flex-YUV.
3147//
3148// Suggested preference order:
3149// - optimal format for texture rendering (mediaplayer behavior)
3150// - optimal SW readable & texture renderable format (flex-YUV support)
3151// - optimal SW readable non-renderable format (flex-YUV bytebuffer support)
3152// - legacy "usable" standard formats
3153//
3154// For legacy support, we prefer a standard format, but will settle for a SW readable
3155// flex-YUV format.
3156status_t ACodec::setSupportedOutputFormat(bool getLegacyFlexibleFormat) {
3157    OMX_VIDEO_PARAM_PORTFORMATTYPE format, legacyFormat;
3158    InitOMXParams(&format);
3159    format.nPortIndex = kPortIndexOutput;
3160
3161    InitOMXParams(&legacyFormat);
3162    // this field will change when we find a suitable legacy format
3163    legacyFormat.eColorFormat = OMX_COLOR_FormatUnused;
3164
3165    for (OMX_U32 index = 0; ; ++index) {
3166        format.nIndex = index;
3167        status_t err = mOMXNode->getParameter(
3168                OMX_IndexParamVideoPortFormat, &format, sizeof(format));
3169        if (err != OK) {
3170            // no more formats, pick legacy format if found
3171            if (legacyFormat.eColorFormat != OMX_COLOR_FormatUnused) {
3172                 memcpy(&format, &legacyFormat, sizeof(format));
3173                 break;
3174            }
3175            return err;
3176        }
3177        if (format.eCompressionFormat != OMX_VIDEO_CodingUnused) {
3178            return OMX_ErrorBadParameter;
3179        }
3180        if (!getLegacyFlexibleFormat) {
3181            break;
3182        }
3183        // standard formats that were exposed to users before
3184        if (format.eColorFormat == OMX_COLOR_FormatYUV420Planar
3185                || format.eColorFormat == OMX_COLOR_FormatYUV420PackedPlanar
3186                || format.eColorFormat == OMX_COLOR_FormatYUV420SemiPlanar
3187                || format.eColorFormat == OMX_COLOR_FormatYUV420PackedSemiPlanar
3188                || format.eColorFormat == OMX_TI_COLOR_FormatYUV420PackedSemiPlanar) {
3189            break;
3190        }
3191        // find best legacy non-standard format
3192        OMX_U32 flexibleEquivalent;
3193        if (legacyFormat.eColorFormat == OMX_COLOR_FormatUnused
3194                && IsFlexibleColorFormat(
3195                        mOMXNode, format.eColorFormat, false /* usingNativeBuffers */,
3196                        &flexibleEquivalent)
3197                && flexibleEquivalent == OMX_COLOR_FormatYUV420Flexible) {
3198            memcpy(&legacyFormat, &format, sizeof(format));
3199        }
3200    }
3201    return mOMXNode->setParameter(
3202            OMX_IndexParamVideoPortFormat, &format, sizeof(format));
3203}
3204
3205static const struct VideoCodingMapEntry {
3206    const char *mMime;
3207    OMX_VIDEO_CODINGTYPE mVideoCodingType;
3208} kVideoCodingMapEntry[] = {
3209    { MEDIA_MIMETYPE_VIDEO_AVC, OMX_VIDEO_CodingAVC },
3210    { MEDIA_MIMETYPE_VIDEO_HEVC, OMX_VIDEO_CodingHEVC },
3211    { MEDIA_MIMETYPE_VIDEO_MPEG4, OMX_VIDEO_CodingMPEG4 },
3212    { MEDIA_MIMETYPE_VIDEO_H263, OMX_VIDEO_CodingH263 },
3213    { MEDIA_MIMETYPE_VIDEO_MPEG2, OMX_VIDEO_CodingMPEG2 },
3214    { MEDIA_MIMETYPE_VIDEO_VP8, OMX_VIDEO_CodingVP8 },
3215    { MEDIA_MIMETYPE_VIDEO_VP9, OMX_VIDEO_CodingVP9 },
3216    { MEDIA_MIMETYPE_VIDEO_DOLBY_VISION, OMX_VIDEO_CodingDolbyVision },
3217};
3218
3219static status_t GetVideoCodingTypeFromMime(
3220        const char *mime, OMX_VIDEO_CODINGTYPE *codingType) {
3221    for (size_t i = 0;
3222         i < sizeof(kVideoCodingMapEntry) / sizeof(kVideoCodingMapEntry[0]);
3223         ++i) {
3224        if (!strcasecmp(mime, kVideoCodingMapEntry[i].mMime)) {
3225            *codingType = kVideoCodingMapEntry[i].mVideoCodingType;
3226            return OK;
3227        }
3228    }
3229
3230    *codingType = OMX_VIDEO_CodingUnused;
3231
3232    return ERROR_UNSUPPORTED;
3233}
3234
3235static status_t GetMimeTypeForVideoCoding(
3236        OMX_VIDEO_CODINGTYPE codingType, AString *mime) {
3237    for (size_t i = 0;
3238         i < sizeof(kVideoCodingMapEntry) / sizeof(kVideoCodingMapEntry[0]);
3239         ++i) {
3240        if (codingType == kVideoCodingMapEntry[i].mVideoCodingType) {
3241            *mime = kVideoCodingMapEntry[i].mMime;
3242            return OK;
3243        }
3244    }
3245
3246    mime->clear();
3247
3248    return ERROR_UNSUPPORTED;
3249}
3250
3251status_t ACodec::setPortBufferNum(OMX_U32 portIndex, int bufferNum) {
3252    OMX_PARAM_PORTDEFINITIONTYPE def;
3253    InitOMXParams(&def);
3254    def.nPortIndex = portIndex;
3255    status_t err;
3256    ALOGD("Setting [%s] %s port buffer number: %d", mComponentName.c_str(),
3257            portIndex == kPortIndexInput ? "input" : "output", bufferNum);
3258    err = mOMXNode->getParameter(
3259        OMX_IndexParamPortDefinition, &def, sizeof(def));
3260    if (err != OK) {
3261        return err;
3262    }
3263    def.nBufferCountActual = bufferNum;
3264    err = mOMXNode->setParameter(
3265        OMX_IndexParamPortDefinition, &def, sizeof(def));
3266    if (err != OK) {
3267        // Component could reject this request.
3268        ALOGW("Fail to set [%s] %s port buffer number: %d", mComponentName.c_str(),
3269            portIndex == kPortIndexInput ? "input" : "output", bufferNum);
3270    }
3271    return OK;
3272}
3273
3274status_t ACodec::setupVideoDecoder(
3275        const char *mime, const sp<AMessage> &msg, bool haveNativeWindow,
3276        bool usingSwRenderer, sp<AMessage> &outputFormat) {
3277    int32_t width, height;
3278    if (!msg->findInt32("width", &width)
3279            || !msg->findInt32("height", &height)) {
3280        return INVALID_OPERATION;
3281    }
3282
3283    OMX_VIDEO_CODINGTYPE compressionFormat;
3284    status_t err = GetVideoCodingTypeFromMime(mime, &compressionFormat);
3285
3286    if (err != OK) {
3287        return err;
3288    }
3289
3290    if (compressionFormat == OMX_VIDEO_CodingVP9) {
3291        OMX_VIDEO_PARAM_PROFILELEVELTYPE params;
3292        InitOMXParams(&params);
3293        params.nPortIndex = kPortIndexInput;
3294        // Check if VP9 decoder advertises supported profiles.
3295        params.nProfileIndex = 0;
3296        status_t err = mOMXNode->getParameter(
3297                OMX_IndexParamVideoProfileLevelQuerySupported,
3298                &params, sizeof(params));
3299        mIsLegacyVP9Decoder = err != OK;
3300    }
3301
3302    err = setVideoPortFormatType(
3303            kPortIndexInput, compressionFormat, OMX_COLOR_FormatUnused);
3304
3305    if (err != OK) {
3306        return err;
3307    }
3308
3309    int32_t tmp;
3310    if (msg->findInt32("color-format", &tmp)) {
3311        OMX_COLOR_FORMATTYPE colorFormat =
3312            static_cast<OMX_COLOR_FORMATTYPE>(tmp);
3313        err = setVideoPortFormatType(
3314                kPortIndexOutput, OMX_VIDEO_CodingUnused, colorFormat, haveNativeWindow);
3315        if (err != OK) {
3316            ALOGW("[%s] does not support color format %d",
3317                  mComponentName.c_str(), colorFormat);
3318            err = setSupportedOutputFormat(!haveNativeWindow /* getLegacyFlexibleFormat */);
3319        }
3320    } else {
3321        err = setSupportedOutputFormat(!haveNativeWindow /* getLegacyFlexibleFormat */);
3322    }
3323
3324    if (err != OK) {
3325        return err;
3326    }
3327
3328    // Set the component input buffer number to be |tmp|. If succeed,
3329    // component will set input port buffer number to be |tmp|. If fail,
3330    // component will keep the same buffer number as before.
3331    if (msg->findInt32("android._num-input-buffers", &tmp)) {
3332        err = setPortBufferNum(kPortIndexInput, tmp);
3333        if (err != OK)
3334            return err;
3335    }
3336
3337    // Set the component output buffer number to be |tmp|. If succeed,
3338    // component will set output port buffer number to be |tmp|. If fail,
3339    // component will keep the same buffer number as before.
3340    if (msg->findInt32("android._num-output-buffers", &tmp)) {
3341        err = setPortBufferNum(kPortIndexOutput, tmp);
3342        if (err != OK)
3343            return err;
3344    }
3345
3346    int32_t frameRateInt;
3347    float frameRateFloat;
3348    if (!msg->findFloat("frame-rate", &frameRateFloat)) {
3349        if (!msg->findInt32("frame-rate", &frameRateInt)) {
3350            frameRateInt = -1;
3351        }
3352        frameRateFloat = (float)frameRateInt;
3353    }
3354
3355    err = setVideoFormatOnPort(
3356            kPortIndexInput, width, height, compressionFormat, frameRateFloat);
3357
3358    if (err != OK) {
3359        return err;
3360    }
3361
3362    err = setVideoFormatOnPort(
3363            kPortIndexOutput, width, height, OMX_VIDEO_CodingUnused);
3364
3365    if (err != OK) {
3366        return err;
3367    }
3368
3369    err = setColorAspectsForVideoDecoder(
3370            width, height, haveNativeWindow | usingSwRenderer, msg, outputFormat);
3371    if (err == ERROR_UNSUPPORTED) { // support is optional
3372        err = OK;
3373    }
3374
3375    if (err != OK) {
3376        return err;
3377    }
3378
3379    err = setHDRStaticInfoForVideoCodec(kPortIndexOutput, msg, outputFormat);
3380    if (err == ERROR_UNSUPPORTED) { // support is optional
3381        err = OK;
3382    }
3383    return err;
3384}
3385
3386status_t ACodec::initDescribeColorAspectsIndex() {
3387    status_t err = mOMXNode->getExtensionIndex(
3388            "OMX.google.android.index.describeColorAspects", &mDescribeColorAspectsIndex);
3389    if (err != OK) {
3390        mDescribeColorAspectsIndex = (OMX_INDEXTYPE)0;
3391    }
3392    return err;
3393}
3394
3395status_t ACodec::setCodecColorAspects(DescribeColorAspectsParams &params, bool verify) {
3396    status_t err = ERROR_UNSUPPORTED;
3397    if (mDescribeColorAspectsIndex) {
3398        err = mOMXNode->setConfig(mDescribeColorAspectsIndex, &params, sizeof(params));
3399    }
3400    ALOGV("[%s] setting color aspects (R:%d(%s), P:%d(%s), M:%d(%s), T:%d(%s)) err=%d(%s)",
3401            mComponentName.c_str(),
3402            params.sAspects.mRange, asString(params.sAspects.mRange),
3403            params.sAspects.mPrimaries, asString(params.sAspects.mPrimaries),
3404            params.sAspects.mMatrixCoeffs, asString(params.sAspects.mMatrixCoeffs),
3405            params.sAspects.mTransfer, asString(params.sAspects.mTransfer),
3406            err, asString(err));
3407
3408    if (verify && err == OK) {
3409        err = getCodecColorAspects(params);
3410    }
3411
3412    ALOGW_IF(err == ERROR_UNSUPPORTED && mDescribeColorAspectsIndex,
3413            "[%s] setting color aspects failed even though codec advertises support",
3414            mComponentName.c_str());
3415    return err;
3416}
3417
3418status_t ACodec::setColorAspectsForVideoDecoder(
3419        int32_t width, int32_t height, bool usingNativeWindow,
3420        const sp<AMessage> &configFormat, sp<AMessage> &outputFormat) {
3421    DescribeColorAspectsParams params;
3422    InitOMXParams(&params);
3423    params.nPortIndex = kPortIndexOutput;
3424
3425    getColorAspectsFromFormat(configFormat, params.sAspects);
3426    if (usingNativeWindow) {
3427        setDefaultCodecColorAspectsIfNeeded(params.sAspects, width, height);
3428        // The default aspects will be set back to the output format during the
3429        // getFormat phase of configure(). Set non-Unspecified values back into the
3430        // format, in case component does not support this enumeration.
3431        setColorAspectsIntoFormat(params.sAspects, outputFormat);
3432    }
3433
3434    (void)initDescribeColorAspectsIndex();
3435
3436    // communicate color aspects to codec
3437    return setCodecColorAspects(params);
3438}
3439
3440status_t ACodec::getCodecColorAspects(DescribeColorAspectsParams &params) {
3441    status_t err = ERROR_UNSUPPORTED;
3442    if (mDescribeColorAspectsIndex) {
3443        err = mOMXNode->getConfig(mDescribeColorAspectsIndex, &params, sizeof(params));
3444    }
3445    ALOGV("[%s] got color aspects (R:%d(%s), P:%d(%s), M:%d(%s), T:%d(%s)) err=%d(%s)",
3446            mComponentName.c_str(),
3447            params.sAspects.mRange, asString(params.sAspects.mRange),
3448            params.sAspects.mPrimaries, asString(params.sAspects.mPrimaries),
3449            params.sAspects.mMatrixCoeffs, asString(params.sAspects.mMatrixCoeffs),
3450            params.sAspects.mTransfer, asString(params.sAspects.mTransfer),
3451            err, asString(err));
3452    if (params.bRequestingDataSpace) {
3453        ALOGV("for dataspace %#x", params.nDataSpace);
3454    }
3455    if (err == ERROR_UNSUPPORTED && mDescribeColorAspectsIndex
3456            && !params.bRequestingDataSpace && !params.bDataSpaceChanged) {
3457        ALOGW("[%s] getting color aspects failed even though codec advertises support",
3458                mComponentName.c_str());
3459    }
3460    return err;
3461}
3462
3463status_t ACodec::getInputColorAspectsForVideoEncoder(sp<AMessage> &format) {
3464    DescribeColorAspectsParams params;
3465    InitOMXParams(&params);
3466    params.nPortIndex = kPortIndexInput;
3467    status_t err = getCodecColorAspects(params);
3468    if (err == OK) {
3469        // we only set encoder input aspects if codec supports them
3470        setColorAspectsIntoFormat(params.sAspects, format, true /* force */);
3471    }
3472    return err;
3473}
3474
3475status_t ACodec::getDataSpace(
3476        DescribeColorAspectsParams &params, android_dataspace *dataSpace /* nonnull */,
3477        bool tryCodec) {
3478    status_t err = OK;
3479    if (tryCodec) {
3480        // request dataspace guidance from codec.
3481        params.bRequestingDataSpace = OMX_TRUE;
3482        err = getCodecColorAspects(params);
3483        params.bRequestingDataSpace = OMX_FALSE;
3484        if (err == OK && params.nDataSpace != HAL_DATASPACE_UNKNOWN) {
3485            *dataSpace = (android_dataspace)params.nDataSpace;
3486            return err;
3487        } else if (err == ERROR_UNSUPPORTED) {
3488            // ignore not-implemented error for dataspace requests
3489            err = OK;
3490        }
3491    }
3492
3493    // this returns legacy versions if available
3494    *dataSpace = getDataSpaceForColorAspects(params.sAspects, true /* mayexpand */);
3495    ALOGV("[%s] using color aspects (R:%d(%s), P:%d(%s), M:%d(%s), T:%d(%s)) "
3496          "and dataspace %#x",
3497            mComponentName.c_str(),
3498            params.sAspects.mRange, asString(params.sAspects.mRange),
3499            params.sAspects.mPrimaries, asString(params.sAspects.mPrimaries),
3500            params.sAspects.mMatrixCoeffs, asString(params.sAspects.mMatrixCoeffs),
3501            params.sAspects.mTransfer, asString(params.sAspects.mTransfer),
3502            *dataSpace);
3503    return err;
3504}
3505
3506
3507status_t ACodec::getColorAspectsAndDataSpaceForVideoDecoder(
3508        int32_t width, int32_t height, const sp<AMessage> &configFormat, sp<AMessage> &outputFormat,
3509        android_dataspace *dataSpace) {
3510    DescribeColorAspectsParams params;
3511    InitOMXParams(&params);
3512    params.nPortIndex = kPortIndexOutput;
3513
3514    // reset default format and get resulting format
3515    getColorAspectsFromFormat(configFormat, params.sAspects);
3516    if (dataSpace != NULL) {
3517        setDefaultCodecColorAspectsIfNeeded(params.sAspects, width, height);
3518    }
3519    status_t err = setCodecColorAspects(params, true /* readBack */);
3520
3521    // we always set specified aspects for decoders
3522    setColorAspectsIntoFormat(params.sAspects, outputFormat);
3523
3524    if (dataSpace != NULL) {
3525        status_t res = getDataSpace(params, dataSpace, err == OK /* tryCodec */);
3526        if (err == OK) {
3527            err = res;
3528        }
3529    }
3530
3531    return err;
3532}
3533
3534// initial video encoder setup for bytebuffer mode
3535status_t ACodec::setColorAspectsForVideoEncoder(
3536        const sp<AMessage> &configFormat, sp<AMessage> &outputFormat, sp<AMessage> &inputFormat) {
3537    // copy config to output format as this is not exposed via getFormat
3538    copyColorConfig(configFormat, outputFormat);
3539
3540    DescribeColorAspectsParams params;
3541    InitOMXParams(&params);
3542    params.nPortIndex = kPortIndexInput;
3543    getColorAspectsFromFormat(configFormat, params.sAspects);
3544
3545    (void)initDescribeColorAspectsIndex();
3546
3547    int32_t usingRecorder;
3548    if (configFormat->findInt32("android._using-recorder", &usingRecorder) && usingRecorder) {
3549        android_dataspace dataSpace = HAL_DATASPACE_BT709;
3550        int32_t width, height;
3551        if (configFormat->findInt32("width", &width)
3552                && configFormat->findInt32("height", &height)) {
3553            setDefaultCodecColorAspectsIfNeeded(params.sAspects, width, height);
3554            status_t err = getDataSpace(
3555                    params, &dataSpace, mDescribeColorAspectsIndex /* tryCodec */);
3556            if (err != OK) {
3557                return err;
3558            }
3559            setColorAspectsIntoFormat(params.sAspects, outputFormat);
3560        }
3561        inputFormat->setInt32("android._dataspace", (int32_t)dataSpace);
3562    }
3563
3564    // communicate color aspects to codec, but do not allow change of the platform aspects
3565    ColorAspects origAspects = params.sAspects;
3566    for (int triesLeft = 2; --triesLeft >= 0; ) {
3567        status_t err = setCodecColorAspects(params, true /* readBack */);
3568        if (err != OK
3569                || !ColorUtils::checkIfAspectsChangedAndUnspecifyThem(
3570                        params.sAspects, origAspects, true /* usePlatformAspects */)) {
3571            return err;
3572        }
3573        ALOGW_IF(triesLeft == 0, "[%s] Codec repeatedly changed requested ColorAspects.",
3574                mComponentName.c_str());
3575    }
3576    return OK;
3577}
3578
3579status_t ACodec::setHDRStaticInfoForVideoCodec(
3580        OMX_U32 portIndex, const sp<AMessage> &configFormat, sp<AMessage> &outputFormat) {
3581    CHECK(portIndex == kPortIndexInput || portIndex == kPortIndexOutput);
3582
3583    DescribeHDRStaticInfoParams params;
3584    InitOMXParams(&params);
3585    params.nPortIndex = portIndex;
3586
3587    HDRStaticInfo *info = &params.sInfo;
3588    if (getHDRStaticInfoFromFormat(configFormat, info)) {
3589        setHDRStaticInfoIntoFormat(params.sInfo, outputFormat);
3590    }
3591
3592    (void)initDescribeHDRStaticInfoIndex();
3593
3594    // communicate HDR static Info to codec
3595    return setHDRStaticInfo(params);
3596}
3597
3598// subsequent initial video encoder setup for surface mode
3599status_t ACodec::setInitialColorAspectsForVideoEncoderSurfaceAndGetDataSpace(
3600        android_dataspace *dataSpace /* nonnull */) {
3601    DescribeColorAspectsParams params;
3602    InitOMXParams(&params);
3603    params.nPortIndex = kPortIndexInput;
3604    ColorAspects &aspects = params.sAspects;
3605
3606    // reset default format and store resulting format into both input and output formats
3607    getColorAspectsFromFormat(mConfigFormat, aspects);
3608    int32_t width, height;
3609    if (mInputFormat->findInt32("width", &width) && mInputFormat->findInt32("height", &height)) {
3610        setDefaultCodecColorAspectsIfNeeded(aspects, width, height);
3611    }
3612    setColorAspectsIntoFormat(aspects, mInputFormat);
3613    setColorAspectsIntoFormat(aspects, mOutputFormat);
3614
3615    // communicate color aspects to codec, but do not allow any change
3616    ColorAspects origAspects = aspects;
3617    status_t err = OK;
3618    for (int triesLeft = 2; mDescribeColorAspectsIndex && --triesLeft >= 0; ) {
3619        status_t err = setCodecColorAspects(params, true /* readBack */);
3620        if (err != OK || !ColorUtils::checkIfAspectsChangedAndUnspecifyThem(aspects, origAspects)) {
3621            break;
3622        }
3623        ALOGW_IF(triesLeft == 0, "[%s] Codec repeatedly changed requested ColorAspects.",
3624                mComponentName.c_str());
3625    }
3626
3627    *dataSpace = HAL_DATASPACE_BT709;
3628    aspects = origAspects; // restore desired color aspects
3629    status_t res = getDataSpace(
3630            params, dataSpace, err == OK && mDescribeColorAspectsIndex /* tryCodec */);
3631    if (err == OK) {
3632        err = res;
3633    }
3634    mInputFormat->setInt32("android._dataspace", (int32_t)*dataSpace);
3635    mInputFormat->setBuffer(
3636            "android._color-aspects", ABuffer::CreateAsCopy(&aspects, sizeof(aspects)));
3637
3638    // update input format with codec supported color aspects (basically set unsupported
3639    // aspects to Unspecified)
3640    if (err == OK) {
3641        (void)getInputColorAspectsForVideoEncoder(mInputFormat);
3642    }
3643
3644    ALOGV("set default color aspects, updated input format to %s, output format to %s",
3645            mInputFormat->debugString(4).c_str(), mOutputFormat->debugString(4).c_str());
3646
3647    return err;
3648}
3649
3650status_t ACodec::getHDRStaticInfoForVideoCodec(OMX_U32 portIndex, sp<AMessage> &format) {
3651    CHECK(portIndex == kPortIndexInput || portIndex == kPortIndexOutput);
3652    DescribeHDRStaticInfoParams params;
3653    InitOMXParams(&params);
3654    params.nPortIndex = portIndex;
3655
3656    status_t err = getHDRStaticInfo(params);
3657    if (err == OK) {
3658        // we only set decodec output HDRStaticInfo if codec supports them
3659        setHDRStaticInfoIntoFormat(params.sInfo, format);
3660    }
3661    return err;
3662}
3663
3664status_t ACodec::initDescribeHDRStaticInfoIndex() {
3665    status_t err = mOMXNode->getExtensionIndex(
3666            "OMX.google.android.index.describeHDRStaticInfo", &mDescribeHDRStaticInfoIndex);
3667    if (err != OK) {
3668        mDescribeHDRStaticInfoIndex = (OMX_INDEXTYPE)0;
3669    }
3670    return err;
3671}
3672
3673status_t ACodec::setHDRStaticInfo(const DescribeHDRStaticInfoParams &params) {
3674    status_t err = ERROR_UNSUPPORTED;
3675    if (mDescribeHDRStaticInfoIndex) {
3676        err = mOMXNode->setConfig(mDescribeHDRStaticInfoIndex, &params, sizeof(params));
3677    }
3678
3679    const HDRStaticInfo *info = &params.sInfo;
3680    ALOGV("[%s] setting  HDRStaticInfo (R: %u %u, G: %u %u, B: %u, %u, W: %u, %u, "
3681            "MaxDispL: %u, MinDispL: %u, MaxContentL: %u, MaxFrameAvgL: %u)",
3682            mComponentName.c_str(),
3683            info->sType1.mR.x, info->sType1.mR.y, info->sType1.mG.x, info->sType1.mG.y,
3684            info->sType1.mB.x, info->sType1.mB.y, info->sType1.mW.x, info->sType1.mW.y,
3685            info->sType1.mMaxDisplayLuminance, info->sType1.mMinDisplayLuminance,
3686            info->sType1.mMaxContentLightLevel, info->sType1.mMaxFrameAverageLightLevel);
3687
3688    ALOGW_IF(err == ERROR_UNSUPPORTED && mDescribeHDRStaticInfoIndex,
3689            "[%s] setting HDRStaticInfo failed even though codec advertises support",
3690            mComponentName.c_str());
3691    return err;
3692}
3693
3694status_t ACodec::getHDRStaticInfo(DescribeHDRStaticInfoParams &params) {
3695    status_t err = ERROR_UNSUPPORTED;
3696    if (mDescribeHDRStaticInfoIndex) {
3697        err = mOMXNode->getConfig(mDescribeHDRStaticInfoIndex, &params, sizeof(params));
3698    }
3699
3700    ALOGW_IF(err == ERROR_UNSUPPORTED && mDescribeHDRStaticInfoIndex,
3701            "[%s] getting HDRStaticInfo failed even though codec advertises support",
3702            mComponentName.c_str());
3703    return err;
3704}
3705
3706status_t ACodec::setupVideoEncoder(
3707        const char *mime, const sp<AMessage> &msg,
3708        sp<AMessage> &outputFormat, sp<AMessage> &inputFormat) {
3709    int32_t tmp;
3710    if (!msg->findInt32("color-format", &tmp)) {
3711        return INVALID_OPERATION;
3712    }
3713
3714    OMX_COLOR_FORMATTYPE colorFormat =
3715        static_cast<OMX_COLOR_FORMATTYPE>(tmp);
3716
3717    status_t err = setVideoPortFormatType(
3718            kPortIndexInput, OMX_VIDEO_CodingUnused, colorFormat);
3719
3720    if (err != OK) {
3721        ALOGE("[%s] does not support color format %d",
3722              mComponentName.c_str(), colorFormat);
3723
3724        return err;
3725    }
3726
3727    /* Input port configuration */
3728
3729    OMX_PARAM_PORTDEFINITIONTYPE def;
3730    InitOMXParams(&def);
3731
3732    OMX_VIDEO_PORTDEFINITIONTYPE *video_def = &def.format.video;
3733
3734    def.nPortIndex = kPortIndexInput;
3735
3736    err = mOMXNode->getParameter(
3737            OMX_IndexParamPortDefinition, &def, sizeof(def));
3738
3739    if (err != OK) {
3740        return err;
3741    }
3742
3743    OMX_VIDEO_CONTROLRATETYPE bitrateMode;
3744    int32_t width, height, bitrate = 0, quality;
3745    if (!msg->findInt32("width", &width)
3746            || !msg->findInt32("height", &height)
3747            || !findVideoBitrateControlInfo(
3748                    msg, &bitrateMode, &bitrate, &quality)) {
3749        return INVALID_OPERATION;
3750    }
3751
3752    video_def->nFrameWidth = width;
3753    video_def->nFrameHeight = height;
3754
3755    int32_t stride;
3756    if (!msg->findInt32("stride", &stride)) {
3757        stride = width;
3758    }
3759
3760    video_def->nStride = stride;
3761
3762    int32_t sliceHeight;
3763    if (!msg->findInt32("slice-height", &sliceHeight)) {
3764        sliceHeight = height;
3765    }
3766
3767    video_def->nSliceHeight = sliceHeight;
3768
3769    def.nBufferSize = (video_def->nStride * video_def->nSliceHeight * 3) / 2;
3770
3771    float framerate;
3772    if (!msg->findFloat("frame-rate", &framerate)) {
3773        int32_t tmp;
3774        if (!msg->findInt32("frame-rate", &tmp)) {
3775            return INVALID_OPERATION;
3776        }
3777        mFps = (double)tmp;
3778    } else {
3779        mFps = (double)framerate;
3780    }
3781    // propagate framerate to the output so that the muxer has it
3782    outputFormat->setInt32("frame-rate", (int32_t)mFps);
3783
3784    video_def->xFramerate = (OMX_U32)(mFps * 65536);
3785    video_def->eCompressionFormat = OMX_VIDEO_CodingUnused;
3786    // this is redundant as it was already set up in setVideoPortFormatType
3787    // FIXME for now skip this only for flexible YUV formats
3788    if (colorFormat != OMX_COLOR_FormatYUV420Flexible) {
3789        video_def->eColorFormat = colorFormat;
3790    }
3791
3792    err = mOMXNode->setParameter(
3793            OMX_IndexParamPortDefinition, &def, sizeof(def));
3794
3795    if (err != OK) {
3796        ALOGE("[%s] failed to set input port definition parameters.",
3797              mComponentName.c_str());
3798
3799        return err;
3800    }
3801
3802    /* Output port configuration */
3803
3804    OMX_VIDEO_CODINGTYPE compressionFormat;
3805    err = GetVideoCodingTypeFromMime(mime, &compressionFormat);
3806
3807    if (err != OK) {
3808        return err;
3809    }
3810
3811    err = setVideoPortFormatType(
3812            kPortIndexOutput, compressionFormat, OMX_COLOR_FormatUnused);
3813
3814    if (err != OK) {
3815        ALOGE("[%s] does not support compression format %d",
3816             mComponentName.c_str(), compressionFormat);
3817
3818        return err;
3819    }
3820
3821    def.nPortIndex = kPortIndexOutput;
3822
3823    err = mOMXNode->getParameter(
3824            OMX_IndexParamPortDefinition, &def, sizeof(def));
3825
3826    if (err != OK) {
3827        return err;
3828    }
3829
3830    video_def->nFrameWidth = width;
3831    video_def->nFrameHeight = height;
3832    video_def->xFramerate = 0;
3833    video_def->nBitrate = bitrate;
3834    video_def->eCompressionFormat = compressionFormat;
3835    video_def->eColorFormat = OMX_COLOR_FormatUnused;
3836
3837    err = mOMXNode->setParameter(
3838            OMX_IndexParamPortDefinition, &def, sizeof(def));
3839
3840    if (err != OK) {
3841        ALOGE("[%s] failed to set output port definition parameters.",
3842              mComponentName.c_str());
3843
3844        return err;
3845    }
3846
3847    int32_t intraRefreshPeriod = 0;
3848    if (msg->findInt32("intra-refresh-period", &intraRefreshPeriod)
3849            && intraRefreshPeriod >= 0) {
3850        err = setIntraRefreshPeriod((uint32_t)intraRefreshPeriod, true);
3851        if (err != OK) {
3852            ALOGI("[%s] failed setIntraRefreshPeriod. Failure is fine since this key is optional",
3853                    mComponentName.c_str());
3854            err = OK;
3855        }
3856    }
3857
3858    configureEncoderLatency(msg);
3859
3860    switch (compressionFormat) {
3861        case OMX_VIDEO_CodingMPEG4:
3862            err = setupMPEG4EncoderParameters(msg);
3863            break;
3864
3865        case OMX_VIDEO_CodingH263:
3866            err = setupH263EncoderParameters(msg);
3867            break;
3868
3869        case OMX_VIDEO_CodingAVC:
3870            err = setupAVCEncoderParameters(msg);
3871            break;
3872
3873        case OMX_VIDEO_CodingHEVC:
3874            err = setupHEVCEncoderParameters(msg);
3875            break;
3876
3877        case OMX_VIDEO_CodingVP8:
3878        case OMX_VIDEO_CodingVP9:
3879            err = setupVPXEncoderParameters(msg, outputFormat);
3880            break;
3881
3882        default:
3883            break;
3884    }
3885
3886    if (err != OK) {
3887        return err;
3888    }
3889
3890    // Set up color aspects on input, but propagate them to the output format, as they will
3891    // not be read back from encoder.
3892    err = setColorAspectsForVideoEncoder(msg, outputFormat, inputFormat);
3893    if (err == ERROR_UNSUPPORTED) {
3894        ALOGI("[%s] cannot encode color aspects. Ignoring.", mComponentName.c_str());
3895        err = OK;
3896    }
3897
3898    if (err != OK) {
3899        return err;
3900    }
3901
3902    err = setHDRStaticInfoForVideoCodec(kPortIndexInput, msg, outputFormat);
3903    if (err == ERROR_UNSUPPORTED) { // support is optional
3904        ALOGI("[%s] cannot encode HDR static metadata. Ignoring.", mComponentName.c_str());
3905        err = OK;
3906    }
3907
3908    if (err != OK) {
3909        return err;
3910    }
3911
3912    switch (compressionFormat) {
3913        case OMX_VIDEO_CodingAVC:
3914        case OMX_VIDEO_CodingHEVC:
3915            err = configureTemporalLayers(msg, true /* inConfigure */, outputFormat);
3916            if (err != OK) {
3917                err = OK; // ignore failure
3918            }
3919            break;
3920
3921        case OMX_VIDEO_CodingVP8:
3922        case OMX_VIDEO_CodingVP9:
3923            // TODO: do we need to support android.generic layering? webrtc layering is
3924            // already set up in setupVPXEncoderParameters.
3925            break;
3926
3927        default:
3928            break;
3929    }
3930
3931    if (err == OK) {
3932        ALOGI("setupVideoEncoder succeeded");
3933    }
3934
3935    return err;
3936}
3937
3938status_t ACodec::setCyclicIntraMacroblockRefresh(const sp<AMessage> &msg, int32_t mode) {
3939    OMX_VIDEO_PARAM_INTRAREFRESHTYPE params;
3940    InitOMXParams(&params);
3941    params.nPortIndex = kPortIndexOutput;
3942
3943    params.eRefreshMode = static_cast<OMX_VIDEO_INTRAREFRESHTYPE>(mode);
3944
3945    if (params.eRefreshMode == OMX_VIDEO_IntraRefreshCyclic ||
3946            params.eRefreshMode == OMX_VIDEO_IntraRefreshBoth) {
3947        int32_t mbs;
3948        if (!msg->findInt32("intra-refresh-CIR-mbs", &mbs)) {
3949            return INVALID_OPERATION;
3950        }
3951        params.nCirMBs = mbs;
3952    }
3953
3954    if (params.eRefreshMode == OMX_VIDEO_IntraRefreshAdaptive ||
3955            params.eRefreshMode == OMX_VIDEO_IntraRefreshBoth) {
3956        int32_t mbs;
3957        if (!msg->findInt32("intra-refresh-AIR-mbs", &mbs)) {
3958            return INVALID_OPERATION;
3959        }
3960        params.nAirMBs = mbs;
3961
3962        int32_t ref;
3963        if (!msg->findInt32("intra-refresh-AIR-ref", &ref)) {
3964            return INVALID_OPERATION;
3965        }
3966        params.nAirRef = ref;
3967    }
3968
3969    status_t err = mOMXNode->setParameter(
3970            OMX_IndexParamVideoIntraRefresh, &params, sizeof(params));
3971    return err;
3972}
3973
3974static OMX_U32 setPFramesSpacing(
3975        float iFramesInterval /* seconds */, int32_t frameRate, uint32_t BFramesSpacing = 0) {
3976    // BFramesSpacing is the number of B frames between I/P frames
3977    // PFramesSpacing (the value to be returned) is the number of P frames between I frames
3978    //
3979    // keyFrameInterval = ((PFramesSpacing + 1) * BFramesSpacing) + PFramesSpacing + 1
3980    //                                     ^^^                            ^^^        ^^^
3981    //                              number of B frames                number of P    I frame
3982    //
3983    //                  = (PFramesSpacing + 1) * (BFramesSpacing + 1)
3984    //
3985    // E.g.
3986    //      I   P   I  : I-interval: 8, nPFrames 1, nBFrames 3
3987    //       BBB BBB
3988
3989    if (iFramesInterval < 0) { // just 1 key frame
3990        return 0xFFFFFFFE; // don't use maxint as key-frame-interval calculation will add 1
3991    } else if (iFramesInterval == 0) { // just key frames
3992        return 0;
3993    }
3994
3995    // round down as key-frame-interval is an upper limit
3996    uint32_t keyFrameInterval = uint32_t(frameRate * iFramesInterval);
3997    OMX_U32 ret = keyFrameInterval / (BFramesSpacing + 1);
3998    return ret > 0 ? ret - 1 : 0;
3999}
4000
4001status_t ACodec::setupMPEG4EncoderParameters(const sp<AMessage> &msg) {
4002    int32_t bitrate;
4003    float iFrameInterval;
4004    if (!msg->findInt32("bitrate", &bitrate)
4005            || !msg->findAsFloat("i-frame-interval", &iFrameInterval)) {
4006        return INVALID_OPERATION;
4007    }
4008
4009    OMX_VIDEO_CONTROLRATETYPE bitrateMode = getVideoBitrateMode(msg);
4010
4011    float frameRate;
4012    if (!msg->findFloat("frame-rate", &frameRate)) {
4013        int32_t tmp;
4014        if (!msg->findInt32("frame-rate", &tmp)) {
4015            return INVALID_OPERATION;
4016        }
4017        frameRate = (float)tmp;
4018    }
4019
4020    OMX_VIDEO_PARAM_MPEG4TYPE mpeg4type;
4021    InitOMXParams(&mpeg4type);
4022    mpeg4type.nPortIndex = kPortIndexOutput;
4023
4024    status_t err = mOMXNode->getParameter(
4025            OMX_IndexParamVideoMpeg4, &mpeg4type, sizeof(mpeg4type));
4026
4027    if (err != OK) {
4028        return err;
4029    }
4030
4031    mpeg4type.nSliceHeaderSpacing = 0;
4032    mpeg4type.bSVH = OMX_FALSE;
4033    mpeg4type.bGov = OMX_FALSE;
4034
4035    mpeg4type.nAllowedPictureTypes =
4036        OMX_VIDEO_PictureTypeI | OMX_VIDEO_PictureTypeP;
4037
4038    mpeg4type.nBFrames = 0;
4039    mpeg4type.nPFrames = setPFramesSpacing(iFrameInterval, frameRate, mpeg4type.nBFrames);
4040    if (mpeg4type.nPFrames == 0) {
4041        mpeg4type.nAllowedPictureTypes = OMX_VIDEO_PictureTypeI;
4042    }
4043    mpeg4type.nIDCVLCThreshold = 0;
4044    mpeg4type.bACPred = OMX_TRUE;
4045    mpeg4type.nMaxPacketSize = 256;
4046    mpeg4type.nTimeIncRes = 1000;
4047    mpeg4type.nHeaderExtension = 0;
4048    mpeg4type.bReversibleVLC = OMX_FALSE;
4049
4050    int32_t profile;
4051    if (msg->findInt32("profile", &profile)) {
4052        int32_t level;
4053        if (!msg->findInt32("level", &level)) {
4054            return INVALID_OPERATION;
4055        }
4056
4057        err = verifySupportForProfileAndLevel(profile, level);
4058
4059        if (err != OK) {
4060            return err;
4061        }
4062
4063        mpeg4type.eProfile = static_cast<OMX_VIDEO_MPEG4PROFILETYPE>(profile);
4064        mpeg4type.eLevel = static_cast<OMX_VIDEO_MPEG4LEVELTYPE>(level);
4065    }
4066
4067    err = mOMXNode->setParameter(
4068            OMX_IndexParamVideoMpeg4, &mpeg4type, sizeof(mpeg4type));
4069
4070    if (err != OK) {
4071        return err;
4072    }
4073
4074    err = configureBitrate(bitrateMode, bitrate);
4075
4076    if (err != OK) {
4077        return err;
4078    }
4079
4080    return setupErrorCorrectionParameters();
4081}
4082
4083status_t ACodec::setupH263EncoderParameters(const sp<AMessage> &msg) {
4084    int32_t bitrate;
4085    float iFrameInterval;
4086    if (!msg->findInt32("bitrate", &bitrate)
4087            || !msg->findAsFloat("i-frame-interval", &iFrameInterval)) {
4088        return INVALID_OPERATION;
4089    }
4090
4091    OMX_VIDEO_CONTROLRATETYPE bitrateMode = getVideoBitrateMode(msg);
4092
4093    float frameRate;
4094    if (!msg->findFloat("frame-rate", &frameRate)) {
4095        int32_t tmp;
4096        if (!msg->findInt32("frame-rate", &tmp)) {
4097            return INVALID_OPERATION;
4098        }
4099        frameRate = (float)tmp;
4100    }
4101
4102    OMX_VIDEO_PARAM_H263TYPE h263type;
4103    InitOMXParams(&h263type);
4104    h263type.nPortIndex = kPortIndexOutput;
4105
4106    status_t err = mOMXNode->getParameter(
4107            OMX_IndexParamVideoH263, &h263type, sizeof(h263type));
4108
4109    if (err != OK) {
4110        return err;
4111    }
4112
4113    h263type.nAllowedPictureTypes =
4114        OMX_VIDEO_PictureTypeI | OMX_VIDEO_PictureTypeP;
4115
4116    h263type.nBFrames = 0;
4117    h263type.nPFrames = setPFramesSpacing(iFrameInterval, frameRate, h263type.nBFrames);
4118    if (h263type.nPFrames == 0) {
4119        h263type.nAllowedPictureTypes = OMX_VIDEO_PictureTypeI;
4120    }
4121
4122    int32_t profile;
4123    if (msg->findInt32("profile", &profile)) {
4124        int32_t level;
4125        if (!msg->findInt32("level", &level)) {
4126            return INVALID_OPERATION;
4127        }
4128
4129        err = verifySupportForProfileAndLevel(profile, level);
4130
4131        if (err != OK) {
4132            return err;
4133        }
4134
4135        h263type.eProfile = static_cast<OMX_VIDEO_H263PROFILETYPE>(profile);
4136        h263type.eLevel = static_cast<OMX_VIDEO_H263LEVELTYPE>(level);
4137    }
4138
4139    h263type.bPLUSPTYPEAllowed = OMX_FALSE;
4140    h263type.bForceRoundingTypeToZero = OMX_FALSE;
4141    h263type.nPictureHeaderRepetition = 0;
4142    h263type.nGOBHeaderInterval = 0;
4143
4144    err = mOMXNode->setParameter(
4145            OMX_IndexParamVideoH263, &h263type, sizeof(h263type));
4146
4147    if (err != OK) {
4148        return err;
4149    }
4150
4151    err = configureBitrate(bitrateMode, bitrate);
4152
4153    if (err != OK) {
4154        return err;
4155    }
4156
4157    return setupErrorCorrectionParameters();
4158}
4159
4160// static
4161int /* OMX_VIDEO_AVCLEVELTYPE */ ACodec::getAVCLevelFor(
4162        int width, int height, int rate, int bitrate,
4163        OMX_VIDEO_AVCPROFILEEXTTYPE profile) {
4164    // convert bitrate to main/baseline profile kbps equivalent
4165    switch ((uint32_t)profile) {
4166        case OMX_VIDEO_AVCProfileHigh10:
4167            bitrate = divUp(bitrate, 3000); break;
4168        case OMX_VIDEO_AVCProfileConstrainedHigh:
4169        case OMX_VIDEO_AVCProfileHigh:
4170            bitrate = divUp(bitrate, 1250); break;
4171        default:
4172            bitrate = divUp(bitrate, 1000); break;
4173    }
4174
4175    // convert size and rate to MBs
4176    width = divUp(width, 16);
4177    height = divUp(height, 16);
4178    int mbs = width * height;
4179    rate *= mbs;
4180    int maxDimension = max(width, height);
4181
4182    static const int limits[][5] = {
4183        /*   MBps     MB   dim  bitrate        level */
4184        {    1485,    99,  28,     64, OMX_VIDEO_AVCLevel1  },
4185        {    1485,    99,  28,    128, OMX_VIDEO_AVCLevel1b },
4186        {    3000,   396,  56,    192, OMX_VIDEO_AVCLevel11 },
4187        {    6000,   396,  56,    384, OMX_VIDEO_AVCLevel12 },
4188        {   11880,   396,  56,    768, OMX_VIDEO_AVCLevel13 },
4189        {   11880,   396,  56,   2000, OMX_VIDEO_AVCLevel2  },
4190        {   19800,   792,  79,   4000, OMX_VIDEO_AVCLevel21 },
4191        {   20250,  1620, 113,   4000, OMX_VIDEO_AVCLevel22 },
4192        {   40500,  1620, 113,  10000, OMX_VIDEO_AVCLevel3  },
4193        {  108000,  3600, 169,  14000, OMX_VIDEO_AVCLevel31 },
4194        {  216000,  5120, 202,  20000, OMX_VIDEO_AVCLevel32 },
4195        {  245760,  8192, 256,  20000, OMX_VIDEO_AVCLevel4  },
4196        {  245760,  8192, 256,  50000, OMX_VIDEO_AVCLevel41 },
4197        {  522240,  8704, 263,  50000, OMX_VIDEO_AVCLevel42 },
4198        {  589824, 22080, 420, 135000, OMX_VIDEO_AVCLevel5  },
4199        {  983040, 36864, 543, 240000, OMX_VIDEO_AVCLevel51 },
4200        { 2073600, 36864, 543, 240000, OMX_VIDEO_AVCLevel52 },
4201    };
4202
4203    for (size_t i = 0; i < ARRAY_SIZE(limits); i++) {
4204        const int (&limit)[5] = limits[i];
4205        if (rate <= limit[0] && mbs <= limit[1] && maxDimension <= limit[2]
4206                && bitrate <= limit[3]) {
4207            return limit[4];
4208        }
4209    }
4210    return 0;
4211}
4212
4213status_t ACodec::setupAVCEncoderParameters(const sp<AMessage> &msg) {
4214    int32_t bitrate;
4215    float iFrameInterval;
4216    if (!msg->findInt32("bitrate", &bitrate)
4217            || !msg->findAsFloat("i-frame-interval", &iFrameInterval)) {
4218        return INVALID_OPERATION;
4219    }
4220
4221    OMX_VIDEO_CONTROLRATETYPE bitrateMode = getVideoBitrateMode(msg);
4222
4223    float frameRate;
4224    if (!msg->findFloat("frame-rate", &frameRate)) {
4225        int32_t tmp;
4226        if (!msg->findInt32("frame-rate", &tmp)) {
4227            return INVALID_OPERATION;
4228        }
4229        frameRate = (float)tmp;
4230    }
4231
4232    status_t err = OK;
4233    int32_t intraRefreshMode = 0;
4234    if (msg->findInt32("intra-refresh-mode", &intraRefreshMode)) {
4235        err = setCyclicIntraMacroblockRefresh(msg, intraRefreshMode);
4236        if (err != OK) {
4237            ALOGE("Setting intra macroblock refresh mode (%d) failed: 0x%x",
4238                    err, intraRefreshMode);
4239            return err;
4240        }
4241    }
4242
4243    OMX_VIDEO_PARAM_AVCTYPE h264type;
4244    InitOMXParams(&h264type);
4245    h264type.nPortIndex = kPortIndexOutput;
4246
4247    err = mOMXNode->getParameter(
4248            OMX_IndexParamVideoAvc, &h264type, sizeof(h264type));
4249
4250    if (err != OK) {
4251        return err;
4252    }
4253
4254    h264type.nAllowedPictureTypes =
4255        OMX_VIDEO_PictureTypeI | OMX_VIDEO_PictureTypeP;
4256
4257    int32_t profile;
4258    if (msg->findInt32("profile", &profile)) {
4259        int32_t level;
4260        if (!msg->findInt32("level", &level)) {
4261            return INVALID_OPERATION;
4262        }
4263
4264        err = verifySupportForProfileAndLevel(profile, level);
4265
4266        if (err != OK) {
4267            return err;
4268        }
4269
4270        h264type.eProfile = static_cast<OMX_VIDEO_AVCPROFILETYPE>(profile);
4271        h264type.eLevel = static_cast<OMX_VIDEO_AVCLEVELTYPE>(level);
4272    } else {
4273        h264type.eProfile = OMX_VIDEO_AVCProfileBaseline;
4274#if 0   /* DON'T YET DEFAULT TO HIGHEST PROFILE */
4275        // Use largest supported profile for AVC recording if profile is not specified.
4276        for (OMX_VIDEO_AVCPROFILETYPE profile : {
4277                OMX_VIDEO_AVCProfileHigh, OMX_VIDEO_AVCProfileMain }) {
4278            if (verifySupportForProfileAndLevel(profile, 0) == OK) {
4279                h264type.eProfile = profile;
4280                break;
4281            }
4282        }
4283#endif
4284    }
4285
4286    ALOGI("setupAVCEncoderParameters with [profile: %s] [level: %s]",
4287            asString(h264type.eProfile), asString(h264type.eLevel));
4288
4289    if (h264type.eProfile == OMX_VIDEO_AVCProfileBaseline) {
4290        h264type.nSliceHeaderSpacing = 0;
4291        h264type.bUseHadamard = OMX_TRUE;
4292        h264type.nRefFrames = 1;
4293        h264type.nBFrames = 0;
4294        h264type.nPFrames = setPFramesSpacing(iFrameInterval, frameRate, h264type.nBFrames);
4295        if (h264type.nPFrames == 0) {
4296            h264type.nAllowedPictureTypes = OMX_VIDEO_PictureTypeI;
4297        }
4298        h264type.nRefIdx10ActiveMinus1 = 0;
4299        h264type.nRefIdx11ActiveMinus1 = 0;
4300        h264type.bEntropyCodingCABAC = OMX_FALSE;
4301        h264type.bWeightedPPrediction = OMX_FALSE;
4302        h264type.bconstIpred = OMX_FALSE;
4303        h264type.bDirect8x8Inference = OMX_FALSE;
4304        h264type.bDirectSpatialTemporal = OMX_FALSE;
4305        h264type.nCabacInitIdc = 0;
4306    } else if (h264type.eProfile == OMX_VIDEO_AVCProfileMain ||
4307            h264type.eProfile == OMX_VIDEO_AVCProfileHigh) {
4308        h264type.nSliceHeaderSpacing = 0;
4309        h264type.bUseHadamard = OMX_TRUE;
4310        h264type.nRefFrames = 2;
4311        h264type.nBFrames = mLatency == 0 ? 1 : std::min(1U, mLatency - 1);
4312
4313        // disable B-frames until MPEG4Writer can guarantee finalizing files with B-frames
4314        h264type.nRefFrames = 1;
4315        h264type.nBFrames = 0;
4316
4317        h264type.nPFrames = setPFramesSpacing(iFrameInterval, frameRate, h264type.nBFrames);
4318        h264type.nAllowedPictureTypes =
4319            OMX_VIDEO_PictureTypeI | OMX_VIDEO_PictureTypeP;
4320        h264type.nRefIdx10ActiveMinus1 = 0;
4321        h264type.nRefIdx11ActiveMinus1 = 0;
4322        h264type.bEntropyCodingCABAC = OMX_TRUE;
4323        h264type.bWeightedPPrediction = OMX_TRUE;
4324        h264type.bconstIpred = OMX_TRUE;
4325        h264type.bDirect8x8Inference = OMX_TRUE;
4326        h264type.bDirectSpatialTemporal = OMX_TRUE;
4327        h264type.nCabacInitIdc = 1;
4328    }
4329
4330    if (h264type.nBFrames != 0) {
4331        h264type.nAllowedPictureTypes |= OMX_VIDEO_PictureTypeB;
4332    }
4333
4334    h264type.bEnableUEP = OMX_FALSE;
4335    h264type.bEnableFMO = OMX_FALSE;
4336    h264type.bEnableASO = OMX_FALSE;
4337    h264type.bEnableRS = OMX_FALSE;
4338    h264type.bFrameMBsOnly = OMX_TRUE;
4339    h264type.bMBAFF = OMX_FALSE;
4340    h264type.eLoopFilterMode = OMX_VIDEO_AVCLoopFilterEnable;
4341
4342    err = mOMXNode->setParameter(
4343            OMX_IndexParamVideoAvc, &h264type, sizeof(h264type));
4344
4345    if (err != OK) {
4346        return err;
4347    }
4348
4349    // TRICKY: if we are enabling temporal layering as well, some codecs may not support layering
4350    // when B-frames are enabled. Detect this now so we can disable B frames if temporal layering
4351    // is preferred.
4352    AString tsSchema;
4353    int32_t preferBFrames = (int32_t)false;
4354    if (msg->findString("ts-schema", &tsSchema)
4355            && (!msg->findInt32("android._prefer-b-frames", &preferBFrames) || !preferBFrames)) {
4356        OMX_VIDEO_PARAM_ANDROID_TEMPORALLAYERINGTYPE layering;
4357        InitOMXParams(&layering);
4358        layering.nPortIndex = kPortIndexOutput;
4359        if (mOMXNode->getParameter(
4360                        (OMX_INDEXTYPE)OMX_IndexParamAndroidVideoTemporalLayering,
4361                        &layering, sizeof(layering)) == OK
4362                && layering.eSupportedPatterns
4363                && layering.nBLayerCountMax == 0) {
4364            h264type.nBFrames = 0;
4365            h264type.nPFrames = setPFramesSpacing(iFrameInterval, frameRate, h264type.nBFrames);
4366            h264type.nAllowedPictureTypes &= ~OMX_VIDEO_PictureTypeB;
4367            ALOGI("disabling B-frames");
4368            err = mOMXNode->setParameter(
4369                    OMX_IndexParamVideoAvc, &h264type, sizeof(h264type));
4370
4371            if (err != OK) {
4372                return err;
4373            }
4374        }
4375    }
4376
4377    return configureBitrate(bitrateMode, bitrate);
4378}
4379
4380status_t ACodec::setupHEVCEncoderParameters(const sp<AMessage> &msg) {
4381    float iFrameInterval;
4382    if (!msg->findAsFloat("i-frame-interval", &iFrameInterval)) {
4383        return INVALID_OPERATION;
4384    }
4385
4386    OMX_VIDEO_CONTROLRATETYPE bitrateMode;
4387    int32_t bitrate, quality;
4388    if (!findVideoBitrateControlInfo(msg, &bitrateMode, &bitrate, &quality)) {
4389        return INVALID_OPERATION;
4390    }
4391
4392    float frameRate;
4393    if (!msg->findFloat("frame-rate", &frameRate)) {
4394        int32_t tmp;
4395        if (!msg->findInt32("frame-rate", &tmp)) {
4396            return INVALID_OPERATION;
4397        }
4398        frameRate = (float)tmp;
4399    }
4400
4401    OMX_VIDEO_PARAM_HEVCTYPE hevcType;
4402    InitOMXParams(&hevcType);
4403    hevcType.nPortIndex = kPortIndexOutput;
4404
4405    status_t err = OK;
4406    err = mOMXNode->getParameter(
4407            (OMX_INDEXTYPE)OMX_IndexParamVideoHevc, &hevcType, sizeof(hevcType));
4408    if (err != OK) {
4409        return err;
4410    }
4411
4412    int32_t profile;
4413    if (msg->findInt32("profile", &profile)) {
4414        int32_t level;
4415        if (!msg->findInt32("level", &level)) {
4416            return INVALID_OPERATION;
4417        }
4418
4419        err = verifySupportForProfileAndLevel(profile, level);
4420        if (err != OK) {
4421            return err;
4422        }
4423
4424        hevcType.eProfile = static_cast<OMX_VIDEO_HEVCPROFILETYPE>(profile);
4425        hevcType.eLevel = static_cast<OMX_VIDEO_HEVCLEVELTYPE>(level);
4426    }
4427    // TODO: finer control?
4428    hevcType.nKeyFrameInterval = setPFramesSpacing(iFrameInterval, frameRate) + 1;
4429
4430    err = mOMXNode->setParameter(
4431            (OMX_INDEXTYPE)OMX_IndexParamVideoHevc, &hevcType, sizeof(hevcType));
4432    if (err != OK) {
4433        return err;
4434    }
4435
4436    return configureBitrate(bitrateMode, bitrate, quality);
4437}
4438
4439status_t ACodec::setupVPXEncoderParameters(const sp<AMessage> &msg, sp<AMessage> &outputFormat) {
4440    int32_t bitrate;
4441    float iFrameInterval = 0;
4442    size_t tsLayers = 0;
4443    OMX_VIDEO_ANDROID_VPXTEMPORALLAYERPATTERNTYPE pattern =
4444        OMX_VIDEO_VPXTemporalLayerPatternNone;
4445    static const uint32_t kVp8LayerRateAlloction
4446        [OMX_VIDEO_ANDROID_MAXVP8TEMPORALLAYERS]
4447        [OMX_VIDEO_ANDROID_MAXVP8TEMPORALLAYERS] = {
4448        {100, 100, 100},  // 1 layer
4449        { 60, 100, 100},  // 2 layers {60%, 40%}
4450        { 40,  60, 100},  // 3 layers {40%, 20%, 40%}
4451    };
4452    if (!msg->findInt32("bitrate", &bitrate)) {
4453        return INVALID_OPERATION;
4454    }
4455    msg->findAsFloat("i-frame-interval", &iFrameInterval);
4456
4457    OMX_VIDEO_CONTROLRATETYPE bitrateMode = getVideoBitrateMode(msg);
4458
4459    float frameRate;
4460    if (!msg->findFloat("frame-rate", &frameRate)) {
4461        int32_t tmp;
4462        if (!msg->findInt32("frame-rate", &tmp)) {
4463            return INVALID_OPERATION;
4464        }
4465        frameRate = (float)tmp;
4466    }
4467
4468    AString tsSchema;
4469    OMX_VIDEO_ANDROID_TEMPORALLAYERINGPATTERNTYPE tsType =
4470        OMX_VIDEO_AndroidTemporalLayeringPatternNone;
4471
4472    if (msg->findString("ts-schema", &tsSchema)) {
4473        unsigned int numLayers = 0;
4474        unsigned int numBLayers = 0;
4475        int tags;
4476        char dummy;
4477        if (sscanf(tsSchema.c_str(), "webrtc.vp8.%u-layer%c", &numLayers, &dummy) == 1
4478                && numLayers > 0) {
4479            pattern = OMX_VIDEO_VPXTemporalLayerPatternWebRTC;
4480            tsType = OMX_VIDEO_AndroidTemporalLayeringPatternWebRTC;
4481            tsLayers = numLayers;
4482        } else if ((tags = sscanf(tsSchema.c_str(), "android.generic.%u%c%u%c",
4483                        &numLayers, &dummy, &numBLayers, &dummy))
4484                && (tags == 1 || (tags == 3 && dummy == '+'))
4485                && numLayers > 0 && numLayers < UINT32_MAX - numBLayers) {
4486            pattern = OMX_VIDEO_VPXTemporalLayerPatternWebRTC;
4487            // VPX does not have a concept of B-frames, so just count all layers
4488            tsType = OMX_VIDEO_AndroidTemporalLayeringPatternAndroid;
4489            tsLayers = numLayers + numBLayers;
4490        } else {
4491            ALOGW("Ignoring unsupported ts-schema [%s]", tsSchema.c_str());
4492        }
4493        tsLayers = min(tsLayers, (size_t)OMX_VIDEO_ANDROID_MAXVP8TEMPORALLAYERS);
4494    }
4495
4496    OMX_VIDEO_PARAM_ANDROID_VP8ENCODERTYPE vp8type;
4497    InitOMXParams(&vp8type);
4498    vp8type.nPortIndex = kPortIndexOutput;
4499    status_t err = mOMXNode->getParameter(
4500            (OMX_INDEXTYPE)OMX_IndexParamVideoAndroidVp8Encoder,
4501            &vp8type, sizeof(vp8type));
4502
4503    if (err == OK) {
4504        if (iFrameInterval > 0) {
4505            vp8type.nKeyFrameInterval = setPFramesSpacing(iFrameInterval, frameRate) + 1;
4506        }
4507        vp8type.eTemporalPattern = pattern;
4508        vp8type.nTemporalLayerCount = tsLayers;
4509        if (tsLayers > 0) {
4510            for (size_t i = 0; i < OMX_VIDEO_ANDROID_MAXVP8TEMPORALLAYERS; i++) {
4511                vp8type.nTemporalLayerBitrateRatio[i] =
4512                    kVp8LayerRateAlloction[tsLayers - 1][i];
4513            }
4514        }
4515        if (bitrateMode == OMX_Video_ControlRateConstant) {
4516            vp8type.nMinQuantizer = 2;
4517            vp8type.nMaxQuantizer = 63;
4518        }
4519
4520        err = mOMXNode->setParameter(
4521                (OMX_INDEXTYPE)OMX_IndexParamVideoAndroidVp8Encoder,
4522                &vp8type, sizeof(vp8type));
4523        if (err != OK) {
4524            ALOGW("Extended VP8 parameters set failed: %d", err);
4525        } else if (tsType == OMX_VIDEO_AndroidTemporalLayeringPatternWebRTC) {
4526            // advertise even single layer WebRTC layering, as it is defined
4527            outputFormat->setString("ts-schema", AStringPrintf("webrtc.vp8.%u-layer", tsLayers));
4528        } else if (tsLayers > 0) {
4529            // tsType == OMX_VIDEO_AndroidTemporalLayeringPatternAndroid
4530            outputFormat->setString("ts-schema", AStringPrintf("android.generic.%u", tsLayers));
4531        }
4532    }
4533
4534    return configureBitrate(bitrateMode, bitrate);
4535}
4536
4537status_t ACodec::verifySupportForProfileAndLevel(
4538        int32_t profile, int32_t level) {
4539    OMX_VIDEO_PARAM_PROFILELEVELTYPE params;
4540    InitOMXParams(&params);
4541    params.nPortIndex = kPortIndexOutput;
4542
4543    for (OMX_U32 index = 0; index <= kMaxIndicesToCheck; ++index) {
4544        params.nProfileIndex = index;
4545        status_t err = mOMXNode->getParameter(
4546                OMX_IndexParamVideoProfileLevelQuerySupported,
4547                &params, sizeof(params));
4548
4549        if (err != OK) {
4550            return err;
4551        }
4552
4553        int32_t supportedProfile = static_cast<int32_t>(params.eProfile);
4554        int32_t supportedLevel = static_cast<int32_t>(params.eLevel);
4555
4556        if (profile == supportedProfile && level <= supportedLevel) {
4557            return OK;
4558        }
4559
4560        if (index == kMaxIndicesToCheck) {
4561            ALOGW("[%s] stopping checking profiles after %u: %x/%x",
4562                    mComponentName.c_str(), index,
4563                    params.eProfile, params.eLevel);
4564        }
4565    }
4566    return ERROR_UNSUPPORTED;
4567}
4568
4569status_t ACodec::configureBitrate(
4570        OMX_VIDEO_CONTROLRATETYPE bitrateMode, int32_t bitrate, int32_t quality) {
4571    OMX_VIDEO_PARAM_BITRATETYPE bitrateType;
4572    InitOMXParams(&bitrateType);
4573    bitrateType.nPortIndex = kPortIndexOutput;
4574
4575    status_t err = mOMXNode->getParameter(
4576            OMX_IndexParamVideoBitrate, &bitrateType, sizeof(bitrateType));
4577
4578    if (err != OK) {
4579        return err;
4580    }
4581
4582    bitrateType.eControlRate = bitrateMode;
4583
4584    // write it out explicitly even if it's a union
4585    if (bitrateMode == OMX_Video_ControlRateConstantQuality) {
4586        bitrateType.nQualityFactor = quality;
4587    } else {
4588        bitrateType.nTargetBitrate = bitrate;
4589    }
4590
4591    return mOMXNode->setParameter(
4592            OMX_IndexParamVideoBitrate, &bitrateType, sizeof(bitrateType));
4593}
4594
4595void ACodec::configureEncoderLatency(const sp<AMessage> &msg) {
4596    if (!mIsEncoder || !mIsVideo) {
4597        return;
4598    }
4599
4600    int32_t latency = 0, bitrateMode;
4601    if (msg->findInt32("latency", &latency) && latency > 0) {
4602        status_t err = setLatency(latency);
4603        if (err != OK) {
4604            ALOGW("[%s] failed setLatency. Failure is fine since this key is optional",
4605                    mComponentName.c_str());
4606            err = OK;
4607        } else {
4608            mLatency = latency;
4609        }
4610    } else if ((!msg->findInt32("bitrate-mode", &bitrateMode) &&
4611            bitrateMode == OMX_Video_ControlRateConstant)) {
4612        // default the latency to be 1 if latency key is not specified or unsupported and bitrateMode
4613        // is CBR.
4614        mLatency = 1;
4615    }
4616}
4617
4618status_t ACodec::setupErrorCorrectionParameters() {
4619    OMX_VIDEO_PARAM_ERRORCORRECTIONTYPE errorCorrectionType;
4620    InitOMXParams(&errorCorrectionType);
4621    errorCorrectionType.nPortIndex = kPortIndexOutput;
4622
4623    status_t err = mOMXNode->getParameter(
4624            OMX_IndexParamVideoErrorCorrection,
4625            &errorCorrectionType, sizeof(errorCorrectionType));
4626
4627    if (err != OK) {
4628        return OK;  // Optional feature. Ignore this failure
4629    }
4630
4631    errorCorrectionType.bEnableHEC = OMX_FALSE;
4632    errorCorrectionType.bEnableResync = OMX_TRUE;
4633    errorCorrectionType.nResynchMarkerSpacing = 256;
4634    errorCorrectionType.bEnableDataPartitioning = OMX_FALSE;
4635    errorCorrectionType.bEnableRVLC = OMX_FALSE;
4636
4637    return mOMXNode->setParameter(
4638            OMX_IndexParamVideoErrorCorrection,
4639            &errorCorrectionType, sizeof(errorCorrectionType));
4640}
4641
4642status_t ACodec::setVideoFormatOnPort(
4643        OMX_U32 portIndex,
4644        int32_t width, int32_t height, OMX_VIDEO_CODINGTYPE compressionFormat,
4645        float frameRate) {
4646    OMX_PARAM_PORTDEFINITIONTYPE def;
4647    InitOMXParams(&def);
4648    def.nPortIndex = portIndex;
4649
4650    OMX_VIDEO_PORTDEFINITIONTYPE *video_def = &def.format.video;
4651
4652    status_t err = mOMXNode->getParameter(
4653            OMX_IndexParamPortDefinition, &def, sizeof(def));
4654    if (err != OK) {
4655        return err;
4656    }
4657
4658    if (portIndex == kPortIndexInput) {
4659        // XXX Need a (much) better heuristic to compute input buffer sizes.
4660        const size_t X = 64 * 1024;
4661        if (def.nBufferSize < X) {
4662            def.nBufferSize = X;
4663        }
4664    }
4665
4666    if (def.eDomain != OMX_PortDomainVideo) {
4667        ALOGE("expected video port, got %s(%d)", asString(def.eDomain), def.eDomain);
4668        return FAILED_TRANSACTION;
4669    }
4670
4671    video_def->nFrameWidth = width;
4672    video_def->nFrameHeight = height;
4673
4674    if (portIndex == kPortIndexInput) {
4675        video_def->eCompressionFormat = compressionFormat;
4676        video_def->eColorFormat = OMX_COLOR_FormatUnused;
4677        if (frameRate >= 0) {
4678            video_def->xFramerate = (OMX_U32)(frameRate * 65536.0f);
4679        }
4680    }
4681
4682    err = mOMXNode->setParameter(
4683            OMX_IndexParamPortDefinition, &def, sizeof(def));
4684
4685    return err;
4686}
4687
4688size_t ACodec::countBuffersOwnedByComponent(OMX_U32 portIndex) const {
4689    size_t n = 0;
4690
4691    for (size_t i = 0; i < mBuffers[portIndex].size(); ++i) {
4692        const BufferInfo &info = mBuffers[portIndex].itemAt(i);
4693
4694        if (info.mStatus == BufferInfo::OWNED_BY_COMPONENT) {
4695            ++n;
4696        }
4697    }
4698
4699    return n;
4700}
4701
4702size_t ACodec::countBuffersOwnedByNativeWindow() const {
4703    size_t n = 0;
4704
4705    for (size_t i = 0; i < mBuffers[kPortIndexOutput].size(); ++i) {
4706        const BufferInfo &info = mBuffers[kPortIndexOutput].itemAt(i);
4707
4708        if (info.mStatus == BufferInfo::OWNED_BY_NATIVE_WINDOW) {
4709            ++n;
4710        }
4711    }
4712
4713    return n;
4714}
4715
4716void ACodec::waitUntilAllPossibleNativeWindowBuffersAreReturnedToUs() {
4717    if (mNativeWindow == NULL) {
4718        return;
4719    }
4720
4721    while (countBuffersOwnedByNativeWindow() > mNumUndequeuedBuffers
4722            && dequeueBufferFromNativeWindow() != NULL) {
4723        // these buffers will be submitted as regular buffers; account for this
4724        if (storingMetadataInDecodedBuffers() && mMetadataBuffersToSubmit > 0) {
4725            --mMetadataBuffersToSubmit;
4726        }
4727    }
4728}
4729
4730bool ACodec::allYourBuffersAreBelongToUs(
4731        OMX_U32 portIndex) {
4732    for (size_t i = 0; i < mBuffers[portIndex].size(); ++i) {
4733        BufferInfo *info = &mBuffers[portIndex].editItemAt(i);
4734
4735        if (info->mStatus != BufferInfo::OWNED_BY_US
4736                && info->mStatus != BufferInfo::OWNED_BY_NATIVE_WINDOW) {
4737            ALOGV("[%s] Buffer %u on port %u still has status %d",
4738                    mComponentName.c_str(),
4739                    info->mBufferID, portIndex, info->mStatus);
4740            return false;
4741        }
4742    }
4743
4744    return true;
4745}
4746
4747bool ACodec::allYourBuffersAreBelongToUs() {
4748    return allYourBuffersAreBelongToUs(kPortIndexInput)
4749        && allYourBuffersAreBelongToUs(kPortIndexOutput);
4750}
4751
4752void ACodec::deferMessage(const sp<AMessage> &msg) {
4753    mDeferredQueue.push_back(msg);
4754}
4755
4756void ACodec::processDeferredMessages() {
4757    List<sp<AMessage> > queue = mDeferredQueue;
4758    mDeferredQueue.clear();
4759
4760    List<sp<AMessage> >::iterator it = queue.begin();
4761    while (it != queue.end()) {
4762        onMessageReceived(*it++);
4763    }
4764}
4765
4766status_t ACodec::getPortFormat(OMX_U32 portIndex, sp<AMessage> &notify) {
4767    const char *niceIndex = portIndex == kPortIndexInput ? "input" : "output";
4768    OMX_PARAM_PORTDEFINITIONTYPE def;
4769    InitOMXParams(&def);
4770    def.nPortIndex = portIndex;
4771
4772    status_t err = mOMXNode->getParameter(OMX_IndexParamPortDefinition, &def, sizeof(def));
4773    if (err != OK) {
4774        return err;
4775    }
4776
4777    if (def.eDir != (portIndex == kPortIndexOutput ? OMX_DirOutput : OMX_DirInput)) {
4778        ALOGE("unexpected dir: %s(%d) on %s port", asString(def.eDir), def.eDir, niceIndex);
4779        return BAD_VALUE;
4780    }
4781
4782    switch (def.eDomain) {
4783        case OMX_PortDomainVideo:
4784        {
4785            OMX_VIDEO_PORTDEFINITIONTYPE *videoDef = &def.format.video;
4786            switch ((int)videoDef->eCompressionFormat) {
4787                case OMX_VIDEO_CodingUnused:
4788                {
4789                    CHECK(mIsEncoder ^ (portIndex == kPortIndexOutput));
4790                    notify->setString("mime", MEDIA_MIMETYPE_VIDEO_RAW);
4791
4792                    notify->setInt32("stride", videoDef->nStride);
4793                    notify->setInt32("slice-height", videoDef->nSliceHeight);
4794                    notify->setInt32("color-format", videoDef->eColorFormat);
4795
4796                    if (mNativeWindow == NULL) {
4797                        DescribeColorFormat2Params describeParams;
4798                        InitOMXParams(&describeParams);
4799                        describeParams.eColorFormat = videoDef->eColorFormat;
4800                        describeParams.nFrameWidth = videoDef->nFrameWidth;
4801                        describeParams.nFrameHeight = videoDef->nFrameHeight;
4802                        describeParams.nStride = videoDef->nStride;
4803                        describeParams.nSliceHeight = videoDef->nSliceHeight;
4804                        describeParams.bUsingNativeBuffers = OMX_FALSE;
4805
4806                        if (DescribeColorFormat(mOMXNode, describeParams)) {
4807                            notify->setBuffer(
4808                                    "image-data",
4809                                    ABuffer::CreateAsCopy(
4810                                            &describeParams.sMediaImage,
4811                                            sizeof(describeParams.sMediaImage)));
4812
4813                            MediaImage2 &img = describeParams.sMediaImage;
4814                            MediaImage2::PlaneInfo *plane = img.mPlane;
4815                            ALOGV("[%s] MediaImage { F(%ux%u) @%u+%d+%d @%u+%d+%d @%u+%d+%d }",
4816                                    mComponentName.c_str(), img.mWidth, img.mHeight,
4817                                    plane[0].mOffset, plane[0].mColInc, plane[0].mRowInc,
4818                                    plane[1].mOffset, plane[1].mColInc, plane[1].mRowInc,
4819                                    plane[2].mOffset, plane[2].mColInc, plane[2].mRowInc);
4820                        }
4821                    }
4822
4823                    int32_t width = (int32_t)videoDef->nFrameWidth;
4824                    int32_t height = (int32_t)videoDef->nFrameHeight;
4825
4826                    if (portIndex == kPortIndexOutput) {
4827                        OMX_CONFIG_RECTTYPE rect;
4828                        InitOMXParams(&rect);
4829                        rect.nPortIndex = portIndex;
4830
4831                        if (mOMXNode->getConfig(
4832                                    (portIndex == kPortIndexOutput ?
4833                                            OMX_IndexConfigCommonOutputCrop :
4834                                            OMX_IndexConfigCommonInputCrop),
4835                                    &rect, sizeof(rect)) != OK) {
4836                            rect.nLeft = 0;
4837                            rect.nTop = 0;
4838                            rect.nWidth = videoDef->nFrameWidth;
4839                            rect.nHeight = videoDef->nFrameHeight;
4840                        }
4841
4842                        if (rect.nLeft < 0 ||
4843                            rect.nTop < 0 ||
4844                            rect.nLeft + rect.nWidth > videoDef->nFrameWidth ||
4845                            rect.nTop + rect.nHeight > videoDef->nFrameHeight) {
4846                            ALOGE("Wrong cropped rect (%d, %d, %u, %u) vs. frame (%u, %u)",
4847                                    rect.nLeft, rect.nTop,
4848                                    rect.nWidth, rect.nHeight,
4849                                    videoDef->nFrameWidth, videoDef->nFrameHeight);
4850                            return BAD_VALUE;
4851                        }
4852
4853                        notify->setRect(
4854                                "crop",
4855                                rect.nLeft,
4856                                rect.nTop,
4857                                rect.nLeft + rect.nWidth - 1,
4858                                rect.nTop + rect.nHeight - 1);
4859
4860                        width = rect.nWidth;
4861                        height = rect.nHeight;
4862
4863                        android_dataspace dataSpace = HAL_DATASPACE_UNKNOWN;
4864                        (void)getColorAspectsAndDataSpaceForVideoDecoder(
4865                                width, height, mConfigFormat, notify,
4866                                mUsingNativeWindow ? &dataSpace : NULL);
4867                        if (mUsingNativeWindow) {
4868                            notify->setInt32("android._dataspace", dataSpace);
4869                        }
4870                        (void)getHDRStaticInfoForVideoCodec(kPortIndexOutput, notify);
4871                    } else {
4872                        (void)getInputColorAspectsForVideoEncoder(notify);
4873                        if (mConfigFormat->contains("hdr-static-info")) {
4874                            (void)getHDRStaticInfoForVideoCodec(kPortIndexInput, notify);
4875                        }
4876                        uint32_t latency = 0;
4877                        if (mIsEncoder && getLatency(&latency) == OK && latency > 0) {
4878                            notify->setInt32("latency", latency);
4879                        }
4880                    }
4881
4882                    break;
4883                }
4884
4885                case OMX_VIDEO_CodingVP8:
4886                case OMX_VIDEO_CodingVP9:
4887                {
4888                    OMX_VIDEO_PARAM_ANDROID_VP8ENCODERTYPE vp8type;
4889                    InitOMXParams(&vp8type);
4890                    vp8type.nPortIndex = kPortIndexOutput;
4891                    status_t err = mOMXNode->getParameter(
4892                            (OMX_INDEXTYPE)OMX_IndexParamVideoAndroidVp8Encoder,
4893                            &vp8type,
4894                            sizeof(vp8type));
4895
4896                    if (err == OK) {
4897                        if (vp8type.eTemporalPattern == OMX_VIDEO_VPXTemporalLayerPatternWebRTC
4898                                && vp8type.nTemporalLayerCount > 0
4899                                && vp8type.nTemporalLayerCount
4900                                        <= OMX_VIDEO_ANDROID_MAXVP8TEMPORALLAYERS) {
4901                            // advertise as android.generic if we configured for android.generic
4902                            AString origSchema;
4903                            if (notify->findString("ts-schema", &origSchema)
4904                                    && origSchema.startsWith("android.generic")) {
4905                                notify->setString("ts-schema", AStringPrintf(
4906                                        "android.generic.%u", vp8type.nTemporalLayerCount));
4907                            } else {
4908                                notify->setString("ts-schema", AStringPrintf(
4909                                        "webrtc.vp8.%u-layer", vp8type.nTemporalLayerCount));
4910                            }
4911                        }
4912                    }
4913                    // Fall through to set up mime.
4914                }
4915
4916                default:
4917                {
4918                    if (mIsEncoder ^ (portIndex == kPortIndexOutput)) {
4919                        // should be CodingUnused
4920                        ALOGE("Raw port video compression format is %s(%d)",
4921                                asString(videoDef->eCompressionFormat),
4922                                videoDef->eCompressionFormat);
4923                        return BAD_VALUE;
4924                    }
4925                    AString mime;
4926                    if (GetMimeTypeForVideoCoding(
4927                        videoDef->eCompressionFormat, &mime) != OK) {
4928                        notify->setString("mime", "application/octet-stream");
4929                    } else {
4930                        notify->setString("mime", mime.c_str());
4931                    }
4932                    uint32_t intraRefreshPeriod = 0;
4933                    if (mIsEncoder && getIntraRefreshPeriod(&intraRefreshPeriod) == OK
4934                            && intraRefreshPeriod > 0) {
4935                        notify->setInt32("intra-refresh-period", intraRefreshPeriod);
4936                    }
4937                    break;
4938                }
4939            }
4940            notify->setInt32("width", videoDef->nFrameWidth);
4941            notify->setInt32("height", videoDef->nFrameHeight);
4942            ALOGV("[%s] %s format is %s", mComponentName.c_str(),
4943                    portIndex == kPortIndexInput ? "input" : "output",
4944                    notify->debugString().c_str());
4945
4946            break;
4947        }
4948
4949        case OMX_PortDomainAudio:
4950        {
4951            OMX_AUDIO_PORTDEFINITIONTYPE *audioDef = &def.format.audio;
4952
4953            switch ((int)audioDef->eEncoding) {
4954                case OMX_AUDIO_CodingPCM:
4955                {
4956                    OMX_AUDIO_PARAM_PCMMODETYPE params;
4957                    InitOMXParams(&params);
4958                    params.nPortIndex = portIndex;
4959
4960                    err = mOMXNode->getParameter(
4961                            OMX_IndexParamAudioPcm, &params, sizeof(params));
4962                    if (err != OK) {
4963                        return err;
4964                    }
4965
4966                    if (params.nChannels <= 0
4967                            || (params.nChannels != 1 && !params.bInterleaved)
4968                            || params.ePCMMode != OMX_AUDIO_PCMModeLinear) {
4969                        ALOGE("unsupported PCM port: %u channels%s, %u-bit",
4970                                params.nChannels,
4971                                params.bInterleaved ? " interleaved" : "",
4972                                params.nBitPerSample);
4973                        return FAILED_TRANSACTION;
4974                    }
4975
4976                    notify->setString("mime", MEDIA_MIMETYPE_AUDIO_RAW);
4977                    notify->setInt32("channel-count", params.nChannels);
4978                    notify->setInt32("sample-rate", params.nSamplingRate);
4979
4980                    AudioEncoding encoding = kAudioEncodingPcm16bit;
4981                    if (params.eNumData == OMX_NumericalDataUnsigned
4982                            && params.nBitPerSample == 8u) {
4983                        encoding = kAudioEncodingPcm8bit;
4984                    } else if (params.eNumData == OMX_NumericalDataFloat
4985                            && params.nBitPerSample == 32u) {
4986                        encoding = kAudioEncodingPcmFloat;
4987                    } else if (params.nBitPerSample != 16u
4988                            || params.eNumData != OMX_NumericalDataSigned) {
4989                        ALOGE("unsupported PCM port: %s(%d), %s(%d) mode ",
4990                                asString(params.eNumData), params.eNumData,
4991                                asString(params.ePCMMode), params.ePCMMode);
4992                        return FAILED_TRANSACTION;
4993                    }
4994                    notify->setInt32("pcm-encoding", encoding);
4995
4996                    if (mChannelMaskPresent) {
4997                        notify->setInt32("channel-mask", mChannelMask);
4998                    }
4999                    break;
5000                }
5001
5002                case OMX_AUDIO_CodingAAC:
5003                {
5004                    OMX_AUDIO_PARAM_AACPROFILETYPE params;
5005                    InitOMXParams(&params);
5006                    params.nPortIndex = portIndex;
5007
5008                    err = mOMXNode->getParameter(
5009                            OMX_IndexParamAudioAac, &params, sizeof(params));
5010                    if (err != OK) {
5011                        return err;
5012                    }
5013
5014                    notify->setString("mime", MEDIA_MIMETYPE_AUDIO_AAC);
5015                    notify->setInt32("channel-count", params.nChannels);
5016                    notify->setInt32("sample-rate", params.nSampleRate);
5017                    break;
5018                }
5019
5020                case OMX_AUDIO_CodingAMR:
5021                {
5022                    OMX_AUDIO_PARAM_AMRTYPE params;
5023                    InitOMXParams(&params);
5024                    params.nPortIndex = portIndex;
5025
5026                    err = mOMXNode->getParameter(
5027                            OMX_IndexParamAudioAmr, &params, sizeof(params));
5028                    if (err != OK) {
5029                        return err;
5030                    }
5031
5032                    notify->setInt32("channel-count", 1);
5033                    if (params.eAMRBandMode >= OMX_AUDIO_AMRBandModeWB0) {
5034                        notify->setString("mime", MEDIA_MIMETYPE_AUDIO_AMR_WB);
5035                        notify->setInt32("sample-rate", 16000);
5036                    } else {
5037                        notify->setString("mime", MEDIA_MIMETYPE_AUDIO_AMR_NB);
5038                        notify->setInt32("sample-rate", 8000);
5039                    }
5040                    break;
5041                }
5042
5043                case OMX_AUDIO_CodingFLAC:
5044                {
5045                    OMX_AUDIO_PARAM_FLACTYPE params;
5046                    InitOMXParams(&params);
5047                    params.nPortIndex = portIndex;
5048
5049                    err = mOMXNode->getParameter(
5050                            OMX_IndexParamAudioFlac, &params, sizeof(params));
5051                    if (err != OK) {
5052                        return err;
5053                    }
5054
5055                    notify->setString("mime", MEDIA_MIMETYPE_AUDIO_FLAC);
5056                    notify->setInt32("channel-count", params.nChannels);
5057                    notify->setInt32("sample-rate", params.nSampleRate);
5058                    break;
5059                }
5060
5061                case OMX_AUDIO_CodingMP3:
5062                {
5063                    OMX_AUDIO_PARAM_MP3TYPE params;
5064                    InitOMXParams(&params);
5065                    params.nPortIndex = portIndex;
5066
5067                    err = mOMXNode->getParameter(
5068                            OMX_IndexParamAudioMp3, &params, sizeof(params));
5069                    if (err != OK) {
5070                        return err;
5071                    }
5072
5073                    notify->setString("mime", MEDIA_MIMETYPE_AUDIO_MPEG);
5074                    notify->setInt32("channel-count", params.nChannels);
5075                    notify->setInt32("sample-rate", params.nSampleRate);
5076                    break;
5077                }
5078
5079                case OMX_AUDIO_CodingVORBIS:
5080                {
5081                    OMX_AUDIO_PARAM_VORBISTYPE params;
5082                    InitOMXParams(&params);
5083                    params.nPortIndex = portIndex;
5084
5085                    err = mOMXNode->getParameter(
5086                            OMX_IndexParamAudioVorbis, &params, sizeof(params));
5087                    if (err != OK) {
5088                        return err;
5089                    }
5090
5091                    notify->setString("mime", MEDIA_MIMETYPE_AUDIO_VORBIS);
5092                    notify->setInt32("channel-count", params.nChannels);
5093                    notify->setInt32("sample-rate", params.nSampleRate);
5094                    break;
5095                }
5096
5097                case OMX_AUDIO_CodingAndroidAC3:
5098                {
5099                    OMX_AUDIO_PARAM_ANDROID_AC3TYPE params;
5100                    InitOMXParams(&params);
5101                    params.nPortIndex = portIndex;
5102
5103                    err = mOMXNode->getParameter(
5104                            (OMX_INDEXTYPE)OMX_IndexParamAudioAndroidAc3,
5105                            &params, sizeof(params));
5106                    if (err != OK) {
5107                        return err;
5108                    }
5109
5110                    notify->setString("mime", MEDIA_MIMETYPE_AUDIO_AC3);
5111                    notify->setInt32("channel-count", params.nChannels);
5112                    notify->setInt32("sample-rate", params.nSampleRate);
5113                    break;
5114                }
5115
5116                case OMX_AUDIO_CodingAndroidEAC3:
5117                {
5118                    OMX_AUDIO_PARAM_ANDROID_EAC3TYPE params;
5119                    InitOMXParams(&params);
5120                    params.nPortIndex = portIndex;
5121
5122                    err = mOMXNode->getParameter(
5123                            (OMX_INDEXTYPE)OMX_IndexParamAudioAndroidEac3,
5124                            &params, sizeof(params));
5125                    if (err != OK) {
5126                        return err;
5127                    }
5128
5129                    notify->setString("mime", MEDIA_MIMETYPE_AUDIO_EAC3);
5130                    notify->setInt32("channel-count", params.nChannels);
5131                    notify->setInt32("sample-rate", params.nSampleRate);
5132                    break;
5133                }
5134
5135                case OMX_AUDIO_CodingAndroidOPUS:
5136                {
5137                    OMX_AUDIO_PARAM_ANDROID_OPUSTYPE params;
5138                    InitOMXParams(&params);
5139                    params.nPortIndex = portIndex;
5140
5141                    err = mOMXNode->getParameter(
5142                            (OMX_INDEXTYPE)OMX_IndexParamAudioAndroidOpus,
5143                            &params, sizeof(params));
5144                    if (err != OK) {
5145                        return err;
5146                    }
5147
5148                    notify->setString("mime", MEDIA_MIMETYPE_AUDIO_OPUS);
5149                    notify->setInt32("channel-count", params.nChannels);
5150                    notify->setInt32("sample-rate", params.nSampleRate);
5151                    break;
5152                }
5153
5154                case OMX_AUDIO_CodingG711:
5155                {
5156                    OMX_AUDIO_PARAM_PCMMODETYPE params;
5157                    InitOMXParams(&params);
5158                    params.nPortIndex = portIndex;
5159
5160                    err = mOMXNode->getParameter(
5161                            (OMX_INDEXTYPE)OMX_IndexParamAudioPcm, &params, sizeof(params));
5162                    if (err != OK) {
5163                        return err;
5164                    }
5165
5166                    const char *mime = NULL;
5167                    if (params.ePCMMode == OMX_AUDIO_PCMModeMULaw) {
5168                        mime = MEDIA_MIMETYPE_AUDIO_G711_MLAW;
5169                    } else if (params.ePCMMode == OMX_AUDIO_PCMModeALaw) {
5170                        mime = MEDIA_MIMETYPE_AUDIO_G711_ALAW;
5171                    } else { // params.ePCMMode == OMX_AUDIO_PCMModeLinear
5172                        mime = MEDIA_MIMETYPE_AUDIO_RAW;
5173                    }
5174                    notify->setString("mime", mime);
5175                    notify->setInt32("channel-count", params.nChannels);
5176                    notify->setInt32("sample-rate", params.nSamplingRate);
5177                    notify->setInt32("pcm-encoding", kAudioEncodingPcm16bit);
5178                    break;
5179                }
5180
5181                case OMX_AUDIO_CodingGSMFR:
5182                {
5183                    OMX_AUDIO_PARAM_PCMMODETYPE params;
5184                    InitOMXParams(&params);
5185                    params.nPortIndex = portIndex;
5186
5187                    err = mOMXNode->getParameter(
5188                                OMX_IndexParamAudioPcm, &params, sizeof(params));
5189                    if (err != OK) {
5190                        return err;
5191                    }
5192
5193                    notify->setString("mime", MEDIA_MIMETYPE_AUDIO_MSGSM);
5194                    notify->setInt32("channel-count", params.nChannels);
5195                    notify->setInt32("sample-rate", params.nSamplingRate);
5196                    break;
5197                }
5198
5199                default:
5200                    ALOGE("Unsupported audio coding: %s(%d)\n",
5201                            asString(audioDef->eEncoding), audioDef->eEncoding);
5202                    return BAD_TYPE;
5203            }
5204            break;
5205        }
5206
5207        default:
5208            ALOGE("Unsupported domain: %s(%d)", asString(def.eDomain), def.eDomain);
5209            return BAD_TYPE;
5210    }
5211
5212    return getVendorParameters(portIndex, notify);
5213}
5214
5215void ACodec::onDataSpaceChanged(android_dataspace dataSpace, const ColorAspects &aspects) {
5216    // aspects are normally communicated in ColorAspects
5217    int32_t range, standard, transfer;
5218    convertCodecColorAspectsToPlatformAspects(aspects, &range, &standard, &transfer);
5219
5220    // if some aspects are unspecified, use dataspace fields
5221    if (range != 0) {
5222        range = (dataSpace & HAL_DATASPACE_RANGE_MASK) >> HAL_DATASPACE_RANGE_SHIFT;
5223    }
5224    if (standard != 0) {
5225        standard = (dataSpace & HAL_DATASPACE_STANDARD_MASK) >> HAL_DATASPACE_STANDARD_SHIFT;
5226    }
5227    if (transfer != 0) {
5228        transfer = (dataSpace & HAL_DATASPACE_TRANSFER_MASK) >> HAL_DATASPACE_TRANSFER_SHIFT;
5229    }
5230
5231    mOutputFormat = mOutputFormat->dup(); // trigger an output format changed event
5232    if (range != 0) {
5233        mOutputFormat->setInt32("color-range", range);
5234    }
5235    if (standard != 0) {
5236        mOutputFormat->setInt32("color-standard", standard);
5237    }
5238    if (transfer != 0) {
5239        mOutputFormat->setInt32("color-transfer", transfer);
5240    }
5241
5242    ALOGD("dataspace changed to %#x (R:%d(%s), P:%d(%s), M:%d(%s), T:%d(%s)) "
5243          "(R:%d(%s), S:%d(%s), T:%d(%s))",
5244            dataSpace,
5245            aspects.mRange, asString(aspects.mRange),
5246            aspects.mPrimaries, asString(aspects.mPrimaries),
5247            aspects.mMatrixCoeffs, asString(aspects.mMatrixCoeffs),
5248            aspects.mTransfer, asString(aspects.mTransfer),
5249            range, asString((ColorRange)range),
5250            standard, asString((ColorStandard)standard),
5251            transfer, asString((ColorTransfer)transfer));
5252}
5253
5254void ACodec::onOutputFormatChanged(sp<const AMessage> expectedFormat) {
5255    // store new output format, at the same time mark that this is no longer the first frame
5256    mOutputFormat = mBaseOutputFormat->dup();
5257
5258    if (getPortFormat(kPortIndexOutput, mOutputFormat) != OK) {
5259        ALOGE("[%s] Failed to get port format to send format change", mComponentName.c_str());
5260        return;
5261    }
5262
5263    if (expectedFormat != NULL) {
5264        sp<const AMessage> changes = expectedFormat->changesFrom(mOutputFormat);
5265        sp<const AMessage> to = mOutputFormat->changesFrom(expectedFormat);
5266        if (changes->countEntries() != 0 || to->countEntries() != 0) {
5267            ALOGW("[%s] BAD CODEC: Output format changed unexpectedly from (diff) %s to (diff) %s",
5268                    mComponentName.c_str(),
5269                    changes->debugString(4).c_str(), to->debugString(4).c_str());
5270        }
5271    }
5272
5273    if (!mIsVideo && !mIsEncoder) {
5274        AudioEncoding pcmEncoding = kAudioEncodingPcm16bit;
5275        (void)mConfigFormat->findInt32("pcm-encoding", (int32_t*)&pcmEncoding);
5276        AudioEncoding codecPcmEncoding = kAudioEncodingPcm16bit;
5277        (void)mOutputFormat->findInt32("pcm-encoding", (int32_t*)&pcmEncoding);
5278
5279        mConverter[kPortIndexOutput] = AudioConverter::Create(codecPcmEncoding, pcmEncoding);
5280        if (mConverter[kPortIndexOutput] != NULL) {
5281            mOutputFormat->setInt32("pcm-encoding", pcmEncoding);
5282        }
5283    }
5284
5285    if (mTunneled) {
5286        sendFormatChange();
5287    }
5288}
5289
5290void ACodec::sendFormatChange() {
5291    AString mime;
5292    CHECK(mOutputFormat->findString("mime", &mime));
5293
5294    if (mime == MEDIA_MIMETYPE_AUDIO_RAW && (mEncoderDelay || mEncoderPadding)) {
5295        int32_t channelCount, sampleRate;
5296        CHECK(mOutputFormat->findInt32("channel-count", &channelCount));
5297        CHECK(mOutputFormat->findInt32("sample-rate", &sampleRate));
5298        if (mSampleRate != 0 && sampleRate != 0) {
5299            // avoiding 32-bit overflows in intermediate values
5300            mEncoderDelay = (int32_t)((((int64_t)mEncoderDelay) * sampleRate) / mSampleRate);
5301            mEncoderPadding = (int32_t)((((int64_t)mEncoderPadding) * sampleRate) / mSampleRate);
5302            mSampleRate = sampleRate;
5303        }
5304        if (mSkipCutBuffer != NULL) {
5305            size_t prevbufsize = mSkipCutBuffer->size();
5306            if (prevbufsize != 0) {
5307                ALOGW("Replacing SkipCutBuffer holding %zu bytes", prevbufsize);
5308            }
5309        }
5310        mSkipCutBuffer = new SkipCutBuffer(mEncoderDelay, mEncoderPadding, channelCount);
5311    }
5312
5313    // mLastOutputFormat is not used when tunneled; doing this just to stay consistent
5314    mLastOutputFormat = mOutputFormat;
5315}
5316
5317void ACodec::signalError(OMX_ERRORTYPE error, status_t internalError) {
5318    ALOGE("signalError(omxError %#x, internalError %d)", error, internalError);
5319
5320    if (internalError == UNKNOWN_ERROR) { // find better error code
5321        const status_t omxStatus = statusFromOMXError(error);
5322        if (omxStatus != 0) {
5323            internalError = omxStatus;
5324        } else {
5325            ALOGW("Invalid OMX error %#x", error);
5326        }
5327    }
5328
5329    mFatalError = true;
5330    mCallback->onError(internalError, ACTION_CODE_FATAL);
5331}
5332
5333status_t ACodec::requestIDRFrame() {
5334    if (!mIsEncoder) {
5335        return ERROR_UNSUPPORTED;
5336    }
5337
5338    OMX_CONFIG_INTRAREFRESHVOPTYPE params;
5339    InitOMXParams(&params);
5340
5341    params.nPortIndex = kPortIndexOutput;
5342    params.IntraRefreshVOP = OMX_TRUE;
5343
5344    return mOMXNode->setConfig(
5345            OMX_IndexConfigVideoIntraVOPRefresh,
5346            &params,
5347            sizeof(params));
5348}
5349
5350////////////////////////////////////////////////////////////////////////////////
5351
5352ACodec::BaseState::BaseState(ACodec *codec, const sp<AState> &parentState)
5353    : AState(parentState),
5354      mCodec(codec) {
5355}
5356
5357ACodec::BaseState::PortMode ACodec::BaseState::getPortMode(
5358        OMX_U32 /* portIndex */) {
5359    return KEEP_BUFFERS;
5360}
5361
5362void ACodec::BaseState::stateExited() {
5363    ++mCodec->mStateGeneration;
5364}
5365
5366bool ACodec::BaseState::onMessageReceived(const sp<AMessage> &msg) {
5367    switch (msg->what()) {
5368        case kWhatInputBufferFilled:
5369        {
5370            onInputBufferFilled(msg);
5371            break;
5372        }
5373
5374        case kWhatOutputBufferDrained:
5375        {
5376            onOutputBufferDrained(msg);
5377            break;
5378        }
5379
5380        case ACodec::kWhatOMXMessageList:
5381        {
5382            return checkOMXMessage(msg) ? onOMXMessageList(msg) : true;
5383        }
5384
5385        case ACodec::kWhatOMXMessageItem:
5386        {
5387            // no need to check as we already did it for kWhatOMXMessageList
5388            return onOMXMessage(msg);
5389        }
5390
5391        case ACodec::kWhatOMXMessage:
5392        {
5393            return checkOMXMessage(msg) ? onOMXMessage(msg) : true;
5394        }
5395
5396        case ACodec::kWhatSetSurface:
5397        {
5398            sp<AReplyToken> replyID;
5399            CHECK(msg->senderAwaitsResponse(&replyID));
5400
5401            sp<RefBase> obj;
5402            CHECK(msg->findObject("surface", &obj));
5403
5404            status_t err = mCodec->handleSetSurface(static_cast<Surface *>(obj.get()));
5405
5406            sp<AMessage> response = new AMessage;
5407            response->setInt32("err", err);
5408            response->postReply(replyID);
5409            break;
5410        }
5411
5412        case ACodec::kWhatCreateInputSurface:
5413        case ACodec::kWhatSetInputSurface:
5414        case ACodec::kWhatSignalEndOfInputStream:
5415        {
5416            // This may result in an app illegal state exception.
5417            ALOGE("Message 0x%x was not handled", msg->what());
5418            mCodec->signalError(OMX_ErrorUndefined, INVALID_OPERATION);
5419            return true;
5420        }
5421
5422        case ACodec::kWhatOMXDied:
5423        {
5424            // This will result in kFlagSawMediaServerDie handling in MediaCodec.
5425            ALOGE("OMX/mediaserver died, signalling error!");
5426            mCodec->mGraphicBufferSource.clear();
5427            mCodec->signalError(OMX_ErrorResourcesLost, DEAD_OBJECT);
5428            break;
5429        }
5430
5431        case ACodec::kWhatReleaseCodecInstance:
5432        {
5433            ALOGI("[%s] forcing the release of codec",
5434                    mCodec->mComponentName.c_str());
5435            status_t err = mCodec->mOMXNode->freeNode();
5436            ALOGE_IF("[%s] failed to release codec instance: err=%d",
5437                       mCodec->mComponentName.c_str(), err);
5438            mCodec->mCallback->onReleaseCompleted();
5439
5440            mCodec->changeState(mCodec->mUninitializedState);
5441            break;
5442        }
5443
5444        case ACodec::kWhatForceStateTransition:
5445        {
5446            ALOGV("Already transitioned --- ignore");
5447            break;
5448        }
5449
5450        default:
5451            return false;
5452    }
5453
5454    return true;
5455}
5456
5457bool ACodec::BaseState::checkOMXMessage(const sp<AMessage> &msg) {
5458    // there is a possibility that this is an outstanding message for a
5459    // codec that we have already destroyed
5460    if (mCodec->mOMXNode == NULL) {
5461        ALOGI("ignoring message as already freed component: %s",
5462                msg->debugString().c_str());
5463        return false;
5464    }
5465
5466    int32_t generation;
5467    CHECK(msg->findInt32("generation", (int32_t*)&generation));
5468    if (generation != mCodec->mNodeGeneration) {
5469        ALOGW("Unexpected message for component: %s, gen %u, cur %u",
5470                msg->debugString().c_str(), generation, mCodec->mNodeGeneration);
5471        return false;
5472    }
5473    return true;
5474}
5475
5476bool ACodec::BaseState::onOMXMessageList(const sp<AMessage> &msg) {
5477    sp<RefBase> obj;
5478    CHECK(msg->findObject("messages", &obj));
5479    sp<MessageList> msgList = static_cast<MessageList *>(obj.get());
5480
5481    bool receivedRenderedEvents = false;
5482    for (std::list<sp<AMessage>>::const_iterator it = msgList->getList().cbegin();
5483          it != msgList->getList().cend(); ++it) {
5484        (*it)->setWhat(ACodec::kWhatOMXMessageItem);
5485        mCodec->handleMessage(*it);
5486        int32_t type;
5487        CHECK((*it)->findInt32("type", &type));
5488        if (type == omx_message::FRAME_RENDERED) {
5489            receivedRenderedEvents = true;
5490        }
5491    }
5492
5493    if (receivedRenderedEvents) {
5494        // NOTE: all buffers are rendered in this case
5495        mCodec->notifyOfRenderedFrames();
5496    }
5497    return true;
5498}
5499
5500bool ACodec::BaseState::onOMXMessage(const sp<AMessage> &msg) {
5501    int32_t type;
5502    CHECK(msg->findInt32("type", &type));
5503
5504    switch (type) {
5505        case omx_message::EVENT:
5506        {
5507            int32_t event, data1, data2;
5508            CHECK(msg->findInt32("event", &event));
5509            CHECK(msg->findInt32("data1", &data1));
5510            CHECK(msg->findInt32("data2", &data2));
5511
5512            if (event == OMX_EventCmdComplete
5513                    && data1 == OMX_CommandFlush
5514                    && data2 == (int32_t)OMX_ALL) {
5515                // Use of this notification is not consistent across
5516                // implementations. We'll drop this notification and rely
5517                // on flush-complete notifications on the individual port
5518                // indices instead.
5519
5520                return true;
5521            }
5522
5523            return onOMXEvent(
5524                    static_cast<OMX_EVENTTYPE>(event),
5525                    static_cast<OMX_U32>(data1),
5526                    static_cast<OMX_U32>(data2));
5527        }
5528
5529        case omx_message::EMPTY_BUFFER_DONE:
5530        {
5531            IOMX::buffer_id bufferID;
5532            int32_t fenceFd;
5533
5534            CHECK(msg->findInt32("buffer", (int32_t*)&bufferID));
5535            CHECK(msg->findInt32("fence_fd", &fenceFd));
5536
5537            return onOMXEmptyBufferDone(bufferID, fenceFd);
5538        }
5539
5540        case omx_message::FILL_BUFFER_DONE:
5541        {
5542            IOMX::buffer_id bufferID;
5543            CHECK(msg->findInt32("buffer", (int32_t*)&bufferID));
5544
5545            int32_t rangeOffset, rangeLength, flags, fenceFd;
5546            int64_t timeUs;
5547
5548            CHECK(msg->findInt32("range_offset", &rangeOffset));
5549            CHECK(msg->findInt32("range_length", &rangeLength));
5550            CHECK(msg->findInt32("flags", &flags));
5551            CHECK(msg->findInt64("timestamp", &timeUs));
5552            CHECK(msg->findInt32("fence_fd", &fenceFd));
5553
5554            return onOMXFillBufferDone(
5555                    bufferID,
5556                    (size_t)rangeOffset, (size_t)rangeLength,
5557                    (OMX_U32)flags,
5558                    timeUs,
5559                    fenceFd);
5560        }
5561
5562        case omx_message::FRAME_RENDERED:
5563        {
5564            int64_t mediaTimeUs, systemNano;
5565
5566            CHECK(msg->findInt64("media_time_us", &mediaTimeUs));
5567            CHECK(msg->findInt64("system_nano", &systemNano));
5568
5569            return onOMXFrameRendered(
5570                    mediaTimeUs, systemNano);
5571        }
5572
5573        default:
5574            ALOGE("Unexpected message type: %d", type);
5575            return false;
5576    }
5577}
5578
5579bool ACodec::BaseState::onOMXFrameRendered(
5580        int64_t mediaTimeUs __unused, nsecs_t systemNano __unused) {
5581    // ignore outside of Executing and PortSettingsChanged states
5582    return true;
5583}
5584
5585bool ACodec::BaseState::onOMXEvent(
5586        OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2) {
5587    if (event == OMX_EventDataSpaceChanged) {
5588        ColorAspects aspects = ColorUtils::unpackToColorAspects(data2);
5589
5590        mCodec->onDataSpaceChanged((android_dataspace)data1, aspects);
5591        return true;
5592    }
5593
5594    if (event != OMX_EventError) {
5595        ALOGV("[%s] EVENT(%d, 0x%08x, 0x%08x)",
5596             mCodec->mComponentName.c_str(), event, data1, data2);
5597
5598        return false;
5599    }
5600
5601    ALOGE("[%s] ERROR(0x%08x)", mCodec->mComponentName.c_str(), data1);
5602
5603    // verify OMX component sends back an error we expect.
5604    OMX_ERRORTYPE omxError = (OMX_ERRORTYPE)data1;
5605    if (!isOMXError(omxError)) {
5606        ALOGW("Invalid OMX error %#x", omxError);
5607        omxError = OMX_ErrorUndefined;
5608    }
5609    mCodec->signalError(omxError);
5610
5611    return true;
5612}
5613
5614bool ACodec::BaseState::onOMXEmptyBufferDone(IOMX::buffer_id bufferID, int fenceFd) {
5615    ALOGV("[%s] onOMXEmptyBufferDone %u",
5616         mCodec->mComponentName.c_str(), bufferID);
5617
5618    BufferInfo *info = mCodec->findBufferByID(kPortIndexInput, bufferID);
5619    BufferInfo::Status status = BufferInfo::getSafeStatus(info);
5620    if (status != BufferInfo::OWNED_BY_COMPONENT) {
5621        ALOGE("Wrong ownership in EBD: %s(%d) buffer #%u", _asString(status), status, bufferID);
5622        mCodec->dumpBuffers(kPortIndexInput);
5623        if (fenceFd >= 0) {
5624            ::close(fenceFd);
5625        }
5626        return false;
5627    }
5628    info->mStatus = BufferInfo::OWNED_BY_US;
5629
5630    // input buffers cannot take fences, so wait for any fence now
5631    (void)mCodec->waitForFence(fenceFd, "onOMXEmptyBufferDone");
5632    fenceFd = -1;
5633
5634    // still save fence for completeness
5635    info->setWriteFence(fenceFd, "onOMXEmptyBufferDone");
5636
5637    // We're in "store-metadata-in-buffers" mode, the underlying
5638    // OMX component had access to data that's implicitly refcounted
5639    // by this "MediaBuffer" object. Now that the OMX component has
5640    // told us that it's done with the input buffer, we can decrement
5641    // the mediaBuffer's reference count.
5642    info->mData->meta()->setObject("mediaBufferHolder", sp<MediaBufferHolder>(nullptr));
5643
5644    PortMode mode = getPortMode(kPortIndexInput);
5645
5646    switch (mode) {
5647        case KEEP_BUFFERS:
5648            break;
5649
5650        case RESUBMIT_BUFFERS:
5651            postFillThisBuffer(info);
5652            break;
5653
5654        case FREE_BUFFERS:
5655        default:
5656            ALOGE("SHOULD NOT REACH HERE: cannot free empty output buffers");
5657            return false;
5658    }
5659
5660    return true;
5661}
5662
5663void ACodec::BaseState::postFillThisBuffer(BufferInfo *info) {
5664    if (mCodec->mPortEOS[kPortIndexInput]) {
5665        return;
5666    }
5667
5668    CHECK_EQ((int)info->mStatus, (int)BufferInfo::OWNED_BY_US);
5669
5670    info->mData->setFormat(mCodec->mInputFormat);
5671    mCodec->mBufferChannel->fillThisBuffer(info->mBufferID);
5672    info->mData.clear();
5673    info->mStatus = BufferInfo::OWNED_BY_UPSTREAM;
5674}
5675
5676void ACodec::BaseState::onInputBufferFilled(const sp<AMessage> &msg) {
5677    IOMX::buffer_id bufferID;
5678    CHECK(msg->findInt32("buffer-id", (int32_t*)&bufferID));
5679    sp<MediaCodecBuffer> buffer;
5680    int32_t err = OK;
5681    bool eos = false;
5682    PortMode mode = getPortMode(kPortIndexInput);
5683    int32_t discarded = 0;
5684    if (msg->findInt32("discarded", &discarded) && discarded) {
5685        // these are unfilled buffers returned by client
5686        // buffers are returned on MediaCodec.flush
5687        mode = KEEP_BUFFERS;
5688    }
5689    sp<RefBase> obj;
5690    CHECK(msg->findObject("buffer", &obj));
5691    buffer = static_cast<MediaCodecBuffer *>(obj.get());
5692
5693    int32_t tmp;
5694    if (buffer != NULL && buffer->meta()->findInt32("eos", &tmp) && tmp) {
5695        eos = true;
5696        err = ERROR_END_OF_STREAM;
5697    }
5698
5699    BufferInfo *info = mCodec->findBufferByID(kPortIndexInput, bufferID);
5700    BufferInfo::Status status = BufferInfo::getSafeStatus(info);
5701    if (status != BufferInfo::OWNED_BY_UPSTREAM) {
5702        ALOGE("Wrong ownership in IBF: %s(%d) buffer #%u", _asString(status), status, bufferID);
5703        mCodec->dumpBuffers(kPortIndexInput);
5704        mCodec->signalError(OMX_ErrorUndefined, FAILED_TRANSACTION);
5705        return;
5706    }
5707
5708    info->mStatus = BufferInfo::OWNED_BY_US;
5709    info->mData = buffer;
5710
5711    switch (mode) {
5712        case KEEP_BUFFERS:
5713        {
5714            if (eos) {
5715                if (!mCodec->mPortEOS[kPortIndexInput]) {
5716                    mCodec->mPortEOS[kPortIndexInput] = true;
5717                    mCodec->mInputEOSResult = err;
5718                }
5719            }
5720            break;
5721        }
5722
5723        case RESUBMIT_BUFFERS:
5724        {
5725            if (buffer != NULL && !mCodec->mPortEOS[kPortIndexInput]) {
5726                // Do not send empty input buffer w/o EOS to the component.
5727                if (buffer->size() == 0 && !eos) {
5728                    postFillThisBuffer(info);
5729                    break;
5730                }
5731
5732                int64_t timeUs;
5733                CHECK(buffer->meta()->findInt64("timeUs", &timeUs));
5734
5735                OMX_U32 flags = OMX_BUFFERFLAG_ENDOFFRAME;
5736
5737                int32_t isCSD = 0;
5738                if (buffer->meta()->findInt32("csd", &isCSD) && isCSD != 0) {
5739                    if (mCodec->mIsLegacyVP9Decoder) {
5740                        ALOGV("[%s] is legacy VP9 decoder. Ignore %u codec specific data",
5741                            mCodec->mComponentName.c_str(), bufferID);
5742                        postFillThisBuffer(info);
5743                        break;
5744                    }
5745                    flags |= OMX_BUFFERFLAG_CODECCONFIG;
5746                }
5747
5748                if (eos) {
5749                    flags |= OMX_BUFFERFLAG_EOS;
5750                }
5751
5752                size_t size = buffer->size();
5753                size_t offset = buffer->offset();
5754                if (buffer->base() != info->mCodecData->base()) {
5755                    ALOGV("[%s] Needs to copy input data for buffer %u. (%p != %p)",
5756                         mCodec->mComponentName.c_str(),
5757                         bufferID,
5758                         buffer->base(), info->mCodecData->base());
5759
5760                    sp<DataConverter> converter = mCodec->mConverter[kPortIndexInput];
5761                    if (converter == NULL || isCSD) {
5762                        converter = getCopyConverter();
5763                    }
5764                    status_t err = converter->convert(buffer, info->mCodecData);
5765                    if (err != OK) {
5766                        mCodec->signalError(OMX_ErrorUndefined, err);
5767                        return;
5768                    }
5769                    size = info->mCodecData->size();
5770                } else {
5771                    info->mCodecData->setRange(offset, size);
5772                }
5773
5774                if (flags & OMX_BUFFERFLAG_CODECCONFIG) {
5775                    ALOGV("[%s] calling emptyBuffer %u w/ codec specific data",
5776                         mCodec->mComponentName.c_str(), bufferID);
5777                } else if (flags & OMX_BUFFERFLAG_EOS) {
5778                    ALOGV("[%s] calling emptyBuffer %u w/ EOS",
5779                         mCodec->mComponentName.c_str(), bufferID);
5780                } else {
5781#if TRACK_BUFFER_TIMING
5782                    ALOGI("[%s] calling emptyBuffer %u w/ time %lld us",
5783                         mCodec->mComponentName.c_str(), bufferID, (long long)timeUs);
5784#else
5785                    ALOGV("[%s] calling emptyBuffer %u w/ time %lld us",
5786                         mCodec->mComponentName.c_str(), bufferID, (long long)timeUs);
5787#endif
5788                }
5789
5790#if TRACK_BUFFER_TIMING
5791                ACodec::BufferStats stats;
5792                stats.mEmptyBufferTimeUs = ALooper::GetNowUs();
5793                stats.mFillBufferDoneTimeUs = -1ll;
5794                mCodec->mBufferStats.add(timeUs, stats);
5795#endif
5796
5797                if (mCodec->storingMetadataInDecodedBuffers()) {
5798                    // try to submit an output buffer for each input buffer
5799                    PortMode outputMode = getPortMode(kPortIndexOutput);
5800
5801                    ALOGV("MetadataBuffersToSubmit=%u portMode=%s",
5802                            mCodec->mMetadataBuffersToSubmit,
5803                            (outputMode == FREE_BUFFERS ? "FREE" :
5804                             outputMode == KEEP_BUFFERS ? "KEEP" : "RESUBMIT"));
5805                    if (outputMode == RESUBMIT_BUFFERS) {
5806                        mCodec->submitOutputMetadataBuffer();
5807                    }
5808                }
5809                info->checkReadFence("onInputBufferFilled");
5810
5811                status_t err2 = OK;
5812                switch (mCodec->mPortMode[kPortIndexInput]) {
5813                case IOMX::kPortModePresetByteBuffer:
5814                case IOMX::kPortModePresetANWBuffer:
5815                case IOMX::kPortModePresetSecureBuffer:
5816                    {
5817                        err2 = mCodec->mOMXNode->emptyBuffer(
5818                            bufferID, info->mCodecData, flags, timeUs, info->mFenceFd);
5819                    }
5820                    break;
5821#ifndef OMX_ANDROID_COMPILE_AS_32BIT_ON_64BIT_PLATFORMS
5822                case IOMX::kPortModeDynamicNativeHandle:
5823                    if (info->mCodecData->size() >= sizeof(VideoNativeHandleMetadata)) {
5824                        VideoNativeHandleMetadata *vnhmd =
5825                            (VideoNativeHandleMetadata*)info->mCodecData->base();
5826                        sp<NativeHandle> handle = NativeHandle::create(
5827                                vnhmd->pHandle, false /* ownsHandle */);
5828                        err2 = mCodec->mOMXNode->emptyBuffer(
5829                            bufferID, handle, flags, timeUs, info->mFenceFd);
5830                    }
5831                    break;
5832                case IOMX::kPortModeDynamicANWBuffer:
5833                    if (info->mCodecData->size() >= sizeof(VideoNativeMetadata)) {
5834                        VideoNativeMetadata *vnmd = (VideoNativeMetadata*)info->mCodecData->base();
5835                        sp<GraphicBuffer> graphicBuffer = GraphicBuffer::from(vnmd->pBuffer);
5836                        err2 = mCodec->mOMXNode->emptyBuffer(
5837                            bufferID, graphicBuffer, flags, timeUs, info->mFenceFd);
5838                    }
5839                    break;
5840#endif
5841                default:
5842                    ALOGW("Can't marshall %s data in %zu sized buffers in %zu-bit mode",
5843                            asString(mCodec->mPortMode[kPortIndexInput]),
5844                            info->mCodecData->size(),
5845                            sizeof(buffer_handle_t) * 8);
5846                    err2 = ERROR_UNSUPPORTED;
5847                    break;
5848                }
5849
5850                info->mFenceFd = -1;
5851                if (err2 != OK) {
5852                    mCodec->signalError(OMX_ErrorUndefined, makeNoSideEffectStatus(err2));
5853                    return;
5854                }
5855                info->mStatus = BufferInfo::OWNED_BY_COMPONENT;
5856                // Hold the reference while component is using the buffer.
5857                info->mData = buffer;
5858
5859                if (!eos && err == OK) {
5860                    getMoreInputDataIfPossible();
5861                } else {
5862                    ALOGV("[%s] Signalled EOS (%d) on the input port",
5863                         mCodec->mComponentName.c_str(), err);
5864
5865                    mCodec->mPortEOS[kPortIndexInput] = true;
5866                    mCodec->mInputEOSResult = err;
5867                }
5868            } else if (!mCodec->mPortEOS[kPortIndexInput]) {
5869                if (err != OK && err != ERROR_END_OF_STREAM) {
5870                    ALOGV("[%s] Signalling EOS on the input port due to error %d",
5871                         mCodec->mComponentName.c_str(), err);
5872                } else {
5873                    ALOGV("[%s] Signalling EOS on the input port",
5874                         mCodec->mComponentName.c_str());
5875                }
5876
5877                ALOGV("[%s] calling emptyBuffer %u signalling EOS",
5878                     mCodec->mComponentName.c_str(), bufferID);
5879
5880                info->checkReadFence("onInputBufferFilled");
5881                status_t err2 = mCodec->mOMXNode->emptyBuffer(
5882                        bufferID, OMXBuffer::sPreset, OMX_BUFFERFLAG_EOS, 0, info->mFenceFd);
5883                info->mFenceFd = -1;
5884                if (err2 != OK) {
5885                    mCodec->signalError(OMX_ErrorUndefined, makeNoSideEffectStatus(err2));
5886                    return;
5887                }
5888                info->mStatus = BufferInfo::OWNED_BY_COMPONENT;
5889
5890                mCodec->mPortEOS[kPortIndexInput] = true;
5891                mCodec->mInputEOSResult = err;
5892            }
5893            break;
5894        }
5895
5896        case FREE_BUFFERS:
5897            break;
5898
5899        default:
5900            ALOGE("invalid port mode: %d", mode);
5901            break;
5902    }
5903}
5904
5905void ACodec::BaseState::getMoreInputDataIfPossible() {
5906    if (mCodec->mPortEOS[kPortIndexInput]) {
5907        return;
5908    }
5909
5910    BufferInfo *eligible = NULL;
5911
5912    for (size_t i = 0; i < mCodec->mBuffers[kPortIndexInput].size(); ++i) {
5913        BufferInfo *info = &mCodec->mBuffers[kPortIndexInput].editItemAt(i);
5914
5915#if 0
5916        if (info->mStatus == BufferInfo::OWNED_BY_UPSTREAM) {
5917            // There's already a "read" pending.
5918            return;
5919        }
5920#endif
5921
5922        if (info->mStatus == BufferInfo::OWNED_BY_US) {
5923            eligible = info;
5924        }
5925    }
5926
5927    if (eligible == NULL) {
5928        return;
5929    }
5930
5931    postFillThisBuffer(eligible);
5932}
5933
5934bool ACodec::BaseState::onOMXFillBufferDone(
5935        IOMX::buffer_id bufferID,
5936        size_t rangeOffset, size_t rangeLength,
5937        OMX_U32 flags,
5938        int64_t timeUs,
5939        int fenceFd) {
5940    ALOGV("[%s] onOMXFillBufferDone %u time %" PRId64 " us, flags = 0x%08x",
5941         mCodec->mComponentName.c_str(), bufferID, timeUs, flags);
5942
5943    ssize_t index;
5944    status_t err= OK;
5945
5946#if TRACK_BUFFER_TIMING
5947    index = mCodec->mBufferStats.indexOfKey(timeUs);
5948    if (index >= 0) {
5949        ACodec::BufferStats *stats = &mCodec->mBufferStats.editValueAt(index);
5950        stats->mFillBufferDoneTimeUs = ALooper::GetNowUs();
5951
5952        ALOGI("frame PTS %lld: %lld",
5953                timeUs,
5954                stats->mFillBufferDoneTimeUs - stats->mEmptyBufferTimeUs);
5955
5956        mCodec->mBufferStats.removeItemsAt(index);
5957        stats = NULL;
5958    }
5959#endif
5960
5961    BufferInfo *info =
5962        mCodec->findBufferByID(kPortIndexOutput, bufferID, &index);
5963    BufferInfo::Status status = BufferInfo::getSafeStatus(info);
5964    if (status != BufferInfo::OWNED_BY_COMPONENT) {
5965        ALOGE("Wrong ownership in FBD: %s(%d) buffer #%u", _asString(status), status, bufferID);
5966        mCodec->dumpBuffers(kPortIndexOutput);
5967        mCodec->signalError(OMX_ErrorUndefined, FAILED_TRANSACTION);
5968        if (fenceFd >= 0) {
5969            ::close(fenceFd);
5970        }
5971        return true;
5972    }
5973
5974    info->mDequeuedAt = ++mCodec->mDequeueCounter;
5975    info->mStatus = BufferInfo::OWNED_BY_US;
5976
5977    if (info->mRenderInfo != NULL) {
5978        // The fence for an emptied buffer must have signaled, but there still could be queued
5979        // or out-of-order dequeued buffers in the render queue prior to this buffer. Drop these,
5980        // as we will soon requeue this buffer to the surface. While in theory we could still keep
5981        // track of buffers that are requeued to the surface, it is better to add support to the
5982        // buffer-queue to notify us of released buffers and their fences (in the future).
5983        mCodec->notifyOfRenderedFrames(true /* dropIncomplete */);
5984    }
5985
5986    // byte buffers cannot take fences, so wait for any fence now
5987    if (mCodec->mNativeWindow == NULL) {
5988        (void)mCodec->waitForFence(fenceFd, "onOMXFillBufferDone");
5989        fenceFd = -1;
5990    }
5991    info->setReadFence(fenceFd, "onOMXFillBufferDone");
5992
5993    PortMode mode = getPortMode(kPortIndexOutput);
5994
5995    switch (mode) {
5996        case KEEP_BUFFERS:
5997            break;
5998
5999        case RESUBMIT_BUFFERS:
6000        {
6001            if (rangeLength == 0 && (!(flags & OMX_BUFFERFLAG_EOS)
6002                    || mCodec->mPortEOS[kPortIndexOutput])) {
6003                ALOGV("[%s] calling fillBuffer %u",
6004                     mCodec->mComponentName.c_str(), info->mBufferID);
6005
6006                err = mCodec->fillBuffer(info);
6007                if (err != OK) {
6008                    mCodec->signalError(OMX_ErrorUndefined, makeNoSideEffectStatus(err));
6009                    return true;
6010                }
6011                break;
6012            }
6013
6014            sp<MediaCodecBuffer> buffer = info->mData;
6015
6016            if (mCodec->mOutputFormat != mCodec->mLastOutputFormat && rangeLength > 0) {
6017                // pretend that output format has changed on the first frame (we used to do this)
6018                if (mCodec->mBaseOutputFormat == mCodec->mOutputFormat) {
6019                    mCodec->onOutputFormatChanged(mCodec->mOutputFormat);
6020                }
6021                mCodec->sendFormatChange();
6022            }
6023            buffer->setFormat(mCodec->mOutputFormat);
6024
6025            if (mCodec->usingSecureBufferOnEncoderOutput()) {
6026                native_handle_t *handle = NULL;
6027                sp<SecureBuffer> secureBuffer = static_cast<SecureBuffer *>(buffer.get());
6028                if (secureBuffer != NULL) {
6029#ifdef OMX_ANDROID_COMPILE_AS_32BIT_ON_64BIT_PLATFORMS
6030                    // handle is only valid on 32-bit/mediaserver process
6031                    handle = NULL;
6032#else
6033                    handle = (native_handle_t *)secureBuffer->getDestinationPointer();
6034#endif
6035                }
6036                buffer->meta()->setPointer("handle", handle);
6037                buffer->meta()->setInt32("rangeOffset", rangeOffset);
6038                buffer->meta()->setInt32("rangeLength", rangeLength);
6039            } else if (buffer->base() == info->mCodecData->base()) {
6040                buffer->setRange(rangeOffset, rangeLength);
6041            } else {
6042                info->mCodecData->setRange(rangeOffset, rangeLength);
6043                // in this case we know that mConverter is not null
6044                status_t err = mCodec->mConverter[kPortIndexOutput]->convert(
6045                        info->mCodecData, buffer);
6046                if (err != OK) {
6047                    mCodec->signalError(OMX_ErrorUndefined, makeNoSideEffectStatus(err));
6048                    return true;
6049                }
6050            }
6051#if 0
6052            if (mCodec->mNativeWindow == NULL) {
6053                if (IsIDR(info->mData->data(), info->mData->size())) {
6054                    ALOGI("IDR frame");
6055                }
6056            }
6057#endif
6058
6059            if (mCodec->mSkipCutBuffer != NULL) {
6060                mCodec->mSkipCutBuffer->submit(buffer);
6061            }
6062            buffer->meta()->setInt64("timeUs", timeUs);
6063
6064            info->mData.clear();
6065
6066            mCodec->mBufferChannel->drainThisBuffer(info->mBufferID, flags);
6067
6068            info->mStatus = BufferInfo::OWNED_BY_DOWNSTREAM;
6069
6070            if (flags & OMX_BUFFERFLAG_EOS) {
6071                ALOGV("[%s] saw output EOS", mCodec->mComponentName.c_str());
6072
6073                mCodec->mCallback->onEos(mCodec->mInputEOSResult);
6074                mCodec->mPortEOS[kPortIndexOutput] = true;
6075            }
6076            break;
6077        }
6078
6079        case FREE_BUFFERS:
6080            err = mCodec->freeBuffer(kPortIndexOutput, index);
6081            if (err != OK) {
6082                mCodec->signalError(OMX_ErrorUndefined, makeNoSideEffectStatus(err));
6083                return true;
6084            }
6085            break;
6086
6087        default:
6088            ALOGE("Invalid port mode: %d", mode);
6089            return false;
6090    }
6091
6092    return true;
6093}
6094
6095void ACodec::BaseState::onOutputBufferDrained(const sp<AMessage> &msg) {
6096    IOMX::buffer_id bufferID;
6097    CHECK(msg->findInt32("buffer-id", (int32_t*)&bufferID));
6098    sp<RefBase> obj;
6099    CHECK(msg->findObject("buffer", &obj));
6100    sp<MediaCodecBuffer> buffer = static_cast<MediaCodecBuffer *>(obj.get());
6101    int32_t discarded = 0;
6102    msg->findInt32("discarded", &discarded);
6103
6104    ssize_t index;
6105    BufferInfo *info = mCodec->findBufferByID(kPortIndexOutput, bufferID, &index);
6106    BufferInfo::Status status = BufferInfo::getSafeStatus(info);
6107    if (status != BufferInfo::OWNED_BY_DOWNSTREAM) {
6108        ALOGE("Wrong ownership in OBD: %s(%d) buffer #%u", _asString(status), status, bufferID);
6109        mCodec->dumpBuffers(kPortIndexOutput);
6110        mCodec->signalError(OMX_ErrorUndefined, FAILED_TRANSACTION);
6111        return;
6112    }
6113    info->mData = buffer;
6114    int32_t render;
6115    if (mCodec->mNativeWindow != NULL
6116            && msg->findInt32("render", &render) && render != 0
6117            && !discarded && buffer->size() != 0) {
6118        ATRACE_NAME("render");
6119        // The client wants this buffer to be rendered.
6120
6121        android_native_rect_t crop;
6122        if (buffer->format()->findRect("crop", &crop.left, &crop.top, &crop.right, &crop.bottom)) {
6123            // NOTE: native window uses extended right-bottom coordinate
6124            ++crop.right;
6125            ++crop.bottom;
6126            if (memcmp(&crop, &mCodec->mLastNativeWindowCrop, sizeof(crop)) != 0) {
6127                mCodec->mLastNativeWindowCrop = crop;
6128                status_t err = native_window_set_crop(mCodec->mNativeWindow.get(), &crop);
6129                ALOGW_IF(err != NO_ERROR, "failed to set crop: %d", err);
6130            }
6131        }
6132
6133        int32_t dataSpace;
6134        if (buffer->format()->findInt32("android._dataspace", &dataSpace)
6135                && dataSpace != mCodec->mLastNativeWindowDataSpace) {
6136            status_t err = native_window_set_buffers_data_space(
6137                    mCodec->mNativeWindow.get(), (android_dataspace)dataSpace);
6138            mCodec->mLastNativeWindowDataSpace = dataSpace;
6139            ALOGW_IF(err != NO_ERROR, "failed to set dataspace: %d", err);
6140        }
6141        if (buffer->format()->contains("hdr-static-info")) {
6142            HDRStaticInfo info;
6143            if (ColorUtils::getHDRStaticInfoFromFormat(buffer->format(), &info)
6144                && memcmp(&mCodec->mLastHDRStaticInfo, &info, sizeof(info))) {
6145                setNativeWindowHdrMetadata(mCodec->mNativeWindow.get(), &info);
6146                mCodec->mLastHDRStaticInfo = info;
6147            }
6148        }
6149
6150        // save buffers sent to the surface so we can get render time when they return
6151        int64_t mediaTimeUs = -1;
6152        buffer->meta()->findInt64("timeUs", &mediaTimeUs);
6153        if (mediaTimeUs >= 0) {
6154            mCodec->mRenderTracker.onFrameQueued(
6155                    mediaTimeUs, info->mGraphicBuffer, new Fence(::dup(info->mFenceFd)));
6156        }
6157
6158        int64_t timestampNs = 0;
6159        if (!msg->findInt64("timestampNs", &timestampNs)) {
6160            // use media timestamp if client did not request a specific render timestamp
6161            if (buffer->meta()->findInt64("timeUs", &timestampNs)) {
6162                ALOGV("using buffer PTS of %lld", (long long)timestampNs);
6163                timestampNs *= 1000;
6164            }
6165        }
6166
6167        status_t err;
6168        err = native_window_set_buffers_timestamp(mCodec->mNativeWindow.get(), timestampNs);
6169        ALOGW_IF(err != NO_ERROR, "failed to set buffer timestamp: %d", err);
6170
6171        info->checkReadFence("onOutputBufferDrained before queueBuffer");
6172        err = mCodec->mNativeWindow->queueBuffer(
6173                    mCodec->mNativeWindow.get(), info->mGraphicBuffer.get(), info->mFenceFd);
6174        info->mFenceFd = -1;
6175        if (err == OK) {
6176            info->mStatus = BufferInfo::OWNED_BY_NATIVE_WINDOW;
6177        } else {
6178            ALOGE("queueBuffer failed in onOutputBufferDrained: %d", err);
6179            mCodec->signalError(OMX_ErrorUndefined, makeNoSideEffectStatus(err));
6180            info->mStatus = BufferInfo::OWNED_BY_US;
6181            // keeping read fence as write fence to avoid clobbering
6182            info->mIsReadFence = false;
6183        }
6184    } else {
6185        if (mCodec->mNativeWindow != NULL && (discarded || buffer->size() != 0)) {
6186            // move read fence into write fence to avoid clobbering
6187            info->mIsReadFence = false;
6188            ATRACE_NAME("frame-drop");
6189        }
6190        info->mStatus = BufferInfo::OWNED_BY_US;
6191    }
6192
6193    PortMode mode = getPortMode(kPortIndexOutput);
6194
6195    switch (mode) {
6196        case KEEP_BUFFERS:
6197        {
6198            // XXX fishy, revisit!!! What about the FREE_BUFFERS case below?
6199
6200            if (info->mStatus == BufferInfo::OWNED_BY_NATIVE_WINDOW) {
6201                // We cannot resubmit the buffer we just rendered, dequeue
6202                // the spare instead.
6203
6204                info = mCodec->dequeueBufferFromNativeWindow();
6205            }
6206            break;
6207        }
6208
6209        case RESUBMIT_BUFFERS:
6210        {
6211            if (!mCodec->mPortEOS[kPortIndexOutput]) {
6212                if (info->mStatus == BufferInfo::OWNED_BY_NATIVE_WINDOW) {
6213                    // We cannot resubmit the buffer we just rendered, dequeue
6214                    // the spare instead.
6215
6216                    info = mCodec->dequeueBufferFromNativeWindow();
6217                }
6218
6219                if (info != NULL) {
6220                    ALOGV("[%s] calling fillBuffer %u",
6221                         mCodec->mComponentName.c_str(), info->mBufferID);
6222                    info->checkWriteFence("onOutputBufferDrained::RESUBMIT_BUFFERS");
6223                    status_t err = mCodec->fillBuffer(info);
6224                    if (err != OK) {
6225                        mCodec->signalError(OMX_ErrorUndefined, makeNoSideEffectStatus(err));
6226                    }
6227                }
6228            }
6229            break;
6230        }
6231
6232        case FREE_BUFFERS:
6233        {
6234            status_t err = mCodec->freeBuffer(kPortIndexOutput, index);
6235            if (err != OK) {
6236                mCodec->signalError(OMX_ErrorUndefined, makeNoSideEffectStatus(err));
6237            }
6238            break;
6239        }
6240
6241        default:
6242            ALOGE("Invalid port mode: %d", mode);
6243            return;
6244    }
6245}
6246
6247////////////////////////////////////////////////////////////////////////////////
6248
6249ACodec::UninitializedState::UninitializedState(ACodec *codec)
6250    : BaseState(codec) {
6251}
6252
6253void ACodec::UninitializedState::stateEntered() {
6254    ALOGV("Now uninitialized");
6255
6256    if (mDeathNotifier != NULL) {
6257        if (mCodec->mOMXNode != NULL) {
6258            auto tOmxNode = mCodec->mOMXNode->getHalInterface();
6259            tOmxNode->unlinkToDeath(mDeathNotifier);
6260        }
6261        mDeathNotifier.clear();
6262    }
6263
6264    mCodec->mUsingNativeWindow = false;
6265    mCodec->mNativeWindow.clear();
6266    mCodec->mNativeWindowUsageBits = 0;
6267    mCodec->mOMX.clear();
6268    mCodec->mOMXNode.clear();
6269    mCodec->mFlags = 0;
6270    mCodec->mPortMode[kPortIndexInput] = IOMX::kPortModePresetByteBuffer;
6271    mCodec->mPortMode[kPortIndexOutput] = IOMX::kPortModePresetByteBuffer;
6272    mCodec->mConverter[0].clear();
6273    mCodec->mConverter[1].clear();
6274    mCodec->mComponentName.clear();
6275}
6276
6277bool ACodec::UninitializedState::onMessageReceived(const sp<AMessage> &msg) {
6278    bool handled = false;
6279
6280    switch (msg->what()) {
6281        case ACodec::kWhatSetup:
6282        {
6283            onSetup(msg);
6284
6285            handled = true;
6286            break;
6287        }
6288
6289        case ACodec::kWhatAllocateComponent:
6290        {
6291            onAllocateComponent(msg);
6292            handled = true;
6293            break;
6294        }
6295
6296        case ACodec::kWhatShutdown:
6297        {
6298            int32_t keepComponentAllocated;
6299            CHECK(msg->findInt32(
6300                        "keepComponentAllocated", &keepComponentAllocated));
6301            ALOGW_IF(keepComponentAllocated,
6302                     "cannot keep component allocated on shutdown in Uninitialized state");
6303            if (keepComponentAllocated) {
6304                mCodec->mCallback->onStopCompleted();
6305            } else {
6306                mCodec->mCallback->onReleaseCompleted();
6307            }
6308            handled = true;
6309            break;
6310        }
6311
6312        case ACodec::kWhatFlush:
6313        {
6314            mCodec->mCallback->onFlushCompleted();
6315            handled = true;
6316            break;
6317        }
6318
6319        case ACodec::kWhatReleaseCodecInstance:
6320        {
6321            // nothing to do, as we have already signaled shutdown
6322            handled = true;
6323            break;
6324        }
6325
6326        default:
6327            return BaseState::onMessageReceived(msg);
6328    }
6329
6330    return handled;
6331}
6332
6333void ACodec::UninitializedState::onSetup(
6334        const sp<AMessage> &msg) {
6335    if (onAllocateComponent(msg)
6336            && mCodec->mLoadedState->onConfigureComponent(msg)) {
6337        mCodec->mLoadedState->onStart();
6338    }
6339}
6340
6341bool ACodec::UninitializedState::onAllocateComponent(const sp<AMessage> &msg) {
6342    ALOGV("onAllocateComponent");
6343
6344    CHECK(mCodec->mOMXNode == NULL);
6345
6346    sp<AMessage> notify = new AMessage(kWhatOMXDied, mCodec);
6347
6348    sp<RefBase> obj;
6349    CHECK(msg->findObject("codecInfo", &obj));
6350    sp<MediaCodecInfo> info = (MediaCodecInfo *)obj.get();
6351    if (info == nullptr) {
6352        ALOGE("Unexpected nullptr for codec information");
6353        mCodec->signalError(OMX_ErrorUndefined, UNKNOWN_ERROR);
6354        return false;
6355    }
6356    AString owner = (info->getOwnerName() == nullptr) ? "default" : info->getOwnerName();
6357
6358    AString componentName;
6359    CHECK(msg->findString("componentName", &componentName));
6360
6361    sp<CodecObserver> observer = new CodecObserver;
6362    sp<IOMX> omx;
6363    sp<IOMXNode> omxNode;
6364
6365    status_t err = NAME_NOT_FOUND;
6366    OMXClient client;
6367    if (client.connect(owner.c_str()) != OK) {
6368        mCodec->signalError(OMX_ErrorUndefined, NO_INIT);
6369        return false;
6370    }
6371    omx = client.interface();
6372
6373    pid_t tid = gettid();
6374    int prevPriority = androidGetThreadPriority(tid);
6375    androidSetThreadPriority(tid, ANDROID_PRIORITY_FOREGROUND);
6376    err = omx->allocateNode(componentName.c_str(), observer, &omxNode);
6377    androidSetThreadPriority(tid, prevPriority);
6378
6379    if (err != OK) {
6380        ALOGE("Unable to instantiate codec '%s' with err %#x.", componentName.c_str(), err);
6381
6382        mCodec->signalError((OMX_ERRORTYPE)err, makeNoSideEffectStatus(err));
6383        return false;
6384    }
6385
6386    mDeathNotifier = new DeathNotifier(notify);
6387    auto tOmxNode = omxNode->getHalInterface();
6388    if (!tOmxNode->linkToDeath(mDeathNotifier, 0)) {
6389        mDeathNotifier.clear();
6390    }
6391
6392    notify = new AMessage(kWhatOMXMessageList, mCodec);
6393    notify->setInt32("generation", ++mCodec->mNodeGeneration);
6394    observer->setNotificationMessage(notify);
6395
6396    mCodec->mComponentName = componentName;
6397    mCodec->mRenderTracker.setComponentName(componentName);
6398    mCodec->mFlags = 0;
6399
6400    if (componentName.endsWith(".secure")) {
6401        mCodec->mFlags |= kFlagIsSecure;
6402        mCodec->mFlags |= kFlagIsGrallocUsageProtected;
6403        mCodec->mFlags |= kFlagPushBlankBuffersToNativeWindowOnShutdown;
6404    }
6405
6406    mCodec->mOMX = omx;
6407    mCodec->mOMXNode = omxNode;
6408    mCodec->mCallback->onComponentAllocated(mCodec->mComponentName.c_str());
6409    mCodec->changeState(mCodec->mLoadedState);
6410
6411    return true;
6412}
6413
6414////////////////////////////////////////////////////////////////////////////////
6415
6416ACodec::LoadedState::LoadedState(ACodec *codec)
6417    : BaseState(codec) {
6418}
6419
6420void ACodec::LoadedState::stateEntered() {
6421    ALOGV("[%s] Now Loaded", mCodec->mComponentName.c_str());
6422
6423    mCodec->mPortEOS[kPortIndexInput] =
6424        mCodec->mPortEOS[kPortIndexOutput] = false;
6425
6426    mCodec->mInputEOSResult = OK;
6427
6428    mCodec->mDequeueCounter = 0;
6429    mCodec->mMetadataBuffersToSubmit = 0;
6430    mCodec->mRepeatFrameDelayUs = -1ll;
6431    mCodec->mInputFormat.clear();
6432    mCodec->mOutputFormat.clear();
6433    mCodec->mBaseOutputFormat.clear();
6434    mCodec->mGraphicBufferSource.clear();
6435
6436    if (mCodec->mShutdownInProgress) {
6437        bool keepComponentAllocated = mCodec->mKeepComponentAllocated;
6438
6439        mCodec->mShutdownInProgress = false;
6440        mCodec->mKeepComponentAllocated = false;
6441
6442        onShutdown(keepComponentAllocated);
6443    }
6444    mCodec->mExplicitShutdown = false;
6445
6446    mCodec->processDeferredMessages();
6447}
6448
6449void ACodec::LoadedState::onShutdown(bool keepComponentAllocated) {
6450    if (!keepComponentAllocated) {
6451        (void)mCodec->mOMXNode->freeNode();
6452
6453        mCodec->changeState(mCodec->mUninitializedState);
6454    }
6455
6456    if (mCodec->mExplicitShutdown) {
6457        if (keepComponentAllocated) {
6458            mCodec->mCallback->onStopCompleted();
6459        } else {
6460            mCodec->mCallback->onReleaseCompleted();
6461        }
6462        mCodec->mExplicitShutdown = false;
6463    }
6464}
6465
6466bool ACodec::LoadedState::onMessageReceived(const sp<AMessage> &msg) {
6467    bool handled = false;
6468
6469    switch (msg->what()) {
6470        case ACodec::kWhatConfigureComponent:
6471        {
6472            onConfigureComponent(msg);
6473            handled = true;
6474            break;
6475        }
6476
6477        case ACodec::kWhatCreateInputSurface:
6478        {
6479            onCreateInputSurface(msg);
6480            handled = true;
6481            break;
6482        }
6483
6484        case ACodec::kWhatSetInputSurface:
6485        {
6486            onSetInputSurface(msg);
6487            handled = true;
6488            break;
6489        }
6490
6491        case ACodec::kWhatStart:
6492        {
6493            onStart();
6494            handled = true;
6495            break;
6496        }
6497
6498        case ACodec::kWhatShutdown:
6499        {
6500            int32_t keepComponentAllocated;
6501            CHECK(msg->findInt32(
6502                        "keepComponentAllocated", &keepComponentAllocated));
6503
6504            mCodec->mExplicitShutdown = true;
6505            onShutdown(keepComponentAllocated);
6506
6507            handled = true;
6508            break;
6509        }
6510
6511        case ACodec::kWhatFlush:
6512        {
6513            mCodec->mCallback->onFlushCompleted();
6514            handled = true;
6515            break;
6516        }
6517
6518        default:
6519            return BaseState::onMessageReceived(msg);
6520    }
6521
6522    return handled;
6523}
6524
6525bool ACodec::LoadedState::onConfigureComponent(
6526        const sp<AMessage> &msg) {
6527    ALOGV("onConfigureComponent");
6528
6529    CHECK(mCodec->mOMXNode != NULL);
6530
6531    status_t err = OK;
6532    AString mime;
6533    if (!msg->findString("mime", &mime)) {
6534        err = BAD_VALUE;
6535    } else {
6536        err = mCodec->configureCodec(mime.c_str(), msg);
6537    }
6538    if (err != OK) {
6539        ALOGE("[%s] configureCodec returning error %d",
6540              mCodec->mComponentName.c_str(), err);
6541
6542        mCodec->signalError(OMX_ErrorUndefined, makeNoSideEffectStatus(err));
6543        return false;
6544    }
6545
6546    mCodec->mCallback->onComponentConfigured(mCodec->mInputFormat, mCodec->mOutputFormat);
6547
6548    return true;
6549}
6550
6551status_t ACodec::LoadedState::setupInputSurface() {
6552    if (mCodec->mGraphicBufferSource == NULL) {
6553        return BAD_VALUE;
6554    }
6555
6556    android_dataspace dataSpace;
6557    status_t err =
6558        mCodec->setInitialColorAspectsForVideoEncoderSurfaceAndGetDataSpace(&dataSpace);
6559    if (err != OK) {
6560        ALOGE("Failed to get default data space");
6561        return err;
6562    }
6563
6564    err = statusFromBinderStatus(
6565            mCodec->mGraphicBufferSource->configure(mCodec->mOMXNode, dataSpace));
6566    if (err != OK) {
6567        ALOGE("[%s] Unable to configure for node (err %d)",
6568              mCodec->mComponentName.c_str(), err);
6569        return err;
6570    }
6571
6572    if (mCodec->mRepeatFrameDelayUs > 0ll) {
6573        err = statusFromBinderStatus(
6574                mCodec->mGraphicBufferSource->setRepeatPreviousFrameDelayUs(
6575                        mCodec->mRepeatFrameDelayUs));
6576
6577        if (err != OK) {
6578            ALOGE("[%s] Unable to configure option to repeat previous "
6579                  "frames (err %d)",
6580                  mCodec->mComponentName.c_str(), err);
6581            return err;
6582        }
6583    }
6584
6585    if (mCodec->mMaxPtsGapUs > 0ll) {
6586        OMX_PARAM_U32TYPE maxPtsGapParams;
6587        InitOMXParams(&maxPtsGapParams);
6588        maxPtsGapParams.nPortIndex = kPortIndexInput;
6589        maxPtsGapParams.nU32 = (uint32_t) mCodec->mMaxPtsGapUs;
6590
6591        err = mCodec->mOMXNode->setParameter(
6592                (OMX_INDEXTYPE)OMX_IndexParamMaxFrameDurationForBitrateControl,
6593                &maxPtsGapParams, sizeof(maxPtsGapParams));
6594
6595        if (err != OK) {
6596            ALOGE("[%s] Unable to configure max timestamp gap (err %d)",
6597                    mCodec->mComponentName.c_str(), err);
6598            return err;
6599        }
6600    }
6601
6602    if (mCodec->mMaxFps > 0) {
6603        err = statusFromBinderStatus(
6604                mCodec->mGraphicBufferSource->setMaxFps(mCodec->mMaxFps));
6605
6606        if (err != OK) {
6607            ALOGE("[%s] Unable to configure max fps (err %d)",
6608                    mCodec->mComponentName.c_str(), err);
6609            return err;
6610        }
6611    }
6612
6613    if (mCodec->mCaptureFps > 0. && mCodec->mFps > 0.) {
6614        err = statusFromBinderStatus(
6615                mCodec->mGraphicBufferSource->setTimeLapseConfig(
6616                        mCodec->mFps, mCodec->mCaptureFps));
6617
6618        if (err != OK) {
6619            ALOGE("[%s] Unable to configure time lapse (err %d)",
6620                    mCodec->mComponentName.c_str(), err);
6621            return err;
6622        }
6623    }
6624
6625    if (mCodec->mCreateInputBuffersSuspended) {
6626        err = statusFromBinderStatus(
6627                mCodec->mGraphicBufferSource->setSuspend(true, -1));
6628
6629        if (err != OK) {
6630            ALOGE("[%s] Unable to configure option to suspend (err %d)",
6631                  mCodec->mComponentName.c_str(), err);
6632            return err;
6633        }
6634    }
6635
6636    uint32_t usageBits;
6637    if (mCodec->mOMXNode->getParameter(
6638            (OMX_INDEXTYPE)OMX_IndexParamConsumerUsageBits,
6639            &usageBits, sizeof(usageBits)) == OK) {
6640        mCodec->mInputFormat->setInt32(
6641                "using-sw-read-often", !!(usageBits & GRALLOC_USAGE_SW_READ_OFTEN));
6642    }
6643
6644    sp<ABuffer> colorAspectsBuffer;
6645    if (mCodec->mInputFormat->findBuffer("android._color-aspects", &colorAspectsBuffer)) {
6646        if (colorAspectsBuffer->size() != sizeof(ColorAspects)) {
6647            return INVALID_OPERATION;
6648        }
6649
6650        err = statusFromBinderStatus(
6651                mCodec->mGraphicBufferSource->setColorAspects(ColorUtils::packToU32(
6652                        *(ColorAspects *)colorAspectsBuffer->base())));
6653
6654        if (err != OK) {
6655            ALOGE("[%s] Unable to configure color aspects (err %d)",
6656                  mCodec->mComponentName.c_str(), err);
6657            return err;
6658        }
6659    }
6660    return OK;
6661}
6662
6663void ACodec::LoadedState::onCreateInputSurface(
6664        const sp<AMessage> & /* msg */) {
6665    ALOGV("onCreateInputSurface");
6666
6667    sp<IGraphicBufferProducer> bufferProducer;
6668    status_t err = mCodec->mOMX->createInputSurface(
6669            &bufferProducer, &mCodec->mGraphicBufferSource);
6670
6671    if (err == OK) {
6672        err = setupInputSurface();
6673    }
6674
6675    if (err == OK) {
6676        mCodec->mCallback->onInputSurfaceCreated(
6677                mCodec->mInputFormat,
6678                mCodec->mOutputFormat,
6679                new BufferProducerWrapper(bufferProducer));
6680    } else {
6681        // Can't use mCodec->signalError() here -- MediaCodec won't forward
6682        // the error through because it's in the "configured" state.  We
6683        // send a kWhatInputSurfaceCreated with an error value instead.
6684        ALOGE("[%s] onCreateInputSurface returning error %d",
6685                mCodec->mComponentName.c_str(), err);
6686        mCodec->mCallback->onInputSurfaceCreationFailed(err);
6687    }
6688}
6689
6690void ACodec::LoadedState::onSetInputSurface(const sp<AMessage> &msg) {
6691    ALOGV("onSetInputSurface");
6692
6693    sp<RefBase> obj;
6694    CHECK(msg->findObject("input-surface", &obj));
6695    sp<PersistentSurface> surface = static_cast<PersistentSurface *>(obj.get());
6696    mCodec->mGraphicBufferSource = surface->getBufferSource();
6697
6698    status_t err = setupInputSurface();
6699
6700    if (err == OK) {
6701        mCodec->mCallback->onInputSurfaceAccepted(
6702                mCodec->mInputFormat, mCodec->mOutputFormat);
6703    } else {
6704        // Can't use mCodec->signalError() here -- MediaCodec won't forward
6705        // the error through because it's in the "configured" state.  We
6706        // send a kWhatInputSurfaceAccepted with an error value instead.
6707        ALOGE("[%s] onSetInputSurface returning error %d",
6708                mCodec->mComponentName.c_str(), err);
6709        mCodec->mCallback->onInputSurfaceDeclined(err);
6710    }
6711}
6712
6713void ACodec::LoadedState::onStart() {
6714    ALOGV("onStart");
6715
6716    status_t err = mCodec->mOMXNode->sendCommand(OMX_CommandStateSet, OMX_StateIdle);
6717    if (err != OK) {
6718        mCodec->signalError(OMX_ErrorUndefined, makeNoSideEffectStatus(err));
6719    } else {
6720        mCodec->changeState(mCodec->mLoadedToIdleState);
6721    }
6722}
6723
6724////////////////////////////////////////////////////////////////////////////////
6725
6726ACodec::LoadedToIdleState::LoadedToIdleState(ACodec *codec)
6727    : BaseState(codec) {
6728}
6729
6730void ACodec::LoadedToIdleState::stateEntered() {
6731    ALOGV("[%s] Now Loaded->Idle", mCodec->mComponentName.c_str());
6732
6733    status_t err;
6734    if ((err = allocateBuffers()) != OK) {
6735        ALOGE("Failed to allocate buffers after transitioning to IDLE state "
6736             "(error 0x%08x)",
6737             err);
6738
6739        mCodec->signalError(OMX_ErrorUndefined, makeNoSideEffectStatus(err));
6740
6741        mCodec->mOMXNode->sendCommand(
6742                OMX_CommandStateSet, OMX_StateLoaded);
6743        if (mCodec->allYourBuffersAreBelongToUs(kPortIndexInput)) {
6744            mCodec->freeBuffersOnPort(kPortIndexInput);
6745        }
6746        if (mCodec->allYourBuffersAreBelongToUs(kPortIndexOutput)) {
6747            mCodec->freeBuffersOnPort(kPortIndexOutput);
6748        }
6749
6750        mCodec->changeState(mCodec->mLoadedState);
6751    }
6752}
6753
6754status_t ACodec::LoadedToIdleState::allocateBuffers() {
6755    status_t err = mCodec->allocateBuffersOnPort(kPortIndexInput);
6756    if (err != OK) {
6757        return err;
6758    }
6759
6760    err = mCodec->allocateBuffersOnPort(kPortIndexOutput);
6761    if (err != OK) {
6762        return err;
6763    }
6764
6765    mCodec->mCallback->onStartCompleted();
6766
6767    return OK;
6768}
6769
6770bool ACodec::LoadedToIdleState::onMessageReceived(const sp<AMessage> &msg) {
6771    switch (msg->what()) {
6772        case kWhatSetParameters:
6773        case kWhatShutdown:
6774        {
6775            mCodec->deferMessage(msg);
6776            return true;
6777        }
6778
6779        case kWhatSignalEndOfInputStream:
6780        {
6781            mCodec->onSignalEndOfInputStream();
6782            return true;
6783        }
6784
6785        case kWhatResume:
6786        {
6787            // We'll be active soon enough.
6788            return true;
6789        }
6790
6791        case kWhatFlush:
6792        {
6793            // We haven't even started yet, so we're flushed alright...
6794            mCodec->mCallback->onFlushCompleted();
6795            return true;
6796        }
6797
6798        default:
6799            return BaseState::onMessageReceived(msg);
6800    }
6801}
6802
6803bool ACodec::LoadedToIdleState::onOMXEvent(
6804        OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2) {
6805    switch (event) {
6806        case OMX_EventCmdComplete:
6807        {
6808            status_t err = OK;
6809            if (data1 != (OMX_U32)OMX_CommandStateSet
6810                    || data2 != (OMX_U32)OMX_StateIdle) {
6811                ALOGE("Unexpected command completion in LoadedToIdleState: %s(%u) %s(%u)",
6812                        asString((OMX_COMMANDTYPE)data1), data1,
6813                        asString((OMX_STATETYPE)data2), data2);
6814                err = FAILED_TRANSACTION;
6815            }
6816
6817            if (err == OK) {
6818                err = mCodec->mOMXNode->sendCommand(
6819                    OMX_CommandStateSet, OMX_StateExecuting);
6820            }
6821
6822            if (err != OK) {
6823                mCodec->signalError(OMX_ErrorUndefined, makeNoSideEffectStatus(err));
6824            } else {
6825                mCodec->changeState(mCodec->mIdleToExecutingState);
6826            }
6827
6828            return true;
6829        }
6830
6831        default:
6832            return BaseState::onOMXEvent(event, data1, data2);
6833    }
6834}
6835
6836////////////////////////////////////////////////////////////////////////////////
6837
6838ACodec::IdleToExecutingState::IdleToExecutingState(ACodec *codec)
6839    : BaseState(codec) {
6840}
6841
6842void ACodec::IdleToExecutingState::stateEntered() {
6843    ALOGV("[%s] Now Idle->Executing", mCodec->mComponentName.c_str());
6844}
6845
6846bool ACodec::IdleToExecutingState::onMessageReceived(const sp<AMessage> &msg) {
6847    switch (msg->what()) {
6848        case kWhatSetParameters:
6849        case kWhatShutdown:
6850        {
6851            mCodec->deferMessage(msg);
6852            return true;
6853        }
6854
6855        case kWhatResume:
6856        {
6857            // We'll be active soon enough.
6858            return true;
6859        }
6860
6861        case kWhatFlush:
6862        {
6863            // We haven't even started yet, so we're flushed alright...
6864            mCodec->mCallback->onFlushCompleted();
6865            return true;
6866        }
6867
6868        case kWhatSignalEndOfInputStream:
6869        {
6870            mCodec->onSignalEndOfInputStream();
6871            return true;
6872        }
6873
6874        default:
6875            return BaseState::onMessageReceived(msg);
6876    }
6877}
6878
6879bool ACodec::IdleToExecutingState::onOMXEvent(
6880        OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2) {
6881    switch (event) {
6882        case OMX_EventCmdComplete:
6883        {
6884            if (data1 != (OMX_U32)OMX_CommandStateSet
6885                    || data2 != (OMX_U32)OMX_StateExecuting) {
6886                ALOGE("Unexpected command completion in IdleToExecutingState: %s(%u) %s(%u)",
6887                        asString((OMX_COMMANDTYPE)data1), data1,
6888                        asString((OMX_STATETYPE)data2), data2);
6889                mCodec->signalError(OMX_ErrorUndefined, FAILED_TRANSACTION);
6890                return true;
6891            }
6892
6893            mCodec->mExecutingState->resume();
6894            mCodec->changeState(mCodec->mExecutingState);
6895
6896            return true;
6897        }
6898
6899        default:
6900            return BaseState::onOMXEvent(event, data1, data2);
6901    }
6902}
6903
6904////////////////////////////////////////////////////////////////////////////////
6905
6906ACodec::ExecutingState::ExecutingState(ACodec *codec)
6907    : BaseState(codec),
6908      mActive(false) {
6909}
6910
6911ACodec::BaseState::PortMode ACodec::ExecutingState::getPortMode(
6912        OMX_U32 /* portIndex */) {
6913    return RESUBMIT_BUFFERS;
6914}
6915
6916void ACodec::ExecutingState::submitOutputMetaBuffers() {
6917    // submit as many buffers as there are input buffers with the codec
6918    // in case we are in port reconfiguring
6919    for (size_t i = 0; i < mCodec->mBuffers[kPortIndexInput].size(); ++i) {
6920        BufferInfo *info = &mCodec->mBuffers[kPortIndexInput].editItemAt(i);
6921
6922        if (info->mStatus == BufferInfo::OWNED_BY_COMPONENT) {
6923            if (mCodec->submitOutputMetadataBuffer() != OK)
6924                break;
6925        }
6926    }
6927
6928    // *** NOTE: THE FOLLOWING WORKAROUND WILL BE REMOVED ***
6929    mCodec->signalSubmitOutputMetadataBufferIfEOS_workaround();
6930}
6931
6932void ACodec::ExecutingState::submitRegularOutputBuffers() {
6933    bool failed = false;
6934    for (size_t i = 0; i < mCodec->mBuffers[kPortIndexOutput].size(); ++i) {
6935        BufferInfo *info = &mCodec->mBuffers[kPortIndexOutput].editItemAt(i);
6936
6937        if (mCodec->mNativeWindow != NULL) {
6938            if (info->mStatus != BufferInfo::OWNED_BY_US
6939                    && info->mStatus != BufferInfo::OWNED_BY_NATIVE_WINDOW) {
6940                ALOGE("buffers should be owned by us or the surface");
6941                failed = true;
6942                break;
6943            }
6944
6945            if (info->mStatus == BufferInfo::OWNED_BY_NATIVE_WINDOW) {
6946                continue;
6947            }
6948        } else {
6949            if (info->mStatus != BufferInfo::OWNED_BY_US) {
6950                ALOGE("buffers should be owned by us");
6951                failed = true;
6952                break;
6953            }
6954        }
6955
6956        ALOGV("[%s] calling fillBuffer %u", mCodec->mComponentName.c_str(), info->mBufferID);
6957
6958        info->checkWriteFence("submitRegularOutputBuffers");
6959        status_t err = mCodec->fillBuffer(info);
6960        if (err != OK) {
6961            failed = true;
6962            break;
6963        }
6964    }
6965
6966    if (failed) {
6967        mCodec->signalError(OMX_ErrorUndefined, FAILED_TRANSACTION);
6968    }
6969}
6970
6971void ACodec::ExecutingState::submitOutputBuffers() {
6972    submitRegularOutputBuffers();
6973    if (mCodec->storingMetadataInDecodedBuffers()) {
6974        submitOutputMetaBuffers();
6975    }
6976}
6977
6978void ACodec::ExecutingState::resume() {
6979    if (mActive) {
6980        ALOGV("[%s] We're already active, no need to resume.", mCodec->mComponentName.c_str());
6981        return;
6982    }
6983
6984    submitOutputBuffers();
6985
6986    // Post all available input buffers
6987    if (mCodec->mBuffers[kPortIndexInput].size() == 0u) {
6988        ALOGW("[%s] we don't have any input buffers to resume", mCodec->mComponentName.c_str());
6989    }
6990
6991    for (size_t i = 0; i < mCodec->mBuffers[kPortIndexInput].size(); i++) {
6992        BufferInfo *info = &mCodec->mBuffers[kPortIndexInput].editItemAt(i);
6993        if (info->mStatus == BufferInfo::OWNED_BY_US) {
6994            postFillThisBuffer(info);
6995        }
6996    }
6997
6998    mActive = true;
6999}
7000
7001void ACodec::ExecutingState::stateEntered() {
7002    ALOGV("[%s] Now Executing", mCodec->mComponentName.c_str());
7003    mCodec->mRenderTracker.clear(systemTime(CLOCK_MONOTONIC));
7004    mCodec->processDeferredMessages();
7005}
7006
7007bool ACodec::ExecutingState::onMessageReceived(const sp<AMessage> &msg) {
7008    bool handled = false;
7009
7010    switch (msg->what()) {
7011        case kWhatShutdown:
7012        {
7013            int32_t keepComponentAllocated;
7014            CHECK(msg->findInt32(
7015                        "keepComponentAllocated", &keepComponentAllocated));
7016
7017            mCodec->mShutdownInProgress = true;
7018            mCodec->mExplicitShutdown = true;
7019            mCodec->mKeepComponentAllocated = keepComponentAllocated;
7020
7021            mActive = false;
7022
7023            status_t err = mCodec->mOMXNode->sendCommand(
7024                    OMX_CommandStateSet, OMX_StateIdle);
7025            if (err != OK) {
7026                if (keepComponentAllocated) {
7027                    mCodec->signalError(OMX_ErrorUndefined, FAILED_TRANSACTION);
7028                }
7029                // TODO: do some recovery here.
7030            } else {
7031                mCodec->changeState(mCodec->mExecutingToIdleState);
7032            }
7033
7034            handled = true;
7035            break;
7036        }
7037
7038        case kWhatFlush:
7039        {
7040            ALOGV("[%s] ExecutingState flushing now "
7041                 "(codec owns %zu/%zu input, %zu/%zu output).",
7042                    mCodec->mComponentName.c_str(),
7043                    mCodec->countBuffersOwnedByComponent(kPortIndexInput),
7044                    mCodec->mBuffers[kPortIndexInput].size(),
7045                    mCodec->countBuffersOwnedByComponent(kPortIndexOutput),
7046                    mCodec->mBuffers[kPortIndexOutput].size());
7047
7048            mActive = false;
7049
7050            status_t err = mCodec->mOMXNode->sendCommand(OMX_CommandFlush, OMX_ALL);
7051            if (err != OK) {
7052                mCodec->signalError(OMX_ErrorUndefined, FAILED_TRANSACTION);
7053            } else {
7054                mCodec->changeState(mCodec->mFlushingState);
7055            }
7056
7057            handled = true;
7058            break;
7059        }
7060
7061        case kWhatResume:
7062        {
7063            resume();
7064
7065            handled = true;
7066            break;
7067        }
7068
7069        case kWhatRequestIDRFrame:
7070        {
7071            status_t err = mCodec->requestIDRFrame();
7072            if (err != OK) {
7073                ALOGW("Requesting an IDR frame failed.");
7074            }
7075
7076            handled = true;
7077            break;
7078        }
7079
7080        case kWhatSetParameters:
7081        {
7082            sp<AMessage> params;
7083            CHECK(msg->findMessage("params", &params));
7084
7085            status_t err = mCodec->setParameters(params);
7086
7087            sp<AMessage> reply;
7088            if (msg->findMessage("reply", &reply)) {
7089                reply->setInt32("err", err);
7090                reply->post();
7091            }
7092
7093            handled = true;
7094            break;
7095        }
7096
7097        case ACodec::kWhatSignalEndOfInputStream:
7098        {
7099            mCodec->onSignalEndOfInputStream();
7100            handled = true;
7101            break;
7102        }
7103
7104        // *** NOTE: THE FOLLOWING WORKAROUND WILL BE REMOVED ***
7105        case kWhatSubmitOutputMetadataBufferIfEOS:
7106        {
7107            if (mCodec->mPortEOS[kPortIndexInput] &&
7108                    !mCodec->mPortEOS[kPortIndexOutput]) {
7109                status_t err = mCodec->submitOutputMetadataBuffer();
7110                if (err == OK) {
7111                    mCodec->signalSubmitOutputMetadataBufferIfEOS_workaround();
7112                }
7113            }
7114            return true;
7115        }
7116
7117        default:
7118            handled = BaseState::onMessageReceived(msg);
7119            break;
7120    }
7121
7122    return handled;
7123}
7124
7125status_t ACodec::setParameters(const sp<AMessage> &params) {
7126    int32_t videoBitrate;
7127    if (params->findInt32("video-bitrate", &videoBitrate)) {
7128        OMX_VIDEO_CONFIG_BITRATETYPE configParams;
7129        InitOMXParams(&configParams);
7130        configParams.nPortIndex = kPortIndexOutput;
7131        configParams.nEncodeBitrate = videoBitrate;
7132
7133        status_t err = mOMXNode->setConfig(
7134                OMX_IndexConfigVideoBitrate,
7135                &configParams,
7136                sizeof(configParams));
7137
7138        if (err != OK) {
7139            ALOGE("setConfig(OMX_IndexConfigVideoBitrate, %d) failed w/ err %d",
7140                   videoBitrate, err);
7141
7142            return err;
7143        }
7144    }
7145
7146    int64_t timeOffsetUs;
7147    if (params->findInt64("time-offset-us", &timeOffsetUs)) {
7148        if (mGraphicBufferSource == NULL) {
7149            ALOGE("[%s] Invalid to set input buffer time offset without surface",
7150                    mComponentName.c_str());
7151            return INVALID_OPERATION;
7152        }
7153
7154        status_t err = statusFromBinderStatus(
7155                mGraphicBufferSource->setTimeOffsetUs(timeOffsetUs));
7156
7157        if (err != OK) {
7158            ALOGE("[%s] Unable to set input buffer time offset (err %d)",
7159                mComponentName.c_str(),
7160                err);
7161            return err;
7162        }
7163    }
7164
7165    int64_t skipFramesBeforeUs;
7166    if (params->findInt64("skip-frames-before", &skipFramesBeforeUs)) {
7167        if (mGraphicBufferSource == NULL) {
7168            ALOGE("[%s] Invalid to set start time without surface",
7169                    mComponentName.c_str());
7170            return INVALID_OPERATION;
7171        }
7172
7173        status_t err = statusFromBinderStatus(
7174                mGraphicBufferSource->setStartTimeUs(skipFramesBeforeUs));
7175
7176        if (err != OK) {
7177            ALOGE("Failed to set parameter 'skip-frames-before' (err %d)", err);
7178            return err;
7179        }
7180    }
7181
7182    int32_t dropInputFrames;
7183    if (params->findInt32("drop-input-frames", &dropInputFrames)) {
7184        if (mGraphicBufferSource == NULL) {
7185            ALOGE("[%s] Invalid to set suspend without surface",
7186                    mComponentName.c_str());
7187            return INVALID_OPERATION;
7188        }
7189
7190        int64_t suspendStartTimeUs = -1;
7191        (void) params->findInt64("drop-start-time-us", &suspendStartTimeUs);
7192        status_t err = statusFromBinderStatus(
7193                mGraphicBufferSource->setSuspend(dropInputFrames != 0, suspendStartTimeUs));
7194
7195        if (err != OK) {
7196            ALOGE("Failed to set parameter 'drop-input-frames' (err %d)", err);
7197            return err;
7198        }
7199    }
7200
7201    int64_t stopTimeUs;
7202    if (params->findInt64("stop-time-us", &stopTimeUs)) {
7203        if (mGraphicBufferSource == NULL) {
7204            ALOGE("[%s] Invalid to set stop time without surface",
7205                    mComponentName.c_str());
7206            return INVALID_OPERATION;
7207        }
7208        status_t err = statusFromBinderStatus(
7209                mGraphicBufferSource->setStopTimeUs(stopTimeUs));
7210
7211        if (err != OK) {
7212            ALOGE("Failed to set parameter 'stop-time-us' (err %d)", err);
7213            return err;
7214        }
7215
7216        int64_t stopTimeOffsetUs;
7217        err = statusFromBinderStatus(
7218                mGraphicBufferSource->getStopTimeOffsetUs(&stopTimeOffsetUs));
7219
7220        if (err != OK) {
7221            ALOGE("Failed to get stop time offset (err %d)", err);
7222            return err;
7223        }
7224        mInputFormat->setInt64("android._stop-time-offset-us", stopTimeOffsetUs);
7225    }
7226
7227    int32_t dummy;
7228    if (params->findInt32("request-sync", &dummy)) {
7229        status_t err = requestIDRFrame();
7230
7231        if (err != OK) {
7232            ALOGE("Requesting a sync frame failed w/ err %d", err);
7233            return err;
7234        }
7235    }
7236
7237    int32_t rateInt = -1;
7238    float rateFloat = -1;
7239    if (!params->findFloat("operating-rate", &rateFloat)) {
7240        params->findInt32("operating-rate", &rateInt);
7241        rateFloat = (float) rateInt; // 16MHz (FLINTMAX) is OK for upper bound.
7242    }
7243    if (rateFloat > 0) {
7244        status_t err = setOperatingRate(rateFloat, mIsVideo);
7245        if (err != OK) {
7246            ALOGI("Failed to set parameter 'operating-rate' (err %d)", err);
7247        }
7248    }
7249
7250    int32_t intraRefreshPeriod = 0;
7251    if (params->findInt32("intra-refresh-period", &intraRefreshPeriod)
7252            && intraRefreshPeriod > 0) {
7253        status_t err = setIntraRefreshPeriod(intraRefreshPeriod, false);
7254        if (err != OK) {
7255            ALOGI("[%s] failed setIntraRefreshPeriod. Failure is fine since this key is optional",
7256                    mComponentName.c_str());
7257            err = OK;
7258        }
7259    }
7260
7261    int32_t latency = 0;
7262    if (params->findInt32("latency", &latency) && latency > 0) {
7263        status_t err = setLatency(latency);
7264        if (err != OK) {
7265            ALOGI("[%s] failed setLatency. Failure is fine since this key is optional",
7266                    mComponentName.c_str());
7267            err = OK;
7268        }
7269    }
7270
7271    // Ignore errors as failure is expected for codecs that aren't video encoders.
7272    (void)configureTemporalLayers(params, false /* inConfigure */, mOutputFormat);
7273
7274    return setVendorParameters(params);
7275}
7276
7277// Removes trailing tags matching |tag| from |key| (e.g. a settings name). |minLength| specifies
7278// the minimum number of characters to keep in |key| (even if it has trailing tags).
7279// (Used to remove trailing 'value' tags in settings names, e.g. to normalize
7280// 'vendor.settingsX.value' to 'vendor.settingsX')
7281static void removeTrailingTags(char *key, size_t minLength, const char *tag) {
7282    size_t length = strlen(key);
7283    size_t tagLength = strlen(tag);
7284    while (length > minLength + tagLength
7285            && !strcmp(key + length - tagLength, tag)
7286            && key[length - tagLength - 1] == '.') {
7287        length -= tagLength + 1;
7288        key[length] = '\0';
7289    }
7290}
7291
7292/**
7293 * Struct encompassing a vendor extension config structure and a potential error status (in case
7294 * the structure is null). Used to iterate through vendor extensions.
7295 */
7296struct VendorExtension {
7297    OMX_CONFIG_ANDROID_VENDOR_EXTENSIONTYPE *config;  // structure does not own config
7298    status_t status;
7299
7300    // create based on an error status
7301    VendorExtension(status_t s_ = NO_INIT) : config(nullptr), status(s_) { }
7302
7303    // create based on a successfully retrieved config structure
7304    VendorExtension(OMX_CONFIG_ANDROID_VENDOR_EXTENSIONTYPE *c_) : config(c_), status(OK) { }
7305};
7306
7307// class VendorExtensions;
7308/**
7309 * Forward iterator to enumerate vendor extensions supported by an OMX component.
7310 */
7311class VendorExtensionIterator {
7312//private:
7313    static constexpr size_t kLastIndex = ~(size_t)0; // last index marker
7314
7315    sp<IOMXNode> mNode;                   // component
7316    size_t mIndex;                        // current android extension index
7317    std::unique_ptr<uint8_t[]> mBacking;  // current extension's backing
7318    VendorExtension mCurrent;             // current extension
7319
7320    VendorExtensionIterator(const sp<IOMXNode> &node, size_t index)
7321        : mNode(node),
7322          mIndex(index) {
7323        mCurrent = retrieve();
7324    }
7325
7326    friend class VendorExtensions;
7327
7328public:
7329    // copy constructor
7330    VendorExtensionIterator(const VendorExtensionIterator &it)
7331        : VendorExtensionIterator(it.mNode, it.mIndex) { }
7332
7333    // retrieves the current extension pointed to by this iterator
7334    VendorExtension retrieve() {
7335        if (mIndex == kLastIndex) {
7336            return NO_INIT;
7337        }
7338
7339        // try with one param first, then retry if extension needs more than 1 param
7340        for (size_t paramSizeUsed = 1;; ) {
7341            if (paramSizeUsed > OMX_MAX_ANDROID_VENDOR_PARAMCOUNT) {
7342                return BAD_VALUE; // this prevents overflow in the following formula
7343            }
7344
7345            size_t size = sizeof(OMX_CONFIG_ANDROID_VENDOR_EXTENSIONTYPE) +
7346                (paramSizeUsed - 1) * sizeof(OMX_CONFIG_ANDROID_VENDOR_EXTENSIONTYPE::param);
7347            mBacking.reset(new uint8_t[size]);
7348            if (!mBacking) {
7349                return NO_MEMORY;
7350            }
7351
7352            OMX_CONFIG_ANDROID_VENDOR_EXTENSIONTYPE *config =
7353                reinterpret_cast<OMX_CONFIG_ANDROID_VENDOR_EXTENSIONTYPE *>(mBacking.get());
7354
7355            InitOMXParams(config);
7356            config->nSize = size;
7357            config->nIndex = mIndex;
7358            config->nParamSizeUsed = paramSizeUsed;
7359            status_t err = mNode->getConfig(
7360                    (OMX_INDEXTYPE)OMX_IndexConfigAndroidVendorExtension, config, size);
7361            if (err == OK && config->nParamCount > paramSizeUsed && paramSizeUsed == 1) {
7362                // reallocate if we need a bigger config
7363                paramSizeUsed = config->nParamCount;
7364                continue;
7365            } else if (err == NOT_ENOUGH_DATA
7366                   || (err != OK && mIndex == 0)) {
7367                // stop iterator on no-more signal, or if index is not at all supported
7368                mIndex = kLastIndex;
7369                return NO_INIT;
7370            } else if (err != OK) {
7371                return err;
7372            } else if (paramSizeUsed != config->nParamSizeUsed) {
7373                return BAD_VALUE; // component shall not modify size of nParam
7374            }
7375
7376            return config;
7377        }
7378    }
7379
7380    // returns extension pointed to by this iterator
7381    VendorExtension operator*() {
7382        return mCurrent;
7383    }
7384
7385    // prefix increment: move to next extension
7386    VendorExtensionIterator &operator++() { // prefix
7387        if (mIndex != kLastIndex) {
7388            ++mIndex;
7389            mCurrent = retrieve();
7390        }
7391        return *this;
7392    }
7393
7394    // iterator equality operators
7395    bool operator==(const VendorExtensionIterator &o) {
7396        return mNode == o.mNode && mIndex == o.mIndex;
7397    }
7398
7399    bool operator!=(const VendorExtensionIterator &o) {
7400        return !(*this == o);
7401    }
7402};
7403
7404/**
7405 * Iterable container for vendor extensions provided by a component
7406 */
7407class VendorExtensions {
7408//private:
7409    sp<IOMXNode> mNode;
7410
7411public:
7412    VendorExtensions(const sp<IOMXNode> &node)
7413        : mNode(node) {
7414    }
7415
7416    VendorExtensionIterator begin() {
7417        return VendorExtensionIterator(mNode, 0);
7418    }
7419
7420    VendorExtensionIterator end() {
7421        return VendorExtensionIterator(mNode, VendorExtensionIterator::kLastIndex);
7422    }
7423};
7424
7425status_t ACodec::setVendorParameters(const sp<AMessage> &params) {
7426    std::map<std::string, std::string> vendorKeys; // maps reduced name to actual name
7427    constexpr char prefix[] = "vendor.";
7428    constexpr size_t prefixLength = sizeof(prefix) - 1;
7429    // longest possible vendor param name
7430    char reducedKey[OMX_MAX_STRINGNAME_SIZE + OMX_MAX_STRINGVALUE_SIZE];
7431
7432    // identify all vendor keys to speed up search later and to detect vendor keys
7433    for (size_t i = params->countEntries(); i; --i) {
7434        AMessage::Type keyType;
7435        const char* key = params->getEntryNameAt(i - 1, &keyType);
7436        if (key != nullptr && !strncmp(key, prefix, prefixLength)
7437                // it is safe to limit format keys to the max vendor param size as we only
7438                // shorten parameter names by removing any trailing 'value' tags, and we
7439                // already remove the vendor prefix.
7440                && strlen(key + prefixLength) < sizeof(reducedKey)
7441                && (keyType == AMessage::kTypeInt32
7442                        || keyType == AMessage::kTypeInt64
7443                        || keyType == AMessage::kTypeString)) {
7444            strcpy(reducedKey, key + prefixLength);
7445            removeTrailingTags(reducedKey, 0, "value");
7446            auto existingKey = vendorKeys.find(reducedKey);
7447            if (existingKey != vendorKeys.end()) {
7448                ALOGW("[%s] vendor parameter '%s' aliases parameter '%s'",
7449                        mComponentName.c_str(), key, existingKey->second.c_str());
7450                // ignore for now
7451            }
7452            vendorKeys.emplace(reducedKey, key);
7453        }
7454    }
7455
7456    // don't bother component if we don't have vendor extensions as they may not have implemented
7457    // the android vendor extension support, which will lead to unnecessary OMX failure logs.
7458    if (vendorKeys.empty()) {
7459        return OK;
7460    }
7461
7462    char key[sizeof(OMX_CONFIG_ANDROID_VENDOR_EXTENSIONTYPE::cName) +
7463            sizeof(OMX_CONFIG_ANDROID_VENDOR_PARAMTYPE::cKey)];
7464
7465    status_t finalError = OK;
7466
7467    // don't try again if component does not have vendor extensions
7468    if (mVendorExtensionsStatus == kExtensionsNone) {
7469        return OK;
7470    }
7471
7472    for (VendorExtension ext : VendorExtensions(mOMXNode)) {
7473        OMX_CONFIG_ANDROID_VENDOR_EXTENSIONTYPE *config = ext.config;
7474        if (config == nullptr) {
7475            return ext.status;
7476        }
7477
7478        mVendorExtensionsStatus = kExtensionsExist;
7479
7480        config->cName[sizeof(config->cName) - 1] = '\0'; // null-terminate name
7481        strcpy(key, (const char *)config->cName);
7482        size_t nameLength = strlen(key);
7483        key[nameLength] = '.';
7484
7485        // don't set vendor extension if client has not provided any of its parameters
7486        // or if client simply unsets parameters that are already unset
7487        bool needToSet = false;
7488        for (size_t paramIndex = 0; paramIndex < config->nParamCount; ++paramIndex) {
7489            // null-terminate param key
7490            config->param[paramIndex].cKey[sizeof(config->param[0].cKey) - 1] = '\0';
7491            strcpy(key + nameLength + 1, (const char *)config->param[paramIndex].cKey);
7492            removeTrailingTags(key, nameLength, "value");
7493            auto existingKey = vendorKeys.find(key);
7494
7495            // don't touch (e.g. change) parameters that are not specified by client
7496            if (existingKey == vendorKeys.end()) {
7497                continue;
7498            }
7499
7500            bool wasSet = config->param[paramIndex].bSet;
7501            switch (config->param[paramIndex].eValueType) {
7502            case OMX_AndroidVendorValueInt32:
7503            {
7504                int32_t value;
7505                config->param[paramIndex].bSet =
7506                    (OMX_BOOL)params->findInt32(existingKey->second.c_str(), &value);
7507                if (config->param[paramIndex].bSet) {
7508                    config->param[paramIndex].nInt32 = value;
7509                }
7510                break;
7511            }
7512            case OMX_AndroidVendorValueInt64:
7513            {
7514                int64_t value;
7515                config->param[paramIndex].bSet =
7516                    (OMX_BOOL)params->findAsInt64(existingKey->second.c_str(), &value);
7517                if (config->param[paramIndex].bSet) {
7518                    config->param[paramIndex].nInt64 = value;
7519                }
7520                break;
7521            }
7522            case OMX_AndroidVendorValueString:
7523            {
7524                AString value;
7525                config->param[paramIndex].bSet =
7526                    (OMX_BOOL)params->findString(existingKey->second.c_str(), &value);
7527                if (config->param[paramIndex].bSet) {
7528                    strncpy((char *)config->param[paramIndex].cString, value.c_str(),
7529                            sizeof(OMX_CONFIG_ANDROID_VENDOR_PARAMTYPE::cString));
7530                }
7531                break;
7532            }
7533            default:
7534                ALOGW("[%s] vendor parameter '%s' is not a supported value",
7535                        mComponentName.c_str(), key);
7536                continue;
7537            }
7538            if (config->param[paramIndex].bSet || wasSet) {
7539                needToSet = true;
7540            }
7541        }
7542
7543        if (needToSet) {
7544            status_t err = mOMXNode->setConfig(
7545                    (OMX_INDEXTYPE)OMX_IndexConfigAndroidVendorExtension,
7546                    config, config->nSize);
7547            if (err != OK) {
7548                key[nameLength] = '\0';
7549                ALOGW("[%s] failed to set vendor extension '%s'", mComponentName.c_str(), key);
7550                // try to set each extension, and return first failure
7551                if (finalError == OK) {
7552                    finalError = err;
7553                }
7554            }
7555        }
7556    }
7557
7558    if (mVendorExtensionsStatus == kExtensionsUnchecked) {
7559        mVendorExtensionsStatus = kExtensionsNone;
7560    }
7561
7562    return finalError;
7563}
7564
7565status_t ACodec::getVendorParameters(OMX_U32 portIndex, sp<AMessage> &format) {
7566    constexpr char prefix[] = "vendor.";
7567    constexpr size_t prefixLength = sizeof(prefix) - 1;
7568    char key[sizeof(OMX_CONFIG_ANDROID_VENDOR_EXTENSIONTYPE::cName) +
7569            sizeof(OMX_CONFIG_ANDROID_VENDOR_PARAMTYPE::cKey) + prefixLength];
7570    strcpy(key, prefix);
7571
7572    // don't try again if component does not have vendor extensions
7573    if (mVendorExtensionsStatus == kExtensionsNone) {
7574        return OK;
7575    }
7576
7577    for (VendorExtension ext : VendorExtensions(mOMXNode)) {
7578        OMX_CONFIG_ANDROID_VENDOR_EXTENSIONTYPE *config = ext.config;
7579        if (config == nullptr) {
7580            return ext.status;
7581        }
7582
7583        mVendorExtensionsStatus = kExtensionsExist;
7584
7585        if (config->eDir != (portIndex == kPortIndexInput ? OMX_DirInput : OMX_DirOutput)) {
7586            continue;
7587        }
7588
7589        config->cName[sizeof(config->cName) - 1] = '\0'; // null-terminate name
7590        strcpy(key + prefixLength, (const char *)config->cName);
7591        size_t nameLength = strlen(key);
7592        key[nameLength] = '.';
7593
7594        for (size_t paramIndex = 0; paramIndex < config->nParamCount; ++paramIndex) {
7595            // null-terminate param key
7596            config->param[paramIndex].cKey[sizeof(config->param[0].cKey) - 1] = '\0';
7597            strcpy(key + nameLength + 1, (const char *)config->param[paramIndex].cKey);
7598            removeTrailingTags(key, nameLength, "value");
7599            if (config->param[paramIndex].bSet) {
7600                switch (config->param[paramIndex].eValueType) {
7601                case OMX_AndroidVendorValueInt32:
7602                {
7603                    format->setInt32(key, config->param[paramIndex].nInt32);
7604                    break;
7605                }
7606                case OMX_AndroidVendorValueInt64:
7607                {
7608                    format->setInt64(key, config->param[paramIndex].nInt64);
7609                    break;
7610                }
7611                case OMX_AndroidVendorValueString:
7612                {
7613                    config->param[paramIndex].cString[OMX_MAX_STRINGVALUE_SIZE - 1] = '\0';
7614                    format->setString(key, (const char *)config->param[paramIndex].cString);
7615                    break;
7616                }
7617                default:
7618                    ALOGW("vendor parameter %s is not a supported value", key);
7619                    continue;
7620                }
7621            }
7622        }
7623    }
7624
7625    if (mVendorExtensionsStatus == kExtensionsUnchecked) {
7626        mVendorExtensionsStatus = kExtensionsNone;
7627    }
7628
7629    return OK;
7630}
7631
7632void ACodec::onSignalEndOfInputStream() {
7633    status_t err = INVALID_OPERATION;
7634    if (mGraphicBufferSource != NULL) {
7635        err = statusFromBinderStatus(mGraphicBufferSource->signalEndOfInputStream());
7636    }
7637    mCallback->onSignaledInputEOS(err);
7638}
7639
7640void ACodec::forceStateTransition(int generation) {
7641    if (generation != mStateGeneration) {
7642        ALOGV("Ignoring stale force state transition message: #%d (now #%d)",
7643                generation, mStateGeneration);
7644        return;
7645    }
7646    ALOGE("State machine stuck");
7647    // Error must have already been signalled to the client.
7648
7649    // Deferred messages will be handled at LoadedState at the end of the
7650    // transition.
7651    mShutdownInProgress = true;
7652    // No shutdown complete callback at the end of the transition.
7653    mExplicitShutdown = false;
7654    mKeepComponentAllocated = true;
7655
7656    status_t err = mOMXNode->sendCommand(OMX_CommandStateSet, OMX_StateIdle);
7657    if (err != OK) {
7658        // TODO: do some recovery here.
7659    } else {
7660        changeState(mExecutingToIdleState);
7661    }
7662}
7663
7664bool ACodec::ExecutingState::onOMXFrameRendered(int64_t mediaTimeUs, nsecs_t systemNano) {
7665    mCodec->onFrameRendered(mediaTimeUs, systemNano);
7666    return true;
7667}
7668
7669bool ACodec::ExecutingState::onOMXEvent(
7670        OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2) {
7671    switch (event) {
7672        case OMX_EventPortSettingsChanged:
7673        {
7674            CHECK_EQ(data1, (OMX_U32)kPortIndexOutput);
7675
7676            mCodec->onOutputFormatChanged();
7677
7678            if (data2 == 0 || data2 == OMX_IndexParamPortDefinition) {
7679                mCodec->mMetadataBuffersToSubmit = 0;
7680                CHECK_EQ(mCodec->mOMXNode->sendCommand(
7681                            OMX_CommandPortDisable, kPortIndexOutput),
7682                         (status_t)OK);
7683
7684                mCodec->freeOutputBuffersNotOwnedByComponent();
7685
7686                mCodec->changeState(mCodec->mOutputPortSettingsChangedState);
7687            } else if (data2 != OMX_IndexConfigCommonOutputCrop
7688                    && data2 != OMX_IndexConfigAndroidIntraRefresh) {
7689                ALOGV("[%s] OMX_EventPortSettingsChanged 0x%08x",
7690                     mCodec->mComponentName.c_str(), data2);
7691            }
7692
7693            return true;
7694        }
7695
7696        case OMX_EventBufferFlag:
7697        {
7698            return true;
7699        }
7700
7701        default:
7702            return BaseState::onOMXEvent(event, data1, data2);
7703    }
7704}
7705
7706////////////////////////////////////////////////////////////////////////////////
7707
7708ACodec::OutputPortSettingsChangedState::OutputPortSettingsChangedState(
7709        ACodec *codec)
7710    : BaseState(codec) {
7711}
7712
7713ACodec::BaseState::PortMode ACodec::OutputPortSettingsChangedState::getPortMode(
7714        OMX_U32 portIndex) {
7715    if (portIndex == kPortIndexOutput) {
7716        return FREE_BUFFERS;
7717    }
7718
7719    CHECK_EQ(portIndex, (OMX_U32)kPortIndexInput);
7720
7721    return RESUBMIT_BUFFERS;
7722}
7723
7724bool ACodec::OutputPortSettingsChangedState::onMessageReceived(
7725        const sp<AMessage> &msg) {
7726    bool handled = false;
7727
7728    switch (msg->what()) {
7729        case kWhatFlush:
7730        case kWhatShutdown: {
7731            if (mCodec->mFatalError) {
7732                sp<AMessage> msg = new AMessage(ACodec::kWhatForceStateTransition, mCodec);
7733                msg->setInt32("generation", mCodec->mStateGeneration);
7734                msg->post(3000000);
7735            }
7736            // fall-through
7737        }
7738        case kWhatResume:
7739        case kWhatSetParameters:
7740        {
7741            if (msg->what() == kWhatResume) {
7742                ALOGV("[%s] Deferring resume", mCodec->mComponentName.c_str());
7743            }
7744
7745            mCodec->deferMessage(msg);
7746            handled = true;
7747            break;
7748        }
7749
7750        case kWhatForceStateTransition:
7751        {
7752            int32_t generation = 0;
7753            CHECK(msg->findInt32("generation", &generation));
7754            mCodec->forceStateTransition(generation);
7755
7756            handled = true;
7757            break;
7758        }
7759
7760        default:
7761            handled = BaseState::onMessageReceived(msg);
7762            break;
7763    }
7764
7765    return handled;
7766}
7767
7768void ACodec::OutputPortSettingsChangedState::stateEntered() {
7769    ALOGV("[%s] Now handling output port settings change",
7770         mCodec->mComponentName.c_str());
7771}
7772
7773bool ACodec::OutputPortSettingsChangedState::onOMXFrameRendered(
7774        int64_t mediaTimeUs, nsecs_t systemNano) {
7775    mCodec->onFrameRendered(mediaTimeUs, systemNano);
7776    return true;
7777}
7778
7779bool ACodec::OutputPortSettingsChangedState::onOMXEvent(
7780        OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2) {
7781    switch (event) {
7782        case OMX_EventCmdComplete:
7783        {
7784            if (data1 == (OMX_U32)OMX_CommandPortDisable) {
7785                if (data2 != (OMX_U32)kPortIndexOutput) {
7786                    ALOGW("ignoring EventCmdComplete CommandPortDisable for port %u", data2);
7787                    return false;
7788                }
7789
7790                ALOGV("[%s] Output port now disabled.", mCodec->mComponentName.c_str());
7791
7792                status_t err = OK;
7793                if (!mCodec->mBuffers[kPortIndexOutput].isEmpty()) {
7794                    ALOGE("disabled port should be empty, but has %zu buffers",
7795                            mCodec->mBuffers[kPortIndexOutput].size());
7796                    err = FAILED_TRANSACTION;
7797                } else {
7798                    mCodec->mAllocator[kPortIndexOutput].clear();
7799                }
7800
7801                if (err == OK) {
7802                    err = mCodec->mOMXNode->sendCommand(
7803                            OMX_CommandPortEnable, kPortIndexOutput);
7804                }
7805
7806                if (err == OK) {
7807                    err = mCodec->allocateBuffersOnPort(kPortIndexOutput);
7808                    ALOGE_IF(err != OK, "Failed to allocate output port buffers after port "
7809                            "reconfiguration: (%d)", err);
7810                    mCodec->mCallback->onOutputBuffersChanged();
7811                }
7812
7813                if (err != OK) {
7814                    mCodec->signalError(OMX_ErrorUndefined, makeNoSideEffectStatus(err));
7815                    ALOGE("Error occurred while disabling the output port");
7816                }
7817
7818                return true;
7819            } else if (data1 == (OMX_U32)OMX_CommandPortEnable) {
7820                if (data2 != (OMX_U32)kPortIndexOutput) {
7821                    ALOGW("ignoring EventCmdComplete OMX_CommandPortEnable for port %u", data2);
7822                    return false;
7823                }
7824
7825                ALOGV("[%s] Output port now reenabled.", mCodec->mComponentName.c_str());
7826
7827                if (mCodec->mExecutingState->active()) {
7828                    mCodec->mExecutingState->submitOutputBuffers();
7829                }
7830
7831                mCodec->changeState(mCodec->mExecutingState);
7832
7833                return true;
7834            }
7835
7836            return false;
7837        }
7838
7839        default:
7840            return BaseState::onOMXEvent(event, data1, data2);
7841    }
7842}
7843
7844////////////////////////////////////////////////////////////////////////////////
7845
7846ACodec::ExecutingToIdleState::ExecutingToIdleState(ACodec *codec)
7847    : BaseState(codec),
7848      mComponentNowIdle(false) {
7849}
7850
7851bool ACodec::ExecutingToIdleState::onMessageReceived(const sp<AMessage> &msg) {
7852    bool handled = false;
7853
7854    switch (msg->what()) {
7855        case kWhatFlush:
7856        {
7857            // Don't send me a flush request if you previously wanted me
7858            // to shutdown.
7859            ALOGW("Ignoring flush request in ExecutingToIdleState");
7860            break;
7861        }
7862
7863        case kWhatShutdown:
7864        {
7865            mCodec->deferMessage(msg);
7866            handled = true;
7867            break;
7868        }
7869
7870        default:
7871            handled = BaseState::onMessageReceived(msg);
7872            break;
7873    }
7874
7875    return handled;
7876}
7877
7878void ACodec::ExecutingToIdleState::stateEntered() {
7879    ALOGV("[%s] Now Executing->Idle", mCodec->mComponentName.c_str());
7880
7881    mComponentNowIdle = false;
7882    mCodec->mLastOutputFormat.clear();
7883}
7884
7885bool ACodec::ExecutingToIdleState::onOMXEvent(
7886        OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2) {
7887    switch (event) {
7888        case OMX_EventCmdComplete:
7889        {
7890            if (data1 != (OMX_U32)OMX_CommandStateSet
7891                    || data2 != (OMX_U32)OMX_StateIdle) {
7892                ALOGE("Unexpected command completion in ExecutingToIdleState: %s(%u) %s(%u)",
7893                        asString((OMX_COMMANDTYPE)data1), data1,
7894                        asString((OMX_STATETYPE)data2), data2);
7895                mCodec->signalError(OMX_ErrorUndefined, FAILED_TRANSACTION);
7896                return true;
7897            }
7898
7899            mComponentNowIdle = true;
7900
7901            changeStateIfWeOwnAllBuffers();
7902
7903            return true;
7904        }
7905
7906        case OMX_EventPortSettingsChanged:
7907        case OMX_EventBufferFlag:
7908        {
7909            // We're shutting down and don't care about this anymore.
7910            return true;
7911        }
7912
7913        default:
7914            return BaseState::onOMXEvent(event, data1, data2);
7915    }
7916}
7917
7918void ACodec::ExecutingToIdleState::changeStateIfWeOwnAllBuffers() {
7919    if (mComponentNowIdle && mCodec->allYourBuffersAreBelongToUs()) {
7920        status_t err = mCodec->mOMXNode->sendCommand(
7921                OMX_CommandStateSet, OMX_StateLoaded);
7922        if (err == OK) {
7923            err = mCodec->freeBuffersOnPort(kPortIndexInput);
7924            status_t err2 = mCodec->freeBuffersOnPort(kPortIndexOutput);
7925            if (err == OK) {
7926                err = err2;
7927            }
7928        }
7929
7930        if ((mCodec->mFlags & kFlagPushBlankBuffersToNativeWindowOnShutdown)
7931                && mCodec->mNativeWindow != NULL) {
7932            // We push enough 1x1 blank buffers to ensure that one of
7933            // them has made it to the display.  This allows the OMX
7934            // component teardown to zero out any protected buffers
7935            // without the risk of scanning out one of those buffers.
7936            pushBlankBuffersToNativeWindow(mCodec->mNativeWindow.get());
7937        }
7938
7939        if (err != OK) {
7940            mCodec->signalError(OMX_ErrorUndefined, FAILED_TRANSACTION);
7941            return;
7942        }
7943
7944        mCodec->changeState(mCodec->mIdleToLoadedState);
7945    }
7946}
7947
7948void ACodec::ExecutingToIdleState::onInputBufferFilled(
7949        const sp<AMessage> &msg) {
7950    BaseState::onInputBufferFilled(msg);
7951
7952    changeStateIfWeOwnAllBuffers();
7953}
7954
7955void ACodec::ExecutingToIdleState::onOutputBufferDrained(
7956        const sp<AMessage> &msg) {
7957    BaseState::onOutputBufferDrained(msg);
7958
7959    changeStateIfWeOwnAllBuffers();
7960}
7961
7962////////////////////////////////////////////////////////////////////////////////
7963
7964ACodec::IdleToLoadedState::IdleToLoadedState(ACodec *codec)
7965    : BaseState(codec) {
7966}
7967
7968bool ACodec::IdleToLoadedState::onMessageReceived(const sp<AMessage> &msg) {
7969    bool handled = false;
7970
7971    switch (msg->what()) {
7972        case kWhatShutdown:
7973        {
7974            mCodec->deferMessage(msg);
7975            handled = true;
7976            break;
7977        }
7978
7979        case kWhatFlush:
7980        {
7981            // Don't send me a flush request if you previously wanted me
7982            // to shutdown.
7983            ALOGE("Got flush request in IdleToLoadedState");
7984            break;
7985        }
7986
7987        default:
7988            handled = BaseState::onMessageReceived(msg);
7989            break;
7990    }
7991
7992    return handled;
7993}
7994
7995void ACodec::IdleToLoadedState::stateEntered() {
7996    ALOGV("[%s] Now Idle->Loaded", mCodec->mComponentName.c_str());
7997}
7998
7999bool ACodec::IdleToLoadedState::onOMXEvent(
8000        OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2) {
8001    switch (event) {
8002        case OMX_EventCmdComplete:
8003        {
8004            if (data1 != (OMX_U32)OMX_CommandStateSet
8005                    || data2 != (OMX_U32)OMX_StateLoaded) {
8006                ALOGE("Unexpected command completion in IdleToLoadedState: %s(%u) %s(%u)",
8007                        asString((OMX_COMMANDTYPE)data1), data1,
8008                        asString((OMX_STATETYPE)data2), data2);
8009                mCodec->signalError(OMX_ErrorUndefined, FAILED_TRANSACTION);
8010                return true;
8011            }
8012
8013            mCodec->changeState(mCodec->mLoadedState);
8014
8015            return true;
8016        }
8017
8018        default:
8019            return BaseState::onOMXEvent(event, data1, data2);
8020    }
8021}
8022
8023////////////////////////////////////////////////////////////////////////////////
8024
8025ACodec::FlushingState::FlushingState(ACodec *codec)
8026    : BaseState(codec) {
8027}
8028
8029void ACodec::FlushingState::stateEntered() {
8030    ALOGV("[%s] Now Flushing", mCodec->mComponentName.c_str());
8031
8032    mFlushComplete[kPortIndexInput] = mFlushComplete[kPortIndexOutput] = false;
8033}
8034
8035bool ACodec::FlushingState::onMessageReceived(const sp<AMessage> &msg) {
8036    bool handled = false;
8037
8038    switch (msg->what()) {
8039        case kWhatShutdown:
8040        {
8041            mCodec->deferMessage(msg);
8042            if (mCodec->mFatalError) {
8043                sp<AMessage> msg = new AMessage(ACodec::kWhatForceStateTransition, mCodec);
8044                msg->setInt32("generation", mCodec->mStateGeneration);
8045                msg->post(3000000);
8046            }
8047            break;
8048        }
8049
8050        case kWhatFlush:
8051        {
8052            // We're already doing this right now.
8053            handled = true;
8054            break;
8055        }
8056
8057        case kWhatForceStateTransition:
8058        {
8059            int32_t generation = 0;
8060            CHECK(msg->findInt32("generation", &generation));
8061            mCodec->forceStateTransition(generation);
8062
8063            handled = true;
8064            break;
8065        }
8066
8067        default:
8068            handled = BaseState::onMessageReceived(msg);
8069            break;
8070    }
8071
8072    return handled;
8073}
8074
8075bool ACodec::FlushingState::onOMXEvent(
8076        OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2) {
8077    ALOGV("[%s] FlushingState onOMXEvent(%u,%d)",
8078            mCodec->mComponentName.c_str(), event, (OMX_S32)data1);
8079
8080    switch (event) {
8081        case OMX_EventCmdComplete:
8082        {
8083            if (data1 != (OMX_U32)OMX_CommandFlush) {
8084                ALOGE("unexpected EventCmdComplete %s(%d) data2:%d in FlushingState",
8085                        asString((OMX_COMMANDTYPE)data1), data1, data2);
8086                mCodec->signalError(OMX_ErrorUndefined, FAILED_TRANSACTION);
8087                return true;
8088            }
8089
8090            if (data2 == kPortIndexInput || data2 == kPortIndexOutput) {
8091                if (mFlushComplete[data2]) {
8092                    ALOGW("Flush already completed for %s port",
8093                            data2 == kPortIndexInput ? "input" : "output");
8094                    return true;
8095                }
8096                mFlushComplete[data2] = true;
8097
8098                if (mFlushComplete[kPortIndexInput] && mFlushComplete[kPortIndexOutput]) {
8099                    changeStateIfWeOwnAllBuffers();
8100                }
8101            } else if (data2 == OMX_ALL) {
8102                if (!mFlushComplete[kPortIndexInput] || !mFlushComplete[kPortIndexOutput]) {
8103                    ALOGW("received flush complete event for OMX_ALL before ports have been"
8104                            "flushed (%d/%d)",
8105                            mFlushComplete[kPortIndexInput], mFlushComplete[kPortIndexOutput]);
8106                    return false;
8107                }
8108
8109                changeStateIfWeOwnAllBuffers();
8110            } else {
8111                ALOGW("data2 not OMX_ALL but %u in EventCmdComplete CommandFlush", data2);
8112            }
8113
8114            return true;
8115        }
8116
8117        case OMX_EventPortSettingsChanged:
8118        {
8119            sp<AMessage> msg = new AMessage(kWhatOMXMessage, mCodec);
8120            msg->setInt32("type", omx_message::EVENT);
8121            msg->setInt32("generation", mCodec->mNodeGeneration);
8122            msg->setInt32("event", event);
8123            msg->setInt32("data1", data1);
8124            msg->setInt32("data2", data2);
8125
8126            ALOGV("[%s] Deferring OMX_EventPortSettingsChanged",
8127                 mCodec->mComponentName.c_str());
8128
8129            mCodec->deferMessage(msg);
8130
8131            return true;
8132        }
8133
8134        default:
8135            return BaseState::onOMXEvent(event, data1, data2);
8136    }
8137
8138    return true;
8139}
8140
8141void ACodec::FlushingState::onOutputBufferDrained(const sp<AMessage> &msg) {
8142    BaseState::onOutputBufferDrained(msg);
8143
8144    changeStateIfWeOwnAllBuffers();
8145}
8146
8147void ACodec::FlushingState::onInputBufferFilled(const sp<AMessage> &msg) {
8148    BaseState::onInputBufferFilled(msg);
8149
8150    changeStateIfWeOwnAllBuffers();
8151}
8152
8153void ACodec::FlushingState::changeStateIfWeOwnAllBuffers() {
8154    if (mFlushComplete[kPortIndexInput]
8155            && mFlushComplete[kPortIndexOutput]
8156            && mCodec->allYourBuffersAreBelongToUs()) {
8157        // We now own all buffers except possibly those still queued with
8158        // the native window for rendering. Let's get those back as well.
8159        mCodec->waitUntilAllPossibleNativeWindowBuffersAreReturnedToUs();
8160
8161        mCodec->mRenderTracker.clear(systemTime(CLOCK_MONOTONIC));
8162
8163        mCodec->mCallback->onFlushCompleted();
8164
8165        mCodec->mPortEOS[kPortIndexInput] =
8166            mCodec->mPortEOS[kPortIndexOutput] = false;
8167
8168        mCodec->mInputEOSResult = OK;
8169
8170        if (mCodec->mSkipCutBuffer != NULL) {
8171            mCodec->mSkipCutBuffer->clear();
8172        }
8173
8174        mCodec->changeState(mCodec->mExecutingState);
8175    }
8176}
8177
8178status_t ACodec::queryCapabilities(
8179        const char* owner, const char* name, const char* mime, bool isEncoder,
8180        MediaCodecInfo::CapabilitiesWriter* caps) {
8181    const char *role = GetComponentRole(isEncoder, mime);
8182    if (role == NULL) {
8183        return BAD_VALUE;
8184    }
8185
8186    OMXClient client;
8187    status_t err = client.connect(owner);
8188    if (err != OK) {
8189        return err;
8190    }
8191
8192    sp<IOMX> omx = client.interface();
8193    sp<CodecObserver> observer = new CodecObserver;
8194    sp<IOMXNode> omxNode;
8195
8196    err = omx->allocateNode(name, observer, &omxNode);
8197    if (err != OK) {
8198        client.disconnect();
8199        return err;
8200    }
8201
8202    err = SetComponentRole(omxNode, role);
8203    if (err != OK) {
8204        omxNode->freeNode();
8205        client.disconnect();
8206        return err;
8207    }
8208
8209    bool isVideo = strncasecmp(mime, "video/", 6) == 0;
8210
8211    if (isVideo) {
8212        OMX_VIDEO_PARAM_PROFILELEVELTYPE param;
8213        InitOMXParams(&param);
8214        param.nPortIndex = isEncoder ? kPortIndexOutput : kPortIndexInput;
8215
8216        for (OMX_U32 index = 0; index <= kMaxIndicesToCheck; ++index) {
8217            param.nProfileIndex = index;
8218            status_t err = omxNode->getParameter(
8219                    OMX_IndexParamVideoProfileLevelQuerySupported,
8220                    &param, sizeof(param));
8221            if (err != OK) {
8222                break;
8223            }
8224            caps->addProfileLevel(param.eProfile, param.eLevel);
8225
8226            // AVC components may not list the constrained profiles explicitly, but
8227            // decoders that support a profile also support its constrained version.
8228            // Encoders must explicitly support constrained profiles.
8229            if (!isEncoder && strcasecmp(mime, MEDIA_MIMETYPE_VIDEO_AVC) == 0) {
8230                if (param.eProfile == OMX_VIDEO_AVCProfileHigh) {
8231                    caps->addProfileLevel(OMX_VIDEO_AVCProfileConstrainedHigh, param.eLevel);
8232                } else if (param.eProfile == OMX_VIDEO_AVCProfileBaseline) {
8233                    caps->addProfileLevel(OMX_VIDEO_AVCProfileConstrainedBaseline, param.eLevel);
8234                }
8235            }
8236
8237            if (index == kMaxIndicesToCheck) {
8238                ALOGW("[%s] stopping checking profiles after %u: %x/%x",
8239                        name, index,
8240                        param.eProfile, param.eLevel);
8241            }
8242        }
8243
8244        // Color format query
8245        // return colors in the order reported by the OMX component
8246        // prefix "flexible" standard ones with the flexible equivalent
8247        OMX_VIDEO_PARAM_PORTFORMATTYPE portFormat;
8248        InitOMXParams(&portFormat);
8249        portFormat.nPortIndex = isEncoder ? kPortIndexInput : kPortIndexOutput;
8250        for (OMX_U32 index = 0; index <= kMaxIndicesToCheck; ++index) {
8251            portFormat.nIndex = index;
8252            status_t err = omxNode->getParameter(
8253                    OMX_IndexParamVideoPortFormat,
8254                    &portFormat, sizeof(portFormat));
8255            if (err != OK) {
8256                break;
8257            }
8258
8259            OMX_U32 flexibleEquivalent;
8260            if (IsFlexibleColorFormat(
8261                    omxNode, portFormat.eColorFormat, false /* usingNativeWindow */,
8262                    &flexibleEquivalent)) {
8263                caps->addColorFormat(flexibleEquivalent);
8264            }
8265            caps->addColorFormat(portFormat.eColorFormat);
8266
8267            if (index == kMaxIndicesToCheck) {
8268                ALOGW("[%s] stopping checking formats after %u: %s(%x)",
8269                        name, index,
8270                        asString(portFormat.eColorFormat), portFormat.eColorFormat);
8271            }
8272        }
8273    } else if (strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_AAC) == 0) {
8274        // More audio codecs if they have profiles.
8275        OMX_AUDIO_PARAM_ANDROID_PROFILETYPE param;
8276        InitOMXParams(&param);
8277        param.nPortIndex = isEncoder ? kPortIndexOutput : kPortIndexInput;
8278        for (OMX_U32 index = 0; index <= kMaxIndicesToCheck; ++index) {
8279            param.nProfileIndex = index;
8280            status_t err = omxNode->getParameter(
8281                    (OMX_INDEXTYPE)OMX_IndexParamAudioProfileQuerySupported,
8282                    &param, sizeof(param));
8283            if (err != OK) {
8284                break;
8285            }
8286            // For audio, level is ignored.
8287            caps->addProfileLevel(param.eProfile, 0 /* level */);
8288
8289            if (index == kMaxIndicesToCheck) {
8290                ALOGW("[%s] stopping checking profiles after %u: %x",
8291                        name, index,
8292                        param.eProfile);
8293            }
8294        }
8295
8296        // NOTE: Without Android extensions, OMX does not provide a way to query
8297        // AAC profile support
8298        if (param.nProfileIndex == 0) {
8299            ALOGW("component %s doesn't support profile query.", name);
8300        }
8301    }
8302
8303    if (isVideo && !isEncoder) {
8304        native_handle_t *sidebandHandle = NULL;
8305        if (omxNode->configureVideoTunnelMode(
8306                kPortIndexOutput, OMX_TRUE, 0, &sidebandHandle) == OK) {
8307            // tunneled playback includes adaptive playback
8308            caps->addFlags(MediaCodecInfo::Capabilities::kFlagSupportsAdaptivePlayback
8309                    | MediaCodecInfo::Capabilities::kFlagSupportsTunneledPlayback);
8310        } else if (omxNode->setPortMode(
8311                kPortIndexOutput, IOMX::kPortModeDynamicANWBuffer) == OK ||
8312                omxNode->prepareForAdaptivePlayback(
8313                kPortIndexOutput, OMX_TRUE,
8314                1280 /* width */, 720 /* height */) == OK) {
8315            caps->addFlags(MediaCodecInfo::Capabilities::kFlagSupportsAdaptivePlayback);
8316        }
8317    }
8318
8319    if (isVideo && isEncoder) {
8320        OMX_VIDEO_CONFIG_ANDROID_INTRAREFRESHTYPE params;
8321        InitOMXParams(&params);
8322        params.nPortIndex = kPortIndexOutput;
8323        // TODO: should we verify if fallback is supported?
8324        if (omxNode->getConfig(
8325                (OMX_INDEXTYPE)OMX_IndexConfigAndroidIntraRefresh,
8326                &params, sizeof(params)) == OK) {
8327            caps->addFlags(MediaCodecInfo::Capabilities::kFlagSupportsIntraRefresh);
8328        }
8329    }
8330
8331    omxNode->freeNode();
8332    client.disconnect();
8333    return OK;
8334}
8335
8336// These are supposed be equivalent to the logic in
8337// "audio_channel_out_mask_from_count".
8338//static
8339status_t ACodec::getOMXChannelMapping(size_t numChannels, OMX_AUDIO_CHANNELTYPE map[]) {
8340    switch (numChannels) {
8341        case 1:
8342            map[0] = OMX_AUDIO_ChannelCF;
8343            break;
8344        case 2:
8345            map[0] = OMX_AUDIO_ChannelLF;
8346            map[1] = OMX_AUDIO_ChannelRF;
8347            break;
8348        case 3:
8349            map[0] = OMX_AUDIO_ChannelLF;
8350            map[1] = OMX_AUDIO_ChannelRF;
8351            map[2] = OMX_AUDIO_ChannelCF;
8352            break;
8353        case 4:
8354            map[0] = OMX_AUDIO_ChannelLF;
8355            map[1] = OMX_AUDIO_ChannelRF;
8356            map[2] = OMX_AUDIO_ChannelLR;
8357            map[3] = OMX_AUDIO_ChannelRR;
8358            break;
8359        case 5:
8360            map[0] = OMX_AUDIO_ChannelLF;
8361            map[1] = OMX_AUDIO_ChannelRF;
8362            map[2] = OMX_AUDIO_ChannelCF;
8363            map[3] = OMX_AUDIO_ChannelLR;
8364            map[4] = OMX_AUDIO_ChannelRR;
8365            break;
8366        case 6:
8367            map[0] = OMX_AUDIO_ChannelLF;
8368            map[1] = OMX_AUDIO_ChannelRF;
8369            map[2] = OMX_AUDIO_ChannelCF;
8370            map[3] = OMX_AUDIO_ChannelLFE;
8371            map[4] = OMX_AUDIO_ChannelLR;
8372            map[5] = OMX_AUDIO_ChannelRR;
8373            break;
8374        case 7:
8375            map[0] = OMX_AUDIO_ChannelLF;
8376            map[1] = OMX_AUDIO_ChannelRF;
8377            map[2] = OMX_AUDIO_ChannelCF;
8378            map[3] = OMX_AUDIO_ChannelLFE;
8379            map[4] = OMX_AUDIO_ChannelLR;
8380            map[5] = OMX_AUDIO_ChannelRR;
8381            map[6] = OMX_AUDIO_ChannelCS;
8382            break;
8383        case 8:
8384            map[0] = OMX_AUDIO_ChannelLF;
8385            map[1] = OMX_AUDIO_ChannelRF;
8386            map[2] = OMX_AUDIO_ChannelCF;
8387            map[3] = OMX_AUDIO_ChannelLFE;
8388            map[4] = OMX_AUDIO_ChannelLR;
8389            map[5] = OMX_AUDIO_ChannelRR;
8390            map[6] = OMX_AUDIO_ChannelLS;
8391            map[7] = OMX_AUDIO_ChannelRS;
8392            break;
8393        default:
8394            return -EINVAL;
8395    }
8396
8397    return OK;
8398}
8399
8400}  // namespace android
8401