ACodec.cpp revision fd866b3aa0d97375de08f8888b95669026c83361
1/*
2 * Copyright (C) 2010 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 *      http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17//#define LOG_NDEBUG 0
18#define LOG_TAG "ACodec"
19
20#ifdef __LP64__
21#define OMX_ANDROID_COMPILE_AS_32BIT_ON_64BIT_PLATFORMS
22#endif
23
24#include <inttypes.h>
25#include <utils/Trace.h>
26
27#include <gui/Surface.h>
28
29#include <media/stagefright/ACodec.h>
30
31#include <binder/MemoryDealer.h>
32
33#include <media/stagefright/foundation/hexdump.h>
34#include <media/stagefright/foundation/ABuffer.h>
35#include <media/stagefright/foundation/ADebug.h>
36#include <media/stagefright/foundation/AMessage.h>
37#include <media/stagefright/foundation/AUtils.h>
38
39#include <media/stagefright/BufferProducerWrapper.h>
40#include <media/stagefright/MediaCodec.h>
41#include <media/stagefright/MediaCodecList.h>
42#include <media/stagefright/MediaDefs.h>
43#include <media/stagefright/OMXClient.h>
44#include <media/stagefright/OMXCodec.h>
45#include <media/stagefright/PersistentSurface.h>
46#include <media/stagefright/SurfaceUtils.h>
47#include <media/hardware/HardwareAPI.h>
48
49#include <OMX_AudioExt.h>
50#include <OMX_VideoExt.h>
51#include <OMX_Component.h>
52#include <OMX_IndexExt.h>
53#include <OMX_AsString.h>
54
55#include "include/avc_utils.h"
56
57namespace android {
58
59// OMX errors are directly mapped into status_t range if
60// there is no corresponding MediaError status code.
61// Use the statusFromOMXError(int32_t omxError) function.
62//
63// Currently this is a direct map.
64// See frameworks/native/include/media/openmax/OMX_Core.h
65//
66// Vendor OMX errors     from 0x90000000 - 0x9000FFFF
67// Extension OMX errors  from 0x8F000000 - 0x90000000
68// Standard OMX errors   from 0x80001000 - 0x80001024 (0x80001024 current)
69//
70
71// returns true if err is a recognized OMX error code.
72// as OMX error is OMX_S32, this is an int32_t type
73static inline bool isOMXError(int32_t err) {
74    return (ERROR_CODEC_MIN <= err && err <= ERROR_CODEC_MAX);
75}
76
77// converts an OMX error to a status_t
78static inline status_t statusFromOMXError(int32_t omxError) {
79    switch (omxError) {
80    case OMX_ErrorInvalidComponentName:
81    case OMX_ErrorComponentNotFound:
82        return NAME_NOT_FOUND; // can trigger illegal argument error for provided names.
83    default:
84        return isOMXError(omxError) ? omxError : 0; // no translation required
85    }
86}
87
88// checks and converts status_t to a non-side-effect status_t
89static inline status_t makeNoSideEffectStatus(status_t err) {
90    switch (err) {
91    // the following errors have side effects and may come
92    // from other code modules. Remap for safety reasons.
93    case INVALID_OPERATION:
94    case DEAD_OBJECT:
95        return UNKNOWN_ERROR;
96    default:
97        return err;
98    }
99}
100
101template<class T>
102static void InitOMXParams(T *params) {
103    params->nSize = sizeof(T);
104    params->nVersion.s.nVersionMajor = 1;
105    params->nVersion.s.nVersionMinor = 0;
106    params->nVersion.s.nRevision = 0;
107    params->nVersion.s.nStep = 0;
108}
109
110struct MessageList : public RefBase {
111    MessageList() {
112    }
113    virtual ~MessageList() {
114    }
115    std::list<sp<AMessage> > &getList() { return mList; }
116private:
117    std::list<sp<AMessage> > mList;
118
119    DISALLOW_EVIL_CONSTRUCTORS(MessageList);
120};
121
122struct CodecObserver : public BnOMXObserver {
123    CodecObserver() {}
124
125    void setNotificationMessage(const sp<AMessage> &msg) {
126        mNotify = msg;
127    }
128
129    // from IOMXObserver
130    virtual void onMessages(const std::list<omx_message> &messages) {
131        if (messages.empty()) {
132            return;
133        }
134
135        sp<AMessage> notify = mNotify->dup();
136        bool first = true;
137        sp<MessageList> msgList = new MessageList();
138        for (std::list<omx_message>::const_iterator it = messages.cbegin();
139              it != messages.cend(); ++it) {
140            const omx_message &omx_msg = *it;
141            if (first) {
142                notify->setInt32("node", omx_msg.node);
143                first = false;
144            }
145
146            sp<AMessage> msg = new AMessage;
147            msg->setInt32("type", omx_msg.type);
148            switch (omx_msg.type) {
149                case omx_message::EVENT:
150                {
151                    msg->setInt32("event", omx_msg.u.event_data.event);
152                    msg->setInt32("data1", omx_msg.u.event_data.data1);
153                    msg->setInt32("data2", omx_msg.u.event_data.data2);
154                    break;
155                }
156
157                case omx_message::EMPTY_BUFFER_DONE:
158                {
159                    msg->setInt32("buffer", omx_msg.u.buffer_data.buffer);
160                    msg->setInt32("fence_fd", omx_msg.fenceFd);
161                    break;
162                }
163
164                case omx_message::FILL_BUFFER_DONE:
165                {
166                    msg->setInt32(
167                            "buffer", omx_msg.u.extended_buffer_data.buffer);
168                    msg->setInt32(
169                            "range_offset",
170                            omx_msg.u.extended_buffer_data.range_offset);
171                    msg->setInt32(
172                            "range_length",
173                            omx_msg.u.extended_buffer_data.range_length);
174                    msg->setInt32(
175                            "flags",
176                            omx_msg.u.extended_buffer_data.flags);
177                    msg->setInt64(
178                            "timestamp",
179                            omx_msg.u.extended_buffer_data.timestamp);
180                    msg->setInt32(
181                            "fence_fd", omx_msg.fenceFd);
182                    break;
183                }
184
185                case omx_message::FRAME_RENDERED:
186                {
187                    msg->setInt64(
188                            "media_time_us", omx_msg.u.render_data.timestamp);
189                    msg->setInt64(
190                            "system_nano", omx_msg.u.render_data.nanoTime);
191                    break;
192                }
193
194                default:
195                    ALOGE("Unrecognized message type: %d", omx_msg.type);
196                    break;
197            }
198            msgList->getList().push_back(msg);
199        }
200        notify->setObject("messages", msgList);
201        notify->post();
202    }
203
204protected:
205    virtual ~CodecObserver() {}
206
207private:
208    sp<AMessage> mNotify;
209
210    DISALLOW_EVIL_CONSTRUCTORS(CodecObserver);
211};
212
213////////////////////////////////////////////////////////////////////////////////
214
215struct ACodec::BaseState : public AState {
216    BaseState(ACodec *codec, const sp<AState> &parentState = NULL);
217
218protected:
219    enum PortMode {
220        KEEP_BUFFERS,
221        RESUBMIT_BUFFERS,
222        FREE_BUFFERS,
223    };
224
225    ACodec *mCodec;
226
227    virtual PortMode getPortMode(OMX_U32 portIndex);
228
229    virtual bool onMessageReceived(const sp<AMessage> &msg);
230
231    virtual bool onOMXEvent(OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2);
232
233    virtual void onOutputBufferDrained(const sp<AMessage> &msg);
234    virtual void onInputBufferFilled(const sp<AMessage> &msg);
235
236    void postFillThisBuffer(BufferInfo *info);
237
238private:
239    // Handles an OMX message. Returns true iff message was handled.
240    bool onOMXMessage(const sp<AMessage> &msg);
241
242    // Handles a list of messages. Returns true iff messages were handled.
243    bool onOMXMessageList(const sp<AMessage> &msg);
244
245    // returns true iff this message is for this component and the component is alive
246    bool checkOMXMessage(const sp<AMessage> &msg);
247
248    bool onOMXEmptyBufferDone(IOMX::buffer_id bufferID, int fenceFd);
249
250    bool onOMXFillBufferDone(
251            IOMX::buffer_id bufferID,
252            size_t rangeOffset, size_t rangeLength,
253            OMX_U32 flags,
254            int64_t timeUs,
255            int fenceFd);
256
257    virtual bool onOMXFrameRendered(int64_t mediaTimeUs, nsecs_t systemNano);
258
259    void getMoreInputDataIfPossible();
260
261    DISALLOW_EVIL_CONSTRUCTORS(BaseState);
262};
263
264////////////////////////////////////////////////////////////////////////////////
265
266struct ACodec::DeathNotifier : public IBinder::DeathRecipient {
267    DeathNotifier(const sp<AMessage> &notify)
268        : mNotify(notify) {
269    }
270
271    virtual void binderDied(const wp<IBinder> &) {
272        mNotify->post();
273    }
274
275protected:
276    virtual ~DeathNotifier() {}
277
278private:
279    sp<AMessage> mNotify;
280
281    DISALLOW_EVIL_CONSTRUCTORS(DeathNotifier);
282};
283
284struct ACodec::UninitializedState : public ACodec::BaseState {
285    UninitializedState(ACodec *codec);
286
287protected:
288    virtual bool onMessageReceived(const sp<AMessage> &msg);
289    virtual void stateEntered();
290
291private:
292    void onSetup(const sp<AMessage> &msg);
293    bool onAllocateComponent(const sp<AMessage> &msg);
294
295    sp<DeathNotifier> mDeathNotifier;
296
297    DISALLOW_EVIL_CONSTRUCTORS(UninitializedState);
298};
299
300////////////////////////////////////////////////////////////////////////////////
301
302struct ACodec::LoadedState : public ACodec::BaseState {
303    LoadedState(ACodec *codec);
304
305protected:
306    virtual bool onMessageReceived(const sp<AMessage> &msg);
307    virtual void stateEntered();
308
309private:
310    friend struct ACodec::UninitializedState;
311
312    bool onConfigureComponent(const sp<AMessage> &msg);
313    void onCreateInputSurface(const sp<AMessage> &msg);
314    void onSetInputSurface(const sp<AMessage> &msg);
315    void onStart();
316    void onShutdown(bool keepComponentAllocated);
317
318    status_t setupInputSurface();
319
320    DISALLOW_EVIL_CONSTRUCTORS(LoadedState);
321};
322
323////////////////////////////////////////////////////////////////////////////////
324
325struct ACodec::LoadedToIdleState : public ACodec::BaseState {
326    LoadedToIdleState(ACodec *codec);
327
328protected:
329    virtual bool onMessageReceived(const sp<AMessage> &msg);
330    virtual bool onOMXEvent(OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2);
331    virtual void stateEntered();
332
333private:
334    status_t allocateBuffers();
335
336    DISALLOW_EVIL_CONSTRUCTORS(LoadedToIdleState);
337};
338
339////////////////////////////////////////////////////////////////////////////////
340
341struct ACodec::IdleToExecutingState : public ACodec::BaseState {
342    IdleToExecutingState(ACodec *codec);
343
344protected:
345    virtual bool onMessageReceived(const sp<AMessage> &msg);
346    virtual bool onOMXEvent(OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2);
347    virtual void stateEntered();
348
349private:
350    DISALLOW_EVIL_CONSTRUCTORS(IdleToExecutingState);
351};
352
353////////////////////////////////////////////////////////////////////////////////
354
355struct ACodec::ExecutingState : public ACodec::BaseState {
356    ExecutingState(ACodec *codec);
357
358    void submitRegularOutputBuffers();
359    void submitOutputMetaBuffers();
360    void submitOutputBuffers();
361
362    // Submit output buffers to the decoder, submit input buffers to client
363    // to fill with data.
364    void resume();
365
366    // Returns true iff input and output buffers are in play.
367    bool active() const { return mActive; }
368
369protected:
370    virtual PortMode getPortMode(OMX_U32 portIndex);
371    virtual bool onMessageReceived(const sp<AMessage> &msg);
372    virtual void stateEntered();
373
374    virtual bool onOMXEvent(OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2);
375    virtual bool onOMXFrameRendered(int64_t mediaTimeUs, nsecs_t systemNano);
376
377private:
378    bool mActive;
379
380    DISALLOW_EVIL_CONSTRUCTORS(ExecutingState);
381};
382
383////////////////////////////////////////////////////////////////////////////////
384
385struct ACodec::OutputPortSettingsChangedState : public ACodec::BaseState {
386    OutputPortSettingsChangedState(ACodec *codec);
387
388protected:
389    virtual PortMode getPortMode(OMX_U32 portIndex);
390    virtual bool onMessageReceived(const sp<AMessage> &msg);
391    virtual void stateEntered();
392
393    virtual bool onOMXEvent(OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2);
394    virtual bool onOMXFrameRendered(int64_t mediaTimeUs, nsecs_t systemNano);
395
396private:
397    DISALLOW_EVIL_CONSTRUCTORS(OutputPortSettingsChangedState);
398};
399
400////////////////////////////////////////////////////////////////////////////////
401
402struct ACodec::ExecutingToIdleState : public ACodec::BaseState {
403    ExecutingToIdleState(ACodec *codec);
404
405protected:
406    virtual bool onMessageReceived(const sp<AMessage> &msg);
407    virtual void stateEntered();
408
409    virtual bool onOMXEvent(OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2);
410
411    virtual void onOutputBufferDrained(const sp<AMessage> &msg);
412    virtual void onInputBufferFilled(const sp<AMessage> &msg);
413
414private:
415    void changeStateIfWeOwnAllBuffers();
416
417    bool mComponentNowIdle;
418
419    DISALLOW_EVIL_CONSTRUCTORS(ExecutingToIdleState);
420};
421
422////////////////////////////////////////////////////////////////////////////////
423
424struct ACodec::IdleToLoadedState : public ACodec::BaseState {
425    IdleToLoadedState(ACodec *codec);
426
427protected:
428    virtual bool onMessageReceived(const sp<AMessage> &msg);
429    virtual void stateEntered();
430
431    virtual bool onOMXEvent(OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2);
432
433private:
434    DISALLOW_EVIL_CONSTRUCTORS(IdleToLoadedState);
435};
436
437////////////////////////////////////////////////////////////////////////////////
438
439struct ACodec::FlushingState : public ACodec::BaseState {
440    FlushingState(ACodec *codec);
441
442protected:
443    virtual bool onMessageReceived(const sp<AMessage> &msg);
444    virtual void stateEntered();
445
446    virtual bool onOMXEvent(OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2);
447
448    virtual void onOutputBufferDrained(const sp<AMessage> &msg);
449    virtual void onInputBufferFilled(const sp<AMessage> &msg);
450
451private:
452    bool mFlushComplete[2];
453
454    void changeStateIfWeOwnAllBuffers();
455
456    DISALLOW_EVIL_CONSTRUCTORS(FlushingState);
457};
458
459////////////////////////////////////////////////////////////////////////////////
460
461void ACodec::BufferInfo::setWriteFence(int fenceFd, const char *dbg) {
462    if (mFenceFd >= 0) {
463        ALOGW("OVERWRITE OF %s fence %d by write fence %d in %s",
464                mIsReadFence ? "read" : "write", mFenceFd, fenceFd, dbg);
465    }
466    mFenceFd = fenceFd;
467    mIsReadFence = false;
468}
469
470void ACodec::BufferInfo::setReadFence(int fenceFd, const char *dbg) {
471    if (mFenceFd >= 0) {
472        ALOGW("OVERWRITE OF %s fence %d by read fence %d in %s",
473                mIsReadFence ? "read" : "write", mFenceFd, fenceFd, dbg);
474    }
475    mFenceFd = fenceFd;
476    mIsReadFence = true;
477}
478
479void ACodec::BufferInfo::checkWriteFence(const char *dbg) {
480    if (mFenceFd >= 0 && mIsReadFence) {
481        ALOGD("REUSING read fence %d as write fence in %s", mFenceFd, dbg);
482    }
483}
484
485void ACodec::BufferInfo::checkReadFence(const char *dbg) {
486    if (mFenceFd >= 0 && !mIsReadFence) {
487        ALOGD("REUSING write fence %d as read fence in %s", mFenceFd, dbg);
488    }
489}
490
491////////////////////////////////////////////////////////////////////////////////
492
493ACodec::ACodec()
494    : mQuirks(0),
495      mNode(0),
496      mSentFormat(false),
497      mIsVideo(false),
498      mIsEncoder(false),
499      mShutdownInProgress(false),
500      mExplicitShutdown(false),
501      mEncoderDelay(0),
502      mEncoderPadding(0),
503      mRotationDegrees(0),
504      mChannelMaskPresent(false),
505      mChannelMask(0),
506      mDequeueCounter(0),
507      mInputMetadataType(kMetadataBufferTypeInvalid),
508      mOutputMetadataType(kMetadataBufferTypeInvalid),
509      mLegacyAdaptiveExperiment(false),
510      mMetadataBuffersToSubmit(0),
511      mRepeatFrameDelayUs(-1ll),
512      mMaxPtsGapUs(-1ll),
513      mMaxFps(-1),
514      mTimePerFrameUs(-1ll),
515      mTimePerCaptureUs(-1ll),
516      mCreateInputBuffersSuspended(false),
517      mTunneled(false) {
518    mUninitializedState = new UninitializedState(this);
519    mLoadedState = new LoadedState(this);
520    mLoadedToIdleState = new LoadedToIdleState(this);
521    mIdleToExecutingState = new IdleToExecutingState(this);
522    mExecutingState = new ExecutingState(this);
523
524    mOutputPortSettingsChangedState =
525        new OutputPortSettingsChangedState(this);
526
527    mExecutingToIdleState = new ExecutingToIdleState(this);
528    mIdleToLoadedState = new IdleToLoadedState(this);
529    mFlushingState = new FlushingState(this);
530
531    mPortEOS[kPortIndexInput] = mPortEOS[kPortIndexOutput] = false;
532    mInputEOSResult = OK;
533
534    changeState(mUninitializedState);
535}
536
537ACodec::~ACodec() {
538}
539
540void ACodec::setNotificationMessage(const sp<AMessage> &msg) {
541    mNotify = msg;
542}
543
544void ACodec::initiateSetup(const sp<AMessage> &msg) {
545    msg->setWhat(kWhatSetup);
546    msg->setTarget(this);
547    msg->post();
548}
549
550void ACodec::signalSetParameters(const sp<AMessage> &params) {
551    sp<AMessage> msg = new AMessage(kWhatSetParameters, this);
552    msg->setMessage("params", params);
553    msg->post();
554}
555
556void ACodec::initiateAllocateComponent(const sp<AMessage> &msg) {
557    msg->setWhat(kWhatAllocateComponent);
558    msg->setTarget(this);
559    msg->post();
560}
561
562void ACodec::initiateConfigureComponent(const sp<AMessage> &msg) {
563    msg->setWhat(kWhatConfigureComponent);
564    msg->setTarget(this);
565    msg->post();
566}
567
568status_t ACodec::setSurface(const sp<Surface> &surface) {
569    sp<AMessage> msg = new AMessage(kWhatSetSurface, this);
570    msg->setObject("surface", surface);
571
572    sp<AMessage> response;
573    status_t err = msg->postAndAwaitResponse(&response);
574
575    if (err == OK) {
576        (void)response->findInt32("err", &err);
577    }
578    return err;
579}
580
581void ACodec::initiateCreateInputSurface() {
582    (new AMessage(kWhatCreateInputSurface, this))->post();
583}
584
585void ACodec::initiateSetInputSurface(
586        const sp<PersistentSurface> &surface) {
587    sp<AMessage> msg = new AMessage(kWhatSetInputSurface, this);
588    msg->setObject("input-surface", surface);
589    msg->post();
590}
591
592void ACodec::signalEndOfInputStream() {
593    (new AMessage(kWhatSignalEndOfInputStream, this))->post();
594}
595
596void ACodec::initiateStart() {
597    (new AMessage(kWhatStart, this))->post();
598}
599
600void ACodec::signalFlush() {
601    ALOGV("[%s] signalFlush", mComponentName.c_str());
602    (new AMessage(kWhatFlush, this))->post();
603}
604
605void ACodec::signalResume() {
606    (new AMessage(kWhatResume, this))->post();
607}
608
609void ACodec::initiateShutdown(bool keepComponentAllocated) {
610    sp<AMessage> msg = new AMessage(kWhatShutdown, this);
611    msg->setInt32("keepComponentAllocated", keepComponentAllocated);
612    msg->post();
613    if (!keepComponentAllocated) {
614        // ensure shutdown completes in 3 seconds
615        (new AMessage(kWhatReleaseCodecInstance, this))->post(3000000);
616    }
617}
618
619void ACodec::signalRequestIDRFrame() {
620    (new AMessage(kWhatRequestIDRFrame, this))->post();
621}
622
623// *** NOTE: THE FOLLOWING WORKAROUND WILL BE REMOVED ***
624// Some codecs may return input buffers before having them processed.
625// This causes a halt if we already signaled an EOS on the input
626// port.  For now keep submitting an output buffer if there was an
627// EOS on the input port, but not yet on the output port.
628void ACodec::signalSubmitOutputMetadataBufferIfEOS_workaround() {
629    if (mPortEOS[kPortIndexInput] && !mPortEOS[kPortIndexOutput] &&
630            mMetadataBuffersToSubmit > 0) {
631        (new AMessage(kWhatSubmitOutputMetadataBufferIfEOS, this))->post();
632    }
633}
634
635status_t ACodec::handleSetSurface(const sp<Surface> &surface) {
636    // allow keeping unset surface
637    if (surface == NULL) {
638        if (mNativeWindow != NULL) {
639            ALOGW("cannot unset a surface");
640            return INVALID_OPERATION;
641        }
642        return OK;
643    }
644
645    // allow keeping unset surface
646    if (mNativeWindow == NULL) {
647        ALOGW("component was not configured with a surface");
648        return INVALID_OPERATION;
649    }
650
651    ANativeWindow *nativeWindow = surface.get();
652    // if we have not yet started the codec, we can simply set the native window
653    if (mBuffers[kPortIndexInput].size() == 0) {
654        mNativeWindow = surface;
655        return OK;
656    }
657
658    // we do not support changing a tunneled surface after start
659    if (mTunneled) {
660        ALOGW("cannot change tunneled surface");
661        return INVALID_OPERATION;
662    }
663
664    status_t err = setupNativeWindowSizeFormatAndUsage(nativeWindow);
665    if (err != OK) {
666        return err;
667    }
668
669    // get min undequeued count. We cannot switch to a surface that has a higher
670    // undequeued count than we allocated.
671    int minUndequeuedBuffers = 0;
672    err = nativeWindow->query(
673            nativeWindow, NATIVE_WINDOW_MIN_UNDEQUEUED_BUFFERS,
674            &minUndequeuedBuffers);
675    if (err != 0) {
676        ALOGE("NATIVE_WINDOW_MIN_UNDEQUEUED_BUFFERS query failed: %s (%d)",
677                strerror(-err), -err);
678        return err;
679    }
680    if (minUndequeuedBuffers > (int)mNumUndequeuedBuffers) {
681        ALOGE("new surface holds onto more buffers (%d) than planned for (%zu)",
682                minUndequeuedBuffers, mNumUndequeuedBuffers);
683        return BAD_VALUE;
684    }
685
686    // we cannot change the number of output buffers while OMX is running
687    // set up surface to the same count
688    Vector<BufferInfo> &buffers = mBuffers[kPortIndexOutput];
689    ALOGV("setting up surface for %zu buffers", buffers.size());
690
691    err = native_window_set_buffer_count(nativeWindow, buffers.size());
692    if (err != 0) {
693        ALOGE("native_window_set_buffer_count failed: %s (%d)", strerror(-err),
694                -err);
695        return err;
696    }
697
698    // need to enable allocation when attaching
699    surface->getIGraphicBufferProducer()->allowAllocation(true);
700
701    // for meta data mode, we move dequeud buffers to the new surface.
702    // for non-meta mode, we must move all registered buffers
703    for (size_t i = 0; i < buffers.size(); ++i) {
704        const BufferInfo &info = buffers[i];
705        // skip undequeued buffers for meta data mode
706        if (storingMetadataInDecodedBuffers()
707                && !mLegacyAdaptiveExperiment
708                && info.mStatus == BufferInfo::OWNED_BY_NATIVE_WINDOW) {
709            ALOGV("skipping buffer %p", info.mGraphicBuffer->getNativeBuffer());
710            continue;
711        }
712        ALOGV("attaching buffer %p", info.mGraphicBuffer->getNativeBuffer());
713
714        err = surface->attachBuffer(info.mGraphicBuffer->getNativeBuffer());
715        if (err != OK) {
716            ALOGE("failed to attach buffer %p to the new surface: %s (%d)",
717                    info.mGraphicBuffer->getNativeBuffer(),
718                    strerror(-err), -err);
719            return err;
720        }
721    }
722
723    // cancel undequeued buffers to new surface
724    if (!storingMetadataInDecodedBuffers() || mLegacyAdaptiveExperiment) {
725        for (size_t i = 0; i < buffers.size(); ++i) {
726            BufferInfo &info = buffers.editItemAt(i);
727            if (info.mStatus == BufferInfo::OWNED_BY_NATIVE_WINDOW) {
728                ALOGV("canceling buffer %p", info.mGraphicBuffer->getNativeBuffer());
729                err = nativeWindow->cancelBuffer(
730                        nativeWindow, info.mGraphicBuffer->getNativeBuffer(), info.mFenceFd);
731                info.mFenceFd = -1;
732                if (err != OK) {
733                    ALOGE("failed to cancel buffer %p to the new surface: %s (%d)",
734                            info.mGraphicBuffer->getNativeBuffer(),
735                            strerror(-err), -err);
736                    return err;
737                }
738            }
739        }
740        // disallow further allocation
741        (void)surface->getIGraphicBufferProducer()->allowAllocation(false);
742    }
743
744    // push blank buffers to previous window if requested
745    if (mFlags & kFlagPushBlankBuffersToNativeWindowOnShutdown) {
746        pushBlankBuffersToNativeWindow(mNativeWindow.get());
747    }
748
749    mNativeWindow = nativeWindow;
750    return OK;
751}
752
753status_t ACodec::allocateBuffersOnPort(OMX_U32 portIndex) {
754    CHECK(portIndex == kPortIndexInput || portIndex == kPortIndexOutput);
755
756    CHECK(mDealer[portIndex] == NULL);
757    CHECK(mBuffers[portIndex].isEmpty());
758
759    status_t err;
760    if (mNativeWindow != NULL && portIndex == kPortIndexOutput) {
761        if (storingMetadataInDecodedBuffers()) {
762            err = allocateOutputMetadataBuffers();
763        } else {
764            err = allocateOutputBuffersFromNativeWindow();
765        }
766    } else {
767        OMX_PARAM_PORTDEFINITIONTYPE def;
768        InitOMXParams(&def);
769        def.nPortIndex = portIndex;
770
771        err = mOMX->getParameter(
772                mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
773
774        if (err == OK) {
775            MetadataBufferType type =
776                portIndex == kPortIndexOutput ? mOutputMetadataType : mInputMetadataType;
777            int32_t bufSize = def.nBufferSize;
778            if (type == kMetadataBufferTypeGrallocSource) {
779                bufSize = sizeof(VideoGrallocMetadata);
780            } else if (type == kMetadataBufferTypeANWBuffer) {
781                bufSize = sizeof(VideoNativeMetadata);
782            }
783
784            // If using gralloc or native source input metadata buffers, allocate largest
785            // metadata size as we prefer to generate native source metadata, but component
786            // may require gralloc source. For camera source, allocate at least enough
787            // size for native metadata buffers.
788            int32_t allottedSize = bufSize;
789            if (portIndex == kPortIndexInput && type >= kMetadataBufferTypeGrallocSource) {
790                bufSize = max(sizeof(VideoGrallocMetadata), sizeof(VideoNativeMetadata));
791            } else if (portIndex == kPortIndexInput && type == kMetadataBufferTypeCameraSource) {
792                bufSize = max(bufSize, (int32_t)sizeof(VideoNativeMetadata));
793            }
794
795            ALOGV("[%s] Allocating %u buffers of size %d/%d (from %u using %s) on %s port",
796                    mComponentName.c_str(),
797                    def.nBufferCountActual, bufSize, allottedSize, def.nBufferSize, asString(type),
798                    portIndex == kPortIndexInput ? "input" : "output");
799
800            size_t totalSize = def.nBufferCountActual * bufSize;
801            mDealer[portIndex] = new MemoryDealer(totalSize, "ACodec");
802
803            for (OMX_U32 i = 0; i < def.nBufferCountActual && err == OK; ++i) {
804                sp<IMemory> mem = mDealer[portIndex]->allocate(bufSize);
805                if (mem == NULL || mem->pointer() == NULL) {
806                    return NO_MEMORY;
807                }
808
809                BufferInfo info;
810                info.mStatus = BufferInfo::OWNED_BY_US;
811                info.mFenceFd = -1;
812                info.mRenderInfo = NULL;
813
814                uint32_t requiresAllocateBufferBit =
815                    (portIndex == kPortIndexInput)
816                        ? OMXCodec::kRequiresAllocateBufferOnInputPorts
817                        : OMXCodec::kRequiresAllocateBufferOnOutputPorts;
818
819                if ((portIndex == kPortIndexInput && (mFlags & kFlagIsSecure))
820                        || (portIndex == kPortIndexOutput && usingMetadataOnEncoderOutput())) {
821                    mem.clear();
822
823                    void *ptr;
824                    err = mOMX->allocateBuffer(
825                            mNode, portIndex, bufSize, &info.mBufferID,
826                            &ptr);
827
828                    info.mData = new ABuffer(ptr, bufSize);
829                } else if (mQuirks & requiresAllocateBufferBit) {
830                    err = mOMX->allocateBufferWithBackup(
831                            mNode, portIndex, mem, &info.mBufferID, allottedSize);
832                } else {
833                    err = mOMX->useBuffer(mNode, portIndex, mem, &info.mBufferID, allottedSize);
834                }
835
836                if (mem != NULL) {
837                    info.mData = new ABuffer(mem->pointer(), bufSize);
838                    if (type == kMetadataBufferTypeANWBuffer) {
839                        ((VideoNativeMetadata *)mem->pointer())->nFenceFd = -1;
840                    }
841                }
842
843                mBuffers[portIndex].push(info);
844            }
845        }
846    }
847
848    if (err != OK) {
849        return err;
850    }
851
852    sp<AMessage> notify = mNotify->dup();
853    notify->setInt32("what", CodecBase::kWhatBuffersAllocated);
854
855    notify->setInt32("portIndex", portIndex);
856
857    sp<PortDescription> desc = new PortDescription;
858
859    for (size_t i = 0; i < mBuffers[portIndex].size(); ++i) {
860        const BufferInfo &info = mBuffers[portIndex][i];
861
862        desc->addBuffer(info.mBufferID, info.mData);
863    }
864
865    notify->setObject("portDesc", desc);
866    notify->post();
867
868    return OK;
869}
870
871status_t ACodec::setupNativeWindowSizeFormatAndUsage(ANativeWindow *nativeWindow /* nonnull */) {
872    OMX_PARAM_PORTDEFINITIONTYPE def;
873    InitOMXParams(&def);
874    def.nPortIndex = kPortIndexOutput;
875
876    status_t err = mOMX->getParameter(
877            mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
878
879    if (err != OK) {
880        return err;
881    }
882
883    OMX_U32 usage = 0;
884    err = mOMX->getGraphicBufferUsage(mNode, kPortIndexOutput, &usage);
885    if (err != 0) {
886        ALOGW("querying usage flags from OMX IL component failed: %d", err);
887        // XXX: Currently this error is logged, but not fatal.
888        usage = 0;
889    }
890    int omxUsage = usage;
891
892    if (mFlags & kFlagIsGrallocUsageProtected) {
893        usage |= GRALLOC_USAGE_PROTECTED;
894    }
895
896    usage |= GRALLOC_USAGE_HW_TEXTURE | GRALLOC_USAGE_EXTERNAL_DISP;
897
898    ALOGV("gralloc usage: %#x(OMX) => %#x(ACodec)", omxUsage, usage);
899    return setNativeWindowSizeFormatAndUsage(
900            nativeWindow,
901            def.format.video.nFrameWidth,
902            def.format.video.nFrameHeight,
903            def.format.video.eColorFormat,
904            mRotationDegrees,
905            usage);
906}
907
908status_t ACodec::configureOutputBuffersFromNativeWindow(
909        OMX_U32 *bufferCount, OMX_U32 *bufferSize,
910        OMX_U32 *minUndequeuedBuffers) {
911    OMX_PARAM_PORTDEFINITIONTYPE def;
912    InitOMXParams(&def);
913    def.nPortIndex = kPortIndexOutput;
914
915    status_t err = mOMX->getParameter(
916            mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
917
918    if (err == OK) {
919        err = setupNativeWindowSizeFormatAndUsage(mNativeWindow.get());
920    }
921    if (err != OK) {
922        return err;
923    }
924
925    // Exits here for tunneled video playback codecs -- i.e. skips native window
926    // buffer allocation step as this is managed by the tunneled OMX omponent
927    // itself and explicitly sets def.nBufferCountActual to 0.
928    if (mTunneled) {
929        ALOGV("Tunneled Playback: skipping native window buffer allocation.");
930        def.nBufferCountActual = 0;
931        err = mOMX->setParameter(
932                mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
933
934        *minUndequeuedBuffers = 0;
935        *bufferCount = 0;
936        *bufferSize = 0;
937        return err;
938    }
939
940    *minUndequeuedBuffers = 0;
941    err = mNativeWindow->query(
942            mNativeWindow.get(), NATIVE_WINDOW_MIN_UNDEQUEUED_BUFFERS,
943            (int *)minUndequeuedBuffers);
944
945    if (err != 0) {
946        ALOGE("NATIVE_WINDOW_MIN_UNDEQUEUED_BUFFERS query failed: %s (%d)",
947                strerror(-err), -err);
948        return err;
949    }
950
951    // FIXME: assume that surface is controlled by app (native window
952    // returns the number for the case when surface is not controlled by app)
953    // FIXME2: This means that minUndeqeueudBufs can be 1 larger than reported
954    // For now, try to allocate 1 more buffer, but don't fail if unsuccessful
955
956    // Use conservative allocation while also trying to reduce starvation
957    //
958    // 1. allocate at least nBufferCountMin + minUndequeuedBuffers - that is the
959    //    minimum needed for the consumer to be able to work
960    // 2. try to allocate two (2) additional buffers to reduce starvation from
961    //    the consumer
962    //    plus an extra buffer to account for incorrect minUndequeuedBufs
963    for (OMX_U32 extraBuffers = 2 + 1; /* condition inside loop */; extraBuffers--) {
964        OMX_U32 newBufferCount =
965            def.nBufferCountMin + *minUndequeuedBuffers + extraBuffers;
966        def.nBufferCountActual = newBufferCount;
967        err = mOMX->setParameter(
968                mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
969
970        if (err == OK) {
971            *minUndequeuedBuffers += extraBuffers;
972            break;
973        }
974
975        ALOGW("[%s] setting nBufferCountActual to %u failed: %d",
976                mComponentName.c_str(), newBufferCount, err);
977        /* exit condition */
978        if (extraBuffers == 0) {
979            return err;
980        }
981    }
982
983    err = native_window_set_buffer_count(
984            mNativeWindow.get(), def.nBufferCountActual);
985
986    if (err != 0) {
987        ALOGE("native_window_set_buffer_count failed: %s (%d)", strerror(-err),
988                -err);
989        return err;
990    }
991
992    *bufferCount = def.nBufferCountActual;
993    *bufferSize =  def.nBufferSize;
994    return err;
995}
996
997status_t ACodec::allocateOutputBuffersFromNativeWindow() {
998    OMX_U32 bufferCount, bufferSize, minUndequeuedBuffers;
999    status_t err = configureOutputBuffersFromNativeWindow(
1000            &bufferCount, &bufferSize, &minUndequeuedBuffers);
1001    if (err != 0)
1002        return err;
1003    mNumUndequeuedBuffers = minUndequeuedBuffers;
1004
1005    if (!storingMetadataInDecodedBuffers()) {
1006        static_cast<Surface*>(mNativeWindow.get())
1007                ->getIGraphicBufferProducer()->allowAllocation(true);
1008    }
1009
1010    ALOGV("[%s] Allocating %u buffers from a native window of size %u on "
1011         "output port",
1012         mComponentName.c_str(), bufferCount, bufferSize);
1013
1014    // Dequeue buffers and send them to OMX
1015    for (OMX_U32 i = 0; i < bufferCount; i++) {
1016        ANativeWindowBuffer *buf;
1017        int fenceFd;
1018        err = mNativeWindow->dequeueBuffer(mNativeWindow.get(), &buf, &fenceFd);
1019        if (err != 0) {
1020            ALOGE("dequeueBuffer failed: %s (%d)", strerror(-err), -err);
1021            break;
1022        }
1023
1024        sp<GraphicBuffer> graphicBuffer(new GraphicBuffer(buf, false));
1025        BufferInfo info;
1026        info.mStatus = BufferInfo::OWNED_BY_US;
1027        info.mFenceFd = fenceFd;
1028        info.mIsReadFence = false;
1029        info.mRenderInfo = NULL;
1030        info.mData = new ABuffer(NULL /* data */, bufferSize /* capacity */);
1031        info.mGraphicBuffer = graphicBuffer;
1032        mBuffers[kPortIndexOutput].push(info);
1033
1034        IOMX::buffer_id bufferId;
1035        err = mOMX->useGraphicBuffer(mNode, kPortIndexOutput, graphicBuffer,
1036                &bufferId);
1037        if (err != 0) {
1038            ALOGE("registering GraphicBuffer %u with OMX IL component failed: "
1039                 "%d", i, err);
1040            break;
1041        }
1042
1043        mBuffers[kPortIndexOutput].editItemAt(i).mBufferID = bufferId;
1044
1045        ALOGV("[%s] Registered graphic buffer with ID %u (pointer = %p)",
1046             mComponentName.c_str(),
1047             bufferId, graphicBuffer.get());
1048    }
1049
1050    OMX_U32 cancelStart;
1051    OMX_U32 cancelEnd;
1052
1053    if (err != 0) {
1054        // If an error occurred while dequeuing we need to cancel any buffers
1055        // that were dequeued.
1056        cancelStart = 0;
1057        cancelEnd = mBuffers[kPortIndexOutput].size();
1058    } else {
1059        // Return the required minimum undequeued buffers to the native window.
1060        cancelStart = bufferCount - minUndequeuedBuffers;
1061        cancelEnd = bufferCount;
1062    }
1063
1064    for (OMX_U32 i = cancelStart; i < cancelEnd; i++) {
1065        BufferInfo *info = &mBuffers[kPortIndexOutput].editItemAt(i);
1066        status_t error = cancelBufferToNativeWindow(info);
1067        if (err == 0) {
1068            err = error;
1069        }
1070    }
1071
1072    if (!storingMetadataInDecodedBuffers()) {
1073        static_cast<Surface*>(mNativeWindow.get())
1074                ->getIGraphicBufferProducer()->allowAllocation(false);
1075    }
1076
1077    return err;
1078}
1079
1080status_t ACodec::allocateOutputMetadataBuffers() {
1081    OMX_U32 bufferCount, bufferSize, minUndequeuedBuffers;
1082    status_t err = configureOutputBuffersFromNativeWindow(
1083            &bufferCount, &bufferSize, &minUndequeuedBuffers);
1084    if (err != 0)
1085        return err;
1086    mNumUndequeuedBuffers = minUndequeuedBuffers;
1087
1088    ALOGV("[%s] Allocating %u meta buffers on output port",
1089         mComponentName.c_str(), bufferCount);
1090
1091    size_t bufSize = mOutputMetadataType == kMetadataBufferTypeANWBuffer ?
1092            sizeof(struct VideoNativeMetadata) : sizeof(struct VideoGrallocMetadata);
1093    size_t totalSize = bufferCount * bufSize;
1094    mDealer[kPortIndexOutput] = new MemoryDealer(totalSize, "ACodec");
1095
1096    // Dequeue buffers and send them to OMX
1097    for (OMX_U32 i = 0; i < bufferCount; i++) {
1098        BufferInfo info;
1099        info.mStatus = BufferInfo::OWNED_BY_NATIVE_WINDOW;
1100        info.mFenceFd = -1;
1101        info.mRenderInfo = NULL;
1102        info.mGraphicBuffer = NULL;
1103        info.mDequeuedAt = mDequeueCounter;
1104
1105        sp<IMemory> mem = mDealer[kPortIndexOutput]->allocate(bufSize);
1106        if (mem == NULL || mem->pointer() == NULL) {
1107            return NO_MEMORY;
1108        }
1109        if (mOutputMetadataType == kMetadataBufferTypeANWBuffer) {
1110            ((VideoNativeMetadata *)mem->pointer())->nFenceFd = -1;
1111        }
1112        info.mData = new ABuffer(mem->pointer(), mem->size());
1113
1114        // we use useBuffer for metadata regardless of quirks
1115        err = mOMX->useBuffer(
1116                mNode, kPortIndexOutput, mem, &info.mBufferID, mem->size());
1117
1118        mBuffers[kPortIndexOutput].push(info);
1119
1120        ALOGV("[%s] allocated meta buffer with ID %u (pointer = %p)",
1121             mComponentName.c_str(), info.mBufferID, mem->pointer());
1122    }
1123
1124    if (mLegacyAdaptiveExperiment) {
1125        // preallocate and preregister buffers
1126        static_cast<Surface *>(mNativeWindow.get())
1127                ->getIGraphicBufferProducer()->allowAllocation(true);
1128
1129        ALOGV("[%s] Allocating %u buffers from a native window of size %u on "
1130             "output port",
1131             mComponentName.c_str(), bufferCount, bufferSize);
1132
1133        // Dequeue buffers then cancel them all
1134        for (OMX_U32 i = 0; i < bufferCount; i++) {
1135            BufferInfo *info = &mBuffers[kPortIndexOutput].editItemAt(i);
1136
1137            ANativeWindowBuffer *buf;
1138            int fenceFd;
1139            err = mNativeWindow->dequeueBuffer(mNativeWindow.get(), &buf, &fenceFd);
1140            if (err != 0) {
1141                ALOGE("dequeueBuffer failed: %s (%d)", strerror(-err), -err);
1142                break;
1143            }
1144
1145            sp<GraphicBuffer> graphicBuffer(new GraphicBuffer(buf, false));
1146            mOMX->updateGraphicBufferInMeta(
1147                    mNode, kPortIndexOutput, graphicBuffer, info->mBufferID);
1148            info->mStatus = BufferInfo::OWNED_BY_US;
1149            info->setWriteFence(fenceFd, "allocateOutputMetadataBuffers for legacy");
1150            info->mGraphicBuffer = graphicBuffer;
1151        }
1152
1153        for (OMX_U32 i = 0; i < mBuffers[kPortIndexOutput].size(); i++) {
1154            BufferInfo *info = &mBuffers[kPortIndexOutput].editItemAt(i);
1155            status_t error = cancelBufferToNativeWindow(info);
1156            if (err == OK) {
1157                err = error;
1158            }
1159        }
1160
1161        static_cast<Surface*>(mNativeWindow.get())
1162                ->getIGraphicBufferProducer()->allowAllocation(false);
1163    }
1164
1165    mMetadataBuffersToSubmit = bufferCount - minUndequeuedBuffers;
1166    return err;
1167}
1168
1169status_t ACodec::submitOutputMetadataBuffer() {
1170    CHECK(storingMetadataInDecodedBuffers());
1171    if (mMetadataBuffersToSubmit == 0)
1172        return OK;
1173
1174    BufferInfo *info = dequeueBufferFromNativeWindow();
1175    if (info == NULL) {
1176        return ERROR_IO;
1177    }
1178
1179    ALOGV("[%s] submitting output meta buffer ID %u for graphic buffer %p",
1180          mComponentName.c_str(), info->mBufferID, info->mGraphicBuffer.get());
1181
1182    --mMetadataBuffersToSubmit;
1183    info->checkWriteFence("submitOutputMetadataBuffer");
1184    status_t err = mOMX->fillBuffer(mNode, info->mBufferID, info->mFenceFd);
1185    info->mFenceFd = -1;
1186    if (err == OK) {
1187        info->mStatus = BufferInfo::OWNED_BY_COMPONENT;
1188    }
1189
1190    return err;
1191}
1192
1193status_t ACodec::waitForFence(int fd, const char *dbg ) {
1194    status_t res = OK;
1195    if (fd >= 0) {
1196        sp<Fence> fence = new Fence(fd);
1197        res = fence->wait(IOMX::kFenceTimeoutMs);
1198        ALOGW_IF(res != OK, "FENCE TIMEOUT for %d in %s", fd, dbg);
1199    }
1200    return res;
1201}
1202
1203// static
1204const char *ACodec::_asString(BufferInfo::Status s) {
1205    switch (s) {
1206        case BufferInfo::OWNED_BY_US:            return "OUR";
1207        case BufferInfo::OWNED_BY_COMPONENT:     return "COMPONENT";
1208        case BufferInfo::OWNED_BY_UPSTREAM:      return "UPSTREAM";
1209        case BufferInfo::OWNED_BY_DOWNSTREAM:    return "DOWNSTREAM";
1210        case BufferInfo::OWNED_BY_NATIVE_WINDOW: return "SURFACE";
1211        case BufferInfo::UNRECOGNIZED:           return "UNRECOGNIZED";
1212        default:                                 return "?";
1213    }
1214}
1215
1216void ACodec::dumpBuffers(OMX_U32 portIndex) {
1217    CHECK(portIndex == kPortIndexInput || portIndex == kPortIndexOutput);
1218    ALOGI("[%s] %s port has %zu buffers:", mComponentName.c_str(),
1219            portIndex == kPortIndexInput ? "input" : "output", mBuffers[portIndex].size());
1220    for (size_t i = 0; i < mBuffers[portIndex].size(); ++i) {
1221        const BufferInfo &info = mBuffers[portIndex][i];
1222        ALOGI("  slot %2zu: #%8u %p/%p %s(%d) dequeued:%u",
1223                i, info.mBufferID, info.mGraphicBuffer.get(),
1224                info.mGraphicBuffer == NULL ? NULL : info.mGraphicBuffer->getNativeBuffer(),
1225                _asString(info.mStatus), info.mStatus, info.mDequeuedAt);
1226    }
1227}
1228
1229status_t ACodec::cancelBufferToNativeWindow(BufferInfo *info) {
1230    CHECK_EQ((int)info->mStatus, (int)BufferInfo::OWNED_BY_US);
1231
1232    ALOGV("[%s] Calling cancelBuffer on buffer %u",
1233         mComponentName.c_str(), info->mBufferID);
1234
1235    info->checkWriteFence("cancelBufferToNativeWindow");
1236    int err = mNativeWindow->cancelBuffer(
1237        mNativeWindow.get(), info->mGraphicBuffer.get(), info->mFenceFd);
1238    info->mFenceFd = -1;
1239
1240    ALOGW_IF(err != 0, "[%s] can not return buffer %u to native window",
1241            mComponentName.c_str(), info->mBufferID);
1242    // change ownership even if cancelBuffer fails
1243    info->mStatus = BufferInfo::OWNED_BY_NATIVE_WINDOW;
1244
1245    return err;
1246}
1247
1248void ACodec::updateRenderInfoForDequeuedBuffer(
1249        ANativeWindowBuffer *buf, int fenceFd, BufferInfo *info) {
1250
1251    info->mRenderInfo =
1252        mRenderTracker.updateInfoForDequeuedBuffer(
1253                buf, fenceFd, info - &mBuffers[kPortIndexOutput][0]);
1254
1255    // check for any fences already signaled
1256    notifyOfRenderedFrames(false /* dropIncomplete */, info->mRenderInfo);
1257}
1258
1259void ACodec::onFrameRendered(int64_t mediaTimeUs, nsecs_t systemNano) {
1260    if (mRenderTracker.onFrameRendered(mediaTimeUs, systemNano) != OK) {
1261        mRenderTracker.dumpRenderQueue();
1262    }
1263}
1264
1265void ACodec::notifyOfRenderedFrames(bool dropIncomplete, FrameRenderTracker::Info *until) {
1266    sp<AMessage> msg = mNotify->dup();
1267    msg->setInt32("what", CodecBase::kWhatOutputFramesRendered);
1268    std::list<FrameRenderTracker::Info> done =
1269        mRenderTracker.checkFencesAndGetRenderedFrames(until, dropIncomplete);
1270
1271    // unlink untracked frames
1272    for (std::list<FrameRenderTracker::Info>::const_iterator it = done.cbegin();
1273            it != done.cend(); ++it) {
1274        ssize_t index = it->getIndex();
1275        if (index >= 0 && (size_t)index < mBuffers[kPortIndexOutput].size()) {
1276            mBuffers[kPortIndexOutput].editItemAt(index).mRenderInfo = NULL;
1277        } else if (index >= 0) {
1278            // THIS SHOULD NEVER HAPPEN
1279            ALOGE("invalid index %zd in %zu", index, mBuffers[kPortIndexOutput].size());
1280        }
1281    }
1282
1283    if (MediaCodec::CreateFramesRenderedMessage(done, msg)) {
1284        msg->post();
1285    }
1286}
1287
1288ACodec::BufferInfo *ACodec::dequeueBufferFromNativeWindow() {
1289    ANativeWindowBuffer *buf;
1290    CHECK(mNativeWindow.get() != NULL);
1291
1292    if (mTunneled) {
1293        ALOGW("dequeueBufferFromNativeWindow() should not be called in tunnel"
1294              " video playback mode mode!");
1295        return NULL;
1296    }
1297
1298    int fenceFd = -1;
1299    do {
1300        status_t err = mNativeWindow->dequeueBuffer(mNativeWindow.get(), &buf, &fenceFd);
1301        if (err != 0) {
1302            ALOGE("dequeueBuffer failed: %s(%d).", asString(err), err);
1303            return NULL;
1304        }
1305
1306        bool stale = false;
1307        for (size_t i = mBuffers[kPortIndexOutput].size(); i-- > 0;) {
1308            BufferInfo *info = &mBuffers[kPortIndexOutput].editItemAt(i);
1309
1310            if (info->mGraphicBuffer != NULL &&
1311                    info->mGraphicBuffer->handle == buf->handle) {
1312                // Since consumers can attach buffers to BufferQueues, it is possible
1313                // that a known yet stale buffer can return from a surface that we
1314                // once used.  We can simply ignore this as we have already dequeued
1315                // this buffer properly.  NOTE: this does not eliminate all cases,
1316                // e.g. it is possible that we have queued the valid buffer to the
1317                // NW, and a stale copy of the same buffer gets dequeued - which will
1318                // be treated as the valid buffer by ACodec.
1319                if (info->mStatus != BufferInfo::OWNED_BY_NATIVE_WINDOW) {
1320                    ALOGI("dequeued stale buffer %p. discarding", buf);
1321                    stale = true;
1322                    break;
1323                }
1324
1325                ALOGV("dequeued buffer %p", info->mGraphicBuffer->getNativeBuffer());
1326                info->mStatus = BufferInfo::OWNED_BY_US;
1327                info->setWriteFence(fenceFd, "dequeueBufferFromNativeWindow");
1328                updateRenderInfoForDequeuedBuffer(buf, fenceFd, info);
1329                return info;
1330            }
1331        }
1332
1333        // It is also possible to receive a previously unregistered buffer
1334        // in non-meta mode. These should be treated as stale buffers. The
1335        // same is possible in meta mode, in which case, it will be treated
1336        // as a normal buffer, which is not desirable.
1337        // TODO: fix this.
1338        if (!stale && (!storingMetadataInDecodedBuffers() || mLegacyAdaptiveExperiment)) {
1339            ALOGI("dequeued unrecognized (stale) buffer %p. discarding", buf);
1340            stale = true;
1341        }
1342        if (stale) {
1343            // TODO: detach stale buffer, but there is no API yet to do it.
1344            buf = NULL;
1345        }
1346    } while (buf == NULL);
1347
1348    // get oldest undequeued buffer
1349    BufferInfo *oldest = NULL;
1350    for (size_t i = mBuffers[kPortIndexOutput].size(); i-- > 0;) {
1351        BufferInfo *info =
1352            &mBuffers[kPortIndexOutput].editItemAt(i);
1353        if (info->mStatus == BufferInfo::OWNED_BY_NATIVE_WINDOW &&
1354            (oldest == NULL ||
1355             // avoid potential issues from counter rolling over
1356             mDequeueCounter - info->mDequeuedAt >
1357                    mDequeueCounter - oldest->mDequeuedAt)) {
1358            oldest = info;
1359        }
1360    }
1361
1362    // it is impossible dequeue a buffer when there are no buffers with ANW
1363    CHECK(oldest != NULL);
1364    // it is impossible to dequeue an unknown buffer in non-meta mode, as the
1365    // while loop above does not complete
1366    CHECK(storingMetadataInDecodedBuffers());
1367
1368    // discard buffer in LRU info and replace with new buffer
1369    oldest->mGraphicBuffer = new GraphicBuffer(buf, false);
1370    oldest->mStatus = BufferInfo::OWNED_BY_US;
1371    oldest->setWriteFence(fenceFd, "dequeueBufferFromNativeWindow for oldest");
1372    mRenderTracker.untrackFrame(oldest->mRenderInfo);
1373    oldest->mRenderInfo = NULL;
1374
1375    mOMX->updateGraphicBufferInMeta(
1376            mNode, kPortIndexOutput, oldest->mGraphicBuffer,
1377            oldest->mBufferID);
1378
1379    if (mOutputMetadataType == kMetadataBufferTypeGrallocSource) {
1380        VideoGrallocMetadata *grallocMeta =
1381            reinterpret_cast<VideoGrallocMetadata *>(oldest->mData->base());
1382        ALOGV("replaced oldest buffer #%u with age %u (%p/%p stored in %p)",
1383                (unsigned)(oldest - &mBuffers[kPortIndexOutput][0]),
1384                mDequeueCounter - oldest->mDequeuedAt,
1385                grallocMeta->pHandle,
1386                oldest->mGraphicBuffer->handle, oldest->mData->base());
1387    } else if (mOutputMetadataType == kMetadataBufferTypeANWBuffer) {
1388        VideoNativeMetadata *nativeMeta =
1389            reinterpret_cast<VideoNativeMetadata *>(oldest->mData->base());
1390        ALOGV("replaced oldest buffer #%u with age %u (%p/%p stored in %p)",
1391                (unsigned)(oldest - &mBuffers[kPortIndexOutput][0]),
1392                mDequeueCounter - oldest->mDequeuedAt,
1393                nativeMeta->pBuffer,
1394                oldest->mGraphicBuffer->getNativeBuffer(), oldest->mData->base());
1395    }
1396
1397    updateRenderInfoForDequeuedBuffer(buf, fenceFd, oldest);
1398    return oldest;
1399}
1400
1401status_t ACodec::freeBuffersOnPort(OMX_U32 portIndex) {
1402    status_t err = OK;
1403    for (size_t i = mBuffers[portIndex].size(); i > 0;) {
1404        i--;
1405        status_t err2 = freeBuffer(portIndex, i);
1406        if (err == OK) {
1407            err = err2;
1408        }
1409    }
1410
1411    // clear mDealer even on an error
1412    mDealer[portIndex].clear();
1413    return err;
1414}
1415
1416status_t ACodec::freeOutputBuffersNotOwnedByComponent() {
1417    status_t err = OK;
1418    for (size_t i = mBuffers[kPortIndexOutput].size(); i > 0;) {
1419        i--;
1420        BufferInfo *info =
1421            &mBuffers[kPortIndexOutput].editItemAt(i);
1422
1423        // At this time some buffers may still be with the component
1424        // or being drained.
1425        if (info->mStatus != BufferInfo::OWNED_BY_COMPONENT &&
1426            info->mStatus != BufferInfo::OWNED_BY_DOWNSTREAM) {
1427            status_t err2 = freeBuffer(kPortIndexOutput, i);
1428            if (err == OK) {
1429                err = err2;
1430            }
1431        }
1432    }
1433
1434    return err;
1435}
1436
1437status_t ACodec::freeBuffer(OMX_U32 portIndex, size_t i) {
1438    BufferInfo *info = &mBuffers[portIndex].editItemAt(i);
1439    status_t err = OK;
1440
1441    // there should not be any fences in the metadata
1442    MetadataBufferType type =
1443        portIndex == kPortIndexOutput ? mOutputMetadataType : mInputMetadataType;
1444    if (type == kMetadataBufferTypeANWBuffer && info->mData != NULL
1445            && info->mData->size() >= sizeof(VideoNativeMetadata)) {
1446        int fenceFd = ((VideoNativeMetadata *)info->mData->data())->nFenceFd;
1447        if (fenceFd >= 0) {
1448            ALOGW("unreleased fence (%d) in %s metadata buffer %zu",
1449                    fenceFd, portIndex == kPortIndexInput ? "input" : "output", i);
1450        }
1451    }
1452
1453    switch (info->mStatus) {
1454        case BufferInfo::OWNED_BY_US:
1455            if (portIndex == kPortIndexOutput && mNativeWindow != NULL) {
1456                (void)cancelBufferToNativeWindow(info);
1457            }
1458            // fall through
1459
1460        case BufferInfo::OWNED_BY_NATIVE_WINDOW:
1461            err = mOMX->freeBuffer(mNode, portIndex, info->mBufferID);
1462            break;
1463
1464        default:
1465            ALOGE("trying to free buffer not owned by us or ANW (%d)", info->mStatus);
1466            err = FAILED_TRANSACTION;
1467            break;
1468    }
1469
1470    if (info->mFenceFd >= 0) {
1471        ::close(info->mFenceFd);
1472    }
1473
1474    if (portIndex == kPortIndexOutput) {
1475        mRenderTracker.untrackFrame(info->mRenderInfo, i);
1476        info->mRenderInfo = NULL;
1477    }
1478
1479    // remove buffer even if mOMX->freeBuffer fails
1480    mBuffers[portIndex].removeAt(i);
1481    return err;
1482}
1483
1484ACodec::BufferInfo *ACodec::findBufferByID(
1485        uint32_t portIndex, IOMX::buffer_id bufferID, ssize_t *index) {
1486    for (size_t i = 0; i < mBuffers[portIndex].size(); ++i) {
1487        BufferInfo *info = &mBuffers[portIndex].editItemAt(i);
1488
1489        if (info->mBufferID == bufferID) {
1490            if (index != NULL) {
1491                *index = i;
1492            }
1493            return info;
1494        }
1495    }
1496
1497    ALOGE("Could not find buffer with ID %u", bufferID);
1498    return NULL;
1499}
1500
1501status_t ACodec::setComponentRole(
1502        bool isEncoder, const char *mime) {
1503    struct MimeToRole {
1504        const char *mime;
1505        const char *decoderRole;
1506        const char *encoderRole;
1507    };
1508
1509    static const MimeToRole kMimeToRole[] = {
1510        { MEDIA_MIMETYPE_AUDIO_MPEG,
1511            "audio_decoder.mp3", "audio_encoder.mp3" },
1512        { MEDIA_MIMETYPE_AUDIO_MPEG_LAYER_I,
1513            "audio_decoder.mp1", "audio_encoder.mp1" },
1514        { MEDIA_MIMETYPE_AUDIO_MPEG_LAYER_II,
1515            "audio_decoder.mp2", "audio_encoder.mp2" },
1516        { MEDIA_MIMETYPE_AUDIO_AMR_NB,
1517            "audio_decoder.amrnb", "audio_encoder.amrnb" },
1518        { MEDIA_MIMETYPE_AUDIO_AMR_WB,
1519            "audio_decoder.amrwb", "audio_encoder.amrwb" },
1520        { MEDIA_MIMETYPE_AUDIO_AAC,
1521            "audio_decoder.aac", "audio_encoder.aac" },
1522        { MEDIA_MIMETYPE_AUDIO_VORBIS,
1523            "audio_decoder.vorbis", "audio_encoder.vorbis" },
1524        { MEDIA_MIMETYPE_AUDIO_OPUS,
1525            "audio_decoder.opus", "audio_encoder.opus" },
1526        { MEDIA_MIMETYPE_AUDIO_G711_MLAW,
1527            "audio_decoder.g711mlaw", "audio_encoder.g711mlaw" },
1528        { MEDIA_MIMETYPE_AUDIO_G711_ALAW,
1529            "audio_decoder.g711alaw", "audio_encoder.g711alaw" },
1530        { MEDIA_MIMETYPE_VIDEO_AVC,
1531            "video_decoder.avc", "video_encoder.avc" },
1532        { MEDIA_MIMETYPE_VIDEO_HEVC,
1533            "video_decoder.hevc", "video_encoder.hevc" },
1534        { MEDIA_MIMETYPE_VIDEO_MPEG4,
1535            "video_decoder.mpeg4", "video_encoder.mpeg4" },
1536        { MEDIA_MIMETYPE_VIDEO_H263,
1537            "video_decoder.h263", "video_encoder.h263" },
1538        { MEDIA_MIMETYPE_VIDEO_VP8,
1539            "video_decoder.vp8", "video_encoder.vp8" },
1540        { MEDIA_MIMETYPE_VIDEO_VP9,
1541            "video_decoder.vp9", "video_encoder.vp9" },
1542        { MEDIA_MIMETYPE_AUDIO_RAW,
1543            "audio_decoder.raw", "audio_encoder.raw" },
1544        { MEDIA_MIMETYPE_AUDIO_FLAC,
1545            "audio_decoder.flac", "audio_encoder.flac" },
1546        { MEDIA_MIMETYPE_AUDIO_MSGSM,
1547            "audio_decoder.gsm", "audio_encoder.gsm" },
1548        { MEDIA_MIMETYPE_VIDEO_MPEG2,
1549            "video_decoder.mpeg2", "video_encoder.mpeg2" },
1550        { MEDIA_MIMETYPE_AUDIO_AC3,
1551            "audio_decoder.ac3", "audio_encoder.ac3" },
1552        { MEDIA_MIMETYPE_AUDIO_EAC3,
1553            "audio_decoder.eac3", "audio_encoder.eac3" },
1554    };
1555
1556    static const size_t kNumMimeToRole =
1557        sizeof(kMimeToRole) / sizeof(kMimeToRole[0]);
1558
1559    size_t i;
1560    for (i = 0; i < kNumMimeToRole; ++i) {
1561        if (!strcasecmp(mime, kMimeToRole[i].mime)) {
1562            break;
1563        }
1564    }
1565
1566    if (i == kNumMimeToRole) {
1567        return ERROR_UNSUPPORTED;
1568    }
1569
1570    const char *role =
1571        isEncoder ? kMimeToRole[i].encoderRole
1572                  : kMimeToRole[i].decoderRole;
1573
1574    if (role != NULL) {
1575        OMX_PARAM_COMPONENTROLETYPE roleParams;
1576        InitOMXParams(&roleParams);
1577
1578        strncpy((char *)roleParams.cRole,
1579                role, OMX_MAX_STRINGNAME_SIZE - 1);
1580
1581        roleParams.cRole[OMX_MAX_STRINGNAME_SIZE - 1] = '\0';
1582
1583        status_t err = mOMX->setParameter(
1584                mNode, OMX_IndexParamStandardComponentRole,
1585                &roleParams, sizeof(roleParams));
1586
1587        if (err != OK) {
1588            ALOGW("[%s] Failed to set standard component role '%s'.",
1589                 mComponentName.c_str(), role);
1590
1591            return err;
1592        }
1593    }
1594
1595    return OK;
1596}
1597
1598status_t ACodec::configureCodec(
1599        const char *mime, const sp<AMessage> &msg) {
1600    int32_t encoder;
1601    if (!msg->findInt32("encoder", &encoder)) {
1602        encoder = false;
1603    }
1604
1605    sp<AMessage> inputFormat = new AMessage();
1606    sp<AMessage> outputFormat = mNotify->dup(); // will use this for kWhatOutputFormatChanged
1607
1608    mIsEncoder = encoder;
1609
1610    mInputMetadataType = kMetadataBufferTypeInvalid;
1611    mOutputMetadataType = kMetadataBufferTypeInvalid;
1612
1613    status_t err = setComponentRole(encoder /* isEncoder */, mime);
1614
1615    if (err != OK) {
1616        return err;
1617    }
1618
1619    int32_t bitRate = 0;
1620    // FLAC encoder doesn't need a bitrate, other encoders do
1621    if (encoder && strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_FLAC)
1622            && !msg->findInt32("bitrate", &bitRate)) {
1623        return INVALID_OPERATION;
1624    }
1625
1626    int32_t storeMeta;
1627    if (encoder
1628            && msg->findInt32("store-metadata-in-buffers", &storeMeta)
1629            && storeMeta != 0) {
1630        err = mOMX->storeMetaDataInBuffers(mNode, kPortIndexInput, OMX_TRUE, &mInputMetadataType);
1631        if (err != OK) {
1632            ALOGE("[%s] storeMetaDataInBuffers (input) failed w/ err %d",
1633                    mComponentName.c_str(), err);
1634
1635            return err;
1636        }
1637        // For this specific case we could be using camera source even if storeMetaDataInBuffers
1638        // returns Gralloc source. Pretend that we are; this will force us to use nBufferSize.
1639        if (mInputMetadataType == kMetadataBufferTypeGrallocSource) {
1640            mInputMetadataType = kMetadataBufferTypeCameraSource;
1641        }
1642
1643        uint32_t usageBits;
1644        if (mOMX->getParameter(
1645                mNode, (OMX_INDEXTYPE)OMX_IndexParamConsumerUsageBits,
1646                &usageBits, sizeof(usageBits)) == OK) {
1647            inputFormat->setInt32(
1648                    "using-sw-read-often", !!(usageBits & GRALLOC_USAGE_SW_READ_OFTEN));
1649        }
1650    }
1651
1652    int32_t prependSPSPPS = 0;
1653    if (encoder
1654            && msg->findInt32("prepend-sps-pps-to-idr-frames", &prependSPSPPS)
1655            && prependSPSPPS != 0) {
1656        OMX_INDEXTYPE index;
1657        err = mOMX->getExtensionIndex(
1658                mNode,
1659                "OMX.google.android.index.prependSPSPPSToIDRFrames",
1660                &index);
1661
1662        if (err == OK) {
1663            PrependSPSPPSToIDRFramesParams params;
1664            InitOMXParams(&params);
1665            params.bEnable = OMX_TRUE;
1666
1667            err = mOMX->setParameter(
1668                    mNode, index, &params, sizeof(params));
1669        }
1670
1671        if (err != OK) {
1672            ALOGE("Encoder could not be configured to emit SPS/PPS before "
1673                  "IDR frames. (err %d)", err);
1674
1675            return err;
1676        }
1677    }
1678
1679    // Only enable metadata mode on encoder output if encoder can prepend
1680    // sps/pps to idr frames, since in metadata mode the bitstream is in an
1681    // opaque handle, to which we don't have access.
1682    int32_t video = !strncasecmp(mime, "video/", 6);
1683    mIsVideo = video;
1684    if (encoder && video) {
1685        OMX_BOOL enable = (OMX_BOOL) (prependSPSPPS
1686            && msg->findInt32("store-metadata-in-buffers-output", &storeMeta)
1687            && storeMeta != 0);
1688
1689        err = mOMX->storeMetaDataInBuffers(mNode, kPortIndexOutput, enable, &mOutputMetadataType);
1690        if (err != OK) {
1691            ALOGE("[%s] storeMetaDataInBuffers (output) failed w/ err %d",
1692                mComponentName.c_str(), err);
1693        }
1694
1695        if (!msg->findInt64(
1696                    "repeat-previous-frame-after",
1697                    &mRepeatFrameDelayUs)) {
1698            mRepeatFrameDelayUs = -1ll;
1699        }
1700
1701        if (!msg->findInt64("max-pts-gap-to-encoder", &mMaxPtsGapUs)) {
1702            mMaxPtsGapUs = -1ll;
1703        }
1704
1705        if (!msg->findFloat("max-fps-to-encoder", &mMaxFps)) {
1706            mMaxFps = -1;
1707        }
1708
1709        if (!msg->findInt64("time-lapse", &mTimePerCaptureUs)) {
1710            mTimePerCaptureUs = -1ll;
1711        }
1712
1713        if (!msg->findInt32(
1714                    "create-input-buffers-suspended",
1715                    (int32_t*)&mCreateInputBuffersSuspended)) {
1716            mCreateInputBuffersSuspended = false;
1717        }
1718    }
1719
1720    // NOTE: we only use native window for video decoders
1721    sp<RefBase> obj;
1722    bool haveNativeWindow = msg->findObject("native-window", &obj)
1723            && obj != NULL && video && !encoder;
1724    mLegacyAdaptiveExperiment = false;
1725    if (video && !encoder) {
1726        inputFormat->setInt32("adaptive-playback", false);
1727
1728        int32_t usageProtected;
1729        if (msg->findInt32("protected", &usageProtected) && usageProtected) {
1730            if (!haveNativeWindow) {
1731                ALOGE("protected output buffers must be sent to an ANativeWindow");
1732                return PERMISSION_DENIED;
1733            }
1734            mFlags |= kFlagIsGrallocUsageProtected;
1735            mFlags |= kFlagPushBlankBuffersToNativeWindowOnShutdown;
1736        }
1737    }
1738    if (haveNativeWindow) {
1739        sp<ANativeWindow> nativeWindow =
1740            static_cast<ANativeWindow *>(static_cast<Surface *>(obj.get()));
1741
1742        // START of temporary support for automatic FRC - THIS WILL BE REMOVED
1743        int32_t autoFrc;
1744        if (msg->findInt32("auto-frc", &autoFrc)) {
1745            bool enabled = autoFrc;
1746            OMX_CONFIG_BOOLEANTYPE config;
1747            InitOMXParams(&config);
1748            config.bEnabled = (OMX_BOOL)enabled;
1749            status_t temp = mOMX->setConfig(
1750                    mNode, (OMX_INDEXTYPE)OMX_IndexConfigAutoFramerateConversion,
1751                    &config, sizeof(config));
1752            if (temp == OK) {
1753                outputFormat->setInt32("auto-frc", enabled);
1754            } else if (enabled) {
1755                ALOGI("codec does not support requested auto-frc (err %d)", temp);
1756            }
1757        }
1758        // END of temporary support for automatic FRC
1759
1760        int32_t tunneled;
1761        if (msg->findInt32("feature-tunneled-playback", &tunneled) &&
1762            tunneled != 0) {
1763            ALOGI("Configuring TUNNELED video playback.");
1764            mTunneled = true;
1765
1766            int32_t audioHwSync = 0;
1767            if (!msg->findInt32("audio-hw-sync", &audioHwSync)) {
1768                ALOGW("No Audio HW Sync provided for video tunnel");
1769            }
1770            err = configureTunneledVideoPlayback(audioHwSync, nativeWindow);
1771            if (err != OK) {
1772                ALOGE("configureTunneledVideoPlayback(%d,%p) failed!",
1773                        audioHwSync, nativeWindow.get());
1774                return err;
1775            }
1776
1777            int32_t maxWidth = 0, maxHeight = 0;
1778            if (msg->findInt32("max-width", &maxWidth) &&
1779                    msg->findInt32("max-height", &maxHeight)) {
1780
1781                err = mOMX->prepareForAdaptivePlayback(
1782                        mNode, kPortIndexOutput, OMX_TRUE, maxWidth, maxHeight);
1783                if (err != OK) {
1784                    ALOGW("[%s] prepareForAdaptivePlayback failed w/ err %d",
1785                            mComponentName.c_str(), err);
1786                    // allow failure
1787                    err = OK;
1788                } else {
1789                    inputFormat->setInt32("max-width", maxWidth);
1790                    inputFormat->setInt32("max-height", maxHeight);
1791                    inputFormat->setInt32("adaptive-playback", true);
1792                }
1793            }
1794        } else {
1795            ALOGV("Configuring CPU controlled video playback.");
1796            mTunneled = false;
1797
1798            // Explicity reset the sideband handle of the window for
1799            // non-tunneled video in case the window was previously used
1800            // for a tunneled video playback.
1801            err = native_window_set_sideband_stream(nativeWindow.get(), NULL);
1802            if (err != OK) {
1803                ALOGE("set_sideband_stream(NULL) failed! (err %d).", err);
1804                return err;
1805            }
1806
1807            // Always try to enable dynamic output buffers on native surface
1808            err = mOMX->storeMetaDataInBuffers(
1809                    mNode, kPortIndexOutput, OMX_TRUE, &mOutputMetadataType);
1810            if (err != OK) {
1811                ALOGE("[%s] storeMetaDataInBuffers failed w/ err %d",
1812                        mComponentName.c_str(), err);
1813
1814                // if adaptive playback has been requested, try JB fallback
1815                // NOTE: THIS FALLBACK MECHANISM WILL BE REMOVED DUE TO ITS
1816                // LARGE MEMORY REQUIREMENT
1817
1818                // we will not do adaptive playback on software accessed
1819                // surfaces as they never had to respond to changes in the
1820                // crop window, and we don't trust that they will be able to.
1821                int usageBits = 0;
1822                bool canDoAdaptivePlayback;
1823
1824                if (nativeWindow->query(
1825                        nativeWindow.get(),
1826                        NATIVE_WINDOW_CONSUMER_USAGE_BITS,
1827                        &usageBits) != OK) {
1828                    canDoAdaptivePlayback = false;
1829                } else {
1830                    canDoAdaptivePlayback =
1831                        (usageBits &
1832                                (GRALLOC_USAGE_SW_READ_MASK |
1833                                 GRALLOC_USAGE_SW_WRITE_MASK)) == 0;
1834                }
1835
1836                int32_t maxWidth = 0, maxHeight = 0;
1837                if (canDoAdaptivePlayback &&
1838                        msg->findInt32("max-width", &maxWidth) &&
1839                        msg->findInt32("max-height", &maxHeight)) {
1840                    ALOGV("[%s] prepareForAdaptivePlayback(%dx%d)",
1841                            mComponentName.c_str(), maxWidth, maxHeight);
1842
1843                    err = mOMX->prepareForAdaptivePlayback(
1844                            mNode, kPortIndexOutput, OMX_TRUE, maxWidth,
1845                            maxHeight);
1846                    ALOGW_IF(err != OK,
1847                            "[%s] prepareForAdaptivePlayback failed w/ err %d",
1848                            mComponentName.c_str(), err);
1849
1850                    if (err == OK) {
1851                        inputFormat->setInt32("max-width", maxWidth);
1852                        inputFormat->setInt32("max-height", maxHeight);
1853                        inputFormat->setInt32("adaptive-playback", true);
1854                    }
1855                }
1856                // allow failure
1857                err = OK;
1858            } else {
1859                ALOGV("[%s] storeMetaDataInBuffers succeeded",
1860                        mComponentName.c_str());
1861                CHECK(storingMetadataInDecodedBuffers());
1862                mLegacyAdaptiveExperiment = ADebug::isExperimentEnabled(
1863                        "legacy-adaptive", !msg->contains("no-experiments"));
1864
1865                inputFormat->setInt32("adaptive-playback", true);
1866            }
1867
1868            int32_t push;
1869            if (msg->findInt32("push-blank-buffers-on-shutdown", &push)
1870                    && push != 0) {
1871                mFlags |= kFlagPushBlankBuffersToNativeWindowOnShutdown;
1872            }
1873        }
1874
1875        int32_t rotationDegrees;
1876        if (msg->findInt32("rotation-degrees", &rotationDegrees)) {
1877            mRotationDegrees = rotationDegrees;
1878        } else {
1879            mRotationDegrees = 0;
1880        }
1881    }
1882
1883    if (video) {
1884        // determine need for software renderer
1885        bool usingSwRenderer = false;
1886        if (haveNativeWindow && mComponentName.startsWith("OMX.google.")) {
1887            usingSwRenderer = true;
1888            haveNativeWindow = false;
1889        }
1890
1891        if (encoder) {
1892            err = setupVideoEncoder(mime, msg);
1893        } else {
1894            err = setupVideoDecoder(mime, msg, haveNativeWindow);
1895        }
1896
1897        if (err != OK) {
1898            return err;
1899        }
1900
1901        if (haveNativeWindow) {
1902            mNativeWindow = static_cast<Surface *>(obj.get());
1903        }
1904
1905        // initialize native window now to get actual output format
1906        // TODO: this is needed for some encoders even though they don't use native window
1907        err = initNativeWindow();
1908        if (err != OK) {
1909            return err;
1910        }
1911
1912        // fallback for devices that do not handle flex-YUV for native buffers
1913        if (haveNativeWindow) {
1914            int32_t requestedColorFormat = OMX_COLOR_FormatUnused;
1915            if (msg->findInt32("color-format", &requestedColorFormat) &&
1916                    requestedColorFormat == OMX_COLOR_FormatYUV420Flexible) {
1917                status_t err = getPortFormat(kPortIndexOutput, outputFormat);
1918                if (err != OK) {
1919                    return err;
1920                }
1921                int32_t colorFormat = OMX_COLOR_FormatUnused;
1922                OMX_U32 flexibleEquivalent = OMX_COLOR_FormatUnused;
1923                if (!outputFormat->findInt32("color-format", &colorFormat)) {
1924                    ALOGE("ouptut port did not have a color format (wrong domain?)");
1925                    return BAD_VALUE;
1926                }
1927                ALOGD("[%s] Requested output format %#x and got %#x.",
1928                        mComponentName.c_str(), requestedColorFormat, colorFormat);
1929                if (!isFlexibleColorFormat(
1930                                mOMX, mNode, colorFormat, haveNativeWindow, &flexibleEquivalent)
1931                        || flexibleEquivalent != (OMX_U32)requestedColorFormat) {
1932                    // device did not handle flex-YUV request for native window, fall back
1933                    // to SW renderer
1934                    ALOGI("[%s] Falling back to software renderer", mComponentName.c_str());
1935                    mNativeWindow.clear();
1936                    haveNativeWindow = false;
1937                    usingSwRenderer = true;
1938                    if (storingMetadataInDecodedBuffers()) {
1939                        err = mOMX->storeMetaDataInBuffers(
1940                                mNode, kPortIndexOutput, OMX_FALSE, &mOutputMetadataType);
1941                        mOutputMetadataType = kMetadataBufferTypeInvalid; // just in case
1942                        // TODO: implement adaptive-playback support for bytebuffer mode.
1943                        // This is done by SW codecs, but most HW codecs don't support it.
1944                        inputFormat->setInt32("adaptive-playback", false);
1945                    }
1946                    if (err == OK) {
1947                        err = mOMX->enableGraphicBuffers(mNode, kPortIndexOutput, OMX_FALSE);
1948                    }
1949                    if (mFlags & kFlagIsGrallocUsageProtected) {
1950                        // fallback is not supported for protected playback
1951                        err = PERMISSION_DENIED;
1952                    } else if (err == OK) {
1953                        err = setupVideoDecoder(mime, msg, false);
1954                    }
1955                }
1956            }
1957        }
1958
1959        if (usingSwRenderer) {
1960            outputFormat->setInt32("using-sw-renderer", 1);
1961        }
1962    } else if (!strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_MPEG)) {
1963        int32_t numChannels, sampleRate;
1964        if (!msg->findInt32("channel-count", &numChannels)
1965                || !msg->findInt32("sample-rate", &sampleRate)) {
1966            // Since we did not always check for these, leave them optional
1967            // and have the decoder figure it all out.
1968            err = OK;
1969        } else {
1970            err = setupRawAudioFormat(
1971                    encoder ? kPortIndexInput : kPortIndexOutput,
1972                    sampleRate,
1973                    numChannels);
1974        }
1975    } else if (!strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_AAC)) {
1976        int32_t numChannels, sampleRate;
1977        if (!msg->findInt32("channel-count", &numChannels)
1978                || !msg->findInt32("sample-rate", &sampleRate)) {
1979            err = INVALID_OPERATION;
1980        } else {
1981            int32_t isADTS, aacProfile;
1982            int32_t sbrMode;
1983            int32_t maxOutputChannelCount;
1984            int32_t pcmLimiterEnable;
1985            drcParams_t drc;
1986            if (!msg->findInt32("is-adts", &isADTS)) {
1987                isADTS = 0;
1988            }
1989            if (!msg->findInt32("aac-profile", &aacProfile)) {
1990                aacProfile = OMX_AUDIO_AACObjectNull;
1991            }
1992            if (!msg->findInt32("aac-sbr-mode", &sbrMode)) {
1993                sbrMode = -1;
1994            }
1995
1996            if (!msg->findInt32("aac-max-output-channel_count", &maxOutputChannelCount)) {
1997                maxOutputChannelCount = -1;
1998            }
1999            if (!msg->findInt32("aac-pcm-limiter-enable", &pcmLimiterEnable)) {
2000                // value is unknown
2001                pcmLimiterEnable = -1;
2002            }
2003            if (!msg->findInt32("aac-encoded-target-level", &drc.encodedTargetLevel)) {
2004                // value is unknown
2005                drc.encodedTargetLevel = -1;
2006            }
2007            if (!msg->findInt32("aac-drc-cut-level", &drc.drcCut)) {
2008                // value is unknown
2009                drc.drcCut = -1;
2010            }
2011            if (!msg->findInt32("aac-drc-boost-level", &drc.drcBoost)) {
2012                // value is unknown
2013                drc.drcBoost = -1;
2014            }
2015            if (!msg->findInt32("aac-drc-heavy-compression", &drc.heavyCompression)) {
2016                // value is unknown
2017                drc.heavyCompression = -1;
2018            }
2019            if (!msg->findInt32("aac-target-ref-level", &drc.targetRefLevel)) {
2020                // value is unknown
2021                drc.targetRefLevel = -1;
2022            }
2023
2024            err = setupAACCodec(
2025                    encoder, numChannels, sampleRate, bitRate, aacProfile,
2026                    isADTS != 0, sbrMode, maxOutputChannelCount, drc,
2027                    pcmLimiterEnable);
2028        }
2029    } else if (!strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_AMR_NB)) {
2030        err = setupAMRCodec(encoder, false /* isWAMR */, bitRate);
2031    } else if (!strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_AMR_WB)) {
2032        err = setupAMRCodec(encoder, true /* isWAMR */, bitRate);
2033    } else if (!strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_G711_ALAW)
2034            || !strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_G711_MLAW)) {
2035        // These are PCM-like formats with a fixed sample rate but
2036        // a variable number of channels.
2037
2038        int32_t numChannels;
2039        if (!msg->findInt32("channel-count", &numChannels)) {
2040            err = INVALID_OPERATION;
2041        } else {
2042            int32_t sampleRate;
2043            if (!msg->findInt32("sample-rate", &sampleRate)) {
2044                sampleRate = 8000;
2045            }
2046            err = setupG711Codec(encoder, sampleRate, numChannels);
2047        }
2048    } else if (!strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_FLAC)) {
2049        int32_t numChannels = 0, sampleRate = 0, compressionLevel = -1;
2050        if (encoder &&
2051                (!msg->findInt32("channel-count", &numChannels)
2052                        || !msg->findInt32("sample-rate", &sampleRate))) {
2053            ALOGE("missing channel count or sample rate for FLAC encoder");
2054            err = INVALID_OPERATION;
2055        } else {
2056            if (encoder) {
2057                if (!msg->findInt32(
2058                            "complexity", &compressionLevel) &&
2059                    !msg->findInt32(
2060                            "flac-compression-level", &compressionLevel)) {
2061                    compressionLevel = 5; // default FLAC compression level
2062                } else if (compressionLevel < 0) {
2063                    ALOGW("compression level %d outside [0..8] range, "
2064                          "using 0",
2065                          compressionLevel);
2066                    compressionLevel = 0;
2067                } else if (compressionLevel > 8) {
2068                    ALOGW("compression level %d outside [0..8] range, "
2069                          "using 8",
2070                          compressionLevel);
2071                    compressionLevel = 8;
2072                }
2073            }
2074            err = setupFlacCodec(
2075                    encoder, numChannels, sampleRate, compressionLevel);
2076        }
2077    } else if (!strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_RAW)) {
2078        int32_t numChannels, sampleRate;
2079        if (encoder
2080                || !msg->findInt32("channel-count", &numChannels)
2081                || !msg->findInt32("sample-rate", &sampleRate)) {
2082            err = INVALID_OPERATION;
2083        } else {
2084            err = setupRawAudioFormat(kPortIndexInput, sampleRate, numChannels);
2085        }
2086    } else if (!strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_AC3)) {
2087        int32_t numChannels;
2088        int32_t sampleRate;
2089        if (!msg->findInt32("channel-count", &numChannels)
2090                || !msg->findInt32("sample-rate", &sampleRate)) {
2091            err = INVALID_OPERATION;
2092        } else {
2093            err = setupAC3Codec(encoder, numChannels, sampleRate);
2094        }
2095    } else if (!strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_EAC3)) {
2096        int32_t numChannels;
2097        int32_t sampleRate;
2098        if (!msg->findInt32("channel-count", &numChannels)
2099                || !msg->findInt32("sample-rate", &sampleRate)) {
2100            err = INVALID_OPERATION;
2101        } else {
2102            err = setupEAC3Codec(encoder, numChannels, sampleRate);
2103        }
2104    }
2105
2106    if (err != OK) {
2107        return err;
2108    }
2109
2110    if (!msg->findInt32("encoder-delay", &mEncoderDelay)) {
2111        mEncoderDelay = 0;
2112    }
2113
2114    if (!msg->findInt32("encoder-padding", &mEncoderPadding)) {
2115        mEncoderPadding = 0;
2116    }
2117
2118    if (msg->findInt32("channel-mask", &mChannelMask)) {
2119        mChannelMaskPresent = true;
2120    } else {
2121        mChannelMaskPresent = false;
2122    }
2123
2124    int32_t maxInputSize;
2125    if (msg->findInt32("max-input-size", &maxInputSize)) {
2126        err = setMinBufferSize(kPortIndexInput, (size_t)maxInputSize);
2127    } else if (!strcmp("OMX.Nvidia.aac.decoder", mComponentName.c_str())) {
2128        err = setMinBufferSize(kPortIndexInput, 8192);  // XXX
2129    }
2130
2131    int32_t priority;
2132    if (msg->findInt32("priority", &priority)) {
2133        err = setPriority(priority);
2134    }
2135
2136    int32_t rateInt = -1;
2137    float rateFloat = -1;
2138    if (!msg->findFloat("operating-rate", &rateFloat)) {
2139        msg->findInt32("operating-rate", &rateInt);
2140        rateFloat = (float)rateInt;  // 16MHz (FLINTMAX) is OK for upper bound.
2141    }
2142    if (rateFloat > 0) {
2143        err = setOperatingRate(rateFloat, video);
2144    }
2145
2146    mBaseOutputFormat = outputFormat;
2147
2148    err = getPortFormat(kPortIndexInput, inputFormat);
2149    if (err == OK) {
2150        err = getPortFormat(kPortIndexOutput, outputFormat);
2151        if (err == OK) {
2152            mInputFormat = inputFormat;
2153            mOutputFormat = outputFormat;
2154        }
2155    }
2156    return err;
2157}
2158
2159status_t ACodec::setPriority(int32_t priority) {
2160    if (priority < 0) {
2161        return BAD_VALUE;
2162    }
2163    OMX_PARAM_U32TYPE config;
2164    InitOMXParams(&config);
2165    config.nU32 = (OMX_U32)priority;
2166    status_t temp = mOMX->setConfig(
2167            mNode, (OMX_INDEXTYPE)OMX_IndexConfigPriority,
2168            &config, sizeof(config));
2169    if (temp != OK) {
2170        ALOGI("codec does not support config priority (err %d)", temp);
2171    }
2172    return OK;
2173}
2174
2175status_t ACodec::setOperatingRate(float rateFloat, bool isVideo) {
2176    if (rateFloat < 0) {
2177        return BAD_VALUE;
2178    }
2179    OMX_U32 rate;
2180    if (isVideo) {
2181        if (rateFloat > 65535) {
2182            return BAD_VALUE;
2183        }
2184        rate = (OMX_U32)(rateFloat * 65536.0f + 0.5f);
2185    } else {
2186        if (rateFloat > UINT_MAX) {
2187            return BAD_VALUE;
2188        }
2189        rate = (OMX_U32)(rateFloat);
2190    }
2191    OMX_PARAM_U32TYPE config;
2192    InitOMXParams(&config);
2193    config.nU32 = rate;
2194    status_t err = mOMX->setConfig(
2195            mNode, (OMX_INDEXTYPE)OMX_IndexConfigOperatingRate,
2196            &config, sizeof(config));
2197    if (err != OK) {
2198        ALOGI("codec does not support config operating rate (err %d)", err);
2199    }
2200    return OK;
2201}
2202
2203status_t ACodec::setMinBufferSize(OMX_U32 portIndex, size_t size) {
2204    OMX_PARAM_PORTDEFINITIONTYPE def;
2205    InitOMXParams(&def);
2206    def.nPortIndex = portIndex;
2207
2208    status_t err = mOMX->getParameter(
2209            mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
2210
2211    if (err != OK) {
2212        return err;
2213    }
2214
2215    if (def.nBufferSize >= size) {
2216        return OK;
2217    }
2218
2219    def.nBufferSize = size;
2220
2221    err = mOMX->setParameter(
2222            mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
2223
2224    if (err != OK) {
2225        return err;
2226    }
2227
2228    err = mOMX->getParameter(
2229            mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
2230
2231    if (err != OK) {
2232        return err;
2233    }
2234
2235    if (def.nBufferSize < size) {
2236        ALOGE("failed to set min buffer size to %zu (is still %u)", size, def.nBufferSize);
2237        return FAILED_TRANSACTION;
2238    }
2239
2240    return OK;
2241}
2242
2243status_t ACodec::selectAudioPortFormat(
2244        OMX_U32 portIndex, OMX_AUDIO_CODINGTYPE desiredFormat) {
2245    OMX_AUDIO_PARAM_PORTFORMATTYPE format;
2246    InitOMXParams(&format);
2247
2248    format.nPortIndex = portIndex;
2249    for (OMX_U32 index = 0;; ++index) {
2250        format.nIndex = index;
2251
2252        status_t err = mOMX->getParameter(
2253                mNode, OMX_IndexParamAudioPortFormat,
2254                &format, sizeof(format));
2255
2256        if (err != OK) {
2257            return err;
2258        }
2259
2260        if (format.eEncoding == desiredFormat) {
2261            break;
2262        }
2263    }
2264
2265    return mOMX->setParameter(
2266            mNode, OMX_IndexParamAudioPortFormat, &format, sizeof(format));
2267}
2268
2269status_t ACodec::setupAACCodec(
2270        bool encoder, int32_t numChannels, int32_t sampleRate,
2271        int32_t bitRate, int32_t aacProfile, bool isADTS, int32_t sbrMode,
2272        int32_t maxOutputChannelCount, const drcParams_t& drc,
2273        int32_t pcmLimiterEnable) {
2274    if (encoder && isADTS) {
2275        return -EINVAL;
2276    }
2277
2278    status_t err = setupRawAudioFormat(
2279            encoder ? kPortIndexInput : kPortIndexOutput,
2280            sampleRate,
2281            numChannels);
2282
2283    if (err != OK) {
2284        return err;
2285    }
2286
2287    if (encoder) {
2288        err = selectAudioPortFormat(kPortIndexOutput, OMX_AUDIO_CodingAAC);
2289
2290        if (err != OK) {
2291            return err;
2292        }
2293
2294        OMX_PARAM_PORTDEFINITIONTYPE def;
2295        InitOMXParams(&def);
2296        def.nPortIndex = kPortIndexOutput;
2297
2298        err = mOMX->getParameter(
2299                mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
2300
2301        if (err != OK) {
2302            return err;
2303        }
2304
2305        def.format.audio.bFlagErrorConcealment = OMX_TRUE;
2306        def.format.audio.eEncoding = OMX_AUDIO_CodingAAC;
2307
2308        err = mOMX->setParameter(
2309                mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
2310
2311        if (err != OK) {
2312            return err;
2313        }
2314
2315        OMX_AUDIO_PARAM_AACPROFILETYPE profile;
2316        InitOMXParams(&profile);
2317        profile.nPortIndex = kPortIndexOutput;
2318
2319        err = mOMX->getParameter(
2320                mNode, OMX_IndexParamAudioAac, &profile, sizeof(profile));
2321
2322        if (err != OK) {
2323            return err;
2324        }
2325
2326        profile.nChannels = numChannels;
2327
2328        profile.eChannelMode =
2329            (numChannels == 1)
2330                ? OMX_AUDIO_ChannelModeMono: OMX_AUDIO_ChannelModeStereo;
2331
2332        profile.nSampleRate = sampleRate;
2333        profile.nBitRate = bitRate;
2334        profile.nAudioBandWidth = 0;
2335        profile.nFrameLength = 0;
2336        profile.nAACtools = OMX_AUDIO_AACToolAll;
2337        profile.nAACERtools = OMX_AUDIO_AACERNone;
2338        profile.eAACProfile = (OMX_AUDIO_AACPROFILETYPE) aacProfile;
2339        profile.eAACStreamFormat = OMX_AUDIO_AACStreamFormatMP4FF;
2340        switch (sbrMode) {
2341        case 0:
2342            // disable sbr
2343            profile.nAACtools &= ~OMX_AUDIO_AACToolAndroidSSBR;
2344            profile.nAACtools &= ~OMX_AUDIO_AACToolAndroidDSBR;
2345            break;
2346        case 1:
2347            // enable single-rate sbr
2348            profile.nAACtools |= OMX_AUDIO_AACToolAndroidSSBR;
2349            profile.nAACtools &= ~OMX_AUDIO_AACToolAndroidDSBR;
2350            break;
2351        case 2:
2352            // enable dual-rate sbr
2353            profile.nAACtools &= ~OMX_AUDIO_AACToolAndroidSSBR;
2354            profile.nAACtools |= OMX_AUDIO_AACToolAndroidDSBR;
2355            break;
2356        case -1:
2357            // enable both modes -> the codec will decide which mode should be used
2358            profile.nAACtools |= OMX_AUDIO_AACToolAndroidSSBR;
2359            profile.nAACtools |= OMX_AUDIO_AACToolAndroidDSBR;
2360            break;
2361        default:
2362            // unsupported sbr mode
2363            return BAD_VALUE;
2364        }
2365
2366
2367        err = mOMX->setParameter(
2368                mNode, OMX_IndexParamAudioAac, &profile, sizeof(profile));
2369
2370        if (err != OK) {
2371            return err;
2372        }
2373
2374        return err;
2375    }
2376
2377    OMX_AUDIO_PARAM_AACPROFILETYPE profile;
2378    InitOMXParams(&profile);
2379    profile.nPortIndex = kPortIndexInput;
2380
2381    err = mOMX->getParameter(
2382            mNode, OMX_IndexParamAudioAac, &profile, sizeof(profile));
2383
2384    if (err != OK) {
2385        return err;
2386    }
2387
2388    profile.nChannels = numChannels;
2389    profile.nSampleRate = sampleRate;
2390
2391    profile.eAACStreamFormat =
2392        isADTS
2393            ? OMX_AUDIO_AACStreamFormatMP4ADTS
2394            : OMX_AUDIO_AACStreamFormatMP4FF;
2395
2396    OMX_AUDIO_PARAM_ANDROID_AACPRESENTATIONTYPE presentation;
2397    presentation.nMaxOutputChannels = maxOutputChannelCount;
2398    presentation.nDrcCut = drc.drcCut;
2399    presentation.nDrcBoost = drc.drcBoost;
2400    presentation.nHeavyCompression = drc.heavyCompression;
2401    presentation.nTargetReferenceLevel = drc.targetRefLevel;
2402    presentation.nEncodedTargetLevel = drc.encodedTargetLevel;
2403    presentation.nPCMLimiterEnable = pcmLimiterEnable;
2404
2405    status_t res = mOMX->setParameter(mNode, OMX_IndexParamAudioAac, &profile, sizeof(profile));
2406    if (res == OK) {
2407        // optional parameters, will not cause configuration failure
2408        mOMX->setParameter(mNode, (OMX_INDEXTYPE)OMX_IndexParamAudioAndroidAacPresentation,
2409                &presentation, sizeof(presentation));
2410    } else {
2411        ALOGW("did not set AudioAndroidAacPresentation due to error %d when setting AudioAac", res);
2412    }
2413    return res;
2414}
2415
2416status_t ACodec::setupAC3Codec(
2417        bool encoder, int32_t numChannels, int32_t sampleRate) {
2418    status_t err = setupRawAudioFormat(
2419            encoder ? kPortIndexInput : kPortIndexOutput, sampleRate, numChannels);
2420
2421    if (err != OK) {
2422        return err;
2423    }
2424
2425    if (encoder) {
2426        ALOGW("AC3 encoding is not supported.");
2427        return INVALID_OPERATION;
2428    }
2429
2430    OMX_AUDIO_PARAM_ANDROID_AC3TYPE def;
2431    InitOMXParams(&def);
2432    def.nPortIndex = kPortIndexInput;
2433
2434    err = mOMX->getParameter(
2435            mNode,
2436            (OMX_INDEXTYPE)OMX_IndexParamAudioAndroidAc3,
2437            &def,
2438            sizeof(def));
2439
2440    if (err != OK) {
2441        return err;
2442    }
2443
2444    def.nChannels = numChannels;
2445    def.nSampleRate = sampleRate;
2446
2447    return mOMX->setParameter(
2448            mNode,
2449            (OMX_INDEXTYPE)OMX_IndexParamAudioAndroidAc3,
2450            &def,
2451            sizeof(def));
2452}
2453
2454status_t ACodec::setupEAC3Codec(
2455        bool encoder, int32_t numChannels, int32_t sampleRate) {
2456    status_t err = setupRawAudioFormat(
2457            encoder ? kPortIndexInput : kPortIndexOutput, sampleRate, numChannels);
2458
2459    if (err != OK) {
2460        return err;
2461    }
2462
2463    if (encoder) {
2464        ALOGW("EAC3 encoding is not supported.");
2465        return INVALID_OPERATION;
2466    }
2467
2468    OMX_AUDIO_PARAM_ANDROID_EAC3TYPE def;
2469    InitOMXParams(&def);
2470    def.nPortIndex = kPortIndexInput;
2471
2472    err = mOMX->getParameter(
2473            mNode,
2474            (OMX_INDEXTYPE)OMX_IndexParamAudioAndroidEac3,
2475            &def,
2476            sizeof(def));
2477
2478    if (err != OK) {
2479        return err;
2480    }
2481
2482    def.nChannels = numChannels;
2483    def.nSampleRate = sampleRate;
2484
2485    return mOMX->setParameter(
2486            mNode,
2487            (OMX_INDEXTYPE)OMX_IndexParamAudioAndroidEac3,
2488            &def,
2489            sizeof(def));
2490}
2491
2492static OMX_AUDIO_AMRBANDMODETYPE pickModeFromBitRate(
2493        bool isAMRWB, int32_t bps) {
2494    if (isAMRWB) {
2495        if (bps <= 6600) {
2496            return OMX_AUDIO_AMRBandModeWB0;
2497        } else if (bps <= 8850) {
2498            return OMX_AUDIO_AMRBandModeWB1;
2499        } else if (bps <= 12650) {
2500            return OMX_AUDIO_AMRBandModeWB2;
2501        } else if (bps <= 14250) {
2502            return OMX_AUDIO_AMRBandModeWB3;
2503        } else if (bps <= 15850) {
2504            return OMX_AUDIO_AMRBandModeWB4;
2505        } else if (bps <= 18250) {
2506            return OMX_AUDIO_AMRBandModeWB5;
2507        } else if (bps <= 19850) {
2508            return OMX_AUDIO_AMRBandModeWB6;
2509        } else if (bps <= 23050) {
2510            return OMX_AUDIO_AMRBandModeWB7;
2511        }
2512
2513        // 23850 bps
2514        return OMX_AUDIO_AMRBandModeWB8;
2515    } else {  // AMRNB
2516        if (bps <= 4750) {
2517            return OMX_AUDIO_AMRBandModeNB0;
2518        } else if (bps <= 5150) {
2519            return OMX_AUDIO_AMRBandModeNB1;
2520        } else if (bps <= 5900) {
2521            return OMX_AUDIO_AMRBandModeNB2;
2522        } else if (bps <= 6700) {
2523            return OMX_AUDIO_AMRBandModeNB3;
2524        } else if (bps <= 7400) {
2525            return OMX_AUDIO_AMRBandModeNB4;
2526        } else if (bps <= 7950) {
2527            return OMX_AUDIO_AMRBandModeNB5;
2528        } else if (bps <= 10200) {
2529            return OMX_AUDIO_AMRBandModeNB6;
2530        }
2531
2532        // 12200 bps
2533        return OMX_AUDIO_AMRBandModeNB7;
2534    }
2535}
2536
2537status_t ACodec::setupAMRCodec(bool encoder, bool isWAMR, int32_t bitrate) {
2538    OMX_AUDIO_PARAM_AMRTYPE def;
2539    InitOMXParams(&def);
2540    def.nPortIndex = encoder ? kPortIndexOutput : kPortIndexInput;
2541
2542    status_t err =
2543        mOMX->getParameter(mNode, OMX_IndexParamAudioAmr, &def, sizeof(def));
2544
2545    if (err != OK) {
2546        return err;
2547    }
2548
2549    def.eAMRFrameFormat = OMX_AUDIO_AMRFrameFormatFSF;
2550    def.eAMRBandMode = pickModeFromBitRate(isWAMR, bitrate);
2551
2552    err = mOMX->setParameter(
2553            mNode, OMX_IndexParamAudioAmr, &def, sizeof(def));
2554
2555    if (err != OK) {
2556        return err;
2557    }
2558
2559    return setupRawAudioFormat(
2560            encoder ? kPortIndexInput : kPortIndexOutput,
2561            isWAMR ? 16000 : 8000 /* sampleRate */,
2562            1 /* numChannels */);
2563}
2564
2565status_t ACodec::setupG711Codec(bool encoder, int32_t sampleRate, int32_t numChannels) {
2566    if (encoder) {
2567        return INVALID_OPERATION;
2568    }
2569
2570    return setupRawAudioFormat(
2571            kPortIndexInput, sampleRate, numChannels);
2572}
2573
2574status_t ACodec::setupFlacCodec(
2575        bool encoder, int32_t numChannels, int32_t sampleRate, int32_t compressionLevel) {
2576
2577    if (encoder) {
2578        OMX_AUDIO_PARAM_FLACTYPE def;
2579        InitOMXParams(&def);
2580        def.nPortIndex = kPortIndexOutput;
2581
2582        // configure compression level
2583        status_t err = mOMX->getParameter(mNode, OMX_IndexParamAudioFlac, &def, sizeof(def));
2584        if (err != OK) {
2585            ALOGE("setupFlacCodec(): Error %d getting OMX_IndexParamAudioFlac parameter", err);
2586            return err;
2587        }
2588        def.nCompressionLevel = compressionLevel;
2589        err = mOMX->setParameter(mNode, OMX_IndexParamAudioFlac, &def, sizeof(def));
2590        if (err != OK) {
2591            ALOGE("setupFlacCodec(): Error %d setting OMX_IndexParamAudioFlac parameter", err);
2592            return err;
2593        }
2594    }
2595
2596    return setupRawAudioFormat(
2597            encoder ? kPortIndexInput : kPortIndexOutput,
2598            sampleRate,
2599            numChannels);
2600}
2601
2602status_t ACodec::setupRawAudioFormat(
2603        OMX_U32 portIndex, int32_t sampleRate, int32_t numChannels) {
2604    OMX_PARAM_PORTDEFINITIONTYPE def;
2605    InitOMXParams(&def);
2606    def.nPortIndex = portIndex;
2607
2608    status_t err = mOMX->getParameter(
2609            mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
2610
2611    if (err != OK) {
2612        return err;
2613    }
2614
2615    def.format.audio.eEncoding = OMX_AUDIO_CodingPCM;
2616
2617    err = mOMX->setParameter(
2618            mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
2619
2620    if (err != OK) {
2621        return err;
2622    }
2623
2624    OMX_AUDIO_PARAM_PCMMODETYPE pcmParams;
2625    InitOMXParams(&pcmParams);
2626    pcmParams.nPortIndex = portIndex;
2627
2628    err = mOMX->getParameter(
2629            mNode, OMX_IndexParamAudioPcm, &pcmParams, sizeof(pcmParams));
2630
2631    if (err != OK) {
2632        return err;
2633    }
2634
2635    pcmParams.nChannels = numChannels;
2636    pcmParams.eNumData = OMX_NumericalDataSigned;
2637    pcmParams.bInterleaved = OMX_TRUE;
2638    pcmParams.nBitPerSample = 16;
2639    pcmParams.nSamplingRate = sampleRate;
2640    pcmParams.ePCMMode = OMX_AUDIO_PCMModeLinear;
2641
2642    if (getOMXChannelMapping(numChannels, pcmParams.eChannelMapping) != OK) {
2643        return OMX_ErrorNone;
2644    }
2645
2646    return mOMX->setParameter(
2647            mNode, OMX_IndexParamAudioPcm, &pcmParams, sizeof(pcmParams));
2648}
2649
2650status_t ACodec::configureTunneledVideoPlayback(
2651        int32_t audioHwSync, const sp<ANativeWindow> &nativeWindow) {
2652    native_handle_t* sidebandHandle;
2653
2654    status_t err = mOMX->configureVideoTunnelMode(
2655            mNode, kPortIndexOutput, OMX_TRUE, audioHwSync, &sidebandHandle);
2656    if (err != OK) {
2657        ALOGE("configureVideoTunnelMode failed! (err %d).", err);
2658        return err;
2659    }
2660
2661    err = native_window_set_sideband_stream(nativeWindow.get(), sidebandHandle);
2662    if (err != OK) {
2663        ALOGE("native_window_set_sideband_stream(%p) failed! (err %d).",
2664                sidebandHandle, err);
2665        return err;
2666    }
2667
2668    return OK;
2669}
2670
2671status_t ACodec::setVideoPortFormatType(
2672        OMX_U32 portIndex,
2673        OMX_VIDEO_CODINGTYPE compressionFormat,
2674        OMX_COLOR_FORMATTYPE colorFormat,
2675        bool usingNativeBuffers) {
2676    OMX_VIDEO_PARAM_PORTFORMATTYPE format;
2677    InitOMXParams(&format);
2678    format.nPortIndex = portIndex;
2679    format.nIndex = 0;
2680    bool found = false;
2681
2682    OMX_U32 index = 0;
2683    for (;;) {
2684        format.nIndex = index;
2685        status_t err = mOMX->getParameter(
2686                mNode, OMX_IndexParamVideoPortFormat,
2687                &format, sizeof(format));
2688
2689        if (err != OK) {
2690            return err;
2691        }
2692
2693        // substitute back flexible color format to codec supported format
2694        OMX_U32 flexibleEquivalent;
2695        if (compressionFormat == OMX_VIDEO_CodingUnused
2696                && isFlexibleColorFormat(
2697                        mOMX, mNode, format.eColorFormat, usingNativeBuffers, &flexibleEquivalent)
2698                && colorFormat == flexibleEquivalent) {
2699            ALOGI("[%s] using color format %#x in place of %#x",
2700                    mComponentName.c_str(), format.eColorFormat, colorFormat);
2701            colorFormat = format.eColorFormat;
2702        }
2703
2704        // The following assertion is violated by TI's video decoder.
2705        // CHECK_EQ(format.nIndex, index);
2706
2707        if (!strcmp("OMX.TI.Video.encoder", mComponentName.c_str())) {
2708            if (portIndex == kPortIndexInput
2709                    && colorFormat == format.eColorFormat) {
2710                // eCompressionFormat does not seem right.
2711                found = true;
2712                break;
2713            }
2714            if (portIndex == kPortIndexOutput
2715                    && compressionFormat == format.eCompressionFormat) {
2716                // eColorFormat does not seem right.
2717                found = true;
2718                break;
2719            }
2720        }
2721
2722        if (format.eCompressionFormat == compressionFormat
2723            && format.eColorFormat == colorFormat) {
2724            found = true;
2725            break;
2726        }
2727
2728        ++index;
2729    }
2730
2731    if (!found) {
2732        return UNKNOWN_ERROR;
2733    }
2734
2735    status_t err = mOMX->setParameter(
2736            mNode, OMX_IndexParamVideoPortFormat,
2737            &format, sizeof(format));
2738
2739    return err;
2740}
2741
2742// Set optimal output format. OMX component lists output formats in the order
2743// of preference, but this got more complicated since the introduction of flexible
2744// YUV formats. We support a legacy behavior for applications that do not use
2745// surface output, do not specify an output format, but expect a "usable" standard
2746// OMX format. SW readable and standard formats must be flex-YUV.
2747//
2748// Suggested preference order:
2749// - optimal format for texture rendering (mediaplayer behavior)
2750// - optimal SW readable & texture renderable format (flex-YUV support)
2751// - optimal SW readable non-renderable format (flex-YUV bytebuffer support)
2752// - legacy "usable" standard formats
2753//
2754// For legacy support, we prefer a standard format, but will settle for a SW readable
2755// flex-YUV format.
2756status_t ACodec::setSupportedOutputFormat(bool getLegacyFlexibleFormat) {
2757    OMX_VIDEO_PARAM_PORTFORMATTYPE format, legacyFormat;
2758    InitOMXParams(&format);
2759    format.nPortIndex = kPortIndexOutput;
2760
2761    InitOMXParams(&legacyFormat);
2762    // this field will change when we find a suitable legacy format
2763    legacyFormat.eColorFormat = OMX_COLOR_FormatUnused;
2764
2765    for (OMX_U32 index = 0; ; ++index) {
2766        format.nIndex = index;
2767        status_t err = mOMX->getParameter(
2768                mNode, OMX_IndexParamVideoPortFormat,
2769                &format, sizeof(format));
2770        if (err != OK) {
2771            // no more formats, pick legacy format if found
2772            if (legacyFormat.eColorFormat != OMX_COLOR_FormatUnused) {
2773                 memcpy(&format, &legacyFormat, sizeof(format));
2774                 break;
2775            }
2776            return err;
2777        }
2778        if (format.eCompressionFormat != OMX_VIDEO_CodingUnused) {
2779            return OMX_ErrorBadParameter;
2780        }
2781        if (!getLegacyFlexibleFormat) {
2782            break;
2783        }
2784        // standard formats that were exposed to users before
2785        if (format.eColorFormat == OMX_COLOR_FormatYUV420Planar
2786                || format.eColorFormat == OMX_COLOR_FormatYUV420PackedPlanar
2787                || format.eColorFormat == OMX_COLOR_FormatYUV420SemiPlanar
2788                || format.eColorFormat == OMX_COLOR_FormatYUV420PackedSemiPlanar
2789                || format.eColorFormat == OMX_TI_COLOR_FormatYUV420PackedSemiPlanar) {
2790            break;
2791        }
2792        // find best legacy non-standard format
2793        OMX_U32 flexibleEquivalent;
2794        if (legacyFormat.eColorFormat == OMX_COLOR_FormatUnused
2795                && isFlexibleColorFormat(
2796                        mOMX, mNode, format.eColorFormat, false /* usingNativeBuffers */,
2797                        &flexibleEquivalent)
2798                && flexibleEquivalent == OMX_COLOR_FormatYUV420Flexible) {
2799            memcpy(&legacyFormat, &format, sizeof(format));
2800        }
2801    }
2802    return mOMX->setParameter(
2803            mNode, OMX_IndexParamVideoPortFormat,
2804            &format, sizeof(format));
2805}
2806
2807static const struct VideoCodingMapEntry {
2808    const char *mMime;
2809    OMX_VIDEO_CODINGTYPE mVideoCodingType;
2810} kVideoCodingMapEntry[] = {
2811    { MEDIA_MIMETYPE_VIDEO_AVC, OMX_VIDEO_CodingAVC },
2812    { MEDIA_MIMETYPE_VIDEO_HEVC, OMX_VIDEO_CodingHEVC },
2813    { MEDIA_MIMETYPE_VIDEO_MPEG4, OMX_VIDEO_CodingMPEG4 },
2814    { MEDIA_MIMETYPE_VIDEO_H263, OMX_VIDEO_CodingH263 },
2815    { MEDIA_MIMETYPE_VIDEO_MPEG2, OMX_VIDEO_CodingMPEG2 },
2816    { MEDIA_MIMETYPE_VIDEO_VP8, OMX_VIDEO_CodingVP8 },
2817    { MEDIA_MIMETYPE_VIDEO_VP9, OMX_VIDEO_CodingVP9 },
2818};
2819
2820static status_t GetVideoCodingTypeFromMime(
2821        const char *mime, OMX_VIDEO_CODINGTYPE *codingType) {
2822    for (size_t i = 0;
2823         i < sizeof(kVideoCodingMapEntry) / sizeof(kVideoCodingMapEntry[0]);
2824         ++i) {
2825        if (!strcasecmp(mime, kVideoCodingMapEntry[i].mMime)) {
2826            *codingType = kVideoCodingMapEntry[i].mVideoCodingType;
2827            return OK;
2828        }
2829    }
2830
2831    *codingType = OMX_VIDEO_CodingUnused;
2832
2833    return ERROR_UNSUPPORTED;
2834}
2835
2836static status_t GetMimeTypeForVideoCoding(
2837        OMX_VIDEO_CODINGTYPE codingType, AString *mime) {
2838    for (size_t i = 0;
2839         i < sizeof(kVideoCodingMapEntry) / sizeof(kVideoCodingMapEntry[0]);
2840         ++i) {
2841        if (codingType == kVideoCodingMapEntry[i].mVideoCodingType) {
2842            *mime = kVideoCodingMapEntry[i].mMime;
2843            return OK;
2844        }
2845    }
2846
2847    mime->clear();
2848
2849    return ERROR_UNSUPPORTED;
2850}
2851
2852status_t ACodec::setupVideoDecoder(
2853        const char *mime, const sp<AMessage> &msg, bool haveNativeWindow) {
2854    int32_t width, height;
2855    if (!msg->findInt32("width", &width)
2856            || !msg->findInt32("height", &height)) {
2857        return INVALID_OPERATION;
2858    }
2859
2860    OMX_VIDEO_CODINGTYPE compressionFormat;
2861    status_t err = GetVideoCodingTypeFromMime(mime, &compressionFormat);
2862
2863    if (err != OK) {
2864        return err;
2865    }
2866
2867    err = setVideoPortFormatType(
2868            kPortIndexInput, compressionFormat, OMX_COLOR_FormatUnused);
2869
2870    if (err != OK) {
2871        return err;
2872    }
2873
2874    int32_t tmp;
2875    if (msg->findInt32("color-format", &tmp)) {
2876        OMX_COLOR_FORMATTYPE colorFormat =
2877            static_cast<OMX_COLOR_FORMATTYPE>(tmp);
2878        err = setVideoPortFormatType(
2879                kPortIndexOutput, OMX_VIDEO_CodingUnused, colorFormat, haveNativeWindow);
2880        if (err != OK) {
2881            ALOGW("[%s] does not support color format %d",
2882                  mComponentName.c_str(), colorFormat);
2883            err = setSupportedOutputFormat(!haveNativeWindow /* getLegacyFlexibleFormat */);
2884        }
2885    } else {
2886        err = setSupportedOutputFormat(!haveNativeWindow /* getLegacyFlexibleFormat */);
2887    }
2888
2889    if (err != OK) {
2890        return err;
2891    }
2892
2893    int32_t frameRateInt;
2894    float frameRateFloat;
2895    if (!msg->findFloat("frame-rate", &frameRateFloat)) {
2896        if (!msg->findInt32("frame-rate", &frameRateInt)) {
2897            frameRateInt = -1;
2898        }
2899        frameRateFloat = (float)frameRateInt;
2900    }
2901
2902    err = setVideoFormatOnPort(
2903            kPortIndexInput, width, height, compressionFormat, frameRateFloat);
2904
2905    if (err != OK) {
2906        return err;
2907    }
2908
2909    err = setVideoFormatOnPort(
2910            kPortIndexOutput, width, height, OMX_VIDEO_CodingUnused);
2911
2912    if (err != OK) {
2913        return err;
2914    }
2915
2916    return OK;
2917}
2918
2919status_t ACodec::setupVideoEncoder(const char *mime, const sp<AMessage> &msg) {
2920    int32_t tmp;
2921    if (!msg->findInt32("color-format", &tmp)) {
2922        return INVALID_OPERATION;
2923    }
2924
2925    OMX_COLOR_FORMATTYPE colorFormat =
2926        static_cast<OMX_COLOR_FORMATTYPE>(tmp);
2927
2928    status_t err = setVideoPortFormatType(
2929            kPortIndexInput, OMX_VIDEO_CodingUnused, colorFormat);
2930
2931    if (err != OK) {
2932        ALOGE("[%s] does not support color format %d",
2933              mComponentName.c_str(), colorFormat);
2934
2935        return err;
2936    }
2937
2938    /* Input port configuration */
2939
2940    OMX_PARAM_PORTDEFINITIONTYPE def;
2941    InitOMXParams(&def);
2942
2943    OMX_VIDEO_PORTDEFINITIONTYPE *video_def = &def.format.video;
2944
2945    def.nPortIndex = kPortIndexInput;
2946
2947    err = mOMX->getParameter(
2948            mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
2949
2950    if (err != OK) {
2951        return err;
2952    }
2953
2954    int32_t width, height, bitrate;
2955    if (!msg->findInt32("width", &width)
2956            || !msg->findInt32("height", &height)
2957            || !msg->findInt32("bitrate", &bitrate)) {
2958        return INVALID_OPERATION;
2959    }
2960
2961    video_def->nFrameWidth = width;
2962    video_def->nFrameHeight = height;
2963
2964    int32_t stride;
2965    if (!msg->findInt32("stride", &stride)) {
2966        stride = width;
2967    }
2968
2969    video_def->nStride = stride;
2970
2971    int32_t sliceHeight;
2972    if (!msg->findInt32("slice-height", &sliceHeight)) {
2973        sliceHeight = height;
2974    }
2975
2976    video_def->nSliceHeight = sliceHeight;
2977
2978    def.nBufferSize = (video_def->nStride * video_def->nSliceHeight * 3) / 2;
2979
2980    float frameRate;
2981    if (!msg->findFloat("frame-rate", &frameRate)) {
2982        int32_t tmp;
2983        if (!msg->findInt32("frame-rate", &tmp)) {
2984            return INVALID_OPERATION;
2985        }
2986        frameRate = (float)tmp;
2987        mTimePerFrameUs = (int64_t) (1000000.0f / frameRate);
2988    }
2989
2990    video_def->xFramerate = (OMX_U32)(frameRate * 65536.0f);
2991    video_def->eCompressionFormat = OMX_VIDEO_CodingUnused;
2992    // this is redundant as it was already set up in setVideoPortFormatType
2993    // FIXME for now skip this only for flexible YUV formats
2994    if (colorFormat != OMX_COLOR_FormatYUV420Flexible) {
2995        video_def->eColorFormat = colorFormat;
2996    }
2997
2998    err = mOMX->setParameter(
2999            mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
3000
3001    if (err != OK) {
3002        ALOGE("[%s] failed to set input port definition parameters.",
3003              mComponentName.c_str());
3004
3005        return err;
3006    }
3007
3008    /* Output port configuration */
3009
3010    OMX_VIDEO_CODINGTYPE compressionFormat;
3011    err = GetVideoCodingTypeFromMime(mime, &compressionFormat);
3012
3013    if (err != OK) {
3014        return err;
3015    }
3016
3017    err = setVideoPortFormatType(
3018            kPortIndexOutput, compressionFormat, OMX_COLOR_FormatUnused);
3019
3020    if (err != OK) {
3021        ALOGE("[%s] does not support compression format %d",
3022             mComponentName.c_str(), compressionFormat);
3023
3024        return err;
3025    }
3026
3027    def.nPortIndex = kPortIndexOutput;
3028
3029    err = mOMX->getParameter(
3030            mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
3031
3032    if (err != OK) {
3033        return err;
3034    }
3035
3036    video_def->nFrameWidth = width;
3037    video_def->nFrameHeight = height;
3038    video_def->xFramerate = 0;
3039    video_def->nBitrate = bitrate;
3040    video_def->eCompressionFormat = compressionFormat;
3041    video_def->eColorFormat = OMX_COLOR_FormatUnused;
3042
3043    err = mOMX->setParameter(
3044            mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
3045
3046    if (err != OK) {
3047        ALOGE("[%s] failed to set output port definition parameters.",
3048              mComponentName.c_str());
3049
3050        return err;
3051    }
3052
3053    switch (compressionFormat) {
3054        case OMX_VIDEO_CodingMPEG4:
3055            err = setupMPEG4EncoderParameters(msg);
3056            break;
3057
3058        case OMX_VIDEO_CodingH263:
3059            err = setupH263EncoderParameters(msg);
3060            break;
3061
3062        case OMX_VIDEO_CodingAVC:
3063            err = setupAVCEncoderParameters(msg);
3064            break;
3065
3066        case OMX_VIDEO_CodingHEVC:
3067            err = setupHEVCEncoderParameters(msg);
3068            break;
3069
3070        case OMX_VIDEO_CodingVP8:
3071        case OMX_VIDEO_CodingVP9:
3072            err = setupVPXEncoderParameters(msg);
3073            break;
3074
3075        default:
3076            break;
3077    }
3078
3079    if (err == OK) {
3080        ALOGI("setupVideoEncoder succeeded");
3081    }
3082
3083    return err;
3084}
3085
3086status_t ACodec::setCyclicIntraMacroblockRefresh(const sp<AMessage> &msg, int32_t mode) {
3087    OMX_VIDEO_PARAM_INTRAREFRESHTYPE params;
3088    InitOMXParams(&params);
3089    params.nPortIndex = kPortIndexOutput;
3090
3091    params.eRefreshMode = static_cast<OMX_VIDEO_INTRAREFRESHTYPE>(mode);
3092
3093    if (params.eRefreshMode == OMX_VIDEO_IntraRefreshCyclic ||
3094            params.eRefreshMode == OMX_VIDEO_IntraRefreshBoth) {
3095        int32_t mbs;
3096        if (!msg->findInt32("intra-refresh-CIR-mbs", &mbs)) {
3097            return INVALID_OPERATION;
3098        }
3099        params.nCirMBs = mbs;
3100    }
3101
3102    if (params.eRefreshMode == OMX_VIDEO_IntraRefreshAdaptive ||
3103            params.eRefreshMode == OMX_VIDEO_IntraRefreshBoth) {
3104        int32_t mbs;
3105        if (!msg->findInt32("intra-refresh-AIR-mbs", &mbs)) {
3106            return INVALID_OPERATION;
3107        }
3108        params.nAirMBs = mbs;
3109
3110        int32_t ref;
3111        if (!msg->findInt32("intra-refresh-AIR-ref", &ref)) {
3112            return INVALID_OPERATION;
3113        }
3114        params.nAirRef = ref;
3115    }
3116
3117    status_t err = mOMX->setParameter(
3118            mNode, OMX_IndexParamVideoIntraRefresh,
3119            &params, sizeof(params));
3120    return err;
3121}
3122
3123static OMX_U32 setPFramesSpacing(int32_t iFramesInterval, int32_t frameRate) {
3124    if (iFramesInterval < 0) {
3125        return 0xFFFFFFFF;
3126    } else if (iFramesInterval == 0) {
3127        return 0;
3128    }
3129    OMX_U32 ret = frameRate * iFramesInterval;
3130    return ret;
3131}
3132
3133static OMX_VIDEO_CONTROLRATETYPE getBitrateMode(const sp<AMessage> &msg) {
3134    int32_t tmp;
3135    if (!msg->findInt32("bitrate-mode", &tmp)) {
3136        return OMX_Video_ControlRateVariable;
3137    }
3138
3139    return static_cast<OMX_VIDEO_CONTROLRATETYPE>(tmp);
3140}
3141
3142status_t ACodec::setupMPEG4EncoderParameters(const sp<AMessage> &msg) {
3143    int32_t bitrate, iFrameInterval;
3144    if (!msg->findInt32("bitrate", &bitrate)
3145            || !msg->findInt32("i-frame-interval", &iFrameInterval)) {
3146        return INVALID_OPERATION;
3147    }
3148
3149    OMX_VIDEO_CONTROLRATETYPE bitrateMode = getBitrateMode(msg);
3150
3151    float frameRate;
3152    if (!msg->findFloat("frame-rate", &frameRate)) {
3153        int32_t tmp;
3154        if (!msg->findInt32("frame-rate", &tmp)) {
3155            return INVALID_OPERATION;
3156        }
3157        frameRate = (float)tmp;
3158    }
3159
3160    OMX_VIDEO_PARAM_MPEG4TYPE mpeg4type;
3161    InitOMXParams(&mpeg4type);
3162    mpeg4type.nPortIndex = kPortIndexOutput;
3163
3164    status_t err = mOMX->getParameter(
3165            mNode, OMX_IndexParamVideoMpeg4, &mpeg4type, sizeof(mpeg4type));
3166
3167    if (err != OK) {
3168        return err;
3169    }
3170
3171    mpeg4type.nSliceHeaderSpacing = 0;
3172    mpeg4type.bSVH = OMX_FALSE;
3173    mpeg4type.bGov = OMX_FALSE;
3174
3175    mpeg4type.nAllowedPictureTypes =
3176        OMX_VIDEO_PictureTypeI | OMX_VIDEO_PictureTypeP;
3177
3178    mpeg4type.nPFrames = setPFramesSpacing(iFrameInterval, frameRate);
3179    if (mpeg4type.nPFrames == 0) {
3180        mpeg4type.nAllowedPictureTypes = OMX_VIDEO_PictureTypeI;
3181    }
3182    mpeg4type.nBFrames = 0;
3183    mpeg4type.nIDCVLCThreshold = 0;
3184    mpeg4type.bACPred = OMX_TRUE;
3185    mpeg4type.nMaxPacketSize = 256;
3186    mpeg4type.nTimeIncRes = 1000;
3187    mpeg4type.nHeaderExtension = 0;
3188    mpeg4type.bReversibleVLC = OMX_FALSE;
3189
3190    int32_t profile;
3191    if (msg->findInt32("profile", &profile)) {
3192        int32_t level;
3193        if (!msg->findInt32("level", &level)) {
3194            return INVALID_OPERATION;
3195        }
3196
3197        err = verifySupportForProfileAndLevel(profile, level);
3198
3199        if (err != OK) {
3200            return err;
3201        }
3202
3203        mpeg4type.eProfile = static_cast<OMX_VIDEO_MPEG4PROFILETYPE>(profile);
3204        mpeg4type.eLevel = static_cast<OMX_VIDEO_MPEG4LEVELTYPE>(level);
3205    }
3206
3207    err = mOMX->setParameter(
3208            mNode, OMX_IndexParamVideoMpeg4, &mpeg4type, sizeof(mpeg4type));
3209
3210    if (err != OK) {
3211        return err;
3212    }
3213
3214    err = configureBitrate(bitrate, bitrateMode);
3215
3216    if (err != OK) {
3217        return err;
3218    }
3219
3220    return setupErrorCorrectionParameters();
3221}
3222
3223status_t ACodec::setupH263EncoderParameters(const sp<AMessage> &msg) {
3224    int32_t bitrate, iFrameInterval;
3225    if (!msg->findInt32("bitrate", &bitrate)
3226            || !msg->findInt32("i-frame-interval", &iFrameInterval)) {
3227        return INVALID_OPERATION;
3228    }
3229
3230    OMX_VIDEO_CONTROLRATETYPE bitrateMode = getBitrateMode(msg);
3231
3232    float frameRate;
3233    if (!msg->findFloat("frame-rate", &frameRate)) {
3234        int32_t tmp;
3235        if (!msg->findInt32("frame-rate", &tmp)) {
3236            return INVALID_OPERATION;
3237        }
3238        frameRate = (float)tmp;
3239    }
3240
3241    OMX_VIDEO_PARAM_H263TYPE h263type;
3242    InitOMXParams(&h263type);
3243    h263type.nPortIndex = kPortIndexOutput;
3244
3245    status_t err = mOMX->getParameter(
3246            mNode, OMX_IndexParamVideoH263, &h263type, sizeof(h263type));
3247
3248    if (err != OK) {
3249        return err;
3250    }
3251
3252    h263type.nAllowedPictureTypes =
3253        OMX_VIDEO_PictureTypeI | OMX_VIDEO_PictureTypeP;
3254
3255    h263type.nPFrames = setPFramesSpacing(iFrameInterval, frameRate);
3256    if (h263type.nPFrames == 0) {
3257        h263type.nAllowedPictureTypes = OMX_VIDEO_PictureTypeI;
3258    }
3259    h263type.nBFrames = 0;
3260
3261    int32_t profile;
3262    if (msg->findInt32("profile", &profile)) {
3263        int32_t level;
3264        if (!msg->findInt32("level", &level)) {
3265            return INVALID_OPERATION;
3266        }
3267
3268        err = verifySupportForProfileAndLevel(profile, level);
3269
3270        if (err != OK) {
3271            return err;
3272        }
3273
3274        h263type.eProfile = static_cast<OMX_VIDEO_H263PROFILETYPE>(profile);
3275        h263type.eLevel = static_cast<OMX_VIDEO_H263LEVELTYPE>(level);
3276    }
3277
3278    h263type.bPLUSPTYPEAllowed = OMX_FALSE;
3279    h263type.bForceRoundingTypeToZero = OMX_FALSE;
3280    h263type.nPictureHeaderRepetition = 0;
3281    h263type.nGOBHeaderInterval = 0;
3282
3283    err = mOMX->setParameter(
3284            mNode, OMX_IndexParamVideoH263, &h263type, sizeof(h263type));
3285
3286    if (err != OK) {
3287        return err;
3288    }
3289
3290    err = configureBitrate(bitrate, bitrateMode);
3291
3292    if (err != OK) {
3293        return err;
3294    }
3295
3296    return setupErrorCorrectionParameters();
3297}
3298
3299// static
3300int /* OMX_VIDEO_AVCLEVELTYPE */ ACodec::getAVCLevelFor(
3301        int width, int height, int rate, int bitrate,
3302        OMX_VIDEO_AVCPROFILETYPE profile) {
3303    // convert bitrate to main/baseline profile kbps equivalent
3304    switch (profile) {
3305        case OMX_VIDEO_AVCProfileHigh10:
3306            bitrate = divUp(bitrate, 3000); break;
3307        case OMX_VIDEO_AVCProfileHigh:
3308            bitrate = divUp(bitrate, 1250); break;
3309        default:
3310            bitrate = divUp(bitrate, 1000); break;
3311    }
3312
3313    // convert size and rate to MBs
3314    width = divUp(width, 16);
3315    height = divUp(height, 16);
3316    int mbs = width * height;
3317    rate *= mbs;
3318    int maxDimension = max(width, height);
3319
3320    static const int limits[][5] = {
3321        /*   MBps     MB   dim  bitrate        level */
3322        {    1485,    99,  28,     64, OMX_VIDEO_AVCLevel1  },
3323        {    1485,    99,  28,    128, OMX_VIDEO_AVCLevel1b },
3324        {    3000,   396,  56,    192, OMX_VIDEO_AVCLevel11 },
3325        {    6000,   396,  56,    384, OMX_VIDEO_AVCLevel12 },
3326        {   11880,   396,  56,    768, OMX_VIDEO_AVCLevel13 },
3327        {   11880,   396,  56,   2000, OMX_VIDEO_AVCLevel2  },
3328        {   19800,   792,  79,   4000, OMX_VIDEO_AVCLevel21 },
3329        {   20250,  1620, 113,   4000, OMX_VIDEO_AVCLevel22 },
3330        {   40500,  1620, 113,  10000, OMX_VIDEO_AVCLevel3  },
3331        {  108000,  3600, 169,  14000, OMX_VIDEO_AVCLevel31 },
3332        {  216000,  5120, 202,  20000, OMX_VIDEO_AVCLevel32 },
3333        {  245760,  8192, 256,  20000, OMX_VIDEO_AVCLevel4  },
3334        {  245760,  8192, 256,  50000, OMX_VIDEO_AVCLevel41 },
3335        {  522240,  8704, 263,  50000, OMX_VIDEO_AVCLevel42 },
3336        {  589824, 22080, 420, 135000, OMX_VIDEO_AVCLevel5  },
3337        {  983040, 36864, 543, 240000, OMX_VIDEO_AVCLevel51 },
3338        { 2073600, 36864, 543, 240000, OMX_VIDEO_AVCLevel52 },
3339    };
3340
3341    for (size_t i = 0; i < ARRAY_SIZE(limits); i++) {
3342        const int (&limit)[5] = limits[i];
3343        if (rate <= limit[0] && mbs <= limit[1] && maxDimension <= limit[2]
3344                && bitrate <= limit[3]) {
3345            return limit[4];
3346        }
3347    }
3348    return 0;
3349}
3350
3351status_t ACodec::setupAVCEncoderParameters(const sp<AMessage> &msg) {
3352    int32_t bitrate, iFrameInterval;
3353    if (!msg->findInt32("bitrate", &bitrate)
3354            || !msg->findInt32("i-frame-interval", &iFrameInterval)) {
3355        return INVALID_OPERATION;
3356    }
3357
3358    OMX_VIDEO_CONTROLRATETYPE bitrateMode = getBitrateMode(msg);
3359
3360    float frameRate;
3361    if (!msg->findFloat("frame-rate", &frameRate)) {
3362        int32_t tmp;
3363        if (!msg->findInt32("frame-rate", &tmp)) {
3364            return INVALID_OPERATION;
3365        }
3366        frameRate = (float)tmp;
3367    }
3368
3369    status_t err = OK;
3370    int32_t intraRefreshMode = 0;
3371    if (msg->findInt32("intra-refresh-mode", &intraRefreshMode)) {
3372        err = setCyclicIntraMacroblockRefresh(msg, intraRefreshMode);
3373        if (err != OK) {
3374            ALOGE("Setting intra macroblock refresh mode (%d) failed: 0x%x",
3375                    err, intraRefreshMode);
3376            return err;
3377        }
3378    }
3379
3380    OMX_VIDEO_PARAM_AVCTYPE h264type;
3381    InitOMXParams(&h264type);
3382    h264type.nPortIndex = kPortIndexOutput;
3383
3384    err = mOMX->getParameter(
3385            mNode, OMX_IndexParamVideoAvc, &h264type, sizeof(h264type));
3386
3387    if (err != OK) {
3388        return err;
3389    }
3390
3391    h264type.nAllowedPictureTypes =
3392        OMX_VIDEO_PictureTypeI | OMX_VIDEO_PictureTypeP;
3393
3394    int32_t profile;
3395    if (msg->findInt32("profile", &profile)) {
3396        int32_t level;
3397        if (!msg->findInt32("level", &level)) {
3398            return INVALID_OPERATION;
3399        }
3400
3401        err = verifySupportForProfileAndLevel(profile, level);
3402
3403        if (err != OK) {
3404            return err;
3405        }
3406
3407        h264type.eProfile = static_cast<OMX_VIDEO_AVCPROFILETYPE>(profile);
3408        h264type.eLevel = static_cast<OMX_VIDEO_AVCLEVELTYPE>(level);
3409    }
3410
3411    // XXX
3412    if (h264type.eProfile != OMX_VIDEO_AVCProfileBaseline) {
3413        ALOGW("Use baseline profile instead of %d for AVC recording",
3414            h264type.eProfile);
3415        h264type.eProfile = OMX_VIDEO_AVCProfileBaseline;
3416    }
3417
3418    if (h264type.eProfile == OMX_VIDEO_AVCProfileBaseline) {
3419        h264type.nSliceHeaderSpacing = 0;
3420        h264type.bUseHadamard = OMX_TRUE;
3421        h264type.nRefFrames = 1;
3422        h264type.nBFrames = 0;
3423        h264type.nPFrames = setPFramesSpacing(iFrameInterval, frameRate);
3424        if (h264type.nPFrames == 0) {
3425            h264type.nAllowedPictureTypes = OMX_VIDEO_PictureTypeI;
3426        }
3427        h264type.nRefIdx10ActiveMinus1 = 0;
3428        h264type.nRefIdx11ActiveMinus1 = 0;
3429        h264type.bEntropyCodingCABAC = OMX_FALSE;
3430        h264type.bWeightedPPrediction = OMX_FALSE;
3431        h264type.bconstIpred = OMX_FALSE;
3432        h264type.bDirect8x8Inference = OMX_FALSE;
3433        h264type.bDirectSpatialTemporal = OMX_FALSE;
3434        h264type.nCabacInitIdc = 0;
3435    }
3436
3437    if (h264type.nBFrames != 0) {
3438        h264type.nAllowedPictureTypes |= OMX_VIDEO_PictureTypeB;
3439    }
3440
3441    h264type.bEnableUEP = OMX_FALSE;
3442    h264type.bEnableFMO = OMX_FALSE;
3443    h264type.bEnableASO = OMX_FALSE;
3444    h264type.bEnableRS = OMX_FALSE;
3445    h264type.bFrameMBsOnly = OMX_TRUE;
3446    h264type.bMBAFF = OMX_FALSE;
3447    h264type.eLoopFilterMode = OMX_VIDEO_AVCLoopFilterEnable;
3448
3449    err = mOMX->setParameter(
3450            mNode, OMX_IndexParamVideoAvc, &h264type, sizeof(h264type));
3451
3452    if (err != OK) {
3453        return err;
3454    }
3455
3456    return configureBitrate(bitrate, bitrateMode);
3457}
3458
3459status_t ACodec::setupHEVCEncoderParameters(const sp<AMessage> &msg) {
3460    int32_t bitrate, iFrameInterval;
3461    if (!msg->findInt32("bitrate", &bitrate)
3462            || !msg->findInt32("i-frame-interval", &iFrameInterval)) {
3463        return INVALID_OPERATION;
3464    }
3465
3466    OMX_VIDEO_CONTROLRATETYPE bitrateMode = getBitrateMode(msg);
3467
3468    float frameRate;
3469    if (!msg->findFloat("frame-rate", &frameRate)) {
3470        int32_t tmp;
3471        if (!msg->findInt32("frame-rate", &tmp)) {
3472            return INVALID_OPERATION;
3473        }
3474        frameRate = (float)tmp;
3475    }
3476
3477    OMX_VIDEO_PARAM_HEVCTYPE hevcType;
3478    InitOMXParams(&hevcType);
3479    hevcType.nPortIndex = kPortIndexOutput;
3480
3481    status_t err = OK;
3482    err = mOMX->getParameter(
3483            mNode, (OMX_INDEXTYPE)OMX_IndexParamVideoHevc, &hevcType, sizeof(hevcType));
3484    if (err != OK) {
3485        return err;
3486    }
3487
3488    int32_t profile;
3489    if (msg->findInt32("profile", &profile)) {
3490        int32_t level;
3491        if (!msg->findInt32("level", &level)) {
3492            return INVALID_OPERATION;
3493        }
3494
3495        err = verifySupportForProfileAndLevel(profile, level);
3496        if (err != OK) {
3497            return err;
3498        }
3499
3500        hevcType.eProfile = static_cast<OMX_VIDEO_HEVCPROFILETYPE>(profile);
3501        hevcType.eLevel = static_cast<OMX_VIDEO_HEVCLEVELTYPE>(level);
3502    }
3503
3504    // TODO: Need OMX structure definition for setting iFrameInterval
3505
3506    err = mOMX->setParameter(
3507            mNode, (OMX_INDEXTYPE)OMX_IndexParamVideoHevc, &hevcType, sizeof(hevcType));
3508    if (err != OK) {
3509        return err;
3510    }
3511
3512    return configureBitrate(bitrate, bitrateMode);
3513}
3514
3515status_t ACodec::setupVPXEncoderParameters(const sp<AMessage> &msg) {
3516    int32_t bitrate;
3517    int32_t iFrameInterval = 0;
3518    size_t tsLayers = 0;
3519    OMX_VIDEO_ANDROID_VPXTEMPORALLAYERPATTERNTYPE pattern =
3520        OMX_VIDEO_VPXTemporalLayerPatternNone;
3521    static const uint32_t kVp8LayerRateAlloction
3522        [OMX_VIDEO_ANDROID_MAXVP8TEMPORALLAYERS]
3523        [OMX_VIDEO_ANDROID_MAXVP8TEMPORALLAYERS] = {
3524        {100, 100, 100},  // 1 layer
3525        { 60, 100, 100},  // 2 layers {60%, 40%}
3526        { 40,  60, 100},  // 3 layers {40%, 20%, 40%}
3527    };
3528    if (!msg->findInt32("bitrate", &bitrate)) {
3529        return INVALID_OPERATION;
3530    }
3531    msg->findInt32("i-frame-interval", &iFrameInterval);
3532
3533    OMX_VIDEO_CONTROLRATETYPE bitrateMode = getBitrateMode(msg);
3534
3535    float frameRate;
3536    if (!msg->findFloat("frame-rate", &frameRate)) {
3537        int32_t tmp;
3538        if (!msg->findInt32("frame-rate", &tmp)) {
3539            return INVALID_OPERATION;
3540        }
3541        frameRate = (float)tmp;
3542    }
3543
3544    AString tsSchema;
3545    if (msg->findString("ts-schema", &tsSchema)) {
3546        if (tsSchema == "webrtc.vp8.1-layer") {
3547            pattern = OMX_VIDEO_VPXTemporalLayerPatternWebRTC;
3548            tsLayers = 1;
3549        } else if (tsSchema == "webrtc.vp8.2-layer") {
3550            pattern = OMX_VIDEO_VPXTemporalLayerPatternWebRTC;
3551            tsLayers = 2;
3552        } else if (tsSchema == "webrtc.vp8.3-layer") {
3553            pattern = OMX_VIDEO_VPXTemporalLayerPatternWebRTC;
3554            tsLayers = 3;
3555        } else {
3556            ALOGW("Unsupported ts-schema [%s]", tsSchema.c_str());
3557        }
3558    }
3559
3560    OMX_VIDEO_PARAM_ANDROID_VP8ENCODERTYPE vp8type;
3561    InitOMXParams(&vp8type);
3562    vp8type.nPortIndex = kPortIndexOutput;
3563    status_t err = mOMX->getParameter(
3564            mNode, (OMX_INDEXTYPE)OMX_IndexParamVideoAndroidVp8Encoder,
3565            &vp8type, sizeof(vp8type));
3566
3567    if (err == OK) {
3568        if (iFrameInterval > 0) {
3569            vp8type.nKeyFrameInterval = setPFramesSpacing(iFrameInterval, frameRate);
3570        }
3571        vp8type.eTemporalPattern = pattern;
3572        vp8type.nTemporalLayerCount = tsLayers;
3573        if (tsLayers > 0) {
3574            for (size_t i = 0; i < OMX_VIDEO_ANDROID_MAXVP8TEMPORALLAYERS; i++) {
3575                vp8type.nTemporalLayerBitrateRatio[i] =
3576                    kVp8LayerRateAlloction[tsLayers - 1][i];
3577            }
3578        }
3579        if (bitrateMode == OMX_Video_ControlRateConstant) {
3580            vp8type.nMinQuantizer = 2;
3581            vp8type.nMaxQuantizer = 63;
3582        }
3583
3584        err = mOMX->setParameter(
3585                mNode, (OMX_INDEXTYPE)OMX_IndexParamVideoAndroidVp8Encoder,
3586                &vp8type, sizeof(vp8type));
3587        if (err != OK) {
3588            ALOGW("Extended VP8 parameters set failed: %d", err);
3589        }
3590    }
3591
3592    return configureBitrate(bitrate, bitrateMode);
3593}
3594
3595status_t ACodec::verifySupportForProfileAndLevel(
3596        int32_t profile, int32_t level) {
3597    OMX_VIDEO_PARAM_PROFILELEVELTYPE params;
3598    InitOMXParams(&params);
3599    params.nPortIndex = kPortIndexOutput;
3600
3601    for (params.nProfileIndex = 0;; ++params.nProfileIndex) {
3602        status_t err = mOMX->getParameter(
3603                mNode,
3604                OMX_IndexParamVideoProfileLevelQuerySupported,
3605                &params,
3606                sizeof(params));
3607
3608        if (err != OK) {
3609            return err;
3610        }
3611
3612        int32_t supportedProfile = static_cast<int32_t>(params.eProfile);
3613        int32_t supportedLevel = static_cast<int32_t>(params.eLevel);
3614
3615        if (profile == supportedProfile && level <= supportedLevel) {
3616            return OK;
3617        }
3618    }
3619}
3620
3621status_t ACodec::configureBitrate(
3622        int32_t bitrate, OMX_VIDEO_CONTROLRATETYPE bitrateMode) {
3623    OMX_VIDEO_PARAM_BITRATETYPE bitrateType;
3624    InitOMXParams(&bitrateType);
3625    bitrateType.nPortIndex = kPortIndexOutput;
3626
3627    status_t err = mOMX->getParameter(
3628            mNode, OMX_IndexParamVideoBitrate,
3629            &bitrateType, sizeof(bitrateType));
3630
3631    if (err != OK) {
3632        return err;
3633    }
3634
3635    bitrateType.eControlRate = bitrateMode;
3636    bitrateType.nTargetBitrate = bitrate;
3637
3638    return mOMX->setParameter(
3639            mNode, OMX_IndexParamVideoBitrate,
3640            &bitrateType, sizeof(bitrateType));
3641}
3642
3643status_t ACodec::setupErrorCorrectionParameters() {
3644    OMX_VIDEO_PARAM_ERRORCORRECTIONTYPE errorCorrectionType;
3645    InitOMXParams(&errorCorrectionType);
3646    errorCorrectionType.nPortIndex = kPortIndexOutput;
3647
3648    status_t err = mOMX->getParameter(
3649            mNode, OMX_IndexParamVideoErrorCorrection,
3650            &errorCorrectionType, sizeof(errorCorrectionType));
3651
3652    if (err != OK) {
3653        return OK;  // Optional feature. Ignore this failure
3654    }
3655
3656    errorCorrectionType.bEnableHEC = OMX_FALSE;
3657    errorCorrectionType.bEnableResync = OMX_TRUE;
3658    errorCorrectionType.nResynchMarkerSpacing = 256;
3659    errorCorrectionType.bEnableDataPartitioning = OMX_FALSE;
3660    errorCorrectionType.bEnableRVLC = OMX_FALSE;
3661
3662    return mOMX->setParameter(
3663            mNode, OMX_IndexParamVideoErrorCorrection,
3664            &errorCorrectionType, sizeof(errorCorrectionType));
3665}
3666
3667status_t ACodec::setVideoFormatOnPort(
3668        OMX_U32 portIndex,
3669        int32_t width, int32_t height, OMX_VIDEO_CODINGTYPE compressionFormat,
3670        float frameRate) {
3671    OMX_PARAM_PORTDEFINITIONTYPE def;
3672    InitOMXParams(&def);
3673    def.nPortIndex = portIndex;
3674
3675    OMX_VIDEO_PORTDEFINITIONTYPE *video_def = &def.format.video;
3676
3677    status_t err = mOMX->getParameter(
3678            mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
3679    if (err != OK) {
3680        return err;
3681    }
3682
3683    if (portIndex == kPortIndexInput) {
3684        // XXX Need a (much) better heuristic to compute input buffer sizes.
3685        const size_t X = 64 * 1024;
3686        if (def.nBufferSize < X) {
3687            def.nBufferSize = X;
3688        }
3689    }
3690
3691    if (def.eDomain != OMX_PortDomainVideo) {
3692        ALOGE("expected video port, got %s(%d)", asString(def.eDomain), def.eDomain);
3693        return FAILED_TRANSACTION;
3694    }
3695
3696    video_def->nFrameWidth = width;
3697    video_def->nFrameHeight = height;
3698
3699    if (portIndex == kPortIndexInput) {
3700        video_def->eCompressionFormat = compressionFormat;
3701        video_def->eColorFormat = OMX_COLOR_FormatUnused;
3702        if (frameRate >= 0) {
3703            video_def->xFramerate = (OMX_U32)(frameRate * 65536.0f);
3704        }
3705    }
3706
3707    err = mOMX->setParameter(
3708            mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
3709
3710    return err;
3711}
3712
3713status_t ACodec::initNativeWindow() {
3714    if (mNativeWindow != NULL) {
3715        return mOMX->enableGraphicBuffers(mNode, kPortIndexOutput, OMX_TRUE);
3716    }
3717
3718    mOMX->enableGraphicBuffers(mNode, kPortIndexOutput, OMX_FALSE);
3719    return OK;
3720}
3721
3722size_t ACodec::countBuffersOwnedByComponent(OMX_U32 portIndex) const {
3723    size_t n = 0;
3724
3725    for (size_t i = 0; i < mBuffers[portIndex].size(); ++i) {
3726        const BufferInfo &info = mBuffers[portIndex].itemAt(i);
3727
3728        if (info.mStatus == BufferInfo::OWNED_BY_COMPONENT) {
3729            ++n;
3730        }
3731    }
3732
3733    return n;
3734}
3735
3736size_t ACodec::countBuffersOwnedByNativeWindow() const {
3737    size_t n = 0;
3738
3739    for (size_t i = 0; i < mBuffers[kPortIndexOutput].size(); ++i) {
3740        const BufferInfo &info = mBuffers[kPortIndexOutput].itemAt(i);
3741
3742        if (info.mStatus == BufferInfo::OWNED_BY_NATIVE_WINDOW) {
3743            ++n;
3744        }
3745    }
3746
3747    return n;
3748}
3749
3750void ACodec::waitUntilAllPossibleNativeWindowBuffersAreReturnedToUs() {
3751    if (mNativeWindow == NULL) {
3752        return;
3753    }
3754
3755    while (countBuffersOwnedByNativeWindow() > mNumUndequeuedBuffers
3756            && dequeueBufferFromNativeWindow() != NULL) {
3757        // these buffers will be submitted as regular buffers; account for this
3758        if (storingMetadataInDecodedBuffers() && mMetadataBuffersToSubmit > 0) {
3759            --mMetadataBuffersToSubmit;
3760        }
3761    }
3762}
3763
3764bool ACodec::allYourBuffersAreBelongToUs(
3765        OMX_U32 portIndex) {
3766    for (size_t i = 0; i < mBuffers[portIndex].size(); ++i) {
3767        BufferInfo *info = &mBuffers[portIndex].editItemAt(i);
3768
3769        if (info->mStatus != BufferInfo::OWNED_BY_US
3770                && info->mStatus != BufferInfo::OWNED_BY_NATIVE_WINDOW) {
3771            ALOGV("[%s] Buffer %u on port %u still has status %d",
3772                    mComponentName.c_str(),
3773                    info->mBufferID, portIndex, info->mStatus);
3774            return false;
3775        }
3776    }
3777
3778    return true;
3779}
3780
3781bool ACodec::allYourBuffersAreBelongToUs() {
3782    return allYourBuffersAreBelongToUs(kPortIndexInput)
3783        && allYourBuffersAreBelongToUs(kPortIndexOutput);
3784}
3785
3786void ACodec::deferMessage(const sp<AMessage> &msg) {
3787    mDeferredQueue.push_back(msg);
3788}
3789
3790void ACodec::processDeferredMessages() {
3791    List<sp<AMessage> > queue = mDeferredQueue;
3792    mDeferredQueue.clear();
3793
3794    List<sp<AMessage> >::iterator it = queue.begin();
3795    while (it != queue.end()) {
3796        onMessageReceived(*it++);
3797    }
3798}
3799
3800// static
3801bool ACodec::describeDefaultColorFormat(DescribeColorFormatParams &params) {
3802    MediaImage &image = params.sMediaImage;
3803    memset(&image, 0, sizeof(image));
3804
3805    image.mType = MediaImage::MEDIA_IMAGE_TYPE_UNKNOWN;
3806    image.mNumPlanes = 0;
3807
3808    const OMX_COLOR_FORMATTYPE fmt = params.eColorFormat;
3809    image.mWidth = params.nFrameWidth;
3810    image.mHeight = params.nFrameHeight;
3811
3812    // only supporting YUV420
3813    if (fmt != OMX_COLOR_FormatYUV420Planar &&
3814        fmt != OMX_COLOR_FormatYUV420PackedPlanar &&
3815        fmt != OMX_COLOR_FormatYUV420SemiPlanar &&
3816        fmt != OMX_COLOR_FormatYUV420PackedSemiPlanar &&
3817        fmt != HAL_PIXEL_FORMAT_YV12) {
3818        ALOGW("do not know color format 0x%x = %d", fmt, fmt);
3819        return false;
3820    }
3821
3822    // TEMPORARY FIX for some vendors that advertise sliceHeight as 0
3823    if (params.nStride != 0 && params.nSliceHeight == 0) {
3824        ALOGW("using sliceHeight=%u instead of what codec advertised (=0)",
3825                params.nFrameHeight);
3826        params.nSliceHeight = params.nFrameHeight;
3827    }
3828
3829    // we need stride and slice-height to be non-zero
3830    if (params.nStride == 0 || params.nSliceHeight == 0) {
3831        ALOGW("cannot describe color format 0x%x = %d with stride=%u and sliceHeight=%u",
3832                fmt, fmt, params.nStride, params.nSliceHeight);
3833        return false;
3834    }
3835
3836    // set-up YUV format
3837    image.mType = MediaImage::MEDIA_IMAGE_TYPE_YUV;
3838    image.mNumPlanes = 3;
3839    image.mBitDepth = 8;
3840    image.mPlane[image.Y].mOffset = 0;
3841    image.mPlane[image.Y].mColInc = 1;
3842    image.mPlane[image.Y].mRowInc = params.nStride;
3843    image.mPlane[image.Y].mHorizSubsampling = 1;
3844    image.mPlane[image.Y].mVertSubsampling = 1;
3845
3846    switch ((int)fmt) {
3847        case HAL_PIXEL_FORMAT_YV12:
3848            if (params.bUsingNativeBuffers) {
3849                size_t ystride = align(params.nStride, 16);
3850                size_t cstride = align(params.nStride / 2, 16);
3851                image.mPlane[image.Y].mRowInc = ystride;
3852
3853                image.mPlane[image.V].mOffset = ystride * params.nSliceHeight;
3854                image.mPlane[image.V].mColInc = 1;
3855                image.mPlane[image.V].mRowInc = cstride;
3856                image.mPlane[image.V].mHorizSubsampling = 2;
3857                image.mPlane[image.V].mVertSubsampling = 2;
3858
3859                image.mPlane[image.U].mOffset = image.mPlane[image.V].mOffset
3860                        + (cstride * params.nSliceHeight / 2);
3861                image.mPlane[image.U].mColInc = 1;
3862                image.mPlane[image.U].mRowInc = cstride;
3863                image.mPlane[image.U].mHorizSubsampling = 2;
3864                image.mPlane[image.U].mVertSubsampling = 2;
3865                break;
3866            } else {
3867                // fall through as YV12 is used for YUV420Planar by some codecs
3868            }
3869
3870        case OMX_COLOR_FormatYUV420Planar:
3871        case OMX_COLOR_FormatYUV420PackedPlanar:
3872            image.mPlane[image.U].mOffset = params.nStride * params.nSliceHeight;
3873            image.mPlane[image.U].mColInc = 1;
3874            image.mPlane[image.U].mRowInc = params.nStride / 2;
3875            image.mPlane[image.U].mHorizSubsampling = 2;
3876            image.mPlane[image.U].mVertSubsampling = 2;
3877
3878            image.mPlane[image.V].mOffset = image.mPlane[image.U].mOffset
3879                    + (params.nStride * params.nSliceHeight / 4);
3880            image.mPlane[image.V].mColInc = 1;
3881            image.mPlane[image.V].mRowInc = params.nStride / 2;
3882            image.mPlane[image.V].mHorizSubsampling = 2;
3883            image.mPlane[image.V].mVertSubsampling = 2;
3884            break;
3885
3886        case OMX_COLOR_FormatYUV420SemiPlanar:
3887            // FIXME: NV21 for sw-encoder, NV12 for decoder and hw-encoder
3888        case OMX_COLOR_FormatYUV420PackedSemiPlanar:
3889            // NV12
3890            image.mPlane[image.U].mOffset = params.nStride * params.nSliceHeight;
3891            image.mPlane[image.U].mColInc = 2;
3892            image.mPlane[image.U].mRowInc = params.nStride;
3893            image.mPlane[image.U].mHorizSubsampling = 2;
3894            image.mPlane[image.U].mVertSubsampling = 2;
3895
3896            image.mPlane[image.V].mOffset = image.mPlane[image.U].mOffset + 1;
3897            image.mPlane[image.V].mColInc = 2;
3898            image.mPlane[image.V].mRowInc = params.nStride;
3899            image.mPlane[image.V].mHorizSubsampling = 2;
3900            image.mPlane[image.V].mVertSubsampling = 2;
3901            break;
3902
3903        default:
3904            TRESPASS();
3905    }
3906    return true;
3907}
3908
3909// static
3910bool ACodec::describeColorFormat(
3911        const sp<IOMX> &omx, IOMX::node_id node,
3912        DescribeColorFormatParams &describeParams)
3913{
3914    OMX_INDEXTYPE describeColorFormatIndex;
3915    if (omx->getExtensionIndex(
3916            node, "OMX.google.android.index.describeColorFormat",
3917            &describeColorFormatIndex) != OK ||
3918        omx->getParameter(
3919            node, describeColorFormatIndex,
3920            &describeParams, sizeof(describeParams)) != OK) {
3921        return describeDefaultColorFormat(describeParams);
3922    }
3923    return describeParams.sMediaImage.mType !=
3924            MediaImage::MEDIA_IMAGE_TYPE_UNKNOWN;
3925}
3926
3927// static
3928bool ACodec::isFlexibleColorFormat(
3929         const sp<IOMX> &omx, IOMX::node_id node,
3930         uint32_t colorFormat, bool usingNativeBuffers, OMX_U32 *flexibleEquivalent) {
3931    DescribeColorFormatParams describeParams;
3932    InitOMXParams(&describeParams);
3933    describeParams.eColorFormat = (OMX_COLOR_FORMATTYPE)colorFormat;
3934    // reasonable dummy values
3935    describeParams.nFrameWidth = 128;
3936    describeParams.nFrameHeight = 128;
3937    describeParams.nStride = 128;
3938    describeParams.nSliceHeight = 128;
3939    describeParams.bUsingNativeBuffers = (OMX_BOOL)usingNativeBuffers;
3940
3941    CHECK(flexibleEquivalent != NULL);
3942
3943    if (!describeColorFormat(omx, node, describeParams)) {
3944        return false;
3945    }
3946
3947    const MediaImage &img = describeParams.sMediaImage;
3948    if (img.mType == MediaImage::MEDIA_IMAGE_TYPE_YUV) {
3949        if (img.mNumPlanes != 3 ||
3950            img.mPlane[img.Y].mHorizSubsampling != 1 ||
3951            img.mPlane[img.Y].mVertSubsampling != 1) {
3952            return false;
3953        }
3954
3955        // YUV 420
3956        if (img.mPlane[img.U].mHorizSubsampling == 2
3957                && img.mPlane[img.U].mVertSubsampling == 2
3958                && img.mPlane[img.V].mHorizSubsampling == 2
3959                && img.mPlane[img.V].mVertSubsampling == 2) {
3960            // possible flexible YUV420 format
3961            if (img.mBitDepth <= 8) {
3962               *flexibleEquivalent = OMX_COLOR_FormatYUV420Flexible;
3963               return true;
3964            }
3965        }
3966    }
3967    return false;
3968}
3969
3970status_t ACodec::getPortFormat(OMX_U32 portIndex, sp<AMessage> &notify) {
3971    const char *niceIndex = portIndex == kPortIndexInput ? "input" : "output";
3972    OMX_PARAM_PORTDEFINITIONTYPE def;
3973    InitOMXParams(&def);
3974    def.nPortIndex = portIndex;
3975
3976    status_t err = mOMX->getParameter(mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
3977    if (err != OK) {
3978        return err;
3979    }
3980
3981    if (def.eDir != (portIndex == kPortIndexOutput ? OMX_DirOutput : OMX_DirInput)) {
3982        ALOGE("unexpected dir: %s(%d) on %s port", asString(def.eDir), def.eDir, niceIndex);
3983        return BAD_VALUE;
3984    }
3985
3986    switch (def.eDomain) {
3987        case OMX_PortDomainVideo:
3988        {
3989            OMX_VIDEO_PORTDEFINITIONTYPE *videoDef = &def.format.video;
3990            switch ((int)videoDef->eCompressionFormat) {
3991                case OMX_VIDEO_CodingUnused:
3992                {
3993                    CHECK(mIsEncoder ^ (portIndex == kPortIndexOutput));
3994                    notify->setString("mime", MEDIA_MIMETYPE_VIDEO_RAW);
3995
3996                    notify->setInt32("stride", videoDef->nStride);
3997                    notify->setInt32("slice-height", videoDef->nSliceHeight);
3998                    notify->setInt32("color-format", videoDef->eColorFormat);
3999
4000                    if (mNativeWindow == NULL) {
4001                        DescribeColorFormatParams describeParams;
4002                        InitOMXParams(&describeParams);
4003                        describeParams.eColorFormat = videoDef->eColorFormat;
4004                        describeParams.nFrameWidth = videoDef->nFrameWidth;
4005                        describeParams.nFrameHeight = videoDef->nFrameHeight;
4006                        describeParams.nStride = videoDef->nStride;
4007                        describeParams.nSliceHeight = videoDef->nSliceHeight;
4008                        describeParams.bUsingNativeBuffers = OMX_FALSE;
4009
4010                        if (describeColorFormat(mOMX, mNode, describeParams)) {
4011                            notify->setBuffer(
4012                                    "image-data",
4013                                    ABuffer::CreateAsCopy(
4014                                            &describeParams.sMediaImage,
4015                                            sizeof(describeParams.sMediaImage)));
4016
4017                            MediaImage *img = &describeParams.sMediaImage;
4018                            ALOGV("[%s] MediaImage { F(%zux%zu) @%zu+%zu+%zu @%zu+%zu+%zu @%zu+%zu+%zu }",
4019                                    mComponentName.c_str(), img->mWidth, img->mHeight,
4020                                    img->mPlane[0].mOffset, img->mPlane[0].mColInc, img->mPlane[0].mRowInc,
4021                                    img->mPlane[1].mOffset, img->mPlane[1].mColInc, img->mPlane[1].mRowInc,
4022                                    img->mPlane[2].mOffset, img->mPlane[2].mColInc, img->mPlane[2].mRowInc);
4023                        }
4024                    }
4025
4026                    if (portIndex != kPortIndexOutput) {
4027                        // TODO: also get input crop
4028                        break;
4029                    }
4030
4031                    OMX_CONFIG_RECTTYPE rect;
4032                    InitOMXParams(&rect);
4033                    rect.nPortIndex = portIndex;
4034
4035                    if (mOMX->getConfig(
4036                                mNode,
4037                                (portIndex == kPortIndexOutput ?
4038                                        OMX_IndexConfigCommonOutputCrop :
4039                                        OMX_IndexConfigCommonInputCrop),
4040                                &rect, sizeof(rect)) != OK) {
4041                        rect.nLeft = 0;
4042                        rect.nTop = 0;
4043                        rect.nWidth = videoDef->nFrameWidth;
4044                        rect.nHeight = videoDef->nFrameHeight;
4045                    }
4046
4047                    if (rect.nLeft < 0 ||
4048                        rect.nTop < 0 ||
4049                        rect.nLeft + rect.nWidth > videoDef->nFrameWidth ||
4050                        rect.nTop + rect.nHeight > videoDef->nFrameHeight) {
4051                        ALOGE("Wrong cropped rect (%d, %d) - (%u, %u) vs. frame (%u, %u)",
4052                                rect.nLeft, rect.nTop,
4053                                rect.nLeft + rect.nWidth, rect.nTop + rect.nHeight,
4054                                videoDef->nFrameWidth, videoDef->nFrameHeight);
4055                        return BAD_VALUE;
4056                    }
4057
4058                    notify->setRect(
4059                            "crop",
4060                            rect.nLeft,
4061                            rect.nTop,
4062                            rect.nLeft + rect.nWidth - 1,
4063                            rect.nTop + rect.nHeight - 1);
4064
4065                    break;
4066                }
4067
4068                case OMX_VIDEO_CodingVP8:
4069                case OMX_VIDEO_CodingVP9:
4070                {
4071                    OMX_VIDEO_PARAM_ANDROID_VP8ENCODERTYPE vp8type;
4072                    InitOMXParams(&vp8type);
4073                    vp8type.nPortIndex = kPortIndexOutput;
4074                    status_t err = mOMX->getParameter(
4075                            mNode,
4076                            (OMX_INDEXTYPE)OMX_IndexParamVideoAndroidVp8Encoder,
4077                            &vp8type,
4078                            sizeof(vp8type));
4079
4080                    if (err == OK) {
4081                        AString tsSchema = "none";
4082                        if (vp8type.eTemporalPattern
4083                                == OMX_VIDEO_VPXTemporalLayerPatternWebRTC) {
4084                            switch (vp8type.nTemporalLayerCount) {
4085                                case 1:
4086                                {
4087                                    tsSchema = "webrtc.vp8.1-layer";
4088                                    break;
4089                                }
4090                                case 2:
4091                                {
4092                                    tsSchema = "webrtc.vp8.2-layer";
4093                                    break;
4094                                }
4095                                case 3:
4096                                {
4097                                    tsSchema = "webrtc.vp8.3-layer";
4098                                    break;
4099                                }
4100                                default:
4101                                {
4102                                    break;
4103                                }
4104                            }
4105                        }
4106                        notify->setString("ts-schema", tsSchema);
4107                    }
4108                    // Fall through to set up mime.
4109                }
4110
4111                default:
4112                {
4113                    if (mIsEncoder ^ (portIndex == kPortIndexOutput)) {
4114                        // should be CodingUnused
4115                        ALOGE("Raw port video compression format is %s(%d)",
4116                                asString(videoDef->eCompressionFormat),
4117                                videoDef->eCompressionFormat);
4118                        return BAD_VALUE;
4119                    }
4120                    AString mime;
4121                    if (GetMimeTypeForVideoCoding(
4122                        videoDef->eCompressionFormat, &mime) != OK) {
4123                        notify->setString("mime", "application/octet-stream");
4124                    } else {
4125                        notify->setString("mime", mime.c_str());
4126                    }
4127                    break;
4128                }
4129            }
4130            notify->setInt32("width", videoDef->nFrameWidth);
4131            notify->setInt32("height", videoDef->nFrameHeight);
4132            ALOGV("[%s] %s format is %s", mComponentName.c_str(),
4133                    portIndex == kPortIndexInput ? "input" : "output",
4134                    notify->debugString().c_str());
4135
4136            break;
4137        }
4138
4139        case OMX_PortDomainAudio:
4140        {
4141            OMX_AUDIO_PORTDEFINITIONTYPE *audioDef = &def.format.audio;
4142
4143            switch ((int)audioDef->eEncoding) {
4144                case OMX_AUDIO_CodingPCM:
4145                {
4146                    OMX_AUDIO_PARAM_PCMMODETYPE params;
4147                    InitOMXParams(&params);
4148                    params.nPortIndex = portIndex;
4149
4150                    err = mOMX->getParameter(
4151                            mNode, OMX_IndexParamAudioPcm, &params, sizeof(params));
4152                    if (err != OK) {
4153                        return err;
4154                    }
4155
4156                    if (params.nChannels <= 0
4157                            || (params.nChannels != 1 && !params.bInterleaved)
4158                            || params.nBitPerSample != 16u
4159                            || params.eNumData != OMX_NumericalDataSigned
4160                            || params.ePCMMode != OMX_AUDIO_PCMModeLinear) {
4161                        ALOGE("unsupported PCM port: %u channels%s, %u-bit, %s(%d), %s(%d) mode ",
4162                                params.nChannels,
4163                                params.bInterleaved ? " interleaved" : "",
4164                                params.nBitPerSample,
4165                                asString(params.eNumData), params.eNumData,
4166                                asString(params.ePCMMode), params.ePCMMode);
4167                        return FAILED_TRANSACTION;
4168                    }
4169
4170                    notify->setString("mime", MEDIA_MIMETYPE_AUDIO_RAW);
4171                    notify->setInt32("channel-count", params.nChannels);
4172                    notify->setInt32("sample-rate", params.nSamplingRate);
4173
4174                    if (mChannelMaskPresent) {
4175                        notify->setInt32("channel-mask", mChannelMask);
4176                    }
4177                    break;
4178                }
4179
4180                case OMX_AUDIO_CodingAAC:
4181                {
4182                    OMX_AUDIO_PARAM_AACPROFILETYPE params;
4183                    InitOMXParams(&params);
4184                    params.nPortIndex = portIndex;
4185
4186                    err = mOMX->getParameter(
4187                            mNode, OMX_IndexParamAudioAac, &params, sizeof(params));
4188                    if (err != OK) {
4189                        return err;
4190                    }
4191
4192                    notify->setString("mime", MEDIA_MIMETYPE_AUDIO_AAC);
4193                    notify->setInt32("channel-count", params.nChannels);
4194                    notify->setInt32("sample-rate", params.nSampleRate);
4195                    break;
4196                }
4197
4198                case OMX_AUDIO_CodingAMR:
4199                {
4200                    OMX_AUDIO_PARAM_AMRTYPE params;
4201                    InitOMXParams(&params);
4202                    params.nPortIndex = portIndex;
4203
4204                    err = mOMX->getParameter(
4205                            mNode, OMX_IndexParamAudioAmr, &params, sizeof(params));
4206                    if (err != OK) {
4207                        return err;
4208                    }
4209
4210                    notify->setInt32("channel-count", 1);
4211                    if (params.eAMRBandMode >= OMX_AUDIO_AMRBandModeWB0) {
4212                        notify->setString("mime", MEDIA_MIMETYPE_AUDIO_AMR_WB);
4213                        notify->setInt32("sample-rate", 16000);
4214                    } else {
4215                        notify->setString("mime", MEDIA_MIMETYPE_AUDIO_AMR_NB);
4216                        notify->setInt32("sample-rate", 8000);
4217                    }
4218                    break;
4219                }
4220
4221                case OMX_AUDIO_CodingFLAC:
4222                {
4223                    OMX_AUDIO_PARAM_FLACTYPE params;
4224                    InitOMXParams(&params);
4225                    params.nPortIndex = portIndex;
4226
4227                    err = mOMX->getParameter(
4228                            mNode, OMX_IndexParamAudioFlac, &params, sizeof(params));
4229                    if (err != OK) {
4230                        return err;
4231                    }
4232
4233                    notify->setString("mime", MEDIA_MIMETYPE_AUDIO_FLAC);
4234                    notify->setInt32("channel-count", params.nChannels);
4235                    notify->setInt32("sample-rate", params.nSampleRate);
4236                    break;
4237                }
4238
4239                case OMX_AUDIO_CodingMP3:
4240                {
4241                    OMX_AUDIO_PARAM_MP3TYPE params;
4242                    InitOMXParams(&params);
4243                    params.nPortIndex = portIndex;
4244
4245                    err = mOMX->getParameter(
4246                            mNode, OMX_IndexParamAudioMp3, &params, sizeof(params));
4247                    if (err != OK) {
4248                        return err;
4249                    }
4250
4251                    notify->setString("mime", MEDIA_MIMETYPE_AUDIO_MPEG);
4252                    notify->setInt32("channel-count", params.nChannels);
4253                    notify->setInt32("sample-rate", params.nSampleRate);
4254                    break;
4255                }
4256
4257                case OMX_AUDIO_CodingVORBIS:
4258                {
4259                    OMX_AUDIO_PARAM_VORBISTYPE params;
4260                    InitOMXParams(&params);
4261                    params.nPortIndex = portIndex;
4262
4263                    err = mOMX->getParameter(
4264                            mNode, OMX_IndexParamAudioVorbis, &params, sizeof(params));
4265                    if (err != OK) {
4266                        return err;
4267                    }
4268
4269                    notify->setString("mime", MEDIA_MIMETYPE_AUDIO_VORBIS);
4270                    notify->setInt32("channel-count", params.nChannels);
4271                    notify->setInt32("sample-rate", params.nSampleRate);
4272                    break;
4273                }
4274
4275                case OMX_AUDIO_CodingAndroidAC3:
4276                {
4277                    OMX_AUDIO_PARAM_ANDROID_AC3TYPE params;
4278                    InitOMXParams(&params);
4279                    params.nPortIndex = portIndex;
4280
4281                    err = mOMX->getParameter(
4282                            mNode, (OMX_INDEXTYPE)OMX_IndexParamAudioAndroidAc3,
4283                            &params, sizeof(params));
4284                    if (err != OK) {
4285                        return err;
4286                    }
4287
4288                    notify->setString("mime", MEDIA_MIMETYPE_AUDIO_AC3);
4289                    notify->setInt32("channel-count", params.nChannels);
4290                    notify->setInt32("sample-rate", params.nSampleRate);
4291                    break;
4292                }
4293
4294                case OMX_AUDIO_CodingAndroidEAC3:
4295                {
4296                    OMX_AUDIO_PARAM_ANDROID_EAC3TYPE params;
4297                    InitOMXParams(&params);
4298                    params.nPortIndex = portIndex;
4299
4300                    err = mOMX->getParameter(
4301                            mNode, (OMX_INDEXTYPE)OMX_IndexParamAudioAndroidEac3,
4302                            &params, sizeof(params));
4303                    if (err != OK) {
4304                        return err;
4305                    }
4306
4307                    notify->setString("mime", MEDIA_MIMETYPE_AUDIO_EAC3);
4308                    notify->setInt32("channel-count", params.nChannels);
4309                    notify->setInt32("sample-rate", params.nSampleRate);
4310                    break;
4311                }
4312
4313                case OMX_AUDIO_CodingAndroidOPUS:
4314                {
4315                    OMX_AUDIO_PARAM_ANDROID_OPUSTYPE params;
4316                    InitOMXParams(&params);
4317                    params.nPortIndex = portIndex;
4318
4319                    err = mOMX->getParameter(
4320                            mNode, (OMX_INDEXTYPE)OMX_IndexParamAudioAndroidOpus,
4321                            &params, sizeof(params));
4322                    if (err != OK) {
4323                        return err;
4324                    }
4325
4326                    notify->setString("mime", MEDIA_MIMETYPE_AUDIO_OPUS);
4327                    notify->setInt32("channel-count", params.nChannels);
4328                    notify->setInt32("sample-rate", params.nSampleRate);
4329                    break;
4330                }
4331
4332                case OMX_AUDIO_CodingG711:
4333                {
4334                    OMX_AUDIO_PARAM_PCMMODETYPE params;
4335                    InitOMXParams(&params);
4336                    params.nPortIndex = portIndex;
4337
4338                    err = mOMX->getParameter(
4339                            mNode, (OMX_INDEXTYPE)OMX_IndexParamAudioPcm, &params, sizeof(params));
4340                    if (err != OK) {
4341                        return err;
4342                    }
4343
4344                    const char *mime = NULL;
4345                    if (params.ePCMMode == OMX_AUDIO_PCMModeMULaw) {
4346                        mime = MEDIA_MIMETYPE_AUDIO_G711_MLAW;
4347                    } else if (params.ePCMMode == OMX_AUDIO_PCMModeALaw) {
4348                        mime = MEDIA_MIMETYPE_AUDIO_G711_ALAW;
4349                    } else { // params.ePCMMode == OMX_AUDIO_PCMModeLinear
4350                        mime = MEDIA_MIMETYPE_AUDIO_RAW;
4351                    }
4352                    notify->setString("mime", mime);
4353                    notify->setInt32("channel-count", params.nChannels);
4354                    notify->setInt32("sample-rate", params.nSamplingRate);
4355                    break;
4356                }
4357
4358                case OMX_AUDIO_CodingGSMFR:
4359                {
4360                    OMX_AUDIO_PARAM_PCMMODETYPE params;
4361                    InitOMXParams(&params);
4362                    params.nPortIndex = portIndex;
4363
4364                    err = mOMX->getParameter(
4365                                mNode, OMX_IndexParamAudioPcm, &params, sizeof(params));
4366                    if (err != OK) {
4367                        return err;
4368                    }
4369
4370                    notify->setString("mime", MEDIA_MIMETYPE_AUDIO_MSGSM);
4371                    notify->setInt32("channel-count", params.nChannels);
4372                    notify->setInt32("sample-rate", params.nSamplingRate);
4373                    break;
4374                }
4375
4376                default:
4377                    ALOGE("Unsupported audio coding: %s(%d)\n",
4378                            asString(audioDef->eEncoding), audioDef->eEncoding);
4379                    return BAD_TYPE;
4380            }
4381            break;
4382        }
4383
4384        default:
4385            ALOGE("Unsupported domain: %s(%d)", asString(def.eDomain), def.eDomain);
4386            return BAD_TYPE;
4387    }
4388
4389    return OK;
4390}
4391
4392void ACodec::sendFormatChange(const sp<AMessage> &reply) {
4393    sp<AMessage> notify = mBaseOutputFormat->dup();
4394    notify->setInt32("what", kWhatOutputFormatChanged);
4395
4396    if (getPortFormat(kPortIndexOutput, notify) != OK) {
4397        ALOGE("[%s] Failed to get port format to send format change", mComponentName.c_str());
4398        return;
4399    }
4400
4401    AString mime;
4402    CHECK(notify->findString("mime", &mime));
4403
4404    int32_t left, top, right, bottom;
4405    if (mime == MEDIA_MIMETYPE_VIDEO_RAW &&
4406        mNativeWindow != NULL &&
4407        notify->findRect("crop", &left, &top, &right, &bottom)) {
4408        // notify renderer of the crop change
4409        // NOTE: native window uses extended right-bottom coordinate
4410        reply->setRect("crop", left, top, right + 1, bottom + 1);
4411    } else if (mime == MEDIA_MIMETYPE_AUDIO_RAW &&
4412               (mEncoderDelay || mEncoderPadding)) {
4413        int32_t channelCount;
4414        CHECK(notify->findInt32("channel-count", &channelCount));
4415        size_t frameSize = channelCount * sizeof(int16_t);
4416        if (mSkipCutBuffer != NULL) {
4417            size_t prevbufsize = mSkipCutBuffer->size();
4418            if (prevbufsize != 0) {
4419                ALOGW("Replacing SkipCutBuffer holding %zu bytes", prevbufsize);
4420            }
4421        }
4422        mSkipCutBuffer = new SkipCutBuffer(
4423                mEncoderDelay * frameSize,
4424                mEncoderPadding * frameSize);
4425    }
4426
4427    notify->post();
4428
4429    mSentFormat = true;
4430}
4431
4432void ACodec::signalError(OMX_ERRORTYPE error, status_t internalError) {
4433    sp<AMessage> notify = mNotify->dup();
4434    notify->setInt32("what", CodecBase::kWhatError);
4435    ALOGE("signalError(omxError %#x, internalError %d)", error, internalError);
4436
4437    if (internalError == UNKNOWN_ERROR) { // find better error code
4438        const status_t omxStatus = statusFromOMXError(error);
4439        if (omxStatus != 0) {
4440            internalError = omxStatus;
4441        } else {
4442            ALOGW("Invalid OMX error %#x", error);
4443        }
4444    }
4445    notify->setInt32("err", internalError);
4446    notify->setInt32("actionCode", ACTION_CODE_FATAL); // could translate from OMX error.
4447    notify->post();
4448}
4449
4450////////////////////////////////////////////////////////////////////////////////
4451
4452ACodec::PortDescription::PortDescription() {
4453}
4454
4455status_t ACodec::requestIDRFrame() {
4456    if (!mIsEncoder) {
4457        return ERROR_UNSUPPORTED;
4458    }
4459
4460    OMX_CONFIG_INTRAREFRESHVOPTYPE params;
4461    InitOMXParams(&params);
4462
4463    params.nPortIndex = kPortIndexOutput;
4464    params.IntraRefreshVOP = OMX_TRUE;
4465
4466    return mOMX->setConfig(
4467            mNode,
4468            OMX_IndexConfigVideoIntraVOPRefresh,
4469            &params,
4470            sizeof(params));
4471}
4472
4473void ACodec::PortDescription::addBuffer(
4474        IOMX::buffer_id id, const sp<ABuffer> &buffer) {
4475    mBufferIDs.push_back(id);
4476    mBuffers.push_back(buffer);
4477}
4478
4479size_t ACodec::PortDescription::countBuffers() {
4480    return mBufferIDs.size();
4481}
4482
4483IOMX::buffer_id ACodec::PortDescription::bufferIDAt(size_t index) const {
4484    return mBufferIDs.itemAt(index);
4485}
4486
4487sp<ABuffer> ACodec::PortDescription::bufferAt(size_t index) const {
4488    return mBuffers.itemAt(index);
4489}
4490
4491////////////////////////////////////////////////////////////////////////////////
4492
4493ACodec::BaseState::BaseState(ACodec *codec, const sp<AState> &parentState)
4494    : AState(parentState),
4495      mCodec(codec) {
4496}
4497
4498ACodec::BaseState::PortMode ACodec::BaseState::getPortMode(
4499        OMX_U32 /* portIndex */) {
4500    return KEEP_BUFFERS;
4501}
4502
4503bool ACodec::BaseState::onMessageReceived(const sp<AMessage> &msg) {
4504    switch (msg->what()) {
4505        case kWhatInputBufferFilled:
4506        {
4507            onInputBufferFilled(msg);
4508            break;
4509        }
4510
4511        case kWhatOutputBufferDrained:
4512        {
4513            onOutputBufferDrained(msg);
4514            break;
4515        }
4516
4517        case ACodec::kWhatOMXMessageList:
4518        {
4519            return checkOMXMessage(msg) ? onOMXMessageList(msg) : true;
4520        }
4521
4522        case ACodec::kWhatOMXMessageItem:
4523        {
4524            // no need to check as we already did it for kWhatOMXMessageList
4525            return onOMXMessage(msg);
4526        }
4527
4528        case ACodec::kWhatOMXMessage:
4529        {
4530            return checkOMXMessage(msg) ? onOMXMessage(msg) : true;
4531        }
4532
4533        case ACodec::kWhatSetSurface:
4534        {
4535            sp<AReplyToken> replyID;
4536            CHECK(msg->senderAwaitsResponse(&replyID));
4537
4538            sp<RefBase> obj;
4539            CHECK(msg->findObject("surface", &obj));
4540
4541            status_t err =
4542                ADebug::isExperimentEnabled("legacy-setsurface") ? BAD_VALUE :
4543                        mCodec->handleSetSurface(static_cast<Surface *>(obj.get()));
4544
4545            sp<AMessage> response = new AMessage;
4546            response->setInt32("err", err);
4547            response->postReply(replyID);
4548            break;
4549        }
4550
4551        case ACodec::kWhatCreateInputSurface:
4552        case ACodec::kWhatSetInputSurface:
4553        case ACodec::kWhatSignalEndOfInputStream:
4554        {
4555            // This may result in an app illegal state exception.
4556            ALOGE("Message 0x%x was not handled", msg->what());
4557            mCodec->signalError(OMX_ErrorUndefined, INVALID_OPERATION);
4558            return true;
4559        }
4560
4561        case ACodec::kWhatOMXDied:
4562        {
4563            // This will result in kFlagSawMediaServerDie handling in MediaCodec.
4564            ALOGE("OMX/mediaserver died, signalling error!");
4565            mCodec->signalError(OMX_ErrorResourcesLost, DEAD_OBJECT);
4566            break;
4567        }
4568
4569        case ACodec::kWhatReleaseCodecInstance:
4570        {
4571            ALOGI("[%s] forcing the release of codec",
4572                    mCodec->mComponentName.c_str());
4573            status_t err = mCodec->mOMX->freeNode(mCodec->mNode);
4574            ALOGE_IF("[%s] failed to release codec instance: err=%d",
4575                       mCodec->mComponentName.c_str(), err);
4576            sp<AMessage> notify = mCodec->mNotify->dup();
4577            notify->setInt32("what", CodecBase::kWhatShutdownCompleted);
4578            notify->post();
4579            break;
4580        }
4581
4582        default:
4583            return false;
4584    }
4585
4586    return true;
4587}
4588
4589bool ACodec::BaseState::checkOMXMessage(const sp<AMessage> &msg) {
4590    // there is a possibility that this is an outstanding message for a
4591    // codec that we have already destroyed
4592    if (mCodec->mNode == 0) {
4593        ALOGI("ignoring message as already freed component: %s",
4594                msg->debugString().c_str());
4595        return false;
4596    }
4597
4598    IOMX::node_id nodeID;
4599    CHECK(msg->findInt32("node", (int32_t*)&nodeID));
4600    if (nodeID != mCodec->mNode) {
4601        ALOGE("Unexpected message for nodeID: %u, should have been %u", nodeID, mCodec->mNode);
4602        return false;
4603    }
4604    return true;
4605}
4606
4607bool ACodec::BaseState::onOMXMessageList(const sp<AMessage> &msg) {
4608    sp<RefBase> obj;
4609    CHECK(msg->findObject("messages", &obj));
4610    sp<MessageList> msgList = static_cast<MessageList *>(obj.get());
4611
4612    bool receivedRenderedEvents = false;
4613    for (std::list<sp<AMessage>>::const_iterator it = msgList->getList().cbegin();
4614          it != msgList->getList().cend(); ++it) {
4615        (*it)->setWhat(ACodec::kWhatOMXMessageItem);
4616        mCodec->handleMessage(*it);
4617        int32_t type;
4618        CHECK((*it)->findInt32("type", &type));
4619        if (type == omx_message::FRAME_RENDERED) {
4620            receivedRenderedEvents = true;
4621        }
4622    }
4623
4624    if (receivedRenderedEvents) {
4625        // NOTE: all buffers are rendered in this case
4626        mCodec->notifyOfRenderedFrames();
4627    }
4628    return true;
4629}
4630
4631bool ACodec::BaseState::onOMXMessage(const sp<AMessage> &msg) {
4632    int32_t type;
4633    CHECK(msg->findInt32("type", &type));
4634
4635    switch (type) {
4636        case omx_message::EVENT:
4637        {
4638            int32_t event, data1, data2;
4639            CHECK(msg->findInt32("event", &event));
4640            CHECK(msg->findInt32("data1", &data1));
4641            CHECK(msg->findInt32("data2", &data2));
4642
4643            if (event == OMX_EventCmdComplete
4644                    && data1 == OMX_CommandFlush
4645                    && data2 == (int32_t)OMX_ALL) {
4646                // Use of this notification is not consistent across
4647                // implementations. We'll drop this notification and rely
4648                // on flush-complete notifications on the individual port
4649                // indices instead.
4650
4651                return true;
4652            }
4653
4654            return onOMXEvent(
4655                    static_cast<OMX_EVENTTYPE>(event),
4656                    static_cast<OMX_U32>(data1),
4657                    static_cast<OMX_U32>(data2));
4658        }
4659
4660        case omx_message::EMPTY_BUFFER_DONE:
4661        {
4662            IOMX::buffer_id bufferID;
4663            int32_t fenceFd;
4664
4665            CHECK(msg->findInt32("buffer", (int32_t*)&bufferID));
4666            CHECK(msg->findInt32("fence_fd", &fenceFd));
4667
4668            return onOMXEmptyBufferDone(bufferID, fenceFd);
4669        }
4670
4671        case omx_message::FILL_BUFFER_DONE:
4672        {
4673            IOMX::buffer_id bufferID;
4674            CHECK(msg->findInt32("buffer", (int32_t*)&bufferID));
4675
4676            int32_t rangeOffset, rangeLength, flags, fenceFd;
4677            int64_t timeUs;
4678
4679            CHECK(msg->findInt32("range_offset", &rangeOffset));
4680            CHECK(msg->findInt32("range_length", &rangeLength));
4681            CHECK(msg->findInt32("flags", &flags));
4682            CHECK(msg->findInt64("timestamp", &timeUs));
4683            CHECK(msg->findInt32("fence_fd", &fenceFd));
4684
4685            return onOMXFillBufferDone(
4686                    bufferID,
4687                    (size_t)rangeOffset, (size_t)rangeLength,
4688                    (OMX_U32)flags,
4689                    timeUs,
4690                    fenceFd);
4691        }
4692
4693        case omx_message::FRAME_RENDERED:
4694        {
4695            int64_t mediaTimeUs, systemNano;
4696
4697            CHECK(msg->findInt64("media_time_us", &mediaTimeUs));
4698            CHECK(msg->findInt64("system_nano", &systemNano));
4699
4700            return onOMXFrameRendered(
4701                    mediaTimeUs, systemNano);
4702        }
4703
4704        default:
4705            ALOGE("Unexpected message type: %d", type);
4706            return false;
4707    }
4708}
4709
4710bool ACodec::BaseState::onOMXFrameRendered(
4711        int64_t mediaTimeUs __unused, nsecs_t systemNano __unused) {
4712    // ignore outside of Executing and PortSettingsChanged states
4713    return true;
4714}
4715
4716bool ACodec::BaseState::onOMXEvent(
4717        OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2) {
4718    if (event != OMX_EventError) {
4719        ALOGV("[%s] EVENT(%d, 0x%08x, 0x%08x)",
4720             mCodec->mComponentName.c_str(), event, data1, data2);
4721
4722        return false;
4723    }
4724
4725    ALOGE("[%s] ERROR(0x%08x)", mCodec->mComponentName.c_str(), data1);
4726
4727    // verify OMX component sends back an error we expect.
4728    OMX_ERRORTYPE omxError = (OMX_ERRORTYPE)data1;
4729    if (!isOMXError(omxError)) {
4730        ALOGW("Invalid OMX error %#x", omxError);
4731        omxError = OMX_ErrorUndefined;
4732    }
4733    mCodec->signalError(omxError);
4734
4735    return true;
4736}
4737
4738bool ACodec::BaseState::onOMXEmptyBufferDone(IOMX::buffer_id bufferID, int fenceFd) {
4739    ALOGV("[%s] onOMXEmptyBufferDone %u",
4740         mCodec->mComponentName.c_str(), bufferID);
4741
4742    BufferInfo *info = mCodec->findBufferByID(kPortIndexInput, bufferID);
4743    BufferInfo::Status status = BufferInfo::getSafeStatus(info);
4744    if (status != BufferInfo::OWNED_BY_COMPONENT) {
4745        ALOGE("Wrong ownership in EBD: %s(%d) buffer #%u", _asString(status), status, bufferID);
4746        mCodec->dumpBuffers(kPortIndexInput);
4747        if (fenceFd >= 0) {
4748            ::close(fenceFd);
4749        }
4750        return false;
4751    }
4752    info->mStatus = BufferInfo::OWNED_BY_US;
4753
4754    // input buffers cannot take fences, so wait for any fence now
4755    (void)mCodec->waitForFence(fenceFd, "onOMXEmptyBufferDone");
4756    fenceFd = -1;
4757
4758    // still save fence for completeness
4759    info->setWriteFence(fenceFd, "onOMXEmptyBufferDone");
4760
4761    // We're in "store-metadata-in-buffers" mode, the underlying
4762    // OMX component had access to data that's implicitly refcounted
4763    // by this "MediaBuffer" object. Now that the OMX component has
4764    // told us that it's done with the input buffer, we can decrement
4765    // the mediaBuffer's reference count.
4766    info->mData->setMediaBufferBase(NULL);
4767
4768    PortMode mode = getPortMode(kPortIndexInput);
4769
4770    switch (mode) {
4771        case KEEP_BUFFERS:
4772            break;
4773
4774        case RESUBMIT_BUFFERS:
4775            postFillThisBuffer(info);
4776            break;
4777
4778        case FREE_BUFFERS:
4779        default:
4780            ALOGE("SHOULD NOT REACH HERE: cannot free empty output buffers");
4781            return false;
4782    }
4783
4784    return true;
4785}
4786
4787void ACodec::BaseState::postFillThisBuffer(BufferInfo *info) {
4788    if (mCodec->mPortEOS[kPortIndexInput]) {
4789        return;
4790    }
4791
4792    CHECK_EQ((int)info->mStatus, (int)BufferInfo::OWNED_BY_US);
4793
4794    sp<AMessage> notify = mCodec->mNotify->dup();
4795    notify->setInt32("what", CodecBase::kWhatFillThisBuffer);
4796    notify->setInt32("buffer-id", info->mBufferID);
4797
4798    info->mData->meta()->clear();
4799    notify->setBuffer("buffer", info->mData);
4800
4801    sp<AMessage> reply = new AMessage(kWhatInputBufferFilled, mCodec);
4802    reply->setInt32("buffer-id", info->mBufferID);
4803
4804    notify->setMessage("reply", reply);
4805
4806    notify->post();
4807
4808    info->mStatus = BufferInfo::OWNED_BY_UPSTREAM;
4809}
4810
4811void ACodec::BaseState::onInputBufferFilled(const sp<AMessage> &msg) {
4812    IOMX::buffer_id bufferID;
4813    CHECK(msg->findInt32("buffer-id", (int32_t*)&bufferID));
4814    sp<ABuffer> buffer;
4815    int32_t err = OK;
4816    bool eos = false;
4817    PortMode mode = getPortMode(kPortIndexInput);
4818
4819    if (!msg->findBuffer("buffer", &buffer)) {
4820        /* these are unfilled buffers returned by client */
4821        CHECK(msg->findInt32("err", &err));
4822
4823        if (err == OK) {
4824            /* buffers with no errors are returned on MediaCodec.flush */
4825            mode = KEEP_BUFFERS;
4826        } else {
4827            ALOGV("[%s] saw error %d instead of an input buffer",
4828                 mCodec->mComponentName.c_str(), err);
4829            eos = true;
4830        }
4831
4832        buffer.clear();
4833    }
4834
4835    int32_t tmp;
4836    if (buffer != NULL && buffer->meta()->findInt32("eos", &tmp) && tmp) {
4837        eos = true;
4838        err = ERROR_END_OF_STREAM;
4839    }
4840
4841    BufferInfo *info = mCodec->findBufferByID(kPortIndexInput, bufferID);
4842    BufferInfo::Status status = BufferInfo::getSafeStatus(info);
4843    if (status != BufferInfo::OWNED_BY_UPSTREAM) {
4844        ALOGE("Wrong ownership in IBF: %s(%d) buffer #%u", _asString(status), status, bufferID);
4845        mCodec->dumpBuffers(kPortIndexInput);
4846        mCodec->signalError(OMX_ErrorUndefined, FAILED_TRANSACTION);
4847        return;
4848    }
4849
4850    info->mStatus = BufferInfo::OWNED_BY_US;
4851
4852    switch (mode) {
4853        case KEEP_BUFFERS:
4854        {
4855            if (eos) {
4856                if (!mCodec->mPortEOS[kPortIndexInput]) {
4857                    mCodec->mPortEOS[kPortIndexInput] = true;
4858                    mCodec->mInputEOSResult = err;
4859                }
4860            }
4861            break;
4862        }
4863
4864        case RESUBMIT_BUFFERS:
4865        {
4866            if (buffer != NULL && !mCodec->mPortEOS[kPortIndexInput]) {
4867                // Do not send empty input buffer w/o EOS to the component.
4868                if (buffer->size() == 0 && !eos) {
4869                    postFillThisBuffer(info);
4870                    break;
4871                }
4872
4873                int64_t timeUs;
4874                CHECK(buffer->meta()->findInt64("timeUs", &timeUs));
4875
4876                OMX_U32 flags = OMX_BUFFERFLAG_ENDOFFRAME;
4877
4878                int32_t isCSD;
4879                if (buffer->meta()->findInt32("csd", &isCSD) && isCSD != 0) {
4880                    flags |= OMX_BUFFERFLAG_CODECCONFIG;
4881                }
4882
4883                if (eos) {
4884                    flags |= OMX_BUFFERFLAG_EOS;
4885                }
4886
4887                if (buffer != info->mData) {
4888                    ALOGV("[%s] Needs to copy input data for buffer %u. (%p != %p)",
4889                         mCodec->mComponentName.c_str(),
4890                         bufferID,
4891                         buffer.get(), info->mData.get());
4892
4893                    if (buffer->size() > info->mData->capacity()) {
4894                        ALOGE("data size (%zu) is greated than buffer capacity (%zu)",
4895                                buffer->size(),           // this is the data received
4896                                info->mData->capacity()); // this is out buffer size
4897                        mCodec->signalError(OMX_ErrorUndefined, FAILED_TRANSACTION);
4898                        return;
4899                    }
4900                    memcpy(info->mData->data(), buffer->data(), buffer->size());
4901                }
4902
4903                if (flags & OMX_BUFFERFLAG_CODECCONFIG) {
4904                    ALOGV("[%s] calling emptyBuffer %u w/ codec specific data",
4905                         mCodec->mComponentName.c_str(), bufferID);
4906                } else if (flags & OMX_BUFFERFLAG_EOS) {
4907                    ALOGV("[%s] calling emptyBuffer %u w/ EOS",
4908                         mCodec->mComponentName.c_str(), bufferID);
4909                } else {
4910#if TRACK_BUFFER_TIMING
4911                    ALOGI("[%s] calling emptyBuffer %u w/ time %lld us",
4912                         mCodec->mComponentName.c_str(), bufferID, (long long)timeUs);
4913#else
4914                    ALOGV("[%s] calling emptyBuffer %u w/ time %lld us",
4915                         mCodec->mComponentName.c_str(), bufferID, (long long)timeUs);
4916#endif
4917                }
4918
4919#if TRACK_BUFFER_TIMING
4920                ACodec::BufferStats stats;
4921                stats.mEmptyBufferTimeUs = ALooper::GetNowUs();
4922                stats.mFillBufferDoneTimeUs = -1ll;
4923                mCodec->mBufferStats.add(timeUs, stats);
4924#endif
4925
4926                if (mCodec->storingMetadataInDecodedBuffers()) {
4927                    // try to submit an output buffer for each input buffer
4928                    PortMode outputMode = getPortMode(kPortIndexOutput);
4929
4930                    ALOGV("MetadataBuffersToSubmit=%u portMode=%s",
4931                            mCodec->mMetadataBuffersToSubmit,
4932                            (outputMode == FREE_BUFFERS ? "FREE" :
4933                             outputMode == KEEP_BUFFERS ? "KEEP" : "RESUBMIT"));
4934                    if (outputMode == RESUBMIT_BUFFERS) {
4935                        mCodec->submitOutputMetadataBuffer();
4936                    }
4937                }
4938                info->checkReadFence("onInputBufferFilled");
4939                status_t err2 = mCodec->mOMX->emptyBuffer(
4940                    mCodec->mNode,
4941                    bufferID,
4942                    0,
4943                    buffer->size(),
4944                    flags,
4945                    timeUs,
4946                    info->mFenceFd);
4947                info->mFenceFd = -1;
4948                if (err2 != OK) {
4949                    mCodec->signalError(OMX_ErrorUndefined, makeNoSideEffectStatus(err2));
4950                    return;
4951                }
4952                info->mStatus = BufferInfo::OWNED_BY_COMPONENT;
4953
4954                if (!eos && err == OK) {
4955                    getMoreInputDataIfPossible();
4956                } else {
4957                    ALOGV("[%s] Signalled EOS (%d) on the input port",
4958                         mCodec->mComponentName.c_str(), err);
4959
4960                    mCodec->mPortEOS[kPortIndexInput] = true;
4961                    mCodec->mInputEOSResult = err;
4962                }
4963            } else if (!mCodec->mPortEOS[kPortIndexInput]) {
4964                if (err != OK && err != ERROR_END_OF_STREAM) {
4965                    ALOGV("[%s] Signalling EOS on the input port due to error %d",
4966                         mCodec->mComponentName.c_str(), err);
4967                } else {
4968                    ALOGV("[%s] Signalling EOS on the input port",
4969                         mCodec->mComponentName.c_str());
4970                }
4971
4972                ALOGV("[%s] calling emptyBuffer %u signalling EOS",
4973                     mCodec->mComponentName.c_str(), bufferID);
4974
4975                info->checkReadFence("onInputBufferFilled");
4976                status_t err2 = mCodec->mOMX->emptyBuffer(
4977                        mCodec->mNode,
4978                        bufferID,
4979                        0,
4980                        0,
4981                        OMX_BUFFERFLAG_EOS,
4982                        0,
4983                        info->mFenceFd);
4984                info->mFenceFd = -1;
4985                if (err2 != OK) {
4986                    mCodec->signalError(OMX_ErrorUndefined, makeNoSideEffectStatus(err2));
4987                    return;
4988                }
4989                info->mStatus = BufferInfo::OWNED_BY_COMPONENT;
4990
4991                mCodec->mPortEOS[kPortIndexInput] = true;
4992                mCodec->mInputEOSResult = err;
4993            }
4994            break;
4995        }
4996
4997        case FREE_BUFFERS:
4998            break;
4999
5000        default:
5001            ALOGE("invalid port mode: %d", mode);
5002            break;
5003    }
5004}
5005
5006void ACodec::BaseState::getMoreInputDataIfPossible() {
5007    if (mCodec->mPortEOS[kPortIndexInput]) {
5008        return;
5009    }
5010
5011    BufferInfo *eligible = NULL;
5012
5013    for (size_t i = 0; i < mCodec->mBuffers[kPortIndexInput].size(); ++i) {
5014        BufferInfo *info = &mCodec->mBuffers[kPortIndexInput].editItemAt(i);
5015
5016#if 0
5017        if (info->mStatus == BufferInfo::OWNED_BY_UPSTREAM) {
5018            // There's already a "read" pending.
5019            return;
5020        }
5021#endif
5022
5023        if (info->mStatus == BufferInfo::OWNED_BY_US) {
5024            eligible = info;
5025        }
5026    }
5027
5028    if (eligible == NULL) {
5029        return;
5030    }
5031
5032    postFillThisBuffer(eligible);
5033}
5034
5035bool ACodec::BaseState::onOMXFillBufferDone(
5036        IOMX::buffer_id bufferID,
5037        size_t rangeOffset, size_t rangeLength,
5038        OMX_U32 flags,
5039        int64_t timeUs,
5040        int fenceFd) {
5041    ALOGV("[%s] onOMXFillBufferDone %u time %" PRId64 " us, flags = 0x%08x",
5042         mCodec->mComponentName.c_str(), bufferID, timeUs, flags);
5043
5044    ssize_t index;
5045    status_t err= OK;
5046
5047#if TRACK_BUFFER_TIMING
5048    index = mCodec->mBufferStats.indexOfKey(timeUs);
5049    if (index >= 0) {
5050        ACodec::BufferStats *stats = &mCodec->mBufferStats.editValueAt(index);
5051        stats->mFillBufferDoneTimeUs = ALooper::GetNowUs();
5052
5053        ALOGI("frame PTS %lld: %lld",
5054                timeUs,
5055                stats->mFillBufferDoneTimeUs - stats->mEmptyBufferTimeUs);
5056
5057        mCodec->mBufferStats.removeItemsAt(index);
5058        stats = NULL;
5059    }
5060#endif
5061
5062    BufferInfo *info =
5063        mCodec->findBufferByID(kPortIndexOutput, bufferID, &index);
5064    BufferInfo::Status status = BufferInfo::getSafeStatus(info);
5065    if (status != BufferInfo::OWNED_BY_COMPONENT) {
5066        ALOGE("Wrong ownership in FBD: %s(%d) buffer #%u", _asString(status), status, bufferID);
5067        mCodec->dumpBuffers(kPortIndexOutput);
5068        mCodec->signalError(OMX_ErrorUndefined, FAILED_TRANSACTION);
5069        if (fenceFd >= 0) {
5070            ::close(fenceFd);
5071        }
5072        return true;
5073    }
5074
5075    info->mDequeuedAt = ++mCodec->mDequeueCounter;
5076    info->mStatus = BufferInfo::OWNED_BY_US;
5077
5078    if (info->mRenderInfo != NULL) {
5079        // The fence for an emptied buffer must have signaled, but there still could be queued
5080        // or out-of-order dequeued buffers in the render queue prior to this buffer. Drop these,
5081        // as we will soon requeue this buffer to the surface. While in theory we could still keep
5082        // track of buffers that are requeued to the surface, it is better to add support to the
5083        // buffer-queue to notify us of released buffers and their fences (in the future).
5084        mCodec->notifyOfRenderedFrames(true /* dropIncomplete */);
5085    }
5086
5087    // byte buffers cannot take fences, so wait for any fence now
5088    if (mCodec->mNativeWindow == NULL) {
5089        (void)mCodec->waitForFence(fenceFd, "onOMXFillBufferDone");
5090        fenceFd = -1;
5091    }
5092    info->setReadFence(fenceFd, "onOMXFillBufferDone");
5093
5094    PortMode mode = getPortMode(kPortIndexOutput);
5095
5096    switch (mode) {
5097        case KEEP_BUFFERS:
5098            break;
5099
5100        case RESUBMIT_BUFFERS:
5101        {
5102            if (rangeLength == 0 && (!(flags & OMX_BUFFERFLAG_EOS)
5103                    || mCodec->mPortEOS[kPortIndexOutput])) {
5104                ALOGV("[%s] calling fillBuffer %u",
5105                     mCodec->mComponentName.c_str(), info->mBufferID);
5106
5107                err = mCodec->mOMX->fillBuffer(mCodec->mNode, info->mBufferID, info->mFenceFd);
5108                info->mFenceFd = -1;
5109                if (err != OK) {
5110                    mCodec->signalError(OMX_ErrorUndefined, makeNoSideEffectStatus(err));
5111                    return true;
5112                }
5113
5114                info->mStatus = BufferInfo::OWNED_BY_COMPONENT;
5115                break;
5116            }
5117
5118            sp<AMessage> reply =
5119                new AMessage(kWhatOutputBufferDrained, mCodec);
5120
5121            if (!mCodec->mSentFormat && rangeLength > 0) {
5122                mCodec->sendFormatChange(reply);
5123            }
5124            if (mCodec->usingMetadataOnEncoderOutput()) {
5125                native_handle_t *handle = NULL;
5126                VideoGrallocMetadata &grallocMeta = *(VideoGrallocMetadata *)info->mData->data();
5127                VideoNativeMetadata &nativeMeta = *(VideoNativeMetadata *)info->mData->data();
5128                if (info->mData->size() >= sizeof(grallocMeta)
5129                        && grallocMeta.eType == kMetadataBufferTypeGrallocSource) {
5130                    handle = (native_handle_t *)grallocMeta.pHandle;
5131                } else if (info->mData->size() >= sizeof(nativeMeta)
5132                        && nativeMeta.eType == kMetadataBufferTypeANWBuffer) {
5133                    handle = (native_handle_t *)nativeMeta.pBuffer->handle;
5134                }
5135                info->mData->meta()->setPointer("handle", handle);
5136                info->mData->meta()->setInt32("rangeOffset", rangeOffset);
5137                info->mData->meta()->setInt32("rangeLength", rangeLength);
5138            } else {
5139                info->mData->setRange(rangeOffset, rangeLength);
5140            }
5141#if 0
5142            if (mCodec->mNativeWindow == NULL) {
5143                if (IsIDR(info->mData)) {
5144                    ALOGI("IDR frame");
5145                }
5146            }
5147#endif
5148
5149            if (mCodec->mSkipCutBuffer != NULL) {
5150                mCodec->mSkipCutBuffer->submit(info->mData);
5151            }
5152            info->mData->meta()->setInt64("timeUs", timeUs);
5153
5154            sp<AMessage> notify = mCodec->mNotify->dup();
5155            notify->setInt32("what", CodecBase::kWhatDrainThisBuffer);
5156            notify->setInt32("buffer-id", info->mBufferID);
5157            notify->setBuffer("buffer", info->mData);
5158            notify->setInt32("flags", flags);
5159
5160            reply->setInt32("buffer-id", info->mBufferID);
5161
5162            notify->setMessage("reply", reply);
5163
5164            notify->post();
5165
5166            info->mStatus = BufferInfo::OWNED_BY_DOWNSTREAM;
5167
5168            if (flags & OMX_BUFFERFLAG_EOS) {
5169                ALOGV("[%s] saw output EOS", mCodec->mComponentName.c_str());
5170
5171                sp<AMessage> notify = mCodec->mNotify->dup();
5172                notify->setInt32("what", CodecBase::kWhatEOS);
5173                notify->setInt32("err", mCodec->mInputEOSResult);
5174                notify->post();
5175
5176                mCodec->mPortEOS[kPortIndexOutput] = true;
5177            }
5178            break;
5179        }
5180
5181        case FREE_BUFFERS:
5182            err = mCodec->freeBuffer(kPortIndexOutput, index);
5183            if (err != OK) {
5184                mCodec->signalError(OMX_ErrorUndefined, makeNoSideEffectStatus(err));
5185                return true;
5186            }
5187            break;
5188
5189        default:
5190            ALOGE("Invalid port mode: %d", mode);
5191            return false;
5192    }
5193
5194    return true;
5195}
5196
5197void ACodec::BaseState::onOutputBufferDrained(const sp<AMessage> &msg) {
5198    IOMX::buffer_id bufferID;
5199    CHECK(msg->findInt32("buffer-id", (int32_t*)&bufferID));
5200    ssize_t index;
5201    BufferInfo *info = mCodec->findBufferByID(kPortIndexOutput, bufferID, &index);
5202    BufferInfo::Status status = BufferInfo::getSafeStatus(info);
5203    if (status != BufferInfo::OWNED_BY_DOWNSTREAM) {
5204        ALOGE("Wrong ownership in OBD: %s(%d) buffer #%u", _asString(status), status, bufferID);
5205        mCodec->dumpBuffers(kPortIndexOutput);
5206        mCodec->signalError(OMX_ErrorUndefined, FAILED_TRANSACTION);
5207        return;
5208    }
5209
5210    android_native_rect_t crop;
5211    if (msg->findRect("crop", &crop.left, &crop.top, &crop.right, &crop.bottom)) {
5212        status_t err = native_window_set_crop(mCodec->mNativeWindow.get(), &crop);
5213        ALOGW_IF(err != NO_ERROR, "failed to set crop: %d", err);
5214    }
5215
5216    int32_t render;
5217    if (mCodec->mNativeWindow != NULL
5218            && msg->findInt32("render", &render) && render != 0
5219            && info->mData != NULL && info->mData->size() != 0) {
5220        ATRACE_NAME("render");
5221        // The client wants this buffer to be rendered.
5222
5223        // save buffers sent to the surface so we can get render time when they return
5224        int64_t mediaTimeUs = -1;
5225        info->mData->meta()->findInt64("timeUs", &mediaTimeUs);
5226        if (mediaTimeUs >= 0) {
5227            mCodec->mRenderTracker.onFrameQueued(
5228                    mediaTimeUs, info->mGraphicBuffer, new Fence(::dup(info->mFenceFd)));
5229        }
5230
5231        int64_t timestampNs = 0;
5232        if (!msg->findInt64("timestampNs", &timestampNs)) {
5233            // use media timestamp if client did not request a specific render timestamp
5234            if (info->mData->meta()->findInt64("timeUs", &timestampNs)) {
5235                ALOGV("using buffer PTS of %lld", (long long)timestampNs);
5236                timestampNs *= 1000;
5237            }
5238        }
5239
5240        status_t err;
5241        err = native_window_set_buffers_timestamp(mCodec->mNativeWindow.get(), timestampNs);
5242        ALOGW_IF(err != NO_ERROR, "failed to set buffer timestamp: %d", err);
5243
5244        info->checkReadFence("onOutputBufferDrained before queueBuffer");
5245        err = mCodec->mNativeWindow->queueBuffer(
5246                    mCodec->mNativeWindow.get(), info->mGraphicBuffer.get(), info->mFenceFd);
5247        info->mFenceFd = -1;
5248        if (err == OK) {
5249            info->mStatus = BufferInfo::OWNED_BY_NATIVE_WINDOW;
5250        } else {
5251            ALOGE("queueBuffer failed in onOutputBufferDrained: %d", err);
5252            mCodec->signalError(OMX_ErrorUndefined, makeNoSideEffectStatus(err));
5253            info->mStatus = BufferInfo::OWNED_BY_US;
5254            // keeping read fence as write fence to avoid clobbering
5255            info->mIsReadFence = false;
5256        }
5257    } else {
5258        if (mCodec->mNativeWindow != NULL &&
5259            (info->mData == NULL || info->mData->size() != 0)) {
5260            // move read fence into write fence to avoid clobbering
5261            info->mIsReadFence = false;
5262            ATRACE_NAME("frame-drop");
5263        }
5264        info->mStatus = BufferInfo::OWNED_BY_US;
5265    }
5266
5267    PortMode mode = getPortMode(kPortIndexOutput);
5268
5269    switch (mode) {
5270        case KEEP_BUFFERS:
5271        {
5272            // XXX fishy, revisit!!! What about the FREE_BUFFERS case below?
5273
5274            if (info->mStatus == BufferInfo::OWNED_BY_NATIVE_WINDOW) {
5275                // We cannot resubmit the buffer we just rendered, dequeue
5276                // the spare instead.
5277
5278                info = mCodec->dequeueBufferFromNativeWindow();
5279            }
5280            break;
5281        }
5282
5283        case RESUBMIT_BUFFERS:
5284        {
5285            if (!mCodec->mPortEOS[kPortIndexOutput]) {
5286                if (info->mStatus == BufferInfo::OWNED_BY_NATIVE_WINDOW) {
5287                    // We cannot resubmit the buffer we just rendered, dequeue
5288                    // the spare instead.
5289
5290                    info = mCodec->dequeueBufferFromNativeWindow();
5291                }
5292
5293                if (info != NULL) {
5294                    ALOGV("[%s] calling fillBuffer %u",
5295                         mCodec->mComponentName.c_str(), info->mBufferID);
5296                    info->checkWriteFence("onOutputBufferDrained::RESUBMIT_BUFFERS");
5297                    status_t err = mCodec->mOMX->fillBuffer(
5298                            mCodec->mNode, info->mBufferID, info->mFenceFd);
5299                    info->mFenceFd = -1;
5300                    if (err == OK) {
5301                        info->mStatus = BufferInfo::OWNED_BY_COMPONENT;
5302                    } else {
5303                        mCodec->signalError(OMX_ErrorUndefined, makeNoSideEffectStatus(err));
5304                    }
5305                }
5306            }
5307            break;
5308        }
5309
5310        case FREE_BUFFERS:
5311        {
5312            status_t err = mCodec->freeBuffer(kPortIndexOutput, index);
5313            if (err != OK) {
5314                mCodec->signalError(OMX_ErrorUndefined, makeNoSideEffectStatus(err));
5315            }
5316            break;
5317        }
5318
5319        default:
5320            ALOGE("Invalid port mode: %d", mode);
5321            return;
5322    }
5323}
5324
5325////////////////////////////////////////////////////////////////////////////////
5326
5327ACodec::UninitializedState::UninitializedState(ACodec *codec)
5328    : BaseState(codec) {
5329}
5330
5331void ACodec::UninitializedState::stateEntered() {
5332    ALOGV("Now uninitialized");
5333
5334    if (mDeathNotifier != NULL) {
5335        IInterface::asBinder(mCodec->mOMX)->unlinkToDeath(mDeathNotifier);
5336        mDeathNotifier.clear();
5337    }
5338
5339    mCodec->mNativeWindow.clear();
5340    mCodec->mNode = 0;
5341    mCodec->mOMX.clear();
5342    mCodec->mQuirks = 0;
5343    mCodec->mFlags = 0;
5344    mCodec->mInputMetadataType = kMetadataBufferTypeInvalid;
5345    mCodec->mOutputMetadataType = kMetadataBufferTypeInvalid;
5346    mCodec->mComponentName.clear();
5347}
5348
5349bool ACodec::UninitializedState::onMessageReceived(const sp<AMessage> &msg) {
5350    bool handled = false;
5351
5352    switch (msg->what()) {
5353        case ACodec::kWhatSetup:
5354        {
5355            onSetup(msg);
5356
5357            handled = true;
5358            break;
5359        }
5360
5361        case ACodec::kWhatAllocateComponent:
5362        {
5363            onAllocateComponent(msg);
5364            handled = true;
5365            break;
5366        }
5367
5368        case ACodec::kWhatShutdown:
5369        {
5370            int32_t keepComponentAllocated;
5371            CHECK(msg->findInt32(
5372                        "keepComponentAllocated", &keepComponentAllocated));
5373            ALOGW_IF(keepComponentAllocated,
5374                     "cannot keep component allocated on shutdown in Uninitialized state");
5375
5376            sp<AMessage> notify = mCodec->mNotify->dup();
5377            notify->setInt32("what", CodecBase::kWhatShutdownCompleted);
5378            notify->post();
5379
5380            handled = true;
5381            break;
5382        }
5383
5384        case ACodec::kWhatFlush:
5385        {
5386            sp<AMessage> notify = mCodec->mNotify->dup();
5387            notify->setInt32("what", CodecBase::kWhatFlushCompleted);
5388            notify->post();
5389
5390            handled = true;
5391            break;
5392        }
5393
5394        case ACodec::kWhatReleaseCodecInstance:
5395        {
5396            // nothing to do, as we have already signaled shutdown
5397            handled = true;
5398            break;
5399        }
5400
5401        default:
5402            return BaseState::onMessageReceived(msg);
5403    }
5404
5405    return handled;
5406}
5407
5408void ACodec::UninitializedState::onSetup(
5409        const sp<AMessage> &msg) {
5410    if (onAllocateComponent(msg)
5411            && mCodec->mLoadedState->onConfigureComponent(msg)) {
5412        mCodec->mLoadedState->onStart();
5413    }
5414}
5415
5416bool ACodec::UninitializedState::onAllocateComponent(const sp<AMessage> &msg) {
5417    ALOGV("onAllocateComponent");
5418
5419    CHECK(mCodec->mNode == 0);
5420
5421    OMXClient client;
5422    if (client.connect() != OK) {
5423        mCodec->signalError(OMX_ErrorUndefined, NO_INIT);
5424        return false;
5425    }
5426
5427    sp<IOMX> omx = client.interface();
5428
5429    sp<AMessage> notify = new AMessage(kWhatOMXDied, mCodec);
5430
5431    mDeathNotifier = new DeathNotifier(notify);
5432    if (IInterface::asBinder(omx)->linkToDeath(mDeathNotifier) != OK) {
5433        // This was a local binder, if it dies so do we, we won't care
5434        // about any notifications in the afterlife.
5435        mDeathNotifier.clear();
5436    }
5437
5438    Vector<OMXCodec::CodecNameAndQuirks> matchingCodecs;
5439
5440    AString mime;
5441
5442    AString componentName;
5443    uint32_t quirks = 0;
5444    int32_t encoder = false;
5445    if (msg->findString("componentName", &componentName)) {
5446        ssize_t index = matchingCodecs.add();
5447        OMXCodec::CodecNameAndQuirks *entry = &matchingCodecs.editItemAt(index);
5448        entry->mName = String8(componentName.c_str());
5449
5450        if (!OMXCodec::findCodecQuirks(
5451                    componentName.c_str(), &entry->mQuirks)) {
5452            entry->mQuirks = 0;
5453        }
5454    } else {
5455        CHECK(msg->findString("mime", &mime));
5456
5457        if (!msg->findInt32("encoder", &encoder)) {
5458            encoder = false;
5459        }
5460
5461        OMXCodec::findMatchingCodecs(
5462                mime.c_str(),
5463                encoder, // createEncoder
5464                NULL,  // matchComponentName
5465                0,     // flags
5466                &matchingCodecs);
5467    }
5468
5469    sp<CodecObserver> observer = new CodecObserver;
5470    IOMX::node_id node = 0;
5471
5472    status_t err = NAME_NOT_FOUND;
5473    for (size_t matchIndex = 0; matchIndex < matchingCodecs.size();
5474            ++matchIndex) {
5475        componentName = matchingCodecs.itemAt(matchIndex).mName.string();
5476        quirks = matchingCodecs.itemAt(matchIndex).mQuirks;
5477
5478        pid_t tid = gettid();
5479        int prevPriority = androidGetThreadPriority(tid);
5480        androidSetThreadPriority(tid, ANDROID_PRIORITY_FOREGROUND);
5481        err = omx->allocateNode(componentName.c_str(), observer, &node);
5482        androidSetThreadPriority(tid, prevPriority);
5483
5484        if (err == OK) {
5485            break;
5486        } else {
5487            ALOGW("Allocating component '%s' failed, try next one.", componentName.c_str());
5488        }
5489
5490        node = 0;
5491    }
5492
5493    if (node == 0) {
5494        if (!mime.empty()) {
5495            ALOGE("Unable to instantiate a %scoder for type '%s' with err %#x.",
5496                    encoder ? "en" : "de", mime.c_str(), err);
5497        } else {
5498            ALOGE("Unable to instantiate codec '%s' with err %#x.", componentName.c_str(), err);
5499        }
5500
5501        mCodec->signalError((OMX_ERRORTYPE)err, makeNoSideEffectStatus(err));
5502        return false;
5503    }
5504
5505    notify = new AMessage(kWhatOMXMessageList, mCodec);
5506    observer->setNotificationMessage(notify);
5507
5508    mCodec->mComponentName = componentName;
5509    mCodec->mRenderTracker.setComponentName(componentName);
5510    mCodec->mFlags = 0;
5511
5512    if (componentName.endsWith(".secure")) {
5513        mCodec->mFlags |= kFlagIsSecure;
5514        mCodec->mFlags |= kFlagIsGrallocUsageProtected;
5515        mCodec->mFlags |= kFlagPushBlankBuffersToNativeWindowOnShutdown;
5516    }
5517
5518    mCodec->mQuirks = quirks;
5519    mCodec->mOMX = omx;
5520    mCodec->mNode = node;
5521
5522    {
5523        sp<AMessage> notify = mCodec->mNotify->dup();
5524        notify->setInt32("what", CodecBase::kWhatComponentAllocated);
5525        notify->setString("componentName", mCodec->mComponentName.c_str());
5526        notify->post();
5527    }
5528
5529    mCodec->changeState(mCodec->mLoadedState);
5530
5531    return true;
5532}
5533
5534////////////////////////////////////////////////////////////////////////////////
5535
5536ACodec::LoadedState::LoadedState(ACodec *codec)
5537    : BaseState(codec) {
5538}
5539
5540void ACodec::LoadedState::stateEntered() {
5541    ALOGV("[%s] Now Loaded", mCodec->mComponentName.c_str());
5542
5543    mCodec->mPortEOS[kPortIndexInput] =
5544        mCodec->mPortEOS[kPortIndexOutput] = false;
5545
5546    mCodec->mInputEOSResult = OK;
5547
5548    mCodec->mDequeueCounter = 0;
5549    mCodec->mMetadataBuffersToSubmit = 0;
5550    mCodec->mRepeatFrameDelayUs = -1ll;
5551    mCodec->mInputFormat.clear();
5552    mCodec->mOutputFormat.clear();
5553    mCodec->mBaseOutputFormat.clear();
5554
5555    if (mCodec->mShutdownInProgress) {
5556        bool keepComponentAllocated = mCodec->mKeepComponentAllocated;
5557
5558        mCodec->mShutdownInProgress = false;
5559        mCodec->mKeepComponentAllocated = false;
5560
5561        onShutdown(keepComponentAllocated);
5562    }
5563    mCodec->mExplicitShutdown = false;
5564
5565    mCodec->processDeferredMessages();
5566}
5567
5568void ACodec::LoadedState::onShutdown(bool keepComponentAllocated) {
5569    if (!keepComponentAllocated) {
5570        (void)mCodec->mOMX->freeNode(mCodec->mNode);
5571
5572        mCodec->changeState(mCodec->mUninitializedState);
5573    }
5574
5575    if (mCodec->mExplicitShutdown) {
5576        sp<AMessage> notify = mCodec->mNotify->dup();
5577        notify->setInt32("what", CodecBase::kWhatShutdownCompleted);
5578        notify->post();
5579        mCodec->mExplicitShutdown = false;
5580    }
5581}
5582
5583bool ACodec::LoadedState::onMessageReceived(const sp<AMessage> &msg) {
5584    bool handled = false;
5585
5586    switch (msg->what()) {
5587        case ACodec::kWhatConfigureComponent:
5588        {
5589            onConfigureComponent(msg);
5590            handled = true;
5591            break;
5592        }
5593
5594        case ACodec::kWhatCreateInputSurface:
5595        {
5596            onCreateInputSurface(msg);
5597            handled = true;
5598            break;
5599        }
5600
5601        case ACodec::kWhatSetInputSurface:
5602        {
5603            onSetInputSurface(msg);
5604            handled = true;
5605            break;
5606        }
5607
5608        case ACodec::kWhatStart:
5609        {
5610            onStart();
5611            handled = true;
5612            break;
5613        }
5614
5615        case ACodec::kWhatShutdown:
5616        {
5617            int32_t keepComponentAllocated;
5618            CHECK(msg->findInt32(
5619                        "keepComponentAllocated", &keepComponentAllocated));
5620
5621            mCodec->mExplicitShutdown = true;
5622            onShutdown(keepComponentAllocated);
5623
5624            handled = true;
5625            break;
5626        }
5627
5628        case ACodec::kWhatFlush:
5629        {
5630            sp<AMessage> notify = mCodec->mNotify->dup();
5631            notify->setInt32("what", CodecBase::kWhatFlushCompleted);
5632            notify->post();
5633
5634            handled = true;
5635            break;
5636        }
5637
5638        default:
5639            return BaseState::onMessageReceived(msg);
5640    }
5641
5642    return handled;
5643}
5644
5645bool ACodec::LoadedState::onConfigureComponent(
5646        const sp<AMessage> &msg) {
5647    ALOGV("onConfigureComponent");
5648
5649    CHECK(mCodec->mNode != 0);
5650
5651    status_t err = OK;
5652    AString mime;
5653    if (!msg->findString("mime", &mime)) {
5654        err = BAD_VALUE;
5655    } else {
5656        err = mCodec->configureCodec(mime.c_str(), msg);
5657    }
5658    if (err != OK) {
5659        ALOGE("[%s] configureCodec returning error %d",
5660              mCodec->mComponentName.c_str(), err);
5661
5662        mCodec->signalError(OMX_ErrorUndefined, makeNoSideEffectStatus(err));
5663        return false;
5664    }
5665
5666    {
5667        sp<AMessage> notify = mCodec->mNotify->dup();
5668        notify->setInt32("what", CodecBase::kWhatComponentConfigured);
5669        notify->setMessage("input-format", mCodec->mInputFormat);
5670        notify->setMessage("output-format", mCodec->mOutputFormat);
5671        notify->post();
5672    }
5673
5674    return true;
5675}
5676
5677status_t ACodec::LoadedState::setupInputSurface() {
5678    status_t err = OK;
5679
5680    if (mCodec->mRepeatFrameDelayUs > 0ll) {
5681        err = mCodec->mOMX->setInternalOption(
5682                mCodec->mNode,
5683                kPortIndexInput,
5684                IOMX::INTERNAL_OPTION_REPEAT_PREVIOUS_FRAME_DELAY,
5685                &mCodec->mRepeatFrameDelayUs,
5686                sizeof(mCodec->mRepeatFrameDelayUs));
5687
5688        if (err != OK) {
5689            ALOGE("[%s] Unable to configure option to repeat previous "
5690                  "frames (err %d)",
5691                  mCodec->mComponentName.c_str(),
5692                  err);
5693            return err;
5694        }
5695    }
5696
5697    if (mCodec->mMaxPtsGapUs > 0ll) {
5698        err = mCodec->mOMX->setInternalOption(
5699                mCodec->mNode,
5700                kPortIndexInput,
5701                IOMX::INTERNAL_OPTION_MAX_TIMESTAMP_GAP,
5702                &mCodec->mMaxPtsGapUs,
5703                sizeof(mCodec->mMaxPtsGapUs));
5704
5705        if (err != OK) {
5706            ALOGE("[%s] Unable to configure max timestamp gap (err %d)",
5707                    mCodec->mComponentName.c_str(),
5708                    err);
5709            return err;
5710        }
5711    }
5712
5713    if (mCodec->mMaxFps > 0) {
5714        err = mCodec->mOMX->setInternalOption(
5715                mCodec->mNode,
5716                kPortIndexInput,
5717                IOMX::INTERNAL_OPTION_MAX_FPS,
5718                &mCodec->mMaxFps,
5719                sizeof(mCodec->mMaxFps));
5720
5721        if (err != OK) {
5722            ALOGE("[%s] Unable to configure max fps (err %d)",
5723                    mCodec->mComponentName.c_str(),
5724                    err);
5725            return err;
5726        }
5727    }
5728
5729    if (mCodec->mTimePerCaptureUs > 0ll
5730            && mCodec->mTimePerFrameUs > 0ll) {
5731        int64_t timeLapse[2];
5732        timeLapse[0] = mCodec->mTimePerFrameUs;
5733        timeLapse[1] = mCodec->mTimePerCaptureUs;
5734        err = mCodec->mOMX->setInternalOption(
5735                mCodec->mNode,
5736                kPortIndexInput,
5737                IOMX::INTERNAL_OPTION_TIME_LAPSE,
5738                &timeLapse[0],
5739                sizeof(timeLapse));
5740
5741        if (err != OK) {
5742            ALOGE("[%s] Unable to configure time lapse (err %d)",
5743                    mCodec->mComponentName.c_str(),
5744                    err);
5745            return err;
5746        }
5747    }
5748
5749    if (mCodec->mCreateInputBuffersSuspended) {
5750        bool suspend = true;
5751        err = mCodec->mOMX->setInternalOption(
5752                mCodec->mNode,
5753                kPortIndexInput,
5754                IOMX::INTERNAL_OPTION_SUSPEND,
5755                &suspend,
5756                sizeof(suspend));
5757
5758        if (err != OK) {
5759            ALOGE("[%s] Unable to configure option to suspend (err %d)",
5760                  mCodec->mComponentName.c_str(),
5761                  err);
5762            return err;
5763        }
5764    }
5765
5766    uint32_t usageBits;
5767    if (mCodec->mOMX->getParameter(
5768            mCodec->mNode, (OMX_INDEXTYPE)OMX_IndexParamConsumerUsageBits,
5769            &usageBits, sizeof(usageBits)) == OK) {
5770        mCodec->mInputFormat->setInt32(
5771                "using-sw-read-often", !!(usageBits & GRALLOC_USAGE_SW_READ_OFTEN));
5772    }
5773
5774    return OK;
5775}
5776
5777void ACodec::LoadedState::onCreateInputSurface(
5778        const sp<AMessage> & /* msg */) {
5779    ALOGV("onCreateInputSurface");
5780
5781    sp<AMessage> notify = mCodec->mNotify->dup();
5782    notify->setInt32("what", CodecBase::kWhatInputSurfaceCreated);
5783
5784    sp<IGraphicBufferProducer> bufferProducer;
5785    status_t err = mCodec->mOMX->createInputSurface(
5786            mCodec->mNode, kPortIndexInput, &bufferProducer, &mCodec->mInputMetadataType);
5787
5788    if (err == OK) {
5789        err = setupInputSurface();
5790    }
5791
5792    if (err == OK) {
5793        notify->setObject("input-surface",
5794                new BufferProducerWrapper(bufferProducer));
5795    } else {
5796        // Can't use mCodec->signalError() here -- MediaCodec won't forward
5797        // the error through because it's in the "configured" state.  We
5798        // send a kWhatInputSurfaceCreated with an error value instead.
5799        ALOGE("[%s] onCreateInputSurface returning error %d",
5800                mCodec->mComponentName.c_str(), err);
5801        notify->setInt32("err", err);
5802    }
5803    notify->post();
5804}
5805
5806void ACodec::LoadedState::onSetInputSurface(
5807        const sp<AMessage> &msg) {
5808    ALOGV("onSetInputSurface");
5809
5810    sp<AMessage> notify = mCodec->mNotify->dup();
5811    notify->setInt32("what", CodecBase::kWhatInputSurfaceAccepted);
5812
5813    sp<RefBase> obj;
5814    CHECK(msg->findObject("input-surface", &obj));
5815    sp<PersistentSurface> surface = static_cast<PersistentSurface *>(obj.get());
5816
5817    status_t err = mCodec->mOMX->setInputSurface(
5818            mCodec->mNode, kPortIndexInput, surface->getBufferConsumer(),
5819            &mCodec->mInputMetadataType);
5820
5821    if (err == OK) {
5822        err = setupInputSurface();
5823    }
5824
5825    if (err != OK) {
5826        // Can't use mCodec->signalError() here -- MediaCodec won't forward
5827        // the error through because it's in the "configured" state.  We
5828        // send a kWhatInputSurfaceAccepted with an error value instead.
5829        ALOGE("[%s] onSetInputSurface returning error %d",
5830                mCodec->mComponentName.c_str(), err);
5831        notify->setInt32("err", err);
5832    }
5833    notify->post();
5834}
5835
5836void ACodec::LoadedState::onStart() {
5837    ALOGV("onStart");
5838
5839    status_t err = mCodec->mOMX->sendCommand(mCodec->mNode, OMX_CommandStateSet, OMX_StateIdle);
5840    if (err != OK) {
5841        mCodec->signalError(OMX_ErrorUndefined, makeNoSideEffectStatus(err));
5842    } else {
5843        mCodec->changeState(mCodec->mLoadedToIdleState);
5844    }
5845}
5846
5847////////////////////////////////////////////////////////////////////////////////
5848
5849ACodec::LoadedToIdleState::LoadedToIdleState(ACodec *codec)
5850    : BaseState(codec) {
5851}
5852
5853void ACodec::LoadedToIdleState::stateEntered() {
5854    ALOGV("[%s] Now Loaded->Idle", mCodec->mComponentName.c_str());
5855
5856    status_t err;
5857    if ((err = allocateBuffers()) != OK) {
5858        ALOGE("Failed to allocate buffers after transitioning to IDLE state "
5859             "(error 0x%08x)",
5860             err);
5861
5862        mCodec->signalError(OMX_ErrorUndefined, makeNoSideEffectStatus(err));
5863
5864        mCodec->changeState(mCodec->mLoadedState);
5865    }
5866}
5867
5868status_t ACodec::LoadedToIdleState::allocateBuffers() {
5869    status_t err = mCodec->allocateBuffersOnPort(kPortIndexInput);
5870
5871    if (err != OK) {
5872        return err;
5873    }
5874
5875    return mCodec->allocateBuffersOnPort(kPortIndexOutput);
5876}
5877
5878bool ACodec::LoadedToIdleState::onMessageReceived(const sp<AMessage> &msg) {
5879    switch (msg->what()) {
5880        case kWhatSetParameters:
5881        case kWhatShutdown:
5882        {
5883            mCodec->deferMessage(msg);
5884            return true;
5885        }
5886
5887        case kWhatSignalEndOfInputStream:
5888        {
5889            mCodec->onSignalEndOfInputStream();
5890            return true;
5891        }
5892
5893        case kWhatResume:
5894        {
5895            // We'll be active soon enough.
5896            return true;
5897        }
5898
5899        case kWhatFlush:
5900        {
5901            // We haven't even started yet, so we're flushed alright...
5902            sp<AMessage> notify = mCodec->mNotify->dup();
5903            notify->setInt32("what", CodecBase::kWhatFlushCompleted);
5904            notify->post();
5905            return true;
5906        }
5907
5908        default:
5909            return BaseState::onMessageReceived(msg);
5910    }
5911}
5912
5913bool ACodec::LoadedToIdleState::onOMXEvent(
5914        OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2) {
5915    switch (event) {
5916        case OMX_EventCmdComplete:
5917        {
5918            status_t err = OK;
5919            if (data1 != (OMX_U32)OMX_CommandStateSet
5920                    || data2 != (OMX_U32)OMX_StateIdle) {
5921                ALOGE("Unexpected command completion in LoadedToIdleState: %s(%u) %s(%u)",
5922                        asString((OMX_COMMANDTYPE)data1), data1,
5923                        asString((OMX_STATETYPE)data2), data2);
5924                err = FAILED_TRANSACTION;
5925            }
5926
5927            if (err == OK) {
5928                err = mCodec->mOMX->sendCommand(
5929                    mCodec->mNode, OMX_CommandStateSet, OMX_StateExecuting);
5930            }
5931
5932            if (err != OK) {
5933                mCodec->signalError(OMX_ErrorUndefined, makeNoSideEffectStatus(err));
5934            } else {
5935                mCodec->changeState(mCodec->mIdleToExecutingState);
5936            }
5937
5938            return true;
5939        }
5940
5941        default:
5942            return BaseState::onOMXEvent(event, data1, data2);
5943    }
5944}
5945
5946////////////////////////////////////////////////////////////////////////////////
5947
5948ACodec::IdleToExecutingState::IdleToExecutingState(ACodec *codec)
5949    : BaseState(codec) {
5950}
5951
5952void ACodec::IdleToExecutingState::stateEntered() {
5953    ALOGV("[%s] Now Idle->Executing", mCodec->mComponentName.c_str());
5954}
5955
5956bool ACodec::IdleToExecutingState::onMessageReceived(const sp<AMessage> &msg) {
5957    switch (msg->what()) {
5958        case kWhatSetParameters:
5959        case kWhatShutdown:
5960        {
5961            mCodec->deferMessage(msg);
5962            return true;
5963        }
5964
5965        case kWhatResume:
5966        {
5967            // We'll be active soon enough.
5968            return true;
5969        }
5970
5971        case kWhatFlush:
5972        {
5973            // We haven't even started yet, so we're flushed alright...
5974            sp<AMessage> notify = mCodec->mNotify->dup();
5975            notify->setInt32("what", CodecBase::kWhatFlushCompleted);
5976            notify->post();
5977
5978            return true;
5979        }
5980
5981        case kWhatSignalEndOfInputStream:
5982        {
5983            mCodec->onSignalEndOfInputStream();
5984            return true;
5985        }
5986
5987        default:
5988            return BaseState::onMessageReceived(msg);
5989    }
5990}
5991
5992bool ACodec::IdleToExecutingState::onOMXEvent(
5993        OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2) {
5994    switch (event) {
5995        case OMX_EventCmdComplete:
5996        {
5997            if (data1 != (OMX_U32)OMX_CommandStateSet
5998                    || data2 != (OMX_U32)OMX_StateExecuting) {
5999                ALOGE("Unexpected command completion in IdleToExecutingState: %s(%u) %s(%u)",
6000                        asString((OMX_COMMANDTYPE)data1), data1,
6001                        asString((OMX_STATETYPE)data2), data2);
6002                mCodec->signalError(OMX_ErrorUndefined, FAILED_TRANSACTION);
6003                return true;
6004            }
6005
6006            mCodec->mExecutingState->resume();
6007            mCodec->changeState(mCodec->mExecutingState);
6008
6009            return true;
6010        }
6011
6012        default:
6013            return BaseState::onOMXEvent(event, data1, data2);
6014    }
6015}
6016
6017////////////////////////////////////////////////////////////////////////////////
6018
6019ACodec::ExecutingState::ExecutingState(ACodec *codec)
6020    : BaseState(codec),
6021      mActive(false) {
6022}
6023
6024ACodec::BaseState::PortMode ACodec::ExecutingState::getPortMode(
6025        OMX_U32 /* portIndex */) {
6026    return RESUBMIT_BUFFERS;
6027}
6028
6029void ACodec::ExecutingState::submitOutputMetaBuffers() {
6030    // submit as many buffers as there are input buffers with the codec
6031    // in case we are in port reconfiguring
6032    for (size_t i = 0; i < mCodec->mBuffers[kPortIndexInput].size(); ++i) {
6033        BufferInfo *info = &mCodec->mBuffers[kPortIndexInput].editItemAt(i);
6034
6035        if (info->mStatus == BufferInfo::OWNED_BY_COMPONENT) {
6036            if (mCodec->submitOutputMetadataBuffer() != OK)
6037                break;
6038        }
6039    }
6040
6041    // *** NOTE: THE FOLLOWING WORKAROUND WILL BE REMOVED ***
6042    mCodec->signalSubmitOutputMetadataBufferIfEOS_workaround();
6043}
6044
6045void ACodec::ExecutingState::submitRegularOutputBuffers() {
6046    bool failed = false;
6047    for (size_t i = 0; i < mCodec->mBuffers[kPortIndexOutput].size(); ++i) {
6048        BufferInfo *info = &mCodec->mBuffers[kPortIndexOutput].editItemAt(i);
6049
6050        if (mCodec->mNativeWindow != NULL) {
6051            if (info->mStatus != BufferInfo::OWNED_BY_US
6052                    && info->mStatus != BufferInfo::OWNED_BY_NATIVE_WINDOW) {
6053                ALOGE("buffers should be owned by us or the surface");
6054                failed = true;
6055                break;
6056            }
6057
6058            if (info->mStatus == BufferInfo::OWNED_BY_NATIVE_WINDOW) {
6059                continue;
6060            }
6061        } else {
6062            if (info->mStatus != BufferInfo::OWNED_BY_US) {
6063                ALOGE("buffers should be owned by us");
6064                failed = true;
6065                break;
6066            }
6067        }
6068
6069        ALOGV("[%s] calling fillBuffer %u", mCodec->mComponentName.c_str(), info->mBufferID);
6070
6071        info->checkWriteFence("submitRegularOutputBuffers");
6072        status_t err = mCodec->mOMX->fillBuffer(mCodec->mNode, info->mBufferID, info->mFenceFd);
6073        info->mFenceFd = -1;
6074        if (err != OK) {
6075            failed = true;
6076            break;
6077        }
6078
6079        info->mStatus = BufferInfo::OWNED_BY_COMPONENT;
6080    }
6081
6082    if (failed) {
6083        mCodec->signalError(OMX_ErrorUndefined, FAILED_TRANSACTION);
6084    }
6085}
6086
6087void ACodec::ExecutingState::submitOutputBuffers() {
6088    submitRegularOutputBuffers();
6089    if (mCodec->storingMetadataInDecodedBuffers()) {
6090        submitOutputMetaBuffers();
6091    }
6092}
6093
6094void ACodec::ExecutingState::resume() {
6095    if (mActive) {
6096        ALOGV("[%s] We're already active, no need to resume.", mCodec->mComponentName.c_str());
6097        return;
6098    }
6099
6100    submitOutputBuffers();
6101
6102    // Post all available input buffers
6103    if (mCodec->mBuffers[kPortIndexInput].size() == 0u) {
6104        ALOGW("[%s] we don't have any input buffers to resume", mCodec->mComponentName.c_str());
6105    }
6106
6107    for (size_t i = 0; i < mCodec->mBuffers[kPortIndexInput].size(); i++) {
6108        BufferInfo *info = &mCodec->mBuffers[kPortIndexInput].editItemAt(i);
6109        if (info->mStatus == BufferInfo::OWNED_BY_US) {
6110            postFillThisBuffer(info);
6111        }
6112    }
6113
6114    mActive = true;
6115}
6116
6117void ACodec::ExecutingState::stateEntered() {
6118    ALOGV("[%s] Now Executing", mCodec->mComponentName.c_str());
6119
6120    mCodec->mRenderTracker.clear(systemTime(CLOCK_MONOTONIC));
6121    mCodec->processDeferredMessages();
6122}
6123
6124bool ACodec::ExecutingState::onMessageReceived(const sp<AMessage> &msg) {
6125    bool handled = false;
6126
6127    switch (msg->what()) {
6128        case kWhatShutdown:
6129        {
6130            int32_t keepComponentAllocated;
6131            CHECK(msg->findInt32(
6132                        "keepComponentAllocated", &keepComponentAllocated));
6133
6134            mCodec->mShutdownInProgress = true;
6135            mCodec->mExplicitShutdown = true;
6136            mCodec->mKeepComponentAllocated = keepComponentAllocated;
6137
6138            mActive = false;
6139
6140            status_t err = mCodec->mOMX->sendCommand(
6141                    mCodec->mNode, OMX_CommandStateSet, OMX_StateIdle);
6142            if (err != OK) {
6143                if (keepComponentAllocated) {
6144                    mCodec->signalError(OMX_ErrorUndefined, FAILED_TRANSACTION);
6145                }
6146                // TODO: do some recovery here.
6147            } else {
6148                mCodec->changeState(mCodec->mExecutingToIdleState);
6149            }
6150
6151            handled = true;
6152            break;
6153        }
6154
6155        case kWhatFlush:
6156        {
6157            ALOGV("[%s] ExecutingState flushing now "
6158                 "(codec owns %zu/%zu input, %zu/%zu output).",
6159                    mCodec->mComponentName.c_str(),
6160                    mCodec->countBuffersOwnedByComponent(kPortIndexInput),
6161                    mCodec->mBuffers[kPortIndexInput].size(),
6162                    mCodec->countBuffersOwnedByComponent(kPortIndexOutput),
6163                    mCodec->mBuffers[kPortIndexOutput].size());
6164
6165            mActive = false;
6166
6167            status_t err = mCodec->mOMX->sendCommand(mCodec->mNode, OMX_CommandFlush, OMX_ALL);
6168            if (err != OK) {
6169                mCodec->signalError(OMX_ErrorUndefined, FAILED_TRANSACTION);
6170            } else {
6171                mCodec->changeState(mCodec->mFlushingState);
6172            }
6173
6174            handled = true;
6175            break;
6176        }
6177
6178        case kWhatResume:
6179        {
6180            resume();
6181
6182            handled = true;
6183            break;
6184        }
6185
6186        case kWhatRequestIDRFrame:
6187        {
6188            status_t err = mCodec->requestIDRFrame();
6189            if (err != OK) {
6190                ALOGW("Requesting an IDR frame failed.");
6191            }
6192
6193            handled = true;
6194            break;
6195        }
6196
6197        case kWhatSetParameters:
6198        {
6199            sp<AMessage> params;
6200            CHECK(msg->findMessage("params", &params));
6201
6202            status_t err = mCodec->setParameters(params);
6203
6204            sp<AMessage> reply;
6205            if (msg->findMessage("reply", &reply)) {
6206                reply->setInt32("err", err);
6207                reply->post();
6208            }
6209
6210            handled = true;
6211            break;
6212        }
6213
6214        case ACodec::kWhatSignalEndOfInputStream:
6215        {
6216            mCodec->onSignalEndOfInputStream();
6217            handled = true;
6218            break;
6219        }
6220
6221        // *** NOTE: THE FOLLOWING WORKAROUND WILL BE REMOVED ***
6222        case kWhatSubmitOutputMetadataBufferIfEOS:
6223        {
6224            if (mCodec->mPortEOS[kPortIndexInput] &&
6225                    !mCodec->mPortEOS[kPortIndexOutput]) {
6226                status_t err = mCodec->submitOutputMetadataBuffer();
6227                if (err == OK) {
6228                    mCodec->signalSubmitOutputMetadataBufferIfEOS_workaround();
6229                }
6230            }
6231            return true;
6232        }
6233
6234        default:
6235            handled = BaseState::onMessageReceived(msg);
6236            break;
6237    }
6238
6239    return handled;
6240}
6241
6242status_t ACodec::setParameters(const sp<AMessage> &params) {
6243    int32_t videoBitrate;
6244    if (params->findInt32("video-bitrate", &videoBitrate)) {
6245        OMX_VIDEO_CONFIG_BITRATETYPE configParams;
6246        InitOMXParams(&configParams);
6247        configParams.nPortIndex = kPortIndexOutput;
6248        configParams.nEncodeBitrate = videoBitrate;
6249
6250        status_t err = mOMX->setConfig(
6251                mNode,
6252                OMX_IndexConfigVideoBitrate,
6253                &configParams,
6254                sizeof(configParams));
6255
6256        if (err != OK) {
6257            ALOGE("setConfig(OMX_IndexConfigVideoBitrate, %d) failed w/ err %d",
6258                   videoBitrate, err);
6259
6260            return err;
6261        }
6262    }
6263
6264    int64_t skipFramesBeforeUs;
6265    if (params->findInt64("skip-frames-before", &skipFramesBeforeUs)) {
6266        status_t err =
6267            mOMX->setInternalOption(
6268                     mNode,
6269                     kPortIndexInput,
6270                     IOMX::INTERNAL_OPTION_START_TIME,
6271                     &skipFramesBeforeUs,
6272                     sizeof(skipFramesBeforeUs));
6273
6274        if (err != OK) {
6275            ALOGE("Failed to set parameter 'skip-frames-before' (err %d)", err);
6276            return err;
6277        }
6278    }
6279
6280    int32_t dropInputFrames;
6281    if (params->findInt32("drop-input-frames", &dropInputFrames)) {
6282        bool suspend = dropInputFrames != 0;
6283
6284        status_t err =
6285            mOMX->setInternalOption(
6286                     mNode,
6287                     kPortIndexInput,
6288                     IOMX::INTERNAL_OPTION_SUSPEND,
6289                     &suspend,
6290                     sizeof(suspend));
6291
6292        if (err != OK) {
6293            ALOGE("Failed to set parameter 'drop-input-frames' (err %d)", err);
6294            return err;
6295        }
6296    }
6297
6298    int32_t dummy;
6299    if (params->findInt32("request-sync", &dummy)) {
6300        status_t err = requestIDRFrame();
6301
6302        if (err != OK) {
6303            ALOGE("Requesting a sync frame failed w/ err %d", err);
6304            return err;
6305        }
6306    }
6307
6308    float rate;
6309    if (params->findFloat("operating-rate", &rate) && rate > 0) {
6310        status_t err = setOperatingRate(rate, mIsVideo);
6311        if (err != OK) {
6312            ALOGE("Failed to set parameter 'operating-rate' (err %d)", err);
6313            return err;
6314        }
6315    }
6316
6317    return OK;
6318}
6319
6320void ACodec::onSignalEndOfInputStream() {
6321    sp<AMessage> notify = mNotify->dup();
6322    notify->setInt32("what", CodecBase::kWhatSignaledInputEOS);
6323
6324    status_t err = mOMX->signalEndOfInputStream(mNode);
6325    if (err != OK) {
6326        notify->setInt32("err", err);
6327    }
6328    notify->post();
6329}
6330
6331bool ACodec::ExecutingState::onOMXFrameRendered(int64_t mediaTimeUs, nsecs_t systemNano) {
6332    mCodec->onFrameRendered(mediaTimeUs, systemNano);
6333    return true;
6334}
6335
6336bool ACodec::ExecutingState::onOMXEvent(
6337        OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2) {
6338    switch (event) {
6339        case OMX_EventPortSettingsChanged:
6340        {
6341            CHECK_EQ(data1, (OMX_U32)kPortIndexOutput);
6342
6343            if (data2 == 0 || data2 == OMX_IndexParamPortDefinition) {
6344                mCodec->mMetadataBuffersToSubmit = 0;
6345                CHECK_EQ(mCodec->mOMX->sendCommand(
6346                            mCodec->mNode,
6347                            OMX_CommandPortDisable, kPortIndexOutput),
6348                         (status_t)OK);
6349
6350                mCodec->freeOutputBuffersNotOwnedByComponent();
6351
6352                mCodec->changeState(mCodec->mOutputPortSettingsChangedState);
6353            } else if (data2 == OMX_IndexConfigCommonOutputCrop) {
6354                mCodec->mSentFormat = false;
6355            } else {
6356                ALOGV("[%s] OMX_EventPortSettingsChanged 0x%08x",
6357                     mCodec->mComponentName.c_str(), data2);
6358            }
6359
6360            return true;
6361        }
6362
6363        case OMX_EventBufferFlag:
6364        {
6365            return true;
6366        }
6367
6368        default:
6369            return BaseState::onOMXEvent(event, data1, data2);
6370    }
6371}
6372
6373////////////////////////////////////////////////////////////////////////////////
6374
6375ACodec::OutputPortSettingsChangedState::OutputPortSettingsChangedState(
6376        ACodec *codec)
6377    : BaseState(codec) {
6378}
6379
6380ACodec::BaseState::PortMode ACodec::OutputPortSettingsChangedState::getPortMode(
6381        OMX_U32 portIndex) {
6382    if (portIndex == kPortIndexOutput) {
6383        return FREE_BUFFERS;
6384    }
6385
6386    CHECK_EQ(portIndex, (OMX_U32)kPortIndexInput);
6387
6388    return RESUBMIT_BUFFERS;
6389}
6390
6391bool ACodec::OutputPortSettingsChangedState::onMessageReceived(
6392        const sp<AMessage> &msg) {
6393    bool handled = false;
6394
6395    switch (msg->what()) {
6396        case kWhatFlush:
6397        case kWhatShutdown:
6398        case kWhatResume:
6399        case kWhatSetParameters:
6400        {
6401            if (msg->what() == kWhatResume) {
6402                ALOGV("[%s] Deferring resume", mCodec->mComponentName.c_str());
6403            }
6404
6405            mCodec->deferMessage(msg);
6406            handled = true;
6407            break;
6408        }
6409
6410        default:
6411            handled = BaseState::onMessageReceived(msg);
6412            break;
6413    }
6414
6415    return handled;
6416}
6417
6418void ACodec::OutputPortSettingsChangedState::stateEntered() {
6419    ALOGV("[%s] Now handling output port settings change",
6420         mCodec->mComponentName.c_str());
6421}
6422
6423bool ACodec::OutputPortSettingsChangedState::onOMXFrameRendered(
6424        int64_t mediaTimeUs, nsecs_t systemNano) {
6425    mCodec->onFrameRendered(mediaTimeUs, systemNano);
6426    return true;
6427}
6428
6429bool ACodec::OutputPortSettingsChangedState::onOMXEvent(
6430        OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2) {
6431    switch (event) {
6432        case OMX_EventCmdComplete:
6433        {
6434            if (data1 == (OMX_U32)OMX_CommandPortDisable) {
6435                if (data2 != (OMX_U32)kPortIndexOutput) {
6436                    ALOGW("ignoring EventCmdComplete CommandPortDisable for port %u", data2);
6437                    return false;
6438                }
6439
6440                ALOGV("[%s] Output port now disabled.", mCodec->mComponentName.c_str());
6441
6442                status_t err = OK;
6443                if (!mCodec->mBuffers[kPortIndexOutput].isEmpty()) {
6444                    ALOGE("disabled port should be empty, but has %zu buffers",
6445                            mCodec->mBuffers[kPortIndexOutput].size());
6446                    err = FAILED_TRANSACTION;
6447                } else {
6448                    mCodec->mDealer[kPortIndexOutput].clear();
6449                }
6450
6451                if (err == OK) {
6452                    err = mCodec->mOMX->sendCommand(
6453                            mCodec->mNode, OMX_CommandPortEnable, kPortIndexOutput);
6454                }
6455
6456                if (err == OK) {
6457                    err = mCodec->allocateBuffersOnPort(kPortIndexOutput);
6458                    ALOGE_IF(err != OK, "Failed to allocate output port buffers after port "
6459                            "reconfiguration: (%d)", err);
6460                }
6461
6462                if (err != OK) {
6463                    mCodec->signalError(OMX_ErrorUndefined, makeNoSideEffectStatus(err));
6464
6465                    // This is technically not correct, but appears to be
6466                    // the only way to free the component instance.
6467                    // Controlled transitioning from excecuting->idle
6468                    // and idle->loaded seem impossible probably because
6469                    // the output port never finishes re-enabling.
6470                    mCodec->mShutdownInProgress = true;
6471                    mCodec->mKeepComponentAllocated = false;
6472                    mCodec->changeState(mCodec->mLoadedState);
6473                }
6474
6475                return true;
6476            } else if (data1 == (OMX_U32)OMX_CommandPortEnable) {
6477                if (data2 != (OMX_U32)kPortIndexOutput) {
6478                    ALOGW("ignoring EventCmdComplete OMX_CommandPortEnable for port %u", data2);
6479                    return false;
6480                }
6481
6482                mCodec->mSentFormat = false;
6483
6484                ALOGV("[%s] Output port now reenabled.", mCodec->mComponentName.c_str());
6485
6486                if (mCodec->mExecutingState->active()) {
6487                    mCodec->mExecutingState->submitOutputBuffers();
6488                }
6489
6490                mCodec->changeState(mCodec->mExecutingState);
6491
6492                return true;
6493            }
6494
6495            return false;
6496        }
6497
6498        default:
6499            return false;
6500    }
6501}
6502
6503////////////////////////////////////////////////////////////////////////////////
6504
6505ACodec::ExecutingToIdleState::ExecutingToIdleState(ACodec *codec)
6506    : BaseState(codec),
6507      mComponentNowIdle(false) {
6508}
6509
6510bool ACodec::ExecutingToIdleState::onMessageReceived(const sp<AMessage> &msg) {
6511    bool handled = false;
6512
6513    switch (msg->what()) {
6514        case kWhatFlush:
6515        {
6516            // Don't send me a flush request if you previously wanted me
6517            // to shutdown.
6518            ALOGW("Ignoring flush request in ExecutingToIdleState");
6519            break;
6520        }
6521
6522        case kWhatShutdown:
6523        {
6524            // We're already doing that...
6525
6526            handled = true;
6527            break;
6528        }
6529
6530        default:
6531            handled = BaseState::onMessageReceived(msg);
6532            break;
6533    }
6534
6535    return handled;
6536}
6537
6538void ACodec::ExecutingToIdleState::stateEntered() {
6539    ALOGV("[%s] Now Executing->Idle", mCodec->mComponentName.c_str());
6540
6541    mComponentNowIdle = false;
6542    mCodec->mSentFormat = false;
6543}
6544
6545bool ACodec::ExecutingToIdleState::onOMXEvent(
6546        OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2) {
6547    switch (event) {
6548        case OMX_EventCmdComplete:
6549        {
6550            if (data1 != (OMX_U32)OMX_CommandStateSet
6551                    || data2 != (OMX_U32)OMX_StateIdle) {
6552                ALOGE("Unexpected command completion in ExecutingToIdleState: %s(%u) %s(%u)",
6553                        asString((OMX_COMMANDTYPE)data1), data1,
6554                        asString((OMX_STATETYPE)data2), data2);
6555                mCodec->signalError(OMX_ErrorUndefined, FAILED_TRANSACTION);
6556                return true;
6557            }
6558
6559            mComponentNowIdle = true;
6560
6561            changeStateIfWeOwnAllBuffers();
6562
6563            return true;
6564        }
6565
6566        case OMX_EventPortSettingsChanged:
6567        case OMX_EventBufferFlag:
6568        {
6569            // We're shutting down and don't care about this anymore.
6570            return true;
6571        }
6572
6573        default:
6574            return BaseState::onOMXEvent(event, data1, data2);
6575    }
6576}
6577
6578void ACodec::ExecutingToIdleState::changeStateIfWeOwnAllBuffers() {
6579    if (mComponentNowIdle && mCodec->allYourBuffersAreBelongToUs()) {
6580        status_t err = mCodec->mOMX->sendCommand(
6581                mCodec->mNode, OMX_CommandStateSet, OMX_StateLoaded);
6582        if (err == OK) {
6583            err = mCodec->freeBuffersOnPort(kPortIndexInput);
6584            status_t err2 = mCodec->freeBuffersOnPort(kPortIndexOutput);
6585            if (err == OK) {
6586                err = err2;
6587            }
6588        }
6589
6590        if ((mCodec->mFlags & kFlagPushBlankBuffersToNativeWindowOnShutdown)
6591                && mCodec->mNativeWindow != NULL) {
6592            // We push enough 1x1 blank buffers to ensure that one of
6593            // them has made it to the display.  This allows the OMX
6594            // component teardown to zero out any protected buffers
6595            // without the risk of scanning out one of those buffers.
6596            pushBlankBuffersToNativeWindow(mCodec->mNativeWindow.get());
6597        }
6598
6599        if (err != OK) {
6600            mCodec->signalError(OMX_ErrorUndefined, FAILED_TRANSACTION);
6601            return;
6602        }
6603
6604        mCodec->changeState(mCodec->mIdleToLoadedState);
6605    }
6606}
6607
6608void ACodec::ExecutingToIdleState::onInputBufferFilled(
6609        const sp<AMessage> &msg) {
6610    BaseState::onInputBufferFilled(msg);
6611
6612    changeStateIfWeOwnAllBuffers();
6613}
6614
6615void ACodec::ExecutingToIdleState::onOutputBufferDrained(
6616        const sp<AMessage> &msg) {
6617    BaseState::onOutputBufferDrained(msg);
6618
6619    changeStateIfWeOwnAllBuffers();
6620}
6621
6622////////////////////////////////////////////////////////////////////////////////
6623
6624ACodec::IdleToLoadedState::IdleToLoadedState(ACodec *codec)
6625    : BaseState(codec) {
6626}
6627
6628bool ACodec::IdleToLoadedState::onMessageReceived(const sp<AMessage> &msg) {
6629    bool handled = false;
6630
6631    switch (msg->what()) {
6632        case kWhatShutdown:
6633        {
6634            // We're already doing that...
6635
6636            handled = true;
6637            break;
6638        }
6639
6640        case kWhatFlush:
6641        {
6642            // Don't send me a flush request if you previously wanted me
6643            // to shutdown.
6644            ALOGE("Got flush request in IdleToLoadedState");
6645            break;
6646        }
6647
6648        default:
6649            handled = BaseState::onMessageReceived(msg);
6650            break;
6651    }
6652
6653    return handled;
6654}
6655
6656void ACodec::IdleToLoadedState::stateEntered() {
6657    ALOGV("[%s] Now Idle->Loaded", mCodec->mComponentName.c_str());
6658}
6659
6660bool ACodec::IdleToLoadedState::onOMXEvent(
6661        OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2) {
6662    switch (event) {
6663        case OMX_EventCmdComplete:
6664        {
6665            if (data1 != (OMX_U32)OMX_CommandStateSet
6666                    || data2 != (OMX_U32)OMX_StateLoaded) {
6667                ALOGE("Unexpected command completion in IdleToLoadedState: %s(%u) %s(%u)",
6668                        asString((OMX_COMMANDTYPE)data1), data1,
6669                        asString((OMX_STATETYPE)data2), data2);
6670                mCodec->signalError(OMX_ErrorUndefined, FAILED_TRANSACTION);
6671                return true;
6672            }
6673
6674            mCodec->changeState(mCodec->mLoadedState);
6675
6676            return true;
6677        }
6678
6679        default:
6680            return BaseState::onOMXEvent(event, data1, data2);
6681    }
6682}
6683
6684////////////////////////////////////////////////////////////////////////////////
6685
6686ACodec::FlushingState::FlushingState(ACodec *codec)
6687    : BaseState(codec) {
6688}
6689
6690void ACodec::FlushingState::stateEntered() {
6691    ALOGV("[%s] Now Flushing", mCodec->mComponentName.c_str());
6692
6693    mFlushComplete[kPortIndexInput] = mFlushComplete[kPortIndexOutput] = false;
6694}
6695
6696bool ACodec::FlushingState::onMessageReceived(const sp<AMessage> &msg) {
6697    bool handled = false;
6698
6699    switch (msg->what()) {
6700        case kWhatShutdown:
6701        {
6702            mCodec->deferMessage(msg);
6703            break;
6704        }
6705
6706        case kWhatFlush:
6707        {
6708            // We're already doing this right now.
6709            handled = true;
6710            break;
6711        }
6712
6713        default:
6714            handled = BaseState::onMessageReceived(msg);
6715            break;
6716    }
6717
6718    return handled;
6719}
6720
6721bool ACodec::FlushingState::onOMXEvent(
6722        OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2) {
6723    ALOGV("[%s] FlushingState onOMXEvent(%u,%d)",
6724            mCodec->mComponentName.c_str(), event, (OMX_S32)data1);
6725
6726    switch (event) {
6727        case OMX_EventCmdComplete:
6728        {
6729            if (data1 != (OMX_U32)OMX_CommandFlush) {
6730                ALOGE("unexpected EventCmdComplete %s(%d) data2:%d in FlushingState",
6731                        asString((OMX_COMMANDTYPE)data1), data1, data2);
6732                mCodec->signalError(OMX_ErrorUndefined, FAILED_TRANSACTION);
6733                return true;
6734            }
6735
6736            if (data2 == kPortIndexInput || data2 == kPortIndexOutput) {
6737                if (mFlushComplete[data2]) {
6738                    ALOGW("Flush already completed for %s port",
6739                            data2 == kPortIndexInput ? "input" : "output");
6740                    return true;
6741                }
6742                mFlushComplete[data2] = true;
6743
6744                if (mFlushComplete[kPortIndexInput] && mFlushComplete[kPortIndexOutput]) {
6745                    changeStateIfWeOwnAllBuffers();
6746                }
6747            } else if (data2 == OMX_ALL) {
6748                if (!mFlushComplete[kPortIndexInput] || !mFlushComplete[kPortIndexOutput]) {
6749                    ALOGW("received flush complete event for OMX_ALL before ports have been"
6750                            "flushed (%d/%d)",
6751                            mFlushComplete[kPortIndexInput], mFlushComplete[kPortIndexOutput]);
6752                    return false;
6753                }
6754
6755                changeStateIfWeOwnAllBuffers();
6756            } else {
6757                ALOGW("data2 not OMX_ALL but %u in EventCmdComplete CommandFlush", data2);
6758            }
6759
6760            return true;
6761        }
6762
6763        case OMX_EventPortSettingsChanged:
6764        {
6765            sp<AMessage> msg = new AMessage(kWhatOMXMessage, mCodec);
6766            msg->setInt32("type", omx_message::EVENT);
6767            msg->setInt32("node", mCodec->mNode);
6768            msg->setInt32("event", event);
6769            msg->setInt32("data1", data1);
6770            msg->setInt32("data2", data2);
6771
6772            ALOGV("[%s] Deferring OMX_EventPortSettingsChanged",
6773                 mCodec->mComponentName.c_str());
6774
6775            mCodec->deferMessage(msg);
6776
6777            return true;
6778        }
6779
6780        default:
6781            return BaseState::onOMXEvent(event, data1, data2);
6782    }
6783
6784    return true;
6785}
6786
6787void ACodec::FlushingState::onOutputBufferDrained(const sp<AMessage> &msg) {
6788    BaseState::onOutputBufferDrained(msg);
6789
6790    changeStateIfWeOwnAllBuffers();
6791}
6792
6793void ACodec::FlushingState::onInputBufferFilled(const sp<AMessage> &msg) {
6794    BaseState::onInputBufferFilled(msg);
6795
6796    changeStateIfWeOwnAllBuffers();
6797}
6798
6799void ACodec::FlushingState::changeStateIfWeOwnAllBuffers() {
6800    if (mFlushComplete[kPortIndexInput]
6801            && mFlushComplete[kPortIndexOutput]
6802            && mCodec->allYourBuffersAreBelongToUs()) {
6803        // We now own all buffers except possibly those still queued with
6804        // the native window for rendering. Let's get those back as well.
6805        mCodec->waitUntilAllPossibleNativeWindowBuffersAreReturnedToUs();
6806
6807        mCodec->mRenderTracker.clear(systemTime(CLOCK_MONOTONIC));
6808
6809        sp<AMessage> notify = mCodec->mNotify->dup();
6810        notify->setInt32("what", CodecBase::kWhatFlushCompleted);
6811        notify->post();
6812
6813        mCodec->mPortEOS[kPortIndexInput] =
6814            mCodec->mPortEOS[kPortIndexOutput] = false;
6815
6816        mCodec->mInputEOSResult = OK;
6817
6818        if (mCodec->mSkipCutBuffer != NULL) {
6819            mCodec->mSkipCutBuffer->clear();
6820        }
6821
6822        mCodec->changeState(mCodec->mExecutingState);
6823    }
6824}
6825
6826}  // namespace android
6827