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