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