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