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