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