ACodec.cpp revision d91dc5a0602f54fc0d4d2187f37b5b8169bb62c3
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/avc_utils.h>
34#include <media/stagefright/foundation/hexdump.h>
35#include <media/stagefright/foundation/ABuffer.h>
36#include <media/stagefright/foundation/ADebug.h>
37#include <media/stagefright/foundation/AMessage.h>
38#include <media/stagefright/foundation/AUtils.h>
39
40#include <media/stagefright/BufferProducerWrapper.h>
41#include <media/stagefright/MediaCodec.h>
42#include <media/stagefright/MediaCodecList.h>
43#include <media/stagefright/MediaDefs.h>
44#include <media/stagefright/OMXClient.h>
45#include <media/stagefright/PersistentSurface.h>
46#include <media/stagefright/SurfaceUtils.h>
47#include <media/hardware/HardwareAPI.h>
48#include <media/OMXBuffer.h>
49#include <media/omx/1.0/WOmxNode.h>
50
51#include <hidlmemory/mapping.h>
52
53#include <media/openmax/OMX_AudioExt.h>
54#include <media/openmax/OMX_VideoExt.h>
55#include <media/openmax/OMX_Component.h>
56#include <media/openmax/OMX_IndexExt.h>
57#include <media/openmax/OMX_AsString.h>
58
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            // avoiding 32-bit overflows in intermediate values
5302            mEncoderDelay = (int32_t)((((int64_t)mEncoderDelay) * sampleRate) / mSampleRate);
5303            mEncoderPadding = (int32_t)((((int64_t)mEncoderPadding) * sampleRate) / mSampleRate);
5304            mSampleRate = sampleRate;
5305        }
5306        if (mSkipCutBuffer != NULL) {
5307            size_t prevbufsize = mSkipCutBuffer->size();
5308            if (prevbufsize != 0) {
5309                ALOGW("Replacing SkipCutBuffer holding %zu bytes", prevbufsize);
5310            }
5311        }
5312        mSkipCutBuffer = new SkipCutBuffer(mEncoderDelay, mEncoderPadding, channelCount);
5313    }
5314
5315    // mLastOutputFormat is not used when tunneled; doing this just to stay consistent
5316    mLastOutputFormat = mOutputFormat;
5317}
5318
5319void ACodec::signalError(OMX_ERRORTYPE error, status_t internalError) {
5320    ALOGE("signalError(omxError %#x, internalError %d)", error, internalError);
5321
5322    if (internalError == UNKNOWN_ERROR) { // find better error code
5323        const status_t omxStatus = statusFromOMXError(error);
5324        if (omxStatus != 0) {
5325            internalError = omxStatus;
5326        } else {
5327            ALOGW("Invalid OMX error %#x", error);
5328        }
5329    }
5330
5331    mFatalError = true;
5332    mCallback->onError(internalError, ACTION_CODE_FATAL);
5333}
5334
5335status_t ACodec::requestIDRFrame() {
5336    if (!mIsEncoder) {
5337        return ERROR_UNSUPPORTED;
5338    }
5339
5340    OMX_CONFIG_INTRAREFRESHVOPTYPE params;
5341    InitOMXParams(&params);
5342
5343    params.nPortIndex = kPortIndexOutput;
5344    params.IntraRefreshVOP = OMX_TRUE;
5345
5346    return mOMXNode->setConfig(
5347            OMX_IndexConfigVideoIntraVOPRefresh,
5348            &params,
5349            sizeof(params));
5350}
5351
5352////////////////////////////////////////////////////////////////////////////////
5353
5354ACodec::BaseState::BaseState(ACodec *codec, const sp<AState> &parentState)
5355    : AState(parentState),
5356      mCodec(codec) {
5357}
5358
5359ACodec::BaseState::PortMode ACodec::BaseState::getPortMode(
5360        OMX_U32 /* portIndex */) {
5361    return KEEP_BUFFERS;
5362}
5363
5364void ACodec::BaseState::stateExited() {
5365    ++mCodec->mStateGeneration;
5366}
5367
5368bool ACodec::BaseState::onMessageReceived(const sp<AMessage> &msg) {
5369    switch (msg->what()) {
5370        case kWhatInputBufferFilled:
5371        {
5372            onInputBufferFilled(msg);
5373            break;
5374        }
5375
5376        case kWhatOutputBufferDrained:
5377        {
5378            onOutputBufferDrained(msg);
5379            break;
5380        }
5381
5382        case ACodec::kWhatOMXMessageList:
5383        {
5384            return checkOMXMessage(msg) ? onOMXMessageList(msg) : true;
5385        }
5386
5387        case ACodec::kWhatOMXMessageItem:
5388        {
5389            // no need to check as we already did it for kWhatOMXMessageList
5390            return onOMXMessage(msg);
5391        }
5392
5393        case ACodec::kWhatOMXMessage:
5394        {
5395            return checkOMXMessage(msg) ? onOMXMessage(msg) : true;
5396        }
5397
5398        case ACodec::kWhatSetSurface:
5399        {
5400            sp<AReplyToken> replyID;
5401            CHECK(msg->senderAwaitsResponse(&replyID));
5402
5403            sp<RefBase> obj;
5404            CHECK(msg->findObject("surface", &obj));
5405
5406            status_t err = mCodec->handleSetSurface(static_cast<Surface *>(obj.get()));
5407
5408            sp<AMessage> response = new AMessage;
5409            response->setInt32("err", err);
5410            response->postReply(replyID);
5411            break;
5412        }
5413
5414        case ACodec::kWhatCreateInputSurface:
5415        case ACodec::kWhatSetInputSurface:
5416        case ACodec::kWhatSignalEndOfInputStream:
5417        {
5418            // This may result in an app illegal state exception.
5419            ALOGE("Message 0x%x was not handled", msg->what());
5420            mCodec->signalError(OMX_ErrorUndefined, INVALID_OPERATION);
5421            return true;
5422        }
5423
5424        case ACodec::kWhatOMXDied:
5425        {
5426            // This will result in kFlagSawMediaServerDie handling in MediaCodec.
5427            ALOGE("OMX/mediaserver died, signalling error!");
5428            mCodec->mGraphicBufferSource.clear();
5429            mCodec->signalError(OMX_ErrorResourcesLost, DEAD_OBJECT);
5430            break;
5431        }
5432
5433        case ACodec::kWhatReleaseCodecInstance:
5434        {
5435            ALOGI("[%s] forcing the release of codec",
5436                    mCodec->mComponentName.c_str());
5437            status_t err = mCodec->mOMXNode->freeNode();
5438            ALOGE_IF("[%s] failed to release codec instance: err=%d",
5439                       mCodec->mComponentName.c_str(), err);
5440            mCodec->mCallback->onReleaseCompleted();
5441
5442            mCodec->changeState(mCodec->mUninitializedState);
5443            break;
5444        }
5445
5446        case ACodec::kWhatForceStateTransition:
5447        {
5448            ALOGV("Already transitioned --- ignore");
5449            break;
5450        }
5451
5452        default:
5453            return false;
5454    }
5455
5456    return true;
5457}
5458
5459bool ACodec::BaseState::checkOMXMessage(const sp<AMessage> &msg) {
5460    // there is a possibility that this is an outstanding message for a
5461    // codec that we have already destroyed
5462    if (mCodec->mOMXNode == NULL) {
5463        ALOGI("ignoring message as already freed component: %s",
5464                msg->debugString().c_str());
5465        return false;
5466    }
5467
5468    int32_t generation;
5469    CHECK(msg->findInt32("generation", (int32_t*)&generation));
5470    if (generation != mCodec->mNodeGeneration) {
5471        ALOGW("Unexpected message for component: %s, gen %u, cur %u",
5472                msg->debugString().c_str(), generation, mCodec->mNodeGeneration);
5473        return false;
5474    }
5475    return true;
5476}
5477
5478bool ACodec::BaseState::onOMXMessageList(const sp<AMessage> &msg) {
5479    sp<RefBase> obj;
5480    CHECK(msg->findObject("messages", &obj));
5481    sp<MessageList> msgList = static_cast<MessageList *>(obj.get());
5482
5483    bool receivedRenderedEvents = false;
5484    for (std::list<sp<AMessage>>::const_iterator it = msgList->getList().cbegin();
5485          it != msgList->getList().cend(); ++it) {
5486        (*it)->setWhat(ACodec::kWhatOMXMessageItem);
5487        mCodec->handleMessage(*it);
5488        int32_t type;
5489        CHECK((*it)->findInt32("type", &type));
5490        if (type == omx_message::FRAME_RENDERED) {
5491            receivedRenderedEvents = true;
5492        }
5493    }
5494
5495    if (receivedRenderedEvents) {
5496        // NOTE: all buffers are rendered in this case
5497        mCodec->notifyOfRenderedFrames();
5498    }
5499    return true;
5500}
5501
5502bool ACodec::BaseState::onOMXMessage(const sp<AMessage> &msg) {
5503    int32_t type;
5504    CHECK(msg->findInt32("type", &type));
5505
5506    switch (type) {
5507        case omx_message::EVENT:
5508        {
5509            int32_t event, data1, data2;
5510            CHECK(msg->findInt32("event", &event));
5511            CHECK(msg->findInt32("data1", &data1));
5512            CHECK(msg->findInt32("data2", &data2));
5513
5514            if (event == OMX_EventCmdComplete
5515                    && data1 == OMX_CommandFlush
5516                    && data2 == (int32_t)OMX_ALL) {
5517                // Use of this notification is not consistent across
5518                // implementations. We'll drop this notification and rely
5519                // on flush-complete notifications on the individual port
5520                // indices instead.
5521
5522                return true;
5523            }
5524
5525            return onOMXEvent(
5526                    static_cast<OMX_EVENTTYPE>(event),
5527                    static_cast<OMX_U32>(data1),
5528                    static_cast<OMX_U32>(data2));
5529        }
5530
5531        case omx_message::EMPTY_BUFFER_DONE:
5532        {
5533            IOMX::buffer_id bufferID;
5534            int32_t fenceFd;
5535
5536            CHECK(msg->findInt32("buffer", (int32_t*)&bufferID));
5537            CHECK(msg->findInt32("fence_fd", &fenceFd));
5538
5539            return onOMXEmptyBufferDone(bufferID, fenceFd);
5540        }
5541
5542        case omx_message::FILL_BUFFER_DONE:
5543        {
5544            IOMX::buffer_id bufferID;
5545            CHECK(msg->findInt32("buffer", (int32_t*)&bufferID));
5546
5547            int32_t rangeOffset, rangeLength, flags, fenceFd;
5548            int64_t timeUs;
5549
5550            CHECK(msg->findInt32("range_offset", &rangeOffset));
5551            CHECK(msg->findInt32("range_length", &rangeLength));
5552            CHECK(msg->findInt32("flags", &flags));
5553            CHECK(msg->findInt64("timestamp", &timeUs));
5554            CHECK(msg->findInt32("fence_fd", &fenceFd));
5555
5556            return onOMXFillBufferDone(
5557                    bufferID,
5558                    (size_t)rangeOffset, (size_t)rangeLength,
5559                    (OMX_U32)flags,
5560                    timeUs,
5561                    fenceFd);
5562        }
5563
5564        case omx_message::FRAME_RENDERED:
5565        {
5566            int64_t mediaTimeUs, systemNano;
5567
5568            CHECK(msg->findInt64("media_time_us", &mediaTimeUs));
5569            CHECK(msg->findInt64("system_nano", &systemNano));
5570
5571            return onOMXFrameRendered(
5572                    mediaTimeUs, systemNano);
5573        }
5574
5575        default:
5576            ALOGE("Unexpected message type: %d", type);
5577            return false;
5578    }
5579}
5580
5581bool ACodec::BaseState::onOMXFrameRendered(
5582        int64_t mediaTimeUs __unused, nsecs_t systemNano __unused) {
5583    // ignore outside of Executing and PortSettingsChanged states
5584    return true;
5585}
5586
5587bool ACodec::BaseState::onOMXEvent(
5588        OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2) {
5589    if (event == OMX_EventDataSpaceChanged) {
5590        ColorAspects aspects = ColorUtils::unpackToColorAspects(data2);
5591
5592        mCodec->onDataSpaceChanged((android_dataspace)data1, aspects);
5593        return true;
5594    }
5595
5596    if (event != OMX_EventError) {
5597        ALOGV("[%s] EVENT(%d, 0x%08x, 0x%08x)",
5598             mCodec->mComponentName.c_str(), event, data1, data2);
5599
5600        return false;
5601    }
5602
5603    ALOGE("[%s] ERROR(0x%08x)", mCodec->mComponentName.c_str(), data1);
5604
5605    // verify OMX component sends back an error we expect.
5606    OMX_ERRORTYPE omxError = (OMX_ERRORTYPE)data1;
5607    if (!isOMXError(omxError)) {
5608        ALOGW("Invalid OMX error %#x", omxError);
5609        omxError = OMX_ErrorUndefined;
5610    }
5611    mCodec->signalError(omxError);
5612
5613    return true;
5614}
5615
5616bool ACodec::BaseState::onOMXEmptyBufferDone(IOMX::buffer_id bufferID, int fenceFd) {
5617    ALOGV("[%s] onOMXEmptyBufferDone %u",
5618         mCodec->mComponentName.c_str(), bufferID);
5619
5620    BufferInfo *info = mCodec->findBufferByID(kPortIndexInput, bufferID);
5621    BufferInfo::Status status = BufferInfo::getSafeStatus(info);
5622    if (status != BufferInfo::OWNED_BY_COMPONENT) {
5623        ALOGE("Wrong ownership in EBD: %s(%d) buffer #%u", _asString(status), status, bufferID);
5624        mCodec->dumpBuffers(kPortIndexInput);
5625        if (fenceFd >= 0) {
5626            ::close(fenceFd);
5627        }
5628        return false;
5629    }
5630    info->mStatus = BufferInfo::OWNED_BY_US;
5631
5632    // input buffers cannot take fences, so wait for any fence now
5633    (void)mCodec->waitForFence(fenceFd, "onOMXEmptyBufferDone");
5634    fenceFd = -1;
5635
5636    // still save fence for completeness
5637    info->setWriteFence(fenceFd, "onOMXEmptyBufferDone");
5638
5639    // We're in "store-metadata-in-buffers" mode, the underlying
5640    // OMX component had access to data that's implicitly refcounted
5641    // by this "MediaBuffer" object. Now that the OMX component has
5642    // told us that it's done with the input buffer, we can decrement
5643    // the mediaBuffer's reference count.
5644    info->mData->setMediaBufferBase(NULL);
5645
5646    PortMode mode = getPortMode(kPortIndexInput);
5647
5648    switch (mode) {
5649        case KEEP_BUFFERS:
5650            break;
5651
5652        case RESUBMIT_BUFFERS:
5653            postFillThisBuffer(info);
5654            break;
5655
5656        case FREE_BUFFERS:
5657        default:
5658            ALOGE("SHOULD NOT REACH HERE: cannot free empty output buffers");
5659            return false;
5660    }
5661
5662    return true;
5663}
5664
5665void ACodec::BaseState::postFillThisBuffer(BufferInfo *info) {
5666    if (mCodec->mPortEOS[kPortIndexInput]) {
5667        return;
5668    }
5669
5670    CHECK_EQ((int)info->mStatus, (int)BufferInfo::OWNED_BY_US);
5671
5672    info->mData->setFormat(mCodec->mInputFormat);
5673    mCodec->mBufferChannel->fillThisBuffer(info->mBufferID);
5674    info->mData.clear();
5675    info->mStatus = BufferInfo::OWNED_BY_UPSTREAM;
5676}
5677
5678void ACodec::BaseState::onInputBufferFilled(const sp<AMessage> &msg) {
5679    IOMX::buffer_id bufferID;
5680    CHECK(msg->findInt32("buffer-id", (int32_t*)&bufferID));
5681    sp<MediaCodecBuffer> buffer;
5682    int32_t err = OK;
5683    bool eos = false;
5684    PortMode mode = getPortMode(kPortIndexInput);
5685    int32_t discarded = 0;
5686    if (msg->findInt32("discarded", &discarded) && discarded) {
5687        // these are unfilled buffers returned by client
5688        // buffers are returned on MediaCodec.flush
5689        mode = KEEP_BUFFERS;
5690    }
5691    sp<RefBase> obj;
5692    CHECK(msg->findObject("buffer", &obj));
5693    buffer = static_cast<MediaCodecBuffer *>(obj.get());
5694
5695    int32_t tmp;
5696    if (buffer != NULL && buffer->meta()->findInt32("eos", &tmp) && tmp) {
5697        eos = true;
5698        err = ERROR_END_OF_STREAM;
5699    }
5700
5701    BufferInfo *info = mCodec->findBufferByID(kPortIndexInput, bufferID);
5702    BufferInfo::Status status = BufferInfo::getSafeStatus(info);
5703    if (status != BufferInfo::OWNED_BY_UPSTREAM) {
5704        ALOGE("Wrong ownership in IBF: %s(%d) buffer #%u", _asString(status), status, bufferID);
5705        mCodec->dumpBuffers(kPortIndexInput);
5706        mCodec->signalError(OMX_ErrorUndefined, FAILED_TRANSACTION);
5707        return;
5708    }
5709
5710    info->mStatus = BufferInfo::OWNED_BY_US;
5711    info->mData = buffer;
5712
5713    switch (mode) {
5714        case KEEP_BUFFERS:
5715        {
5716            if (eos) {
5717                if (!mCodec->mPortEOS[kPortIndexInput]) {
5718                    mCodec->mPortEOS[kPortIndexInput] = true;
5719                    mCodec->mInputEOSResult = err;
5720                }
5721            }
5722            break;
5723        }
5724
5725        case RESUBMIT_BUFFERS:
5726        {
5727            if (buffer != NULL && !mCodec->mPortEOS[kPortIndexInput]) {
5728                // Do not send empty input buffer w/o EOS to the component.
5729                if (buffer->size() == 0 && !eos) {
5730                    postFillThisBuffer(info);
5731                    break;
5732                }
5733
5734                int64_t timeUs;
5735                CHECK(buffer->meta()->findInt64("timeUs", &timeUs));
5736
5737                OMX_U32 flags = OMX_BUFFERFLAG_ENDOFFRAME;
5738
5739                int32_t isCSD = 0;
5740                if (buffer->meta()->findInt32("csd", &isCSD) && isCSD != 0) {
5741                    if (mCodec->mIsLegacyVP9Decoder) {
5742                        ALOGV("[%s] is legacy VP9 decoder. Ignore %u codec specific data",
5743                            mCodec->mComponentName.c_str(), bufferID);
5744                        postFillThisBuffer(info);
5745                        break;
5746                    }
5747                    flags |= OMX_BUFFERFLAG_CODECCONFIG;
5748                }
5749
5750                if (eos) {
5751                    flags |= OMX_BUFFERFLAG_EOS;
5752                }
5753
5754                size_t size = buffer->size();
5755                size_t offset = buffer->offset();
5756                if (buffer->base() != info->mCodecData->base()) {
5757                    ALOGV("[%s] Needs to copy input data for buffer %u. (%p != %p)",
5758                         mCodec->mComponentName.c_str(),
5759                         bufferID,
5760                         buffer->base(), info->mCodecData->base());
5761
5762                    sp<DataConverter> converter = mCodec->mConverter[kPortIndexInput];
5763                    if (converter == NULL || isCSD) {
5764                        converter = getCopyConverter();
5765                    }
5766                    status_t err = converter->convert(buffer, info->mCodecData);
5767                    if (err != OK) {
5768                        mCodec->signalError(OMX_ErrorUndefined, err);
5769                        return;
5770                    }
5771                    size = info->mCodecData->size();
5772                } else {
5773                    info->mCodecData->setRange(offset, size);
5774                }
5775
5776                if (flags & OMX_BUFFERFLAG_CODECCONFIG) {
5777                    ALOGV("[%s] calling emptyBuffer %u w/ codec specific data",
5778                         mCodec->mComponentName.c_str(), bufferID);
5779                } else if (flags & OMX_BUFFERFLAG_EOS) {
5780                    ALOGV("[%s] calling emptyBuffer %u w/ EOS",
5781                         mCodec->mComponentName.c_str(), bufferID);
5782                } else {
5783#if TRACK_BUFFER_TIMING
5784                    ALOGI("[%s] calling emptyBuffer %u w/ time %lld us",
5785                         mCodec->mComponentName.c_str(), bufferID, (long long)timeUs);
5786#else
5787                    ALOGV("[%s] calling emptyBuffer %u w/ time %lld us",
5788                         mCodec->mComponentName.c_str(), bufferID, (long long)timeUs);
5789#endif
5790                }
5791
5792#if TRACK_BUFFER_TIMING
5793                ACodec::BufferStats stats;
5794                stats.mEmptyBufferTimeUs = ALooper::GetNowUs();
5795                stats.mFillBufferDoneTimeUs = -1ll;
5796                mCodec->mBufferStats.add(timeUs, stats);
5797#endif
5798
5799                if (mCodec->storingMetadataInDecodedBuffers()) {
5800                    // try to submit an output buffer for each input buffer
5801                    PortMode outputMode = getPortMode(kPortIndexOutput);
5802
5803                    ALOGV("MetadataBuffersToSubmit=%u portMode=%s",
5804                            mCodec->mMetadataBuffersToSubmit,
5805                            (outputMode == FREE_BUFFERS ? "FREE" :
5806                             outputMode == KEEP_BUFFERS ? "KEEP" : "RESUBMIT"));
5807                    if (outputMode == RESUBMIT_BUFFERS) {
5808                        mCodec->submitOutputMetadataBuffer();
5809                    }
5810                }
5811                info->checkReadFence("onInputBufferFilled");
5812
5813                status_t err2 = OK;
5814                switch (mCodec->mPortMode[kPortIndexInput]) {
5815                case IOMX::kPortModePresetByteBuffer:
5816                case IOMX::kPortModePresetANWBuffer:
5817                case IOMX::kPortModePresetSecureBuffer:
5818                    {
5819                        err2 = mCodec->mOMXNode->emptyBuffer(
5820                            bufferID, info->mCodecData, flags, timeUs, info->mFenceFd);
5821                    }
5822                    break;
5823#ifndef OMX_ANDROID_COMPILE_AS_32BIT_ON_64BIT_PLATFORMS
5824                case IOMX::kPortModeDynamicNativeHandle:
5825                    if (info->mCodecData->size() >= sizeof(VideoNativeHandleMetadata)) {
5826                        VideoNativeHandleMetadata *vnhmd =
5827                            (VideoNativeHandleMetadata*)info->mCodecData->base();
5828                        sp<NativeHandle> handle = NativeHandle::create(
5829                                vnhmd->pHandle, false /* ownsHandle */);
5830                        err2 = mCodec->mOMXNode->emptyBuffer(
5831                            bufferID, handle, flags, timeUs, info->mFenceFd);
5832                    }
5833                    break;
5834                case IOMX::kPortModeDynamicANWBuffer:
5835                    if (info->mCodecData->size() >= sizeof(VideoNativeMetadata)) {
5836                        VideoNativeMetadata *vnmd = (VideoNativeMetadata*)info->mCodecData->base();
5837                        sp<GraphicBuffer> graphicBuffer = GraphicBuffer::from(vnmd->pBuffer);
5838                        err2 = mCodec->mOMXNode->emptyBuffer(
5839                            bufferID, graphicBuffer, flags, timeUs, info->mFenceFd);
5840                    }
5841                    break;
5842#endif
5843                default:
5844                    ALOGW("Can't marshall %s data in %zu sized buffers in %zu-bit mode",
5845                            asString(mCodec->mPortMode[kPortIndexInput]),
5846                            info->mCodecData->size(),
5847                            sizeof(buffer_handle_t) * 8);
5848                    err2 = ERROR_UNSUPPORTED;
5849                    break;
5850                }
5851
5852                info->mFenceFd = -1;
5853                if (err2 != OK) {
5854                    mCodec->signalError(OMX_ErrorUndefined, makeNoSideEffectStatus(err2));
5855                    return;
5856                }
5857                info->mStatus = BufferInfo::OWNED_BY_COMPONENT;
5858                // Hold the reference while component is using the buffer.
5859                info->mData = buffer;
5860
5861                if (!eos && err == OK) {
5862                    getMoreInputDataIfPossible();
5863                } else {
5864                    ALOGV("[%s] Signalled EOS (%d) on the input port",
5865                         mCodec->mComponentName.c_str(), err);
5866
5867                    mCodec->mPortEOS[kPortIndexInput] = true;
5868                    mCodec->mInputEOSResult = err;
5869                }
5870            } else if (!mCodec->mPortEOS[kPortIndexInput]) {
5871                if (err != OK && err != ERROR_END_OF_STREAM) {
5872                    ALOGV("[%s] Signalling EOS on the input port due to error %d",
5873                         mCodec->mComponentName.c_str(), err);
5874                } else {
5875                    ALOGV("[%s] Signalling EOS on the input port",
5876                         mCodec->mComponentName.c_str());
5877                }
5878
5879                ALOGV("[%s] calling emptyBuffer %u signalling EOS",
5880                     mCodec->mComponentName.c_str(), bufferID);
5881
5882                info->checkReadFence("onInputBufferFilled");
5883                status_t err2 = mCodec->mOMXNode->emptyBuffer(
5884                        bufferID, OMXBuffer::sPreset, OMX_BUFFERFLAG_EOS, 0, info->mFenceFd);
5885                info->mFenceFd = -1;
5886                if (err2 != OK) {
5887                    mCodec->signalError(OMX_ErrorUndefined, makeNoSideEffectStatus(err2));
5888                    return;
5889                }
5890                info->mStatus = BufferInfo::OWNED_BY_COMPONENT;
5891
5892                mCodec->mPortEOS[kPortIndexInput] = true;
5893                mCodec->mInputEOSResult = err;
5894            }
5895            break;
5896        }
5897
5898        case FREE_BUFFERS:
5899            break;
5900
5901        default:
5902            ALOGE("invalid port mode: %d", mode);
5903            break;
5904    }
5905}
5906
5907void ACodec::BaseState::getMoreInputDataIfPossible() {
5908    if (mCodec->mPortEOS[kPortIndexInput]) {
5909        return;
5910    }
5911
5912    BufferInfo *eligible = NULL;
5913
5914    for (size_t i = 0; i < mCodec->mBuffers[kPortIndexInput].size(); ++i) {
5915        BufferInfo *info = &mCodec->mBuffers[kPortIndexInput].editItemAt(i);
5916
5917#if 0
5918        if (info->mStatus == BufferInfo::OWNED_BY_UPSTREAM) {
5919            // There's already a "read" pending.
5920            return;
5921        }
5922#endif
5923
5924        if (info->mStatus == BufferInfo::OWNED_BY_US) {
5925            eligible = info;
5926        }
5927    }
5928
5929    if (eligible == NULL) {
5930        return;
5931    }
5932
5933    postFillThisBuffer(eligible);
5934}
5935
5936bool ACodec::BaseState::onOMXFillBufferDone(
5937        IOMX::buffer_id bufferID,
5938        size_t rangeOffset, size_t rangeLength,
5939        OMX_U32 flags,
5940        int64_t timeUs,
5941        int fenceFd) {
5942    ALOGV("[%s] onOMXFillBufferDone %u time %" PRId64 " us, flags = 0x%08x",
5943         mCodec->mComponentName.c_str(), bufferID, timeUs, flags);
5944
5945    ssize_t index;
5946    status_t err= OK;
5947
5948#if TRACK_BUFFER_TIMING
5949    index = mCodec->mBufferStats.indexOfKey(timeUs);
5950    if (index >= 0) {
5951        ACodec::BufferStats *stats = &mCodec->mBufferStats.editValueAt(index);
5952        stats->mFillBufferDoneTimeUs = ALooper::GetNowUs();
5953
5954        ALOGI("frame PTS %lld: %lld",
5955                timeUs,
5956                stats->mFillBufferDoneTimeUs - stats->mEmptyBufferTimeUs);
5957
5958        mCodec->mBufferStats.removeItemsAt(index);
5959        stats = NULL;
5960    }
5961#endif
5962
5963    BufferInfo *info =
5964        mCodec->findBufferByID(kPortIndexOutput, bufferID, &index);
5965    BufferInfo::Status status = BufferInfo::getSafeStatus(info);
5966    if (status != BufferInfo::OWNED_BY_COMPONENT) {
5967        ALOGE("Wrong ownership in FBD: %s(%d) buffer #%u", _asString(status), status, bufferID);
5968        mCodec->dumpBuffers(kPortIndexOutput);
5969        mCodec->signalError(OMX_ErrorUndefined, FAILED_TRANSACTION);
5970        if (fenceFd >= 0) {
5971            ::close(fenceFd);
5972        }
5973        return true;
5974    }
5975
5976    info->mDequeuedAt = ++mCodec->mDequeueCounter;
5977    info->mStatus = BufferInfo::OWNED_BY_US;
5978
5979    if (info->mRenderInfo != NULL) {
5980        // The fence for an emptied buffer must have signaled, but there still could be queued
5981        // or out-of-order dequeued buffers in the render queue prior to this buffer. Drop these,
5982        // as we will soon requeue this buffer to the surface. While in theory we could still keep
5983        // track of buffers that are requeued to the surface, it is better to add support to the
5984        // buffer-queue to notify us of released buffers and their fences (in the future).
5985        mCodec->notifyOfRenderedFrames(true /* dropIncomplete */);
5986    }
5987
5988    // byte buffers cannot take fences, so wait for any fence now
5989    if (mCodec->mNativeWindow == NULL) {
5990        (void)mCodec->waitForFence(fenceFd, "onOMXFillBufferDone");
5991        fenceFd = -1;
5992    }
5993    info->setReadFence(fenceFd, "onOMXFillBufferDone");
5994
5995    PortMode mode = getPortMode(kPortIndexOutput);
5996
5997    switch (mode) {
5998        case KEEP_BUFFERS:
5999            break;
6000
6001        case RESUBMIT_BUFFERS:
6002        {
6003            if (rangeLength == 0 && (!(flags & OMX_BUFFERFLAG_EOS)
6004                    || mCodec->mPortEOS[kPortIndexOutput])) {
6005                ALOGV("[%s] calling fillBuffer %u",
6006                     mCodec->mComponentName.c_str(), info->mBufferID);
6007
6008                err = mCodec->fillBuffer(info);
6009                if (err != OK) {
6010                    mCodec->signalError(OMX_ErrorUndefined, makeNoSideEffectStatus(err));
6011                    return true;
6012                }
6013                break;
6014            }
6015
6016            sp<MediaCodecBuffer> buffer = info->mData;
6017
6018            if (mCodec->mOutputFormat != mCodec->mLastOutputFormat && rangeLength > 0) {
6019                // pretend that output format has changed on the first frame (we used to do this)
6020                if (mCodec->mBaseOutputFormat == mCodec->mOutputFormat) {
6021                    mCodec->onOutputFormatChanged(mCodec->mOutputFormat);
6022                }
6023                mCodec->sendFormatChange();
6024            }
6025            buffer->setFormat(mCodec->mOutputFormat);
6026
6027            if (mCodec->usingSecureBufferOnEncoderOutput()) {
6028                native_handle_t *handle = NULL;
6029                sp<SecureBuffer> secureBuffer = static_cast<SecureBuffer *>(buffer.get());
6030                if (secureBuffer != NULL) {
6031#ifdef OMX_ANDROID_COMPILE_AS_32BIT_ON_64BIT_PLATFORMS
6032                    // handle is only valid on 32-bit/mediaserver process
6033                    handle = NULL;
6034#else
6035                    handle = (native_handle_t *)secureBuffer->getDestinationPointer();
6036#endif
6037                }
6038                buffer->meta()->setPointer("handle", handle);
6039                buffer->meta()->setInt32("rangeOffset", rangeOffset);
6040                buffer->meta()->setInt32("rangeLength", rangeLength);
6041            } else if (buffer->base() == info->mCodecData->base()) {
6042                buffer->setRange(rangeOffset, rangeLength);
6043            } else {
6044                info->mCodecData->setRange(rangeOffset, rangeLength);
6045                // in this case we know that mConverter is not null
6046                status_t err = mCodec->mConverter[kPortIndexOutput]->convert(
6047                        info->mCodecData, buffer);
6048                if (err != OK) {
6049                    mCodec->signalError(OMX_ErrorUndefined, makeNoSideEffectStatus(err));
6050                    return true;
6051                }
6052            }
6053#if 0
6054            if (mCodec->mNativeWindow == NULL) {
6055                if (IsIDR(info->mData->data(), info->mData->size())) {
6056                    ALOGI("IDR frame");
6057                }
6058            }
6059#endif
6060
6061            if (mCodec->mSkipCutBuffer != NULL) {
6062                mCodec->mSkipCutBuffer->submit(buffer);
6063            }
6064            buffer->meta()->setInt64("timeUs", timeUs);
6065
6066            info->mData.clear();
6067
6068            mCodec->mBufferChannel->drainThisBuffer(info->mBufferID, flags);
6069
6070            info->mStatus = BufferInfo::OWNED_BY_DOWNSTREAM;
6071
6072            if (flags & OMX_BUFFERFLAG_EOS) {
6073                ALOGV("[%s] saw output EOS", mCodec->mComponentName.c_str());
6074
6075                mCodec->mCallback->onEos(mCodec->mInputEOSResult);
6076                mCodec->mPortEOS[kPortIndexOutput] = true;
6077            }
6078            break;
6079        }
6080
6081        case FREE_BUFFERS:
6082            err = mCodec->freeBuffer(kPortIndexOutput, index);
6083            if (err != OK) {
6084                mCodec->signalError(OMX_ErrorUndefined, makeNoSideEffectStatus(err));
6085                return true;
6086            }
6087            break;
6088
6089        default:
6090            ALOGE("Invalid port mode: %d", mode);
6091            return false;
6092    }
6093
6094    return true;
6095}
6096
6097void ACodec::BaseState::onOutputBufferDrained(const sp<AMessage> &msg) {
6098    IOMX::buffer_id bufferID;
6099    CHECK(msg->findInt32("buffer-id", (int32_t*)&bufferID));
6100    sp<RefBase> obj;
6101    CHECK(msg->findObject("buffer", &obj));
6102    sp<MediaCodecBuffer> buffer = static_cast<MediaCodecBuffer *>(obj.get());
6103    int32_t discarded = 0;
6104    msg->findInt32("discarded", &discarded);
6105
6106    ssize_t index;
6107    BufferInfo *info = mCodec->findBufferByID(kPortIndexOutput, bufferID, &index);
6108    BufferInfo::Status status = BufferInfo::getSafeStatus(info);
6109    if (status != BufferInfo::OWNED_BY_DOWNSTREAM) {
6110        ALOGE("Wrong ownership in OBD: %s(%d) buffer #%u", _asString(status), status, bufferID);
6111        mCodec->dumpBuffers(kPortIndexOutput);
6112        mCodec->signalError(OMX_ErrorUndefined, FAILED_TRANSACTION);
6113        return;
6114    }
6115    info->mData = buffer;
6116    int32_t render;
6117    if (mCodec->mNativeWindow != NULL
6118            && msg->findInt32("render", &render) && render != 0
6119            && !discarded && buffer->size() != 0) {
6120        ATRACE_NAME("render");
6121        // The client wants this buffer to be rendered.
6122
6123        android_native_rect_t crop;
6124        if (buffer->format()->findRect("crop", &crop.left, &crop.top, &crop.right, &crop.bottom)) {
6125            // NOTE: native window uses extended right-bottom coordinate
6126            ++crop.right;
6127            ++crop.bottom;
6128            if (memcmp(&crop, &mCodec->mLastNativeWindowCrop, sizeof(crop)) != 0) {
6129                mCodec->mLastNativeWindowCrop = crop;
6130                status_t err = native_window_set_crop(mCodec->mNativeWindow.get(), &crop);
6131                ALOGW_IF(err != NO_ERROR, "failed to set crop: %d", err);
6132            }
6133        }
6134
6135        int32_t dataSpace;
6136        if (buffer->format()->findInt32("android._dataspace", &dataSpace)
6137                && dataSpace != mCodec->mLastNativeWindowDataSpace) {
6138            status_t err = native_window_set_buffers_data_space(
6139                    mCodec->mNativeWindow.get(), (android_dataspace)dataSpace);
6140            mCodec->mLastNativeWindowDataSpace = dataSpace;
6141            ALOGW_IF(err != NO_ERROR, "failed to set dataspace: %d", err);
6142        }
6143
6144        // save buffers sent to the surface so we can get render time when they return
6145        int64_t mediaTimeUs = -1;
6146        buffer->meta()->findInt64("timeUs", &mediaTimeUs);
6147        if (mediaTimeUs >= 0) {
6148            mCodec->mRenderTracker.onFrameQueued(
6149                    mediaTimeUs, info->mGraphicBuffer, new Fence(::dup(info->mFenceFd)));
6150        }
6151
6152        int64_t timestampNs = 0;
6153        if (!msg->findInt64("timestampNs", &timestampNs)) {
6154            // use media timestamp if client did not request a specific render timestamp
6155            if (buffer->meta()->findInt64("timeUs", &timestampNs)) {
6156                ALOGV("using buffer PTS of %lld", (long long)timestampNs);
6157                timestampNs *= 1000;
6158            }
6159        }
6160
6161        status_t err;
6162        err = native_window_set_buffers_timestamp(mCodec->mNativeWindow.get(), timestampNs);
6163        ALOGW_IF(err != NO_ERROR, "failed to set buffer timestamp: %d", err);
6164
6165        info->checkReadFence("onOutputBufferDrained before queueBuffer");
6166        err = mCodec->mNativeWindow->queueBuffer(
6167                    mCodec->mNativeWindow.get(), info->mGraphicBuffer.get(), info->mFenceFd);
6168        info->mFenceFd = -1;
6169        if (err == OK) {
6170            info->mStatus = BufferInfo::OWNED_BY_NATIVE_WINDOW;
6171        } else {
6172            ALOGE("queueBuffer failed in onOutputBufferDrained: %d", err);
6173            mCodec->signalError(OMX_ErrorUndefined, makeNoSideEffectStatus(err));
6174            info->mStatus = BufferInfo::OWNED_BY_US;
6175            // keeping read fence as write fence to avoid clobbering
6176            info->mIsReadFence = false;
6177        }
6178    } else {
6179        if (mCodec->mNativeWindow != NULL && (discarded || buffer->size() != 0)) {
6180            // move read fence into write fence to avoid clobbering
6181            info->mIsReadFence = false;
6182            ATRACE_NAME("frame-drop");
6183        }
6184        info->mStatus = BufferInfo::OWNED_BY_US;
6185    }
6186
6187    PortMode mode = getPortMode(kPortIndexOutput);
6188
6189    switch (mode) {
6190        case KEEP_BUFFERS:
6191        {
6192            // XXX fishy, revisit!!! What about the FREE_BUFFERS case below?
6193
6194            if (info->mStatus == BufferInfo::OWNED_BY_NATIVE_WINDOW) {
6195                // We cannot resubmit the buffer we just rendered, dequeue
6196                // the spare instead.
6197
6198                info = mCodec->dequeueBufferFromNativeWindow();
6199            }
6200            break;
6201        }
6202
6203        case RESUBMIT_BUFFERS:
6204        {
6205            if (!mCodec->mPortEOS[kPortIndexOutput]) {
6206                if (info->mStatus == BufferInfo::OWNED_BY_NATIVE_WINDOW) {
6207                    // We cannot resubmit the buffer we just rendered, dequeue
6208                    // the spare instead.
6209
6210                    info = mCodec->dequeueBufferFromNativeWindow();
6211                }
6212
6213                if (info != NULL) {
6214                    ALOGV("[%s] calling fillBuffer %u",
6215                         mCodec->mComponentName.c_str(), info->mBufferID);
6216                    info->checkWriteFence("onOutputBufferDrained::RESUBMIT_BUFFERS");
6217                    status_t err = mCodec->fillBuffer(info);
6218                    if (err != OK) {
6219                        mCodec->signalError(OMX_ErrorUndefined, makeNoSideEffectStatus(err));
6220                    }
6221                }
6222            }
6223            break;
6224        }
6225
6226        case FREE_BUFFERS:
6227        {
6228            status_t err = mCodec->freeBuffer(kPortIndexOutput, index);
6229            if (err != OK) {
6230                mCodec->signalError(OMX_ErrorUndefined, makeNoSideEffectStatus(err));
6231            }
6232            break;
6233        }
6234
6235        default:
6236            ALOGE("Invalid port mode: %d", mode);
6237            return;
6238    }
6239}
6240
6241////////////////////////////////////////////////////////////////////////////////
6242
6243ACodec::UninitializedState::UninitializedState(ACodec *codec)
6244    : BaseState(codec) {
6245}
6246
6247void ACodec::UninitializedState::stateEntered() {
6248    ALOGV("Now uninitialized");
6249
6250    if (mDeathNotifier != NULL) {
6251        if (mCodec->mOMXNode != NULL) {
6252            if (mCodec->getTrebleFlag()) {
6253                auto tOmxNode = mCodec->mOMXNode->getHalInterface();
6254                tOmxNode->unlinkToDeath(mDeathNotifier);
6255            } else {
6256                sp<IBinder> binder = IInterface::asBinder(mCodec->mOMXNode);
6257                binder->unlinkToDeath(mDeathNotifier);
6258            }
6259        }
6260        mDeathNotifier.clear();
6261    }
6262
6263    mCodec->mUsingNativeWindow = false;
6264    mCodec->mNativeWindow.clear();
6265    mCodec->mNativeWindowUsageBits = 0;
6266    mCodec->mOMX.clear();
6267    mCodec->mOMXNode.clear();
6268    mCodec->mFlags = 0;
6269    mCodec->mPortMode[kPortIndexInput] = IOMX::kPortModePresetByteBuffer;
6270    mCodec->mPortMode[kPortIndexOutput] = IOMX::kPortModePresetByteBuffer;
6271    mCodec->mConverter[0].clear();
6272    mCodec->mConverter[1].clear();
6273    mCodec->mComponentName.clear();
6274}
6275
6276bool ACodec::UninitializedState::onMessageReceived(const sp<AMessage> &msg) {
6277    bool handled = false;
6278
6279    switch (msg->what()) {
6280        case ACodec::kWhatSetup:
6281        {
6282            onSetup(msg);
6283
6284            handled = true;
6285            break;
6286        }
6287
6288        case ACodec::kWhatAllocateComponent:
6289        {
6290            onAllocateComponent(msg);
6291            handled = true;
6292            break;
6293        }
6294
6295        case ACodec::kWhatShutdown:
6296        {
6297            int32_t keepComponentAllocated;
6298            CHECK(msg->findInt32(
6299                        "keepComponentAllocated", &keepComponentAllocated));
6300            ALOGW_IF(keepComponentAllocated,
6301                     "cannot keep component allocated on shutdown in Uninitialized state");
6302            if (keepComponentAllocated) {
6303                mCodec->mCallback->onStopCompleted();
6304            } else {
6305                mCodec->mCallback->onReleaseCompleted();
6306            }
6307            handled = true;
6308            break;
6309        }
6310
6311        case ACodec::kWhatFlush:
6312        {
6313            mCodec->mCallback->onFlushCompleted();
6314            handled = true;
6315            break;
6316        }
6317
6318        case ACodec::kWhatReleaseCodecInstance:
6319        {
6320            // nothing to do, as we have already signaled shutdown
6321            handled = true;
6322            break;
6323        }
6324
6325        default:
6326            return BaseState::onMessageReceived(msg);
6327    }
6328
6329    return handled;
6330}
6331
6332void ACodec::UninitializedState::onSetup(
6333        const sp<AMessage> &msg) {
6334    if (onAllocateComponent(msg)
6335            && mCodec->mLoadedState->onConfigureComponent(msg)) {
6336        mCodec->mLoadedState->onStart();
6337    }
6338}
6339
6340bool ACodec::UninitializedState::onAllocateComponent(const sp<AMessage> &msg) {
6341    ALOGV("onAllocateComponent");
6342
6343    CHECK(mCodec->mOMXNode == NULL);
6344
6345    sp<AMessage> notify = new AMessage(kWhatOMXDied, mCodec);
6346
6347    Vector<AString> matchingCodecs;
6348    Vector<AString> owners;
6349
6350    AString mime;
6351
6352    AString componentName;
6353    int32_t encoder = false;
6354    if (msg->findString("componentName", &componentName)) {
6355        sp<IMediaCodecList> list = MediaCodecList::getInstance();
6356        if (list == nullptr) {
6357            ALOGE("Unable to obtain MediaCodecList while "
6358                    "attempting to create codec \"%s\"",
6359                    componentName.c_str());
6360            mCodec->signalError(OMX_ErrorUndefined, NO_INIT);
6361            return false;
6362        }
6363        ssize_t index = list->findCodecByName(componentName.c_str());
6364        if (index < 0) {
6365            ALOGE("Unable to find codec \"%s\"",
6366                    componentName.c_str());
6367            mCodec->signalError(OMX_ErrorInvalidComponent, NAME_NOT_FOUND);
6368            return false;
6369        }
6370        sp<MediaCodecInfo> info = list->getCodecInfo(index);
6371        if (info == nullptr) {
6372            ALOGE("Unexpected error (index out-of-bound) while "
6373                    "retrieving information for codec \"%s\"",
6374                    componentName.c_str());
6375            mCodec->signalError(OMX_ErrorUndefined, UNKNOWN_ERROR);
6376            return false;
6377        }
6378        matchingCodecs.add(info->getCodecName());
6379        owners.add(info->getOwnerName() == nullptr ?
6380                "default" : info->getOwnerName());
6381    } else {
6382        CHECK(msg->findString("mime", &mime));
6383
6384        if (!msg->findInt32("encoder", &encoder)) {
6385            encoder = false;
6386        }
6387
6388        MediaCodecList::findMatchingCodecs(
6389                mime.c_str(),
6390                encoder, // createEncoder
6391                0,       // flags
6392                &matchingCodecs,
6393                &owners);
6394    }
6395
6396    sp<CodecObserver> observer = new CodecObserver;
6397    sp<IOMX> omx;
6398    sp<IOMXNode> omxNode;
6399
6400    status_t err = NAME_NOT_FOUND;
6401    for (size_t matchIndex = 0; matchIndex < matchingCodecs.size();
6402            ++matchIndex) {
6403        componentName = matchingCodecs[matchIndex];
6404
6405        OMXClient client;
6406        bool trebleFlag;
6407        if (client.connect(owners[matchIndex].c_str(), &trebleFlag) != OK) {
6408            mCodec->signalError(OMX_ErrorUndefined, NO_INIT);
6409            return false;
6410        }
6411        omx = client.interface();
6412
6413        pid_t tid = gettid();
6414        int prevPriority = androidGetThreadPriority(tid);
6415        androidSetThreadPriority(tid, ANDROID_PRIORITY_FOREGROUND);
6416        err = omx->allocateNode(componentName.c_str(), observer, &omxNode);
6417        androidSetThreadPriority(tid, prevPriority);
6418
6419        if (err == OK) {
6420            mCodec->setTrebleFlag(trebleFlag);
6421            break;
6422        } else {
6423            ALOGW("Allocating component '%s' failed, try next one.", componentName.c_str());
6424        }
6425
6426        omxNode = NULL;
6427    }
6428
6429    if (omxNode == NULL) {
6430        if (!mime.empty()) {
6431            ALOGE("Unable to instantiate a %scoder for type '%s' with err %#x.",
6432                    encoder ? "en" : "de", mime.c_str(), err);
6433        } else {
6434            ALOGE("Unable to instantiate codec '%s' with err %#x.", componentName.c_str(), err);
6435        }
6436
6437        mCodec->signalError((OMX_ERRORTYPE)err, makeNoSideEffectStatus(err));
6438        return false;
6439    }
6440
6441    mDeathNotifier = new DeathNotifier(notify);
6442    if (mCodec->getTrebleFlag()) {
6443        auto tOmxNode = omxNode->getHalInterface();
6444        if (!tOmxNode->linkToDeath(mDeathNotifier, 0)) {
6445            mDeathNotifier.clear();
6446        }
6447    } else {
6448        if (IInterface::asBinder(omxNode)->linkToDeath(mDeathNotifier) != OK) {
6449            // This was a local binder, if it dies so do we, we won't care
6450            // about any notifications in the afterlife.
6451            mDeathNotifier.clear();
6452        }
6453    }
6454
6455    notify = new AMessage(kWhatOMXMessageList, mCodec);
6456    notify->setInt32("generation", ++mCodec->mNodeGeneration);
6457    observer->setNotificationMessage(notify);
6458
6459    mCodec->mComponentName = componentName;
6460    mCodec->mRenderTracker.setComponentName(componentName);
6461    mCodec->mFlags = 0;
6462
6463    if (componentName.endsWith(".secure")) {
6464        mCodec->mFlags |= kFlagIsSecure;
6465        mCodec->mFlags |= kFlagIsGrallocUsageProtected;
6466        mCodec->mFlags |= kFlagPushBlankBuffersToNativeWindowOnShutdown;
6467    }
6468
6469    mCodec->mOMX = omx;
6470    mCodec->mOMXNode = omxNode;
6471    mCodec->mCallback->onComponentAllocated(mCodec->mComponentName.c_str());
6472    mCodec->changeState(mCodec->mLoadedState);
6473
6474    return true;
6475}
6476
6477////////////////////////////////////////////////////////////////////////////////
6478
6479ACodec::LoadedState::LoadedState(ACodec *codec)
6480    : BaseState(codec) {
6481}
6482
6483void ACodec::LoadedState::stateEntered() {
6484    ALOGV("[%s] Now Loaded", mCodec->mComponentName.c_str());
6485
6486    mCodec->mPortEOS[kPortIndexInput] =
6487        mCodec->mPortEOS[kPortIndexOutput] = false;
6488
6489    mCodec->mInputEOSResult = OK;
6490
6491    mCodec->mDequeueCounter = 0;
6492    mCodec->mMetadataBuffersToSubmit = 0;
6493    mCodec->mRepeatFrameDelayUs = -1ll;
6494    mCodec->mInputFormat.clear();
6495    mCodec->mOutputFormat.clear();
6496    mCodec->mBaseOutputFormat.clear();
6497    mCodec->mGraphicBufferSource.clear();
6498
6499    if (mCodec->mShutdownInProgress) {
6500        bool keepComponentAllocated = mCodec->mKeepComponentAllocated;
6501
6502        mCodec->mShutdownInProgress = false;
6503        mCodec->mKeepComponentAllocated = false;
6504
6505        onShutdown(keepComponentAllocated);
6506    }
6507    mCodec->mExplicitShutdown = false;
6508
6509    mCodec->processDeferredMessages();
6510}
6511
6512void ACodec::LoadedState::onShutdown(bool keepComponentAllocated) {
6513    if (!keepComponentAllocated) {
6514        (void)mCodec->mOMXNode->freeNode();
6515
6516        mCodec->changeState(mCodec->mUninitializedState);
6517    }
6518
6519    if (mCodec->mExplicitShutdown) {
6520        if (keepComponentAllocated) {
6521            mCodec->mCallback->onStopCompleted();
6522        } else {
6523            mCodec->mCallback->onReleaseCompleted();
6524        }
6525        mCodec->mExplicitShutdown = false;
6526    }
6527}
6528
6529bool ACodec::LoadedState::onMessageReceived(const sp<AMessage> &msg) {
6530    bool handled = false;
6531
6532    switch (msg->what()) {
6533        case ACodec::kWhatConfigureComponent:
6534        {
6535            onConfigureComponent(msg);
6536            handled = true;
6537            break;
6538        }
6539
6540        case ACodec::kWhatCreateInputSurface:
6541        {
6542            onCreateInputSurface(msg);
6543            handled = true;
6544            break;
6545        }
6546
6547        case ACodec::kWhatSetInputSurface:
6548        {
6549            onSetInputSurface(msg);
6550            handled = true;
6551            break;
6552        }
6553
6554        case ACodec::kWhatStart:
6555        {
6556            onStart();
6557            handled = true;
6558            break;
6559        }
6560
6561        case ACodec::kWhatShutdown:
6562        {
6563            int32_t keepComponentAllocated;
6564            CHECK(msg->findInt32(
6565                        "keepComponentAllocated", &keepComponentAllocated));
6566
6567            mCodec->mExplicitShutdown = true;
6568            onShutdown(keepComponentAllocated);
6569
6570            handled = true;
6571            break;
6572        }
6573
6574        case ACodec::kWhatFlush:
6575        {
6576            mCodec->mCallback->onFlushCompleted();
6577            handled = true;
6578            break;
6579        }
6580
6581        default:
6582            return BaseState::onMessageReceived(msg);
6583    }
6584
6585    return handled;
6586}
6587
6588bool ACodec::LoadedState::onConfigureComponent(
6589        const sp<AMessage> &msg) {
6590    ALOGV("onConfigureComponent");
6591
6592    CHECK(mCodec->mOMXNode != NULL);
6593
6594    status_t err = OK;
6595    AString mime;
6596    if (!msg->findString("mime", &mime)) {
6597        err = BAD_VALUE;
6598    } else {
6599        err = mCodec->configureCodec(mime.c_str(), msg);
6600    }
6601    if (err != OK) {
6602        ALOGE("[%s] configureCodec returning error %d",
6603              mCodec->mComponentName.c_str(), err);
6604
6605        mCodec->signalError(OMX_ErrorUndefined, makeNoSideEffectStatus(err));
6606        return false;
6607    }
6608
6609    mCodec->mCallback->onComponentConfigured(mCodec->mInputFormat, mCodec->mOutputFormat);
6610
6611    return true;
6612}
6613
6614status_t ACodec::LoadedState::setupInputSurface() {
6615    if (mCodec->mGraphicBufferSource == NULL) {
6616        return BAD_VALUE;
6617    }
6618
6619    android_dataspace dataSpace;
6620    status_t err =
6621        mCodec->setInitialColorAspectsForVideoEncoderSurfaceAndGetDataSpace(&dataSpace);
6622    if (err != OK) {
6623        ALOGE("Failed to get default data space");
6624        return err;
6625    }
6626
6627    err = statusFromBinderStatus(
6628            mCodec->mGraphicBufferSource->configure(mCodec->mOMXNode, dataSpace));
6629    if (err != OK) {
6630        ALOGE("[%s] Unable to configure for node (err %d)",
6631              mCodec->mComponentName.c_str(), err);
6632        return err;
6633    }
6634
6635    if (mCodec->mRepeatFrameDelayUs > 0ll) {
6636        err = statusFromBinderStatus(
6637                mCodec->mGraphicBufferSource->setRepeatPreviousFrameDelayUs(
6638                        mCodec->mRepeatFrameDelayUs));
6639
6640        if (err != OK) {
6641            ALOGE("[%s] Unable to configure option to repeat previous "
6642                  "frames (err %d)",
6643                  mCodec->mComponentName.c_str(), err);
6644            return err;
6645        }
6646    }
6647
6648    if (mCodec->mMaxPtsGapUs > 0ll) {
6649        OMX_PARAM_U32TYPE maxPtsGapParams;
6650        InitOMXParams(&maxPtsGapParams);
6651        maxPtsGapParams.nPortIndex = kPortIndexInput;
6652        maxPtsGapParams.nU32 = (uint32_t) mCodec->mMaxPtsGapUs;
6653
6654        err = mCodec->mOMXNode->setParameter(
6655                (OMX_INDEXTYPE)OMX_IndexParamMaxFrameDurationForBitrateControl,
6656                &maxPtsGapParams, sizeof(maxPtsGapParams));
6657
6658        if (err != OK) {
6659            ALOGE("[%s] Unable to configure max timestamp gap (err %d)",
6660                    mCodec->mComponentName.c_str(), err);
6661            return err;
6662        }
6663    }
6664
6665    if (mCodec->mMaxFps > 0) {
6666        err = statusFromBinderStatus(
6667                mCodec->mGraphicBufferSource->setMaxFps(mCodec->mMaxFps));
6668
6669        if (err != OK) {
6670            ALOGE("[%s] Unable to configure max fps (err %d)",
6671                    mCodec->mComponentName.c_str(), err);
6672            return err;
6673        }
6674    }
6675
6676    if (mCodec->mCaptureFps > 0. && mCodec->mFps > 0.) {
6677        err = statusFromBinderStatus(
6678                mCodec->mGraphicBufferSource->setTimeLapseConfig(
6679                        mCodec->mFps, mCodec->mCaptureFps));
6680
6681        if (err != OK) {
6682            ALOGE("[%s] Unable to configure time lapse (err %d)",
6683                    mCodec->mComponentName.c_str(), err);
6684            return err;
6685        }
6686    }
6687
6688    if (mCodec->mCreateInputBuffersSuspended) {
6689        err = statusFromBinderStatus(
6690                mCodec->mGraphicBufferSource->setSuspend(true, -1));
6691
6692        if (err != OK) {
6693            ALOGE("[%s] Unable to configure option to suspend (err %d)",
6694                  mCodec->mComponentName.c_str(), err);
6695            return err;
6696        }
6697    }
6698
6699    uint32_t usageBits;
6700    if (mCodec->mOMXNode->getParameter(
6701            (OMX_INDEXTYPE)OMX_IndexParamConsumerUsageBits,
6702            &usageBits, sizeof(usageBits)) == OK) {
6703        mCodec->mInputFormat->setInt32(
6704                "using-sw-read-often", !!(usageBits & GRALLOC_USAGE_SW_READ_OFTEN));
6705    }
6706
6707    sp<ABuffer> colorAspectsBuffer;
6708    if (mCodec->mInputFormat->findBuffer("android._color-aspects", &colorAspectsBuffer)) {
6709        if (colorAspectsBuffer->size() != sizeof(ColorAspects)) {
6710            return INVALID_OPERATION;
6711        }
6712
6713        err = statusFromBinderStatus(
6714                mCodec->mGraphicBufferSource->setColorAspects(ColorUtils::packToU32(
6715                        *(ColorAspects *)colorAspectsBuffer->base())));
6716
6717        if (err != OK) {
6718            ALOGE("[%s] Unable to configure color aspects (err %d)",
6719                  mCodec->mComponentName.c_str(), err);
6720            return err;
6721        }
6722    }
6723    return OK;
6724}
6725
6726void ACodec::LoadedState::onCreateInputSurface(
6727        const sp<AMessage> & /* msg */) {
6728    ALOGV("onCreateInputSurface");
6729
6730    sp<IGraphicBufferProducer> bufferProducer;
6731    status_t err = mCodec->mOMX->createInputSurface(
6732            &bufferProducer, &mCodec->mGraphicBufferSource);
6733
6734    if (err == OK) {
6735        err = setupInputSurface();
6736    }
6737
6738    if (err == OK) {
6739        mCodec->mCallback->onInputSurfaceCreated(
6740                mCodec->mInputFormat,
6741                mCodec->mOutputFormat,
6742                new BufferProducerWrapper(bufferProducer));
6743    } else {
6744        // Can't use mCodec->signalError() here -- MediaCodec won't forward
6745        // the error through because it's in the "configured" state.  We
6746        // send a kWhatInputSurfaceCreated with an error value instead.
6747        ALOGE("[%s] onCreateInputSurface returning error %d",
6748                mCodec->mComponentName.c_str(), err);
6749        mCodec->mCallback->onInputSurfaceCreationFailed(err);
6750    }
6751}
6752
6753void ACodec::LoadedState::onSetInputSurface(const sp<AMessage> &msg) {
6754    ALOGV("onSetInputSurface");
6755
6756    sp<RefBase> obj;
6757    CHECK(msg->findObject("input-surface", &obj));
6758    sp<PersistentSurface> surface = static_cast<PersistentSurface *>(obj.get());
6759    mCodec->mGraphicBufferSource = surface->getBufferSource();
6760
6761    status_t err = setupInputSurface();
6762
6763    if (err == OK) {
6764        mCodec->mCallback->onInputSurfaceAccepted(
6765                mCodec->mInputFormat, mCodec->mOutputFormat);
6766    } else {
6767        // Can't use mCodec->signalError() here -- MediaCodec won't forward
6768        // the error through because it's in the "configured" state.  We
6769        // send a kWhatInputSurfaceAccepted with an error value instead.
6770        ALOGE("[%s] onSetInputSurface returning error %d",
6771                mCodec->mComponentName.c_str(), err);
6772        mCodec->mCallback->onInputSurfaceDeclined(err);
6773    }
6774}
6775
6776void ACodec::LoadedState::onStart() {
6777    ALOGV("onStart");
6778
6779    status_t err = mCodec->mOMXNode->sendCommand(OMX_CommandStateSet, OMX_StateIdle);
6780    if (err != OK) {
6781        mCodec->signalError(OMX_ErrorUndefined, makeNoSideEffectStatus(err));
6782    } else {
6783        mCodec->changeState(mCodec->mLoadedToIdleState);
6784    }
6785}
6786
6787////////////////////////////////////////////////////////////////////////////////
6788
6789ACodec::LoadedToIdleState::LoadedToIdleState(ACodec *codec)
6790    : BaseState(codec) {
6791}
6792
6793void ACodec::LoadedToIdleState::stateEntered() {
6794    ALOGV("[%s] Now Loaded->Idle", mCodec->mComponentName.c_str());
6795
6796    status_t err;
6797    if ((err = allocateBuffers()) != OK) {
6798        ALOGE("Failed to allocate buffers after transitioning to IDLE state "
6799             "(error 0x%08x)",
6800             err);
6801
6802        mCodec->signalError(OMX_ErrorUndefined, makeNoSideEffectStatus(err));
6803
6804        mCodec->mOMXNode->sendCommand(
6805                OMX_CommandStateSet, OMX_StateLoaded);
6806        if (mCodec->allYourBuffersAreBelongToUs(kPortIndexInput)) {
6807            mCodec->freeBuffersOnPort(kPortIndexInput);
6808        }
6809        if (mCodec->allYourBuffersAreBelongToUs(kPortIndexOutput)) {
6810            mCodec->freeBuffersOnPort(kPortIndexOutput);
6811        }
6812
6813        mCodec->changeState(mCodec->mLoadedState);
6814    }
6815}
6816
6817status_t ACodec::LoadedToIdleState::allocateBuffers() {
6818    status_t err = mCodec->allocateBuffersOnPort(kPortIndexInput);
6819    if (err != OK) {
6820        return err;
6821    }
6822
6823    err = mCodec->allocateBuffersOnPort(kPortIndexOutput);
6824    if (err != OK) {
6825        return err;
6826    }
6827
6828    mCodec->mCallback->onStartCompleted();
6829
6830    return OK;
6831}
6832
6833bool ACodec::LoadedToIdleState::onMessageReceived(const sp<AMessage> &msg) {
6834    switch (msg->what()) {
6835        case kWhatSetParameters:
6836        case kWhatShutdown:
6837        {
6838            mCodec->deferMessage(msg);
6839            return true;
6840        }
6841
6842        case kWhatSignalEndOfInputStream:
6843        {
6844            mCodec->onSignalEndOfInputStream();
6845            return true;
6846        }
6847
6848        case kWhatResume:
6849        {
6850            // We'll be active soon enough.
6851            return true;
6852        }
6853
6854        case kWhatFlush:
6855        {
6856            // We haven't even started yet, so we're flushed alright...
6857            mCodec->mCallback->onFlushCompleted();
6858            return true;
6859        }
6860
6861        default:
6862            return BaseState::onMessageReceived(msg);
6863    }
6864}
6865
6866bool ACodec::LoadedToIdleState::onOMXEvent(
6867        OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2) {
6868    switch (event) {
6869        case OMX_EventCmdComplete:
6870        {
6871            status_t err = OK;
6872            if (data1 != (OMX_U32)OMX_CommandStateSet
6873                    || data2 != (OMX_U32)OMX_StateIdle) {
6874                ALOGE("Unexpected command completion in LoadedToIdleState: %s(%u) %s(%u)",
6875                        asString((OMX_COMMANDTYPE)data1), data1,
6876                        asString((OMX_STATETYPE)data2), data2);
6877                err = FAILED_TRANSACTION;
6878            }
6879
6880            if (err == OK) {
6881                err = mCodec->mOMXNode->sendCommand(
6882                    OMX_CommandStateSet, OMX_StateExecuting);
6883            }
6884
6885            if (err != OK) {
6886                mCodec->signalError(OMX_ErrorUndefined, makeNoSideEffectStatus(err));
6887            } else {
6888                mCodec->changeState(mCodec->mIdleToExecutingState);
6889            }
6890
6891            return true;
6892        }
6893
6894        default:
6895            return BaseState::onOMXEvent(event, data1, data2);
6896    }
6897}
6898
6899////////////////////////////////////////////////////////////////////////////////
6900
6901ACodec::IdleToExecutingState::IdleToExecutingState(ACodec *codec)
6902    : BaseState(codec) {
6903}
6904
6905void ACodec::IdleToExecutingState::stateEntered() {
6906    ALOGV("[%s] Now Idle->Executing", mCodec->mComponentName.c_str());
6907}
6908
6909bool ACodec::IdleToExecutingState::onMessageReceived(const sp<AMessage> &msg) {
6910    switch (msg->what()) {
6911        case kWhatSetParameters:
6912        case kWhatShutdown:
6913        {
6914            mCodec->deferMessage(msg);
6915            return true;
6916        }
6917
6918        case kWhatResume:
6919        {
6920            // We'll be active soon enough.
6921            return true;
6922        }
6923
6924        case kWhatFlush:
6925        {
6926            // We haven't even started yet, so we're flushed alright...
6927            mCodec->mCallback->onFlushCompleted();
6928            return true;
6929        }
6930
6931        case kWhatSignalEndOfInputStream:
6932        {
6933            mCodec->onSignalEndOfInputStream();
6934            return true;
6935        }
6936
6937        default:
6938            return BaseState::onMessageReceived(msg);
6939    }
6940}
6941
6942bool ACodec::IdleToExecutingState::onOMXEvent(
6943        OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2) {
6944    switch (event) {
6945        case OMX_EventCmdComplete:
6946        {
6947            if (data1 != (OMX_U32)OMX_CommandStateSet
6948                    || data2 != (OMX_U32)OMX_StateExecuting) {
6949                ALOGE("Unexpected command completion in IdleToExecutingState: %s(%u) %s(%u)",
6950                        asString((OMX_COMMANDTYPE)data1), data1,
6951                        asString((OMX_STATETYPE)data2), data2);
6952                mCodec->signalError(OMX_ErrorUndefined, FAILED_TRANSACTION);
6953                return true;
6954            }
6955
6956            mCodec->mExecutingState->resume();
6957            mCodec->changeState(mCodec->mExecutingState);
6958
6959            return true;
6960        }
6961
6962        default:
6963            return BaseState::onOMXEvent(event, data1, data2);
6964    }
6965}
6966
6967////////////////////////////////////////////////////////////////////////////////
6968
6969ACodec::ExecutingState::ExecutingState(ACodec *codec)
6970    : BaseState(codec),
6971      mActive(false) {
6972}
6973
6974ACodec::BaseState::PortMode ACodec::ExecutingState::getPortMode(
6975        OMX_U32 /* portIndex */) {
6976    return RESUBMIT_BUFFERS;
6977}
6978
6979void ACodec::ExecutingState::submitOutputMetaBuffers() {
6980    // submit as many buffers as there are input buffers with the codec
6981    // in case we are in port reconfiguring
6982    for (size_t i = 0; i < mCodec->mBuffers[kPortIndexInput].size(); ++i) {
6983        BufferInfo *info = &mCodec->mBuffers[kPortIndexInput].editItemAt(i);
6984
6985        if (info->mStatus == BufferInfo::OWNED_BY_COMPONENT) {
6986            if (mCodec->submitOutputMetadataBuffer() != OK)
6987                break;
6988        }
6989    }
6990
6991    // *** NOTE: THE FOLLOWING WORKAROUND WILL BE REMOVED ***
6992    mCodec->signalSubmitOutputMetadataBufferIfEOS_workaround();
6993}
6994
6995void ACodec::ExecutingState::submitRegularOutputBuffers() {
6996    bool failed = false;
6997    for (size_t i = 0; i < mCodec->mBuffers[kPortIndexOutput].size(); ++i) {
6998        BufferInfo *info = &mCodec->mBuffers[kPortIndexOutput].editItemAt(i);
6999
7000        if (mCodec->mNativeWindow != NULL) {
7001            if (info->mStatus != BufferInfo::OWNED_BY_US
7002                    && info->mStatus != BufferInfo::OWNED_BY_NATIVE_WINDOW) {
7003                ALOGE("buffers should be owned by us or the surface");
7004                failed = true;
7005                break;
7006            }
7007
7008            if (info->mStatus == BufferInfo::OWNED_BY_NATIVE_WINDOW) {
7009                continue;
7010            }
7011        } else {
7012            if (info->mStatus != BufferInfo::OWNED_BY_US) {
7013                ALOGE("buffers should be owned by us");
7014                failed = true;
7015                break;
7016            }
7017        }
7018
7019        ALOGV("[%s] calling fillBuffer %u", mCodec->mComponentName.c_str(), info->mBufferID);
7020
7021        info->checkWriteFence("submitRegularOutputBuffers");
7022        status_t err = mCodec->fillBuffer(info);
7023        if (err != OK) {
7024            failed = true;
7025            break;
7026        }
7027    }
7028
7029    if (failed) {
7030        mCodec->signalError(OMX_ErrorUndefined, FAILED_TRANSACTION);
7031    }
7032}
7033
7034void ACodec::ExecutingState::submitOutputBuffers() {
7035    submitRegularOutputBuffers();
7036    if (mCodec->storingMetadataInDecodedBuffers()) {
7037        submitOutputMetaBuffers();
7038    }
7039}
7040
7041void ACodec::ExecutingState::resume() {
7042    if (mActive) {
7043        ALOGV("[%s] We're already active, no need to resume.", mCodec->mComponentName.c_str());
7044        return;
7045    }
7046
7047    submitOutputBuffers();
7048
7049    // Post all available input buffers
7050    if (mCodec->mBuffers[kPortIndexInput].size() == 0u) {
7051        ALOGW("[%s] we don't have any input buffers to resume", mCodec->mComponentName.c_str());
7052    }
7053
7054    for (size_t i = 0; i < mCodec->mBuffers[kPortIndexInput].size(); i++) {
7055        BufferInfo *info = &mCodec->mBuffers[kPortIndexInput].editItemAt(i);
7056        if (info->mStatus == BufferInfo::OWNED_BY_US) {
7057            postFillThisBuffer(info);
7058        }
7059    }
7060
7061    mActive = true;
7062}
7063
7064void ACodec::ExecutingState::stateEntered() {
7065    ALOGV("[%s] Now Executing", mCodec->mComponentName.c_str());
7066    mCodec->mRenderTracker.clear(systemTime(CLOCK_MONOTONIC));
7067    mCodec->processDeferredMessages();
7068}
7069
7070bool ACodec::ExecutingState::onMessageReceived(const sp<AMessage> &msg) {
7071    bool handled = false;
7072
7073    switch (msg->what()) {
7074        case kWhatShutdown:
7075        {
7076            int32_t keepComponentAllocated;
7077            CHECK(msg->findInt32(
7078                        "keepComponentAllocated", &keepComponentAllocated));
7079
7080            mCodec->mShutdownInProgress = true;
7081            mCodec->mExplicitShutdown = true;
7082            mCodec->mKeepComponentAllocated = keepComponentAllocated;
7083
7084            mActive = false;
7085
7086            status_t err = mCodec->mOMXNode->sendCommand(
7087                    OMX_CommandStateSet, OMX_StateIdle);
7088            if (err != OK) {
7089                if (keepComponentAllocated) {
7090                    mCodec->signalError(OMX_ErrorUndefined, FAILED_TRANSACTION);
7091                }
7092                // TODO: do some recovery here.
7093            } else {
7094                mCodec->changeState(mCodec->mExecutingToIdleState);
7095            }
7096
7097            handled = true;
7098            break;
7099        }
7100
7101        case kWhatFlush:
7102        {
7103            ALOGV("[%s] ExecutingState flushing now "
7104                 "(codec owns %zu/%zu input, %zu/%zu output).",
7105                    mCodec->mComponentName.c_str(),
7106                    mCodec->countBuffersOwnedByComponent(kPortIndexInput),
7107                    mCodec->mBuffers[kPortIndexInput].size(),
7108                    mCodec->countBuffersOwnedByComponent(kPortIndexOutput),
7109                    mCodec->mBuffers[kPortIndexOutput].size());
7110
7111            mActive = false;
7112
7113            status_t err = mCodec->mOMXNode->sendCommand(OMX_CommandFlush, OMX_ALL);
7114            if (err != OK) {
7115                mCodec->signalError(OMX_ErrorUndefined, FAILED_TRANSACTION);
7116            } else {
7117                mCodec->changeState(mCodec->mFlushingState);
7118            }
7119
7120            handled = true;
7121            break;
7122        }
7123
7124        case kWhatResume:
7125        {
7126            resume();
7127
7128            handled = true;
7129            break;
7130        }
7131
7132        case kWhatRequestIDRFrame:
7133        {
7134            status_t err = mCodec->requestIDRFrame();
7135            if (err != OK) {
7136                ALOGW("Requesting an IDR frame failed.");
7137            }
7138
7139            handled = true;
7140            break;
7141        }
7142
7143        case kWhatSetParameters:
7144        {
7145            sp<AMessage> params;
7146            CHECK(msg->findMessage("params", &params));
7147
7148            status_t err = mCodec->setParameters(params);
7149
7150            sp<AMessage> reply;
7151            if (msg->findMessage("reply", &reply)) {
7152                reply->setInt32("err", err);
7153                reply->post();
7154            }
7155
7156            handled = true;
7157            break;
7158        }
7159
7160        case ACodec::kWhatSignalEndOfInputStream:
7161        {
7162            mCodec->onSignalEndOfInputStream();
7163            handled = true;
7164            break;
7165        }
7166
7167        // *** NOTE: THE FOLLOWING WORKAROUND WILL BE REMOVED ***
7168        case kWhatSubmitOutputMetadataBufferIfEOS:
7169        {
7170            if (mCodec->mPortEOS[kPortIndexInput] &&
7171                    !mCodec->mPortEOS[kPortIndexOutput]) {
7172                status_t err = mCodec->submitOutputMetadataBuffer();
7173                if (err == OK) {
7174                    mCodec->signalSubmitOutputMetadataBufferIfEOS_workaround();
7175                }
7176            }
7177            return true;
7178        }
7179
7180        default:
7181            handled = BaseState::onMessageReceived(msg);
7182            break;
7183    }
7184
7185    return handled;
7186}
7187
7188status_t ACodec::setParameters(const sp<AMessage> &params) {
7189    int32_t videoBitrate;
7190    if (params->findInt32("video-bitrate", &videoBitrate)) {
7191        OMX_VIDEO_CONFIG_BITRATETYPE configParams;
7192        InitOMXParams(&configParams);
7193        configParams.nPortIndex = kPortIndexOutput;
7194        configParams.nEncodeBitrate = videoBitrate;
7195
7196        status_t err = mOMXNode->setConfig(
7197                OMX_IndexConfigVideoBitrate,
7198                &configParams,
7199                sizeof(configParams));
7200
7201        if (err != OK) {
7202            ALOGE("setConfig(OMX_IndexConfigVideoBitrate, %d) failed w/ err %d",
7203                   videoBitrate, err);
7204
7205            return err;
7206        }
7207    }
7208
7209    int64_t timeOffsetUs;
7210    if (params->findInt64("time-offset-us", &timeOffsetUs)) {
7211        if (mGraphicBufferSource == NULL) {
7212            ALOGE("[%s] Invalid to set input buffer time offset without surface",
7213                    mComponentName.c_str());
7214            return INVALID_OPERATION;
7215        }
7216
7217        status_t err = statusFromBinderStatus(
7218                mGraphicBufferSource->setTimeOffsetUs(timeOffsetUs));
7219
7220        if (err != OK) {
7221            ALOGE("[%s] Unable to set input buffer time offset (err %d)",
7222                mComponentName.c_str(),
7223                err);
7224            return err;
7225        }
7226    }
7227
7228    int64_t skipFramesBeforeUs;
7229    if (params->findInt64("skip-frames-before", &skipFramesBeforeUs)) {
7230        if (mGraphicBufferSource == NULL) {
7231            ALOGE("[%s] Invalid to set start time without surface",
7232                    mComponentName.c_str());
7233            return INVALID_OPERATION;
7234        }
7235
7236        status_t err = statusFromBinderStatus(
7237                mGraphicBufferSource->setStartTimeUs(skipFramesBeforeUs));
7238
7239        if (err != OK) {
7240            ALOGE("Failed to set parameter 'skip-frames-before' (err %d)", err);
7241            return err;
7242        }
7243    }
7244
7245    int32_t dropInputFrames;
7246    if (params->findInt32("drop-input-frames", &dropInputFrames)) {
7247        if (mGraphicBufferSource == NULL) {
7248            ALOGE("[%s] Invalid to set suspend without surface",
7249                    mComponentName.c_str());
7250            return INVALID_OPERATION;
7251        }
7252
7253        int64_t suspendStartTimeUs = -1;
7254        (void) params->findInt64("drop-start-time-us", &suspendStartTimeUs);
7255        status_t err = statusFromBinderStatus(
7256                mGraphicBufferSource->setSuspend(dropInputFrames != 0, suspendStartTimeUs));
7257
7258        if (err != OK) {
7259            ALOGE("Failed to set parameter 'drop-input-frames' (err %d)", err);
7260            return err;
7261        }
7262    }
7263
7264    int64_t stopTimeUs;
7265    if (params->findInt64("stop-time-us", &stopTimeUs)) {
7266        if (mGraphicBufferSource == NULL) {
7267            ALOGE("[%s] Invalid to set stop time without surface",
7268                    mComponentName.c_str());
7269            return INVALID_OPERATION;
7270        }
7271        status_t err = statusFromBinderStatus(
7272                mGraphicBufferSource->setStopTimeUs(stopTimeUs));
7273
7274        if (err != OK) {
7275            ALOGE("Failed to set parameter 'stop-time-us' (err %d)", err);
7276            return err;
7277        }
7278
7279        int64_t stopTimeOffsetUs;
7280        err = statusFromBinderStatus(
7281                mGraphicBufferSource->getStopTimeOffsetUs(&stopTimeOffsetUs));
7282
7283        if (err != OK) {
7284            ALOGE("Failed to get stop time offset (err %d)", err);
7285            return err;
7286        }
7287        mInputFormat->setInt64("android._stop-time-offset-us", stopTimeOffsetUs);
7288    }
7289
7290    int32_t dummy;
7291    if (params->findInt32("request-sync", &dummy)) {
7292        status_t err = requestIDRFrame();
7293
7294        if (err != OK) {
7295            ALOGE("Requesting a sync frame failed w/ err %d", err);
7296            return err;
7297        }
7298    }
7299
7300    float rate;
7301    if (params->findFloat("operating-rate", &rate) && rate > 0) {
7302        status_t err = setOperatingRate(rate, mIsVideo);
7303        if (err != OK) {
7304            ALOGE("Failed to set parameter 'operating-rate' (err %d)", err);
7305            return err;
7306        }
7307    }
7308
7309    int32_t intraRefreshPeriod = 0;
7310    if (params->findInt32("intra-refresh-period", &intraRefreshPeriod)
7311            && intraRefreshPeriod > 0) {
7312        status_t err = setIntraRefreshPeriod(intraRefreshPeriod, false);
7313        if (err != OK) {
7314            ALOGI("[%s] failed setIntraRefreshPeriod. Failure is fine since this key is optional",
7315                    mComponentName.c_str());
7316            err = OK;
7317        }
7318    }
7319
7320    int32_t latency = 0;
7321    if (params->findInt32("latency", &latency) && latency > 0) {
7322        status_t err = setLatency(latency);
7323        if (err != OK) {
7324            ALOGI("[%s] failed setLatency. Failure is fine since this key is optional",
7325                    mComponentName.c_str());
7326            err = OK;
7327        }
7328    }
7329
7330    status_t err = configureTemporalLayers(params, false /* inConfigure */, mOutputFormat);
7331    if (err != OK) {
7332        err = OK; // ignore failure
7333    }
7334
7335    return setVendorParameters(params);
7336}
7337
7338// Removes trailing tags matching |tag| from |key| (e.g. a settings name). |minLength| specifies
7339// the minimum number of characters to keep in |key| (even if it has trailing tags).
7340// (Used to remove trailing 'value' tags in settings names, e.g. to normalize
7341// 'vendor.settingsX.value' to 'vendor.settingsX')
7342static void removeTrailingTags(char *key, size_t minLength, const char *tag) {
7343    size_t length = strlen(key);
7344    size_t tagLength = strlen(tag);
7345    while (length > minLength + tagLength
7346            && !strcmp(key + length - tagLength, tag)
7347            && key[length - tagLength - 1] == '.') {
7348        length -= tagLength + 1;
7349        key[length] = '\0';
7350    }
7351}
7352
7353/**
7354 * Struct encompassing a vendor extension config structure and a potential error status (in case
7355 * the structure is null). Used to iterate through vendor extensions.
7356 */
7357struct VendorExtension {
7358    OMX_CONFIG_ANDROID_VENDOR_EXTENSIONTYPE *config;  // structure does not own config
7359    status_t status;
7360
7361    // create based on an error status
7362    VendorExtension(status_t s_ = NO_INIT) : config(nullptr), status(s_) { }
7363
7364    // create based on a successfully retrieved config structure
7365    VendorExtension(OMX_CONFIG_ANDROID_VENDOR_EXTENSIONTYPE *c_) : config(c_), status(OK) { }
7366};
7367
7368// class VendorExtensions;
7369/**
7370 * Forward iterator to enumerate vendor extensions supported by an OMX component.
7371 */
7372class VendorExtensionIterator {
7373//private:
7374    static constexpr size_t kLastIndex = ~(size_t)0; // last index marker
7375
7376    sp<IOMXNode> mNode;                   // component
7377    size_t mIndex;                        // current android extension index
7378    std::unique_ptr<uint8_t[]> mBacking;  // current extension's backing
7379    VendorExtension mCurrent;             // current extension
7380
7381    VendorExtensionIterator(const sp<IOMXNode> &node, size_t index)
7382        : mNode(node),
7383          mIndex(index) {
7384        mCurrent = retrieve();
7385    }
7386
7387    friend class VendorExtensions;
7388
7389public:
7390    // copy constructor
7391    VendorExtensionIterator(const VendorExtensionIterator &it)
7392        : VendorExtensionIterator(it.mNode, it.mIndex) { }
7393
7394    // retrieves the current extension pointed to by this iterator
7395    VendorExtension retrieve() {
7396        if (mIndex == kLastIndex) {
7397            return NO_INIT;
7398        }
7399
7400        // try with one param first, then retry if extension needs more than 1 param
7401        for (size_t paramSizeUsed = 1;; ) {
7402            if (paramSizeUsed > OMX_MAX_ANDROID_VENDOR_PARAMCOUNT) {
7403                return BAD_VALUE; // this prevents overflow in the following formula
7404            }
7405
7406            size_t size = sizeof(OMX_CONFIG_ANDROID_VENDOR_EXTENSIONTYPE) +
7407                (paramSizeUsed - 1) * sizeof(OMX_CONFIG_ANDROID_VENDOR_EXTENSIONTYPE::param);
7408            mBacking.reset(new uint8_t[size]);
7409            if (!mBacking) {
7410                return NO_MEMORY;
7411            }
7412
7413            OMX_CONFIG_ANDROID_VENDOR_EXTENSIONTYPE *config =
7414                reinterpret_cast<OMX_CONFIG_ANDROID_VENDOR_EXTENSIONTYPE *>(mBacking.get());
7415
7416            InitOMXParams(config);
7417            config->nSize = size;
7418            config->nIndex = mIndex;
7419            config->nParamSizeUsed = paramSizeUsed;
7420            status_t err = mNode->getConfig(
7421                    (OMX_INDEXTYPE)OMX_IndexConfigAndroidVendorExtension, config, size);
7422            if (err == OK && config->nParamCount > paramSizeUsed && paramSizeUsed == 1) {
7423                // reallocate if we need a bigger config
7424                paramSizeUsed = config->nParamCount;
7425                continue;
7426            } else if (err == NOT_ENOUGH_DATA
7427                   || (err != OK && mIndex == 0)) {
7428                // stop iterator on no-more signal, or if index is not at all supported
7429                mIndex = kLastIndex;
7430                return NO_INIT;
7431            } else if (err != OK) {
7432                return err;
7433            } else if (paramSizeUsed != config->nParamSizeUsed) {
7434                return BAD_VALUE; // component shall not modify size of nParam
7435            }
7436
7437            return config;
7438        }
7439    }
7440
7441    // returns extension pointed to by this iterator
7442    VendorExtension operator*() {
7443        return mCurrent;
7444    }
7445
7446    // prefix increment: move to next extension
7447    VendorExtensionIterator &operator++() { // prefix
7448        if (mIndex != kLastIndex) {
7449            ++mIndex;
7450            mCurrent = retrieve();
7451        }
7452        return *this;
7453    }
7454
7455    // iterator equality operators
7456    bool operator==(const VendorExtensionIterator &o) {
7457        return mNode == o.mNode && mIndex == o.mIndex;
7458    }
7459
7460    bool operator!=(const VendorExtensionIterator &o) {
7461        return !(*this == o);
7462    }
7463};
7464
7465/**
7466 * Iterable container for vendor extensions provided by a component
7467 */
7468class VendorExtensions {
7469//private:
7470    sp<IOMXNode> mNode;
7471
7472public:
7473    VendorExtensions(const sp<IOMXNode> &node)
7474        : mNode(node) {
7475    }
7476
7477    VendorExtensionIterator begin() {
7478        return VendorExtensionIterator(mNode, 0);
7479    }
7480
7481    VendorExtensionIterator end() {
7482        return VendorExtensionIterator(mNode, VendorExtensionIterator::kLastIndex);
7483    }
7484};
7485
7486status_t ACodec::setVendorParameters(const sp<AMessage> &params) {
7487    std::map<std::string, std::string> vendorKeys; // maps reduced name to actual name
7488    constexpr char prefix[] = "vendor.";
7489    constexpr size_t prefixLength = sizeof(prefix) - 1;
7490    // longest possible vendor param name
7491    char reducedKey[OMX_MAX_STRINGNAME_SIZE + OMX_MAX_STRINGVALUE_SIZE];
7492
7493    // identify all vendor keys to speed up search later and to detect vendor keys
7494    for (size_t i = params->countEntries(); i; --i) {
7495        AMessage::Type keyType;
7496        const char* key = params->getEntryNameAt(i - 1, &keyType);
7497        if (key != nullptr && !strncmp(key, prefix, prefixLength)
7498                // it is safe to limit format keys to the max vendor param size as we only
7499                // shorten parameter names by removing any trailing 'value' tags, and we
7500                // already remove the vendor prefix.
7501                && strlen(key + prefixLength) < sizeof(reducedKey)
7502                && (keyType == AMessage::kTypeInt32
7503                        || keyType == AMessage::kTypeInt64
7504                        || keyType == AMessage::kTypeString)) {
7505            strcpy(reducedKey, key + prefixLength);
7506            removeTrailingTags(reducedKey, 0, "value");
7507            auto existingKey = vendorKeys.find(reducedKey);
7508            if (existingKey != vendorKeys.end()) {
7509                ALOGW("[%s] vendor parameter '%s' aliases parameter '%s'",
7510                        mComponentName.c_str(), key, existingKey->second.c_str());
7511                // ignore for now
7512            }
7513            vendorKeys.emplace(reducedKey, key);
7514        }
7515    }
7516
7517    // don't bother component if we don't have vendor extensions as they may not have implemented
7518    // the android vendor extension support, which will lead to unnecessary OMX failure logs.
7519    if (vendorKeys.empty()) {
7520        return OK;
7521    }
7522
7523    char key[sizeof(OMX_CONFIG_ANDROID_VENDOR_EXTENSIONTYPE::cName) +
7524            sizeof(OMX_CONFIG_ANDROID_VENDOR_PARAMTYPE::cKey)];
7525
7526    status_t finalError = OK;
7527
7528    // don't try again if component does not have vendor extensions
7529    if (mVendorExtensionsStatus == kExtensionsNone) {
7530        return OK;
7531    }
7532
7533    for (VendorExtension ext : VendorExtensions(mOMXNode)) {
7534        OMX_CONFIG_ANDROID_VENDOR_EXTENSIONTYPE *config = ext.config;
7535        if (config == nullptr) {
7536            return ext.status;
7537        }
7538
7539        mVendorExtensionsStatus = kExtensionsExist;
7540
7541        config->cName[sizeof(config->cName) - 1] = '\0'; // null-terminate name
7542        strcpy(key, (const char *)config->cName);
7543        size_t nameLength = strlen(key);
7544        key[nameLength] = '.';
7545
7546        // don't set vendor extension if client has not provided any of its parameters
7547        // or if client simply unsets parameters that are already unset
7548        bool needToSet = false;
7549        for (size_t paramIndex = 0; paramIndex < config->nParamCount; ++paramIndex) {
7550            // null-terminate param key
7551            config->param[paramIndex].cKey[sizeof(config->param[0].cKey) - 1] = '\0';
7552            strcpy(key + nameLength + 1, (const char *)config->param[paramIndex].cKey);
7553            removeTrailingTags(key, nameLength, "value");
7554            auto existingKey = vendorKeys.find(key);
7555
7556            // don't touch (e.g. change) parameters that are not specified by client
7557            if (existingKey == vendorKeys.end()) {
7558                continue;
7559            }
7560
7561            bool wasSet = config->param[paramIndex].bSet;
7562            switch (config->param[paramIndex].eValueType) {
7563            case OMX_AndroidVendorValueInt32:
7564            {
7565                int32_t value;
7566                config->param[paramIndex].bSet =
7567                    (OMX_BOOL)params->findInt32(existingKey->second.c_str(), &value);
7568                if (config->param[paramIndex].bSet) {
7569                    config->param[paramIndex].nInt32 = value;
7570                }
7571                break;
7572            }
7573            case OMX_AndroidVendorValueInt64:
7574            {
7575                int64_t value;
7576                config->param[paramIndex].bSet =
7577                    (OMX_BOOL)params->findAsInt64(existingKey->second.c_str(), &value);
7578                if (config->param[paramIndex].bSet) {
7579                    config->param[paramIndex].nInt64 = value;
7580                }
7581                break;
7582            }
7583            case OMX_AndroidVendorValueString:
7584            {
7585                AString value;
7586                config->param[paramIndex].bSet =
7587                    (OMX_BOOL)params->findString(existingKey->second.c_str(), &value);
7588                if (config->param[paramIndex].bSet) {
7589                    strncpy((char *)config->param[paramIndex].cString, value.c_str(),
7590                            sizeof(OMX_CONFIG_ANDROID_VENDOR_PARAMTYPE::cString));
7591                }
7592                break;
7593            }
7594            default:
7595                ALOGW("[%s] vendor parameter '%s' is not a supported value",
7596                        mComponentName.c_str(), key);
7597                continue;
7598            }
7599            if (config->param[paramIndex].bSet || wasSet) {
7600                needToSet = true;
7601            }
7602        }
7603
7604        if (needToSet) {
7605            status_t err = mOMXNode->setConfig(
7606                    (OMX_INDEXTYPE)OMX_IndexConfigAndroidVendorExtension,
7607                    config, config->nSize);
7608            if (err != OK) {
7609                key[nameLength] = '\0';
7610                ALOGW("[%s] failed to set vendor extension '%s'", mComponentName.c_str(), key);
7611                // try to set each extension, and return first failure
7612                if (finalError == OK) {
7613                    finalError = err;
7614                }
7615            }
7616        }
7617    }
7618
7619    if (mVendorExtensionsStatus == kExtensionsUnchecked) {
7620        mVendorExtensionsStatus = kExtensionsNone;
7621    }
7622
7623    return finalError;
7624}
7625
7626status_t ACodec::getVendorParameters(OMX_U32 portIndex, sp<AMessage> &format) {
7627    constexpr char prefix[] = "vendor.";
7628    constexpr size_t prefixLength = sizeof(prefix) - 1;
7629    char key[sizeof(OMX_CONFIG_ANDROID_VENDOR_EXTENSIONTYPE::cName) +
7630            sizeof(OMX_CONFIG_ANDROID_VENDOR_PARAMTYPE::cKey) + prefixLength];
7631    strcpy(key, prefix);
7632
7633    // don't try again if component does not have vendor extensions
7634    if (mVendorExtensionsStatus == kExtensionsNone) {
7635        return OK;
7636    }
7637
7638    for (VendorExtension ext : VendorExtensions(mOMXNode)) {
7639        OMX_CONFIG_ANDROID_VENDOR_EXTENSIONTYPE *config = ext.config;
7640        if (config == nullptr) {
7641            return ext.status;
7642        }
7643
7644        mVendorExtensionsStatus = kExtensionsExist;
7645
7646        if (config->eDir != (portIndex == kPortIndexInput ? OMX_DirInput : OMX_DirOutput)) {
7647            continue;
7648        }
7649
7650        config->cName[sizeof(config->cName) - 1] = '\0'; // null-terminate name
7651        strcpy(key + prefixLength, (const char *)config->cName);
7652        size_t nameLength = strlen(key);
7653        key[nameLength] = '.';
7654
7655        for (size_t paramIndex = 0; paramIndex < config->nParamCount; ++paramIndex) {
7656            // null-terminate param key
7657            config->param[paramIndex].cKey[sizeof(config->param[0].cKey) - 1] = '\0';
7658            strcpy(key + nameLength + 1, (const char *)config->param[paramIndex].cKey);
7659            removeTrailingTags(key, nameLength, "value");
7660            if (config->param[paramIndex].bSet) {
7661                switch (config->param[paramIndex].eValueType) {
7662                case OMX_AndroidVendorValueInt32:
7663                {
7664                    format->setInt32(key, config->param[paramIndex].nInt32);
7665                    break;
7666                }
7667                case OMX_AndroidVendorValueInt64:
7668                {
7669                    format->setInt64(key, config->param[paramIndex].nInt64);
7670                    break;
7671                }
7672                case OMX_AndroidVendorValueString:
7673                {
7674                    config->param[paramIndex].cString[OMX_MAX_STRINGVALUE_SIZE - 1] = '\0';
7675                    format->setString(key, (const char *)config->param[paramIndex].cString);
7676                    break;
7677                }
7678                default:
7679                    ALOGW("vendor parameter %s is not a supported value", key);
7680                    continue;
7681                }
7682            }
7683        }
7684    }
7685
7686    if (mVendorExtensionsStatus == kExtensionsUnchecked) {
7687        mVendorExtensionsStatus = kExtensionsNone;
7688    }
7689
7690    return OK;
7691}
7692
7693void ACodec::onSignalEndOfInputStream() {
7694    status_t err = INVALID_OPERATION;
7695    if (mGraphicBufferSource != NULL) {
7696        err = statusFromBinderStatus(mGraphicBufferSource->signalEndOfInputStream());
7697    }
7698    mCallback->onSignaledInputEOS(err);
7699}
7700
7701void ACodec::forceStateTransition(int generation) {
7702    if (generation != mStateGeneration) {
7703        ALOGV("Ignoring stale force state transition message: #%d (now #%d)",
7704                generation, mStateGeneration);
7705        return;
7706    }
7707    ALOGE("State machine stuck");
7708    // Error must have already been signalled to the client.
7709
7710    // Deferred messages will be handled at LoadedState at the end of the
7711    // transition.
7712    mShutdownInProgress = true;
7713    // No shutdown complete callback at the end of the transition.
7714    mExplicitShutdown = false;
7715    mKeepComponentAllocated = true;
7716
7717    status_t err = mOMXNode->sendCommand(OMX_CommandStateSet, OMX_StateIdle);
7718    if (err != OK) {
7719        // TODO: do some recovery here.
7720    } else {
7721        changeState(mExecutingToIdleState);
7722    }
7723}
7724
7725bool ACodec::ExecutingState::onOMXFrameRendered(int64_t mediaTimeUs, nsecs_t systemNano) {
7726    mCodec->onFrameRendered(mediaTimeUs, systemNano);
7727    return true;
7728}
7729
7730bool ACodec::ExecutingState::onOMXEvent(
7731        OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2) {
7732    switch (event) {
7733        case OMX_EventPortSettingsChanged:
7734        {
7735            CHECK_EQ(data1, (OMX_U32)kPortIndexOutput);
7736
7737            mCodec->onOutputFormatChanged();
7738
7739            if (data2 == 0 || data2 == OMX_IndexParamPortDefinition) {
7740                mCodec->mMetadataBuffersToSubmit = 0;
7741                CHECK_EQ(mCodec->mOMXNode->sendCommand(
7742                            OMX_CommandPortDisable, kPortIndexOutput),
7743                         (status_t)OK);
7744
7745                mCodec->freeOutputBuffersNotOwnedByComponent();
7746
7747                mCodec->changeState(mCodec->mOutputPortSettingsChangedState);
7748            } else if (data2 != OMX_IndexConfigCommonOutputCrop
7749                    && data2 != OMX_IndexConfigAndroidIntraRefresh) {
7750                ALOGV("[%s] OMX_EventPortSettingsChanged 0x%08x",
7751                     mCodec->mComponentName.c_str(), data2);
7752            }
7753
7754            return true;
7755        }
7756
7757        case OMX_EventBufferFlag:
7758        {
7759            return true;
7760        }
7761
7762        default:
7763            return BaseState::onOMXEvent(event, data1, data2);
7764    }
7765}
7766
7767////////////////////////////////////////////////////////////////////////////////
7768
7769ACodec::OutputPortSettingsChangedState::OutputPortSettingsChangedState(
7770        ACodec *codec)
7771    : BaseState(codec) {
7772}
7773
7774ACodec::BaseState::PortMode ACodec::OutputPortSettingsChangedState::getPortMode(
7775        OMX_U32 portIndex) {
7776    if (portIndex == kPortIndexOutput) {
7777        return FREE_BUFFERS;
7778    }
7779
7780    CHECK_EQ(portIndex, (OMX_U32)kPortIndexInput);
7781
7782    return RESUBMIT_BUFFERS;
7783}
7784
7785bool ACodec::OutputPortSettingsChangedState::onMessageReceived(
7786        const sp<AMessage> &msg) {
7787    bool handled = false;
7788
7789    switch (msg->what()) {
7790        case kWhatFlush:
7791        case kWhatShutdown: {
7792            if (mCodec->mFatalError) {
7793                sp<AMessage> msg = new AMessage(ACodec::kWhatForceStateTransition, mCodec);
7794                msg->setInt32("generation", mCodec->mStateGeneration);
7795                msg->post(3000000);
7796            }
7797            // fall-through
7798        }
7799        case kWhatResume:
7800        case kWhatSetParameters:
7801        {
7802            if (msg->what() == kWhatResume) {
7803                ALOGV("[%s] Deferring resume", mCodec->mComponentName.c_str());
7804            }
7805
7806            mCodec->deferMessage(msg);
7807            handled = true;
7808            break;
7809        }
7810
7811        case kWhatForceStateTransition:
7812        {
7813            int32_t generation = 0;
7814            CHECK(msg->findInt32("generation", &generation));
7815            mCodec->forceStateTransition(generation);
7816
7817            handled = true;
7818            break;
7819        }
7820
7821        default:
7822            handled = BaseState::onMessageReceived(msg);
7823            break;
7824    }
7825
7826    return handled;
7827}
7828
7829void ACodec::OutputPortSettingsChangedState::stateEntered() {
7830    ALOGV("[%s] Now handling output port settings change",
7831         mCodec->mComponentName.c_str());
7832}
7833
7834bool ACodec::OutputPortSettingsChangedState::onOMXFrameRendered(
7835        int64_t mediaTimeUs, nsecs_t systemNano) {
7836    mCodec->onFrameRendered(mediaTimeUs, systemNano);
7837    return true;
7838}
7839
7840bool ACodec::OutputPortSettingsChangedState::onOMXEvent(
7841        OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2) {
7842    switch (event) {
7843        case OMX_EventCmdComplete:
7844        {
7845            if (data1 == (OMX_U32)OMX_CommandPortDisable) {
7846                if (data2 != (OMX_U32)kPortIndexOutput) {
7847                    ALOGW("ignoring EventCmdComplete CommandPortDisable for port %u", data2);
7848                    return false;
7849                }
7850
7851                ALOGV("[%s] Output port now disabled.", mCodec->mComponentName.c_str());
7852
7853                status_t err = OK;
7854                if (!mCodec->mBuffers[kPortIndexOutput].isEmpty()) {
7855                    ALOGE("disabled port should be empty, but has %zu buffers",
7856                            mCodec->mBuffers[kPortIndexOutput].size());
7857                    err = FAILED_TRANSACTION;
7858                } else {
7859                    if (mCodec->getTrebleFlag()) {
7860                        mCodec->mAllocator[kPortIndexOutput].clear();
7861                    } else {
7862                        mCodec->mDealer[kPortIndexOutput].clear();
7863                    }
7864                }
7865
7866                if (err == OK) {
7867                    err = mCodec->mOMXNode->sendCommand(
7868                            OMX_CommandPortEnable, kPortIndexOutput);
7869                }
7870
7871                if (err == OK) {
7872                    err = mCodec->allocateBuffersOnPort(kPortIndexOutput);
7873                    ALOGE_IF(err != OK, "Failed to allocate output port buffers after port "
7874                            "reconfiguration: (%d)", err);
7875                    mCodec->mCallback->onOutputBuffersChanged();
7876                }
7877
7878                if (err != OK) {
7879                    mCodec->signalError(OMX_ErrorUndefined, makeNoSideEffectStatus(err));
7880                    ALOGE("Error occurred while disabling the output port");
7881                }
7882
7883                return true;
7884            } else if (data1 == (OMX_U32)OMX_CommandPortEnable) {
7885                if (data2 != (OMX_U32)kPortIndexOutput) {
7886                    ALOGW("ignoring EventCmdComplete OMX_CommandPortEnable for port %u", data2);
7887                    return false;
7888                }
7889
7890                ALOGV("[%s] Output port now reenabled.", mCodec->mComponentName.c_str());
7891
7892                if (mCodec->mExecutingState->active()) {
7893                    mCodec->mExecutingState->submitOutputBuffers();
7894                }
7895
7896                mCodec->changeState(mCodec->mExecutingState);
7897
7898                return true;
7899            }
7900
7901            return false;
7902        }
7903
7904        default:
7905            return BaseState::onOMXEvent(event, data1, data2);
7906    }
7907}
7908
7909////////////////////////////////////////////////////////////////////////////////
7910
7911ACodec::ExecutingToIdleState::ExecutingToIdleState(ACodec *codec)
7912    : BaseState(codec),
7913      mComponentNowIdle(false) {
7914}
7915
7916bool ACodec::ExecutingToIdleState::onMessageReceived(const sp<AMessage> &msg) {
7917    bool handled = false;
7918
7919    switch (msg->what()) {
7920        case kWhatFlush:
7921        {
7922            // Don't send me a flush request if you previously wanted me
7923            // to shutdown.
7924            ALOGW("Ignoring flush request in ExecutingToIdleState");
7925            break;
7926        }
7927
7928        case kWhatShutdown:
7929        {
7930            mCodec->deferMessage(msg);
7931            handled = true;
7932            break;
7933        }
7934
7935        default:
7936            handled = BaseState::onMessageReceived(msg);
7937            break;
7938    }
7939
7940    return handled;
7941}
7942
7943void ACodec::ExecutingToIdleState::stateEntered() {
7944    ALOGV("[%s] Now Executing->Idle", mCodec->mComponentName.c_str());
7945
7946    mComponentNowIdle = false;
7947    mCodec->mLastOutputFormat.clear();
7948}
7949
7950bool ACodec::ExecutingToIdleState::onOMXEvent(
7951        OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2) {
7952    switch (event) {
7953        case OMX_EventCmdComplete:
7954        {
7955            if (data1 != (OMX_U32)OMX_CommandStateSet
7956                    || data2 != (OMX_U32)OMX_StateIdle) {
7957                ALOGE("Unexpected command completion in ExecutingToIdleState: %s(%u) %s(%u)",
7958                        asString((OMX_COMMANDTYPE)data1), data1,
7959                        asString((OMX_STATETYPE)data2), data2);
7960                mCodec->signalError(OMX_ErrorUndefined, FAILED_TRANSACTION);
7961                return true;
7962            }
7963
7964            mComponentNowIdle = true;
7965
7966            changeStateIfWeOwnAllBuffers();
7967
7968            return true;
7969        }
7970
7971        case OMX_EventPortSettingsChanged:
7972        case OMX_EventBufferFlag:
7973        {
7974            // We're shutting down and don't care about this anymore.
7975            return true;
7976        }
7977
7978        default:
7979            return BaseState::onOMXEvent(event, data1, data2);
7980    }
7981}
7982
7983void ACodec::ExecutingToIdleState::changeStateIfWeOwnAllBuffers() {
7984    if (mComponentNowIdle && mCodec->allYourBuffersAreBelongToUs()) {
7985        status_t err = mCodec->mOMXNode->sendCommand(
7986                OMX_CommandStateSet, OMX_StateLoaded);
7987        if (err == OK) {
7988            err = mCodec->freeBuffersOnPort(kPortIndexInput);
7989            status_t err2 = mCodec->freeBuffersOnPort(kPortIndexOutput);
7990            if (err == OK) {
7991                err = err2;
7992            }
7993        }
7994
7995        if ((mCodec->mFlags & kFlagPushBlankBuffersToNativeWindowOnShutdown)
7996                && mCodec->mNativeWindow != NULL) {
7997            // We push enough 1x1 blank buffers to ensure that one of
7998            // them has made it to the display.  This allows the OMX
7999            // component teardown to zero out any protected buffers
8000            // without the risk of scanning out one of those buffers.
8001            pushBlankBuffersToNativeWindow(mCodec->mNativeWindow.get());
8002        }
8003
8004        if (err != OK) {
8005            mCodec->signalError(OMX_ErrorUndefined, FAILED_TRANSACTION);
8006            return;
8007        }
8008
8009        mCodec->changeState(mCodec->mIdleToLoadedState);
8010    }
8011}
8012
8013void ACodec::ExecutingToIdleState::onInputBufferFilled(
8014        const sp<AMessage> &msg) {
8015    BaseState::onInputBufferFilled(msg);
8016
8017    changeStateIfWeOwnAllBuffers();
8018}
8019
8020void ACodec::ExecutingToIdleState::onOutputBufferDrained(
8021        const sp<AMessage> &msg) {
8022    BaseState::onOutputBufferDrained(msg);
8023
8024    changeStateIfWeOwnAllBuffers();
8025}
8026
8027////////////////////////////////////////////////////////////////////////////////
8028
8029ACodec::IdleToLoadedState::IdleToLoadedState(ACodec *codec)
8030    : BaseState(codec) {
8031}
8032
8033bool ACodec::IdleToLoadedState::onMessageReceived(const sp<AMessage> &msg) {
8034    bool handled = false;
8035
8036    switch (msg->what()) {
8037        case kWhatShutdown:
8038        {
8039            mCodec->deferMessage(msg);
8040            handled = true;
8041            break;
8042        }
8043
8044        case kWhatFlush:
8045        {
8046            // Don't send me a flush request if you previously wanted me
8047            // to shutdown.
8048            ALOGE("Got flush request in IdleToLoadedState");
8049            break;
8050        }
8051
8052        default:
8053            handled = BaseState::onMessageReceived(msg);
8054            break;
8055    }
8056
8057    return handled;
8058}
8059
8060void ACodec::IdleToLoadedState::stateEntered() {
8061    ALOGV("[%s] Now Idle->Loaded", mCodec->mComponentName.c_str());
8062}
8063
8064bool ACodec::IdleToLoadedState::onOMXEvent(
8065        OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2) {
8066    switch (event) {
8067        case OMX_EventCmdComplete:
8068        {
8069            if (data1 != (OMX_U32)OMX_CommandStateSet
8070                    || data2 != (OMX_U32)OMX_StateLoaded) {
8071                ALOGE("Unexpected command completion in IdleToLoadedState: %s(%u) %s(%u)",
8072                        asString((OMX_COMMANDTYPE)data1), data1,
8073                        asString((OMX_STATETYPE)data2), data2);
8074                mCodec->signalError(OMX_ErrorUndefined, FAILED_TRANSACTION);
8075                return true;
8076            }
8077
8078            mCodec->changeState(mCodec->mLoadedState);
8079
8080            return true;
8081        }
8082
8083        default:
8084            return BaseState::onOMXEvent(event, data1, data2);
8085    }
8086}
8087
8088////////////////////////////////////////////////////////////////////////////////
8089
8090ACodec::FlushingState::FlushingState(ACodec *codec)
8091    : BaseState(codec) {
8092}
8093
8094void ACodec::FlushingState::stateEntered() {
8095    ALOGV("[%s] Now Flushing", mCodec->mComponentName.c_str());
8096
8097    mFlushComplete[kPortIndexInput] = mFlushComplete[kPortIndexOutput] = false;
8098}
8099
8100bool ACodec::FlushingState::onMessageReceived(const sp<AMessage> &msg) {
8101    bool handled = false;
8102
8103    switch (msg->what()) {
8104        case kWhatShutdown:
8105        {
8106            mCodec->deferMessage(msg);
8107            if (mCodec->mFatalError) {
8108                sp<AMessage> msg = new AMessage(ACodec::kWhatForceStateTransition, mCodec);
8109                msg->setInt32("generation", mCodec->mStateGeneration);
8110                msg->post(3000000);
8111            }
8112            break;
8113        }
8114
8115        case kWhatFlush:
8116        {
8117            // We're already doing this right now.
8118            handled = true;
8119            break;
8120        }
8121
8122        case kWhatForceStateTransition:
8123        {
8124            int32_t generation = 0;
8125            CHECK(msg->findInt32("generation", &generation));
8126            mCodec->forceStateTransition(generation);
8127
8128            handled = true;
8129            break;
8130        }
8131
8132        default:
8133            handled = BaseState::onMessageReceived(msg);
8134            break;
8135    }
8136
8137    return handled;
8138}
8139
8140bool ACodec::FlushingState::onOMXEvent(
8141        OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2) {
8142    ALOGV("[%s] FlushingState onOMXEvent(%u,%d)",
8143            mCodec->mComponentName.c_str(), event, (OMX_S32)data1);
8144
8145    switch (event) {
8146        case OMX_EventCmdComplete:
8147        {
8148            if (data1 != (OMX_U32)OMX_CommandFlush) {
8149                ALOGE("unexpected EventCmdComplete %s(%d) data2:%d in FlushingState",
8150                        asString((OMX_COMMANDTYPE)data1), data1, data2);
8151                mCodec->signalError(OMX_ErrorUndefined, FAILED_TRANSACTION);
8152                return true;
8153            }
8154
8155            if (data2 == kPortIndexInput || data2 == kPortIndexOutput) {
8156                if (mFlushComplete[data2]) {
8157                    ALOGW("Flush already completed for %s port",
8158                            data2 == kPortIndexInput ? "input" : "output");
8159                    return true;
8160                }
8161                mFlushComplete[data2] = true;
8162
8163                if (mFlushComplete[kPortIndexInput] && mFlushComplete[kPortIndexOutput]) {
8164                    changeStateIfWeOwnAllBuffers();
8165                }
8166            } else if (data2 == OMX_ALL) {
8167                if (!mFlushComplete[kPortIndexInput] || !mFlushComplete[kPortIndexOutput]) {
8168                    ALOGW("received flush complete event for OMX_ALL before ports have been"
8169                            "flushed (%d/%d)",
8170                            mFlushComplete[kPortIndexInput], mFlushComplete[kPortIndexOutput]);
8171                    return false;
8172                }
8173
8174                changeStateIfWeOwnAllBuffers();
8175            } else {
8176                ALOGW("data2 not OMX_ALL but %u in EventCmdComplete CommandFlush", data2);
8177            }
8178
8179            return true;
8180        }
8181
8182        case OMX_EventPortSettingsChanged:
8183        {
8184            sp<AMessage> msg = new AMessage(kWhatOMXMessage, mCodec);
8185            msg->setInt32("type", omx_message::EVENT);
8186            msg->setInt32("generation", mCodec->mNodeGeneration);
8187            msg->setInt32("event", event);
8188            msg->setInt32("data1", data1);
8189            msg->setInt32("data2", data2);
8190
8191            ALOGV("[%s] Deferring OMX_EventPortSettingsChanged",
8192                 mCodec->mComponentName.c_str());
8193
8194            mCodec->deferMessage(msg);
8195
8196            return true;
8197        }
8198
8199        default:
8200            return BaseState::onOMXEvent(event, data1, data2);
8201    }
8202
8203    return true;
8204}
8205
8206void ACodec::FlushingState::onOutputBufferDrained(const sp<AMessage> &msg) {
8207    BaseState::onOutputBufferDrained(msg);
8208
8209    changeStateIfWeOwnAllBuffers();
8210}
8211
8212void ACodec::FlushingState::onInputBufferFilled(const sp<AMessage> &msg) {
8213    BaseState::onInputBufferFilled(msg);
8214
8215    changeStateIfWeOwnAllBuffers();
8216}
8217
8218void ACodec::FlushingState::changeStateIfWeOwnAllBuffers() {
8219    if (mFlushComplete[kPortIndexInput]
8220            && mFlushComplete[kPortIndexOutput]
8221            && mCodec->allYourBuffersAreBelongToUs()) {
8222        // We now own all buffers except possibly those still queued with
8223        // the native window for rendering. Let's get those back as well.
8224        mCodec->waitUntilAllPossibleNativeWindowBuffersAreReturnedToUs();
8225
8226        mCodec->mRenderTracker.clear(systemTime(CLOCK_MONOTONIC));
8227
8228        mCodec->mCallback->onFlushCompleted();
8229
8230        mCodec->mPortEOS[kPortIndexInput] =
8231            mCodec->mPortEOS[kPortIndexOutput] = false;
8232
8233        mCodec->mInputEOSResult = OK;
8234
8235        if (mCodec->mSkipCutBuffer != NULL) {
8236            mCodec->mSkipCutBuffer->clear();
8237        }
8238
8239        mCodec->changeState(mCodec->mExecutingState);
8240    }
8241}
8242
8243status_t ACodec::queryCapabilities(
8244        const char* owner, const char* name, const char* mime, bool isEncoder,
8245        MediaCodecInfo::CapabilitiesWriter* caps) {
8246    const char *role = GetComponentRole(isEncoder, mime);
8247    if (role == NULL) {
8248        return BAD_VALUE;
8249    }
8250
8251    OMXClient client;
8252    status_t err = client.connect(owner);
8253    if (err != OK) {
8254        return err;
8255    }
8256
8257    sp<IOMX> omx = client.interface();
8258    sp<CodecObserver> observer = new CodecObserver;
8259    sp<IOMXNode> omxNode;
8260
8261    err = omx->allocateNode(name, observer, &omxNode);
8262    if (err != OK) {
8263        client.disconnect();
8264        return err;
8265    }
8266
8267    err = SetComponentRole(omxNode, role);
8268    if (err != OK) {
8269        omxNode->freeNode();
8270        client.disconnect();
8271        return err;
8272    }
8273
8274    bool isVideo = strncasecmp(mime, "video/", 6) == 0;
8275
8276    if (isVideo) {
8277        OMX_VIDEO_PARAM_PROFILELEVELTYPE param;
8278        InitOMXParams(&param);
8279        param.nPortIndex = isEncoder ? kPortIndexOutput : kPortIndexInput;
8280
8281        for (OMX_U32 index = 0; index <= kMaxIndicesToCheck; ++index) {
8282            param.nProfileIndex = index;
8283            status_t err = omxNode->getParameter(
8284                    OMX_IndexParamVideoProfileLevelQuerySupported,
8285                    &param, sizeof(param));
8286            if (err != OK) {
8287                break;
8288            }
8289            caps->addProfileLevel(param.eProfile, param.eLevel);
8290
8291            // AVC components may not list the constrained profiles explicitly, but
8292            // decoders that support a profile also support its constrained version.
8293            // Encoders must explicitly support constrained profiles.
8294            if (!isEncoder && strcasecmp(mime, MEDIA_MIMETYPE_VIDEO_AVC) == 0) {
8295                if (param.eProfile == OMX_VIDEO_AVCProfileHigh) {
8296                    caps->addProfileLevel(OMX_VIDEO_AVCProfileConstrainedHigh, param.eLevel);
8297                } else if (param.eProfile == OMX_VIDEO_AVCProfileBaseline) {
8298                    caps->addProfileLevel(OMX_VIDEO_AVCProfileConstrainedBaseline, param.eLevel);
8299                }
8300            }
8301
8302            if (index == kMaxIndicesToCheck) {
8303                ALOGW("[%s] stopping checking profiles after %u: %x/%x",
8304                        name, index,
8305                        param.eProfile, param.eLevel);
8306            }
8307        }
8308
8309        // Color format query
8310        // return colors in the order reported by the OMX component
8311        // prefix "flexible" standard ones with the flexible equivalent
8312        OMX_VIDEO_PARAM_PORTFORMATTYPE portFormat;
8313        InitOMXParams(&portFormat);
8314        portFormat.nPortIndex = isEncoder ? kPortIndexInput : kPortIndexOutput;
8315        for (OMX_U32 index = 0; index <= kMaxIndicesToCheck; ++index) {
8316            portFormat.nIndex = index;
8317            status_t err = omxNode->getParameter(
8318                    OMX_IndexParamVideoPortFormat,
8319                    &portFormat, sizeof(portFormat));
8320            if (err != OK) {
8321                break;
8322            }
8323
8324            OMX_U32 flexibleEquivalent;
8325            if (IsFlexibleColorFormat(
8326                    omxNode, portFormat.eColorFormat, false /* usingNativeWindow */,
8327                    &flexibleEquivalent)) {
8328                caps->addColorFormat(flexibleEquivalent);
8329            }
8330            caps->addColorFormat(portFormat.eColorFormat);
8331
8332            if (index == kMaxIndicesToCheck) {
8333                ALOGW("[%s] stopping checking formats after %u: %s(%x)",
8334                        name, index,
8335                        asString(portFormat.eColorFormat), portFormat.eColorFormat);
8336            }
8337        }
8338    } else if (strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_AAC) == 0) {
8339        // More audio codecs if they have profiles.
8340        OMX_AUDIO_PARAM_ANDROID_PROFILETYPE param;
8341        InitOMXParams(&param);
8342        param.nPortIndex = isEncoder ? kPortIndexOutput : kPortIndexInput;
8343        for (OMX_U32 index = 0; index <= kMaxIndicesToCheck; ++index) {
8344            param.nProfileIndex = index;
8345            status_t err = omxNode->getParameter(
8346                    (OMX_INDEXTYPE)OMX_IndexParamAudioProfileQuerySupported,
8347                    &param, sizeof(param));
8348            if (err != OK) {
8349                break;
8350            }
8351            // For audio, level is ignored.
8352            caps->addProfileLevel(param.eProfile, 0 /* level */);
8353
8354            if (index == kMaxIndicesToCheck) {
8355                ALOGW("[%s] stopping checking profiles after %u: %x",
8356                        name, index,
8357                        param.eProfile);
8358            }
8359        }
8360
8361        // NOTE: Without Android extensions, OMX does not provide a way to query
8362        // AAC profile support
8363        if (param.nProfileIndex == 0) {
8364            ALOGW("component %s doesn't support profile query.", name);
8365        }
8366    }
8367
8368    if (isVideo && !isEncoder) {
8369        native_handle_t *sidebandHandle = NULL;
8370        if (omxNode->configureVideoTunnelMode(
8371                kPortIndexOutput, OMX_TRUE, 0, &sidebandHandle) == OK) {
8372            // tunneled playback includes adaptive playback
8373            caps->addFlags(MediaCodecInfo::Capabilities::kFlagSupportsAdaptivePlayback
8374                    | MediaCodecInfo::Capabilities::kFlagSupportsTunneledPlayback);
8375        } else if (omxNode->setPortMode(
8376                kPortIndexOutput, IOMX::kPortModeDynamicANWBuffer) == OK ||
8377                omxNode->prepareForAdaptivePlayback(
8378                kPortIndexOutput, OMX_TRUE,
8379                1280 /* width */, 720 /* height */) == OK) {
8380            caps->addFlags(MediaCodecInfo::Capabilities::kFlagSupportsAdaptivePlayback);
8381        }
8382    }
8383
8384    if (isVideo && isEncoder) {
8385        OMX_VIDEO_CONFIG_ANDROID_INTRAREFRESHTYPE params;
8386        InitOMXParams(&params);
8387        params.nPortIndex = kPortIndexOutput;
8388        // TODO: should we verify if fallback is supported?
8389        if (omxNode->getConfig(
8390                (OMX_INDEXTYPE)OMX_IndexConfigAndroidIntraRefresh,
8391                &params, sizeof(params)) == OK) {
8392            caps->addFlags(MediaCodecInfo::Capabilities::kFlagSupportsIntraRefresh);
8393        }
8394    }
8395
8396    omxNode->freeNode();
8397    client.disconnect();
8398    return OK;
8399}
8400
8401// These are supposed be equivalent to the logic in
8402// "audio_channel_out_mask_from_count".
8403//static
8404status_t ACodec::getOMXChannelMapping(size_t numChannels, OMX_AUDIO_CHANNELTYPE map[]) {
8405    switch (numChannels) {
8406        case 1:
8407            map[0] = OMX_AUDIO_ChannelCF;
8408            break;
8409        case 2:
8410            map[0] = OMX_AUDIO_ChannelLF;
8411            map[1] = OMX_AUDIO_ChannelRF;
8412            break;
8413        case 3:
8414            map[0] = OMX_AUDIO_ChannelLF;
8415            map[1] = OMX_AUDIO_ChannelRF;
8416            map[2] = OMX_AUDIO_ChannelCF;
8417            break;
8418        case 4:
8419            map[0] = OMX_AUDIO_ChannelLF;
8420            map[1] = OMX_AUDIO_ChannelRF;
8421            map[2] = OMX_AUDIO_ChannelLR;
8422            map[3] = OMX_AUDIO_ChannelRR;
8423            break;
8424        case 5:
8425            map[0] = OMX_AUDIO_ChannelLF;
8426            map[1] = OMX_AUDIO_ChannelRF;
8427            map[2] = OMX_AUDIO_ChannelCF;
8428            map[3] = OMX_AUDIO_ChannelLR;
8429            map[4] = OMX_AUDIO_ChannelRR;
8430            break;
8431        case 6:
8432            map[0] = OMX_AUDIO_ChannelLF;
8433            map[1] = OMX_AUDIO_ChannelRF;
8434            map[2] = OMX_AUDIO_ChannelCF;
8435            map[3] = OMX_AUDIO_ChannelLFE;
8436            map[4] = OMX_AUDIO_ChannelLR;
8437            map[5] = OMX_AUDIO_ChannelRR;
8438            break;
8439        case 7:
8440            map[0] = OMX_AUDIO_ChannelLF;
8441            map[1] = OMX_AUDIO_ChannelRF;
8442            map[2] = OMX_AUDIO_ChannelCF;
8443            map[3] = OMX_AUDIO_ChannelLFE;
8444            map[4] = OMX_AUDIO_ChannelLR;
8445            map[5] = OMX_AUDIO_ChannelRR;
8446            map[6] = OMX_AUDIO_ChannelCS;
8447            break;
8448        case 8:
8449            map[0] = OMX_AUDIO_ChannelLF;
8450            map[1] = OMX_AUDIO_ChannelRF;
8451            map[2] = OMX_AUDIO_ChannelCF;
8452            map[3] = OMX_AUDIO_ChannelLFE;
8453            map[4] = OMX_AUDIO_ChannelLR;
8454            map[5] = OMX_AUDIO_ChannelRR;
8455            map[6] = OMX_AUDIO_ChannelLS;
8456            map[7] = OMX_AUDIO_ChannelRS;
8457            break;
8458        default:
8459            return -EINVAL;
8460    }
8461
8462    return OK;
8463}
8464
8465void ACodec::setTrebleFlag(bool trebleFlag) {
8466    mTrebleFlag = trebleFlag;
8467}
8468
8469bool ACodec::getTrebleFlag() const {
8470    return mTrebleFlag;
8471}
8472
8473}  // namespace android
8474