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