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