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