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