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