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