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