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