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