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