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