ACodec.cpp revision e40cda70eec141fa05cbcca1de420fdb22b98be6
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#include <media/stagefright/ACodec.h>
21
22#include <binder/MemoryDealer.h>
23
24#include <media/stagefright/foundation/hexdump.h>
25#include <media/stagefright/foundation/ABuffer.h>
26#include <media/stagefright/foundation/ADebug.h>
27#include <media/stagefright/foundation/AMessage.h>
28
29#include <media/stagefright/BufferProducerWrapper.h>
30#include <media/stagefright/MediaCodecList.h>
31#include <media/stagefright/MediaDefs.h>
32#include <media/stagefright/NativeWindowWrapper.h>
33#include <media/stagefright/OMXClient.h>
34#include <media/stagefright/OMXCodec.h>
35
36#include <media/hardware/HardwareAPI.h>
37
38#include <OMX_Component.h>
39
40#include "include/avc_utils.h"
41
42namespace android {
43
44template<class T>
45static void InitOMXParams(T *params) {
46    params->nSize = sizeof(T);
47    params->nVersion.s.nVersionMajor = 1;
48    params->nVersion.s.nVersionMinor = 0;
49    params->nVersion.s.nRevision = 0;
50    params->nVersion.s.nStep = 0;
51}
52
53struct CodecObserver : public BnOMXObserver {
54    CodecObserver() {}
55
56    void setNotificationMessage(const sp<AMessage> &msg) {
57        mNotify = msg;
58    }
59
60    // from IOMXObserver
61    virtual void onMessage(const omx_message &omx_msg) {
62        sp<AMessage> msg = mNotify->dup();
63
64        msg->setInt32("type", omx_msg.type);
65        msg->setPointer("node", omx_msg.node);
66
67        switch (omx_msg.type) {
68            case omx_message::EVENT:
69            {
70                msg->setInt32("event", omx_msg.u.event_data.event);
71                msg->setInt32("data1", omx_msg.u.event_data.data1);
72                msg->setInt32("data2", omx_msg.u.event_data.data2);
73                break;
74            }
75
76            case omx_message::EMPTY_BUFFER_DONE:
77            {
78                msg->setPointer("buffer", omx_msg.u.buffer_data.buffer);
79                break;
80            }
81
82            case omx_message::FILL_BUFFER_DONE:
83            {
84                msg->setPointer(
85                        "buffer", omx_msg.u.extended_buffer_data.buffer);
86                msg->setInt32(
87                        "range_offset",
88                        omx_msg.u.extended_buffer_data.range_offset);
89                msg->setInt32(
90                        "range_length",
91                        omx_msg.u.extended_buffer_data.range_length);
92                msg->setInt32(
93                        "flags",
94                        omx_msg.u.extended_buffer_data.flags);
95                msg->setInt64(
96                        "timestamp",
97                        omx_msg.u.extended_buffer_data.timestamp);
98                msg->setPointer(
99                        "platform_private",
100                        omx_msg.u.extended_buffer_data.platform_private);
101                msg->setPointer(
102                        "data_ptr",
103                        omx_msg.u.extended_buffer_data.data_ptr);
104                break;
105            }
106
107            default:
108                TRESPASS();
109                break;
110        }
111
112        msg->post();
113    }
114
115protected:
116    virtual ~CodecObserver() {}
117
118private:
119    sp<AMessage> mNotify;
120
121    DISALLOW_EVIL_CONSTRUCTORS(CodecObserver);
122};
123
124////////////////////////////////////////////////////////////////////////////////
125
126struct ACodec::BaseState : public AState {
127    BaseState(ACodec *codec, const sp<AState> &parentState = NULL);
128
129protected:
130    enum PortMode {
131        KEEP_BUFFERS,
132        RESUBMIT_BUFFERS,
133        FREE_BUFFERS,
134    };
135
136    ACodec *mCodec;
137
138    virtual PortMode getPortMode(OMX_U32 portIndex);
139
140    virtual bool onMessageReceived(const sp<AMessage> &msg);
141
142    virtual bool onOMXEvent(OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2);
143
144    virtual void onOutputBufferDrained(const sp<AMessage> &msg);
145    virtual void onInputBufferFilled(const sp<AMessage> &msg);
146
147    void postFillThisBuffer(BufferInfo *info);
148
149private:
150    bool onOMXMessage(const sp<AMessage> &msg);
151
152    bool onOMXEmptyBufferDone(IOMX::buffer_id bufferID);
153
154    bool onOMXFillBufferDone(
155            IOMX::buffer_id bufferID,
156            size_t rangeOffset, size_t rangeLength,
157            OMX_U32 flags,
158            int64_t timeUs,
159            void *platformPrivate,
160            void *dataPtr);
161
162    void getMoreInputDataIfPossible();
163
164    DISALLOW_EVIL_CONSTRUCTORS(BaseState);
165};
166
167////////////////////////////////////////////////////////////////////////////////
168
169struct ACodec::DeathNotifier : public IBinder::DeathRecipient {
170    DeathNotifier(const sp<AMessage> &notify)
171        : mNotify(notify) {
172    }
173
174    virtual void binderDied(const wp<IBinder> &) {
175        mNotify->post();
176    }
177
178protected:
179    virtual ~DeathNotifier() {}
180
181private:
182    sp<AMessage> mNotify;
183
184    DISALLOW_EVIL_CONSTRUCTORS(DeathNotifier);
185};
186
187struct ACodec::UninitializedState : public ACodec::BaseState {
188    UninitializedState(ACodec *codec);
189
190protected:
191    virtual bool onMessageReceived(const sp<AMessage> &msg);
192    virtual void stateEntered();
193
194private:
195    void onSetup(const sp<AMessage> &msg);
196    bool onAllocateComponent(const sp<AMessage> &msg);
197
198    sp<DeathNotifier> mDeathNotifier;
199
200    DISALLOW_EVIL_CONSTRUCTORS(UninitializedState);
201};
202
203////////////////////////////////////////////////////////////////////////////////
204
205struct ACodec::LoadedState : public ACodec::BaseState {
206    LoadedState(ACodec *codec);
207
208protected:
209    virtual bool onMessageReceived(const sp<AMessage> &msg);
210    virtual void stateEntered();
211
212private:
213    friend struct ACodec::UninitializedState;
214
215    bool onConfigureComponent(const sp<AMessage> &msg);
216    void onCreateInputSurface(const sp<AMessage> &msg);
217    void onStart();
218    void onShutdown(bool keepComponentAllocated);
219
220    DISALLOW_EVIL_CONSTRUCTORS(LoadedState);
221};
222
223////////////////////////////////////////////////////////////////////////////////
224
225struct ACodec::LoadedToIdleState : public ACodec::BaseState {
226    LoadedToIdleState(ACodec *codec);
227
228protected:
229    virtual bool onMessageReceived(const sp<AMessage> &msg);
230    virtual bool onOMXEvent(OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2);
231    virtual void stateEntered();
232
233private:
234    status_t allocateBuffers();
235
236    DISALLOW_EVIL_CONSTRUCTORS(LoadedToIdleState);
237};
238
239////////////////////////////////////////////////////////////////////////////////
240
241struct ACodec::IdleToExecutingState : public ACodec::BaseState {
242    IdleToExecutingState(ACodec *codec);
243
244protected:
245    virtual bool onMessageReceived(const sp<AMessage> &msg);
246    virtual bool onOMXEvent(OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2);
247    virtual void stateEntered();
248
249private:
250    DISALLOW_EVIL_CONSTRUCTORS(IdleToExecutingState);
251};
252
253////////////////////////////////////////////////////////////////////////////////
254
255struct ACodec::ExecutingState : public ACodec::BaseState {
256    ExecutingState(ACodec *codec);
257
258    void submitRegularOutputBuffers();
259    void submitOutputMetaBuffers();
260    void submitOutputBuffers();
261
262    // Submit output buffers to the decoder, submit input buffers to client
263    // to fill with data.
264    void resume();
265
266    // Returns true iff input and output buffers are in play.
267    bool active() const { return mActive; }
268
269protected:
270    virtual PortMode getPortMode(OMX_U32 portIndex);
271    virtual bool onMessageReceived(const sp<AMessage> &msg);
272    virtual void stateEntered();
273
274    virtual bool onOMXEvent(OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2);
275
276private:
277    bool mActive;
278
279    DISALLOW_EVIL_CONSTRUCTORS(ExecutingState);
280};
281
282////////////////////////////////////////////////////////////////////////////////
283
284struct ACodec::OutputPortSettingsChangedState : public ACodec::BaseState {
285    OutputPortSettingsChangedState(ACodec *codec);
286
287protected:
288    virtual PortMode getPortMode(OMX_U32 portIndex);
289    virtual bool onMessageReceived(const sp<AMessage> &msg);
290    virtual void stateEntered();
291
292    virtual bool onOMXEvent(OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2);
293
294private:
295    DISALLOW_EVIL_CONSTRUCTORS(OutputPortSettingsChangedState);
296};
297
298////////////////////////////////////////////////////////////////////////////////
299
300struct ACodec::ExecutingToIdleState : public ACodec::BaseState {
301    ExecutingToIdleState(ACodec *codec);
302
303protected:
304    virtual bool onMessageReceived(const sp<AMessage> &msg);
305    virtual void stateEntered();
306
307    virtual bool onOMXEvent(OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2);
308
309    virtual void onOutputBufferDrained(const sp<AMessage> &msg);
310    virtual void onInputBufferFilled(const sp<AMessage> &msg);
311
312private:
313    void changeStateIfWeOwnAllBuffers();
314
315    bool mComponentNowIdle;
316
317    DISALLOW_EVIL_CONSTRUCTORS(ExecutingToIdleState);
318};
319
320////////////////////////////////////////////////////////////////////////////////
321
322struct ACodec::IdleToLoadedState : public ACodec::BaseState {
323    IdleToLoadedState(ACodec *codec);
324
325protected:
326    virtual bool onMessageReceived(const sp<AMessage> &msg);
327    virtual void stateEntered();
328
329    virtual bool onOMXEvent(OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2);
330
331private:
332    DISALLOW_EVIL_CONSTRUCTORS(IdleToLoadedState);
333};
334
335////////////////////////////////////////////////////////////////////////////////
336
337struct ACodec::FlushingState : public ACodec::BaseState {
338    FlushingState(ACodec *codec);
339
340protected:
341    virtual bool onMessageReceived(const sp<AMessage> &msg);
342    virtual void stateEntered();
343
344    virtual bool onOMXEvent(OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2);
345
346    virtual void onOutputBufferDrained(const sp<AMessage> &msg);
347    virtual void onInputBufferFilled(const sp<AMessage> &msg);
348
349private:
350    bool mFlushComplete[2];
351
352    void changeStateIfWeOwnAllBuffers();
353
354    DISALLOW_EVIL_CONSTRUCTORS(FlushingState);
355};
356
357////////////////////////////////////////////////////////////////////////////////
358
359ACodec::ACodec()
360    : mQuirks(0),
361      mNode(NULL),
362      mSentFormat(false),
363      mIsEncoder(false),
364      mUseMetadataOnEncoderOutput(false),
365      mShutdownInProgress(false),
366      mEncoderDelay(0),
367      mEncoderPadding(0),
368      mChannelMaskPresent(false),
369      mChannelMask(0),
370      mDequeueCounter(0),
371      mStoreMetaDataInOutputBuffers(false),
372      mMetaDataBuffersToSubmit(0) {
373    mUninitializedState = new UninitializedState(this);
374    mLoadedState = new LoadedState(this);
375    mLoadedToIdleState = new LoadedToIdleState(this);
376    mIdleToExecutingState = new IdleToExecutingState(this);
377    mExecutingState = new ExecutingState(this);
378
379    mOutputPortSettingsChangedState =
380        new OutputPortSettingsChangedState(this);
381
382    mExecutingToIdleState = new ExecutingToIdleState(this);
383    mIdleToLoadedState = new IdleToLoadedState(this);
384    mFlushingState = new FlushingState(this);
385
386    mPortEOS[kPortIndexInput] = mPortEOS[kPortIndexOutput] = false;
387    mInputEOSResult = OK;
388
389    changeState(mUninitializedState);
390}
391
392ACodec::~ACodec() {
393}
394
395void ACodec::setNotificationMessage(const sp<AMessage> &msg) {
396    mNotify = msg;
397}
398
399void ACodec::initiateSetup(const sp<AMessage> &msg) {
400    msg->setWhat(kWhatSetup);
401    msg->setTarget(id());
402    msg->post();
403}
404
405void ACodec::signalSetParameters(const sp<AMessage> &params) {
406    sp<AMessage> msg = new AMessage(kWhatSetParameters, id());
407    msg->setMessage("params", params);
408    msg->post();
409}
410
411void ACodec::initiateAllocateComponent(const sp<AMessage> &msg) {
412    msg->setWhat(kWhatAllocateComponent);
413    msg->setTarget(id());
414    msg->post();
415}
416
417void ACodec::initiateConfigureComponent(const sp<AMessage> &msg) {
418    msg->setWhat(kWhatConfigureComponent);
419    msg->setTarget(id());
420    msg->post();
421}
422
423void ACodec::initiateCreateInputSurface() {
424    (new AMessage(kWhatCreateInputSurface, id()))->post();
425}
426
427void ACodec::signalEndOfInputStream() {
428    (new AMessage(kWhatSignalEndOfInputStream, id()))->post();
429}
430
431void ACodec::initiateStart() {
432    (new AMessage(kWhatStart, id()))->post();
433}
434
435void ACodec::signalFlush() {
436    ALOGV("[%s] signalFlush", mComponentName.c_str());
437    (new AMessage(kWhatFlush, id()))->post();
438}
439
440void ACodec::signalResume() {
441    (new AMessage(kWhatResume, id()))->post();
442}
443
444void ACodec::initiateShutdown(bool keepComponentAllocated) {
445    sp<AMessage> msg = new AMessage(kWhatShutdown, id());
446    msg->setInt32("keepComponentAllocated", keepComponentAllocated);
447    msg->post();
448}
449
450void ACodec::signalRequestIDRFrame() {
451    (new AMessage(kWhatRequestIDRFrame, id()))->post();
452}
453
454status_t ACodec::allocateBuffersOnPort(OMX_U32 portIndex) {
455    CHECK(portIndex == kPortIndexInput || portIndex == kPortIndexOutput);
456
457    CHECK(mDealer[portIndex] == NULL);
458    CHECK(mBuffers[portIndex].isEmpty());
459
460    status_t err;
461    if (mNativeWindow != NULL && portIndex == kPortIndexOutput) {
462        if (mStoreMetaDataInOutputBuffers) {
463            err = allocateOutputMetaDataBuffers();
464        } else {
465            err = allocateOutputBuffersFromNativeWindow();
466        }
467    } else {
468        OMX_PARAM_PORTDEFINITIONTYPE def;
469        InitOMXParams(&def);
470        def.nPortIndex = portIndex;
471
472        err = mOMX->getParameter(
473                mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
474
475        if (err == OK) {
476            ALOGV("[%s] Allocating %lu buffers of size %lu on %s port",
477                    mComponentName.c_str(),
478                    def.nBufferCountActual, def.nBufferSize,
479                    portIndex == kPortIndexInput ? "input" : "output");
480
481            size_t totalSize = def.nBufferCountActual * def.nBufferSize;
482            mDealer[portIndex] = new MemoryDealer(totalSize, "ACodec");
483
484            for (OMX_U32 i = 0; i < def.nBufferCountActual; ++i) {
485                sp<IMemory> mem = mDealer[portIndex]->allocate(def.nBufferSize);
486                CHECK(mem.get() != NULL);
487
488                BufferInfo info;
489                info.mStatus = BufferInfo::OWNED_BY_US;
490
491                uint32_t requiresAllocateBufferBit =
492                    (portIndex == kPortIndexInput)
493                        ? OMXCodec::kRequiresAllocateBufferOnInputPorts
494                        : OMXCodec::kRequiresAllocateBufferOnOutputPorts;
495
496                if ((portIndex == kPortIndexInput && (mFlags & kFlagIsSecure))
497                        || mUseMetadataOnEncoderOutput) {
498                    mem.clear();
499
500                    void *ptr;
501                    err = mOMX->allocateBuffer(
502                            mNode, portIndex, def.nBufferSize, &info.mBufferID,
503                            &ptr);
504
505                    int32_t bufSize = mUseMetadataOnEncoderOutput ?
506                            (4 + sizeof(buffer_handle_t)) : def.nBufferSize;
507
508                    info.mData = new ABuffer(ptr, bufSize);
509                } else if (mQuirks & requiresAllocateBufferBit) {
510                    err = mOMX->allocateBufferWithBackup(
511                            mNode, portIndex, mem, &info.mBufferID);
512                } else {
513                    err = mOMX->useBuffer(mNode, portIndex, mem, &info.mBufferID);
514                }
515
516                if (mem != NULL) {
517                    info.mData = new ABuffer(mem->pointer(), def.nBufferSize);
518                }
519
520                mBuffers[portIndex].push(info);
521            }
522        }
523    }
524
525    if (err != OK) {
526        return err;
527    }
528
529    sp<AMessage> notify = mNotify->dup();
530    notify->setInt32("what", ACodec::kWhatBuffersAllocated);
531
532    notify->setInt32("portIndex", portIndex);
533
534    sp<PortDescription> desc = new PortDescription;
535
536    for (size_t i = 0; i < mBuffers[portIndex].size(); ++i) {
537        const BufferInfo &info = mBuffers[portIndex][i];
538
539        desc->addBuffer(info.mBufferID, info.mData);
540    }
541
542    notify->setObject("portDesc", desc);
543    notify->post();
544
545    return OK;
546}
547
548status_t ACodec::configureOutputBuffersFromNativeWindow(
549        OMX_U32 *bufferCount, OMX_U32 *bufferSize,
550        OMX_U32 *minUndequeuedBuffers) {
551    OMX_PARAM_PORTDEFINITIONTYPE def;
552    InitOMXParams(&def);
553    def.nPortIndex = kPortIndexOutput;
554
555    status_t err = mOMX->getParameter(
556            mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
557
558    if (err != OK) {
559        return err;
560    }
561
562    err = native_window_set_buffers_geometry(
563            mNativeWindow.get(),
564            def.format.video.nFrameWidth,
565            def.format.video.nFrameHeight,
566            def.format.video.eColorFormat);
567
568    if (err != 0) {
569        ALOGE("native_window_set_buffers_geometry failed: %s (%d)",
570                strerror(-err), -err);
571        return err;
572    }
573
574    // Set up the native window.
575    OMX_U32 usage = 0;
576    err = mOMX->getGraphicBufferUsage(mNode, kPortIndexOutput, &usage);
577    if (err != 0) {
578        ALOGW("querying usage flags from OMX IL component failed: %d", err);
579        // XXX: Currently this error is logged, but not fatal.
580        usage = 0;
581    }
582
583    if (mFlags & kFlagIsSecure) {
584        usage |= GRALLOC_USAGE_PROTECTED;
585    }
586
587    // Make sure to check whether either Stagefright or the video decoder
588    // requested protected buffers.
589    if (usage & GRALLOC_USAGE_PROTECTED) {
590        // Verify that the ANativeWindow sends images directly to
591        // SurfaceFlinger.
592        int queuesToNativeWindow = 0;
593        err = mNativeWindow->query(
594                mNativeWindow.get(), NATIVE_WINDOW_QUEUES_TO_WINDOW_COMPOSER,
595                &queuesToNativeWindow);
596        if (err != 0) {
597            ALOGE("error authenticating native window: %d", err);
598            return err;
599        }
600        if (queuesToNativeWindow != 1) {
601            ALOGE("native window could not be authenticated");
602            return PERMISSION_DENIED;
603        }
604    }
605
606    err = native_window_set_usage(
607            mNativeWindow.get(),
608            usage | GRALLOC_USAGE_HW_TEXTURE | GRALLOC_USAGE_EXTERNAL_DISP);
609
610    if (err != 0) {
611        ALOGE("native_window_set_usage failed: %s (%d)", strerror(-err), -err);
612        return err;
613    }
614
615    *minUndequeuedBuffers = 0;
616    err = mNativeWindow->query(
617            mNativeWindow.get(), NATIVE_WINDOW_MIN_UNDEQUEUED_BUFFERS,
618            (int *)minUndequeuedBuffers);
619
620    if (err != 0) {
621        ALOGE("NATIVE_WINDOW_MIN_UNDEQUEUED_BUFFERS query failed: %s (%d)",
622                strerror(-err), -err);
623        return err;
624    }
625
626    // XXX: Is this the right logic to use?  It's not clear to me what the OMX
627    // buffer counts refer to - how do they account for the renderer holding on
628    // to buffers?
629    if (def.nBufferCountActual < def.nBufferCountMin + *minUndequeuedBuffers) {
630        OMX_U32 newBufferCount = def.nBufferCountMin + *minUndequeuedBuffers;
631        def.nBufferCountActual = newBufferCount;
632        err = mOMX->setParameter(
633                mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
634
635        if (err != OK) {
636            ALOGE("[%s] setting nBufferCountActual to %lu failed: %d",
637                    mComponentName.c_str(), newBufferCount, err);
638            return err;
639        }
640    }
641
642    err = native_window_set_buffer_count(
643            mNativeWindow.get(), def.nBufferCountActual);
644
645    if (err != 0) {
646        ALOGE("native_window_set_buffer_count failed: %s (%d)", strerror(-err),
647                -err);
648        return err;
649    }
650
651    *bufferCount = def.nBufferCountActual;
652    *bufferSize =  def.nBufferSize;
653    return err;
654}
655
656status_t ACodec::allocateOutputBuffersFromNativeWindow() {
657    OMX_U32 bufferCount, bufferSize, minUndequeuedBuffers;
658    status_t err = configureOutputBuffersFromNativeWindow(
659            &bufferCount, &bufferSize, &minUndequeuedBuffers);
660    if (err != 0)
661        return err;
662
663    ALOGV("[%s] Allocating %lu buffers from a native window of size %lu on "
664         "output port",
665         mComponentName.c_str(), bufferCount, bufferSize);
666
667    // Dequeue buffers and send them to OMX
668    for (OMX_U32 i = 0; i < bufferCount; i++) {
669        ANativeWindowBuffer *buf;
670        err = native_window_dequeue_buffer_and_wait(mNativeWindow.get(), &buf);
671        if (err != 0) {
672            ALOGE("dequeueBuffer failed: %s (%d)", strerror(-err), -err);
673            break;
674        }
675
676        sp<GraphicBuffer> graphicBuffer(new GraphicBuffer(buf, false));
677        BufferInfo info;
678        info.mStatus = BufferInfo::OWNED_BY_US;
679        info.mData = new ABuffer(NULL /* data */, bufferSize /* capacity */);
680        info.mGraphicBuffer = graphicBuffer;
681        mBuffers[kPortIndexOutput].push(info);
682
683        IOMX::buffer_id bufferId;
684        err = mOMX->useGraphicBuffer(mNode, kPortIndexOutput, graphicBuffer,
685                &bufferId);
686        if (err != 0) {
687            ALOGE("registering GraphicBuffer %lu with OMX IL component failed: "
688                 "%d", i, err);
689            break;
690        }
691
692        mBuffers[kPortIndexOutput].editItemAt(i).mBufferID = bufferId;
693
694        ALOGV("[%s] Registered graphic buffer with ID %p (pointer = %p)",
695             mComponentName.c_str(),
696             bufferId, graphicBuffer.get());
697    }
698
699    OMX_U32 cancelStart;
700    OMX_U32 cancelEnd;
701
702    if (err != 0) {
703        // If an error occurred while dequeuing we need to cancel any buffers
704        // that were dequeued.
705        cancelStart = 0;
706        cancelEnd = mBuffers[kPortIndexOutput].size();
707    } else {
708        // Return the required minimum undequeued buffers to the native window.
709        cancelStart = bufferCount - minUndequeuedBuffers;
710        cancelEnd = bufferCount;
711    }
712
713    for (OMX_U32 i = cancelStart; i < cancelEnd; i++) {
714        BufferInfo *info = &mBuffers[kPortIndexOutput].editItemAt(i);
715        cancelBufferToNativeWindow(info);
716    }
717
718    return err;
719}
720
721status_t ACodec::allocateOutputMetaDataBuffers() {
722    OMX_U32 bufferCount, bufferSize, minUndequeuedBuffers;
723    status_t err = configureOutputBuffersFromNativeWindow(
724            &bufferCount, &bufferSize, &minUndequeuedBuffers);
725    if (err != 0)
726        return err;
727
728    ALOGV("[%s] Allocating %lu meta buffers on output port",
729         mComponentName.c_str(), bufferCount);
730
731    size_t totalSize = bufferCount * 8;
732    mDealer[kPortIndexOutput] = new MemoryDealer(totalSize, "ACodec");
733
734    // Dequeue buffers and send them to OMX
735    for (OMX_U32 i = 0; i < bufferCount; i++) {
736        BufferInfo info;
737        info.mStatus = BufferInfo::OWNED_BY_NATIVE_WINDOW;
738        info.mGraphicBuffer = NULL;
739        info.mDequeuedAt = mDequeueCounter;
740
741        sp<IMemory> mem = mDealer[kPortIndexOutput]->allocate(
742                sizeof(struct VideoDecoderOutputMetaData));
743        CHECK(mem.get() != NULL);
744        info.mData = new ABuffer(mem->pointer(), mem->size());
745
746        // we use useBuffer for metadata regardless of quirks
747        err = mOMX->useBuffer(
748                mNode, kPortIndexOutput, mem, &info.mBufferID);
749
750        mBuffers[kPortIndexOutput].push(info);
751
752        ALOGV("[%s] allocated meta buffer with ID %p (pointer = %p)",
753             mComponentName.c_str(), info.mBufferID, mem->pointer());
754    }
755
756    mMetaDataBuffersToSubmit = bufferCount - minUndequeuedBuffers;
757    return err;
758}
759
760status_t ACodec::submitOutputMetaDataBuffer() {
761    CHECK(mStoreMetaDataInOutputBuffers);
762    if (mMetaDataBuffersToSubmit == 0)
763        return OK;
764
765    BufferInfo *info = dequeueBufferFromNativeWindow();
766    if (info == NULL)
767        return ERROR_IO;
768
769    ALOGV("[%s] submitting output meta buffer ID %p for graphic buffer %p",
770          mComponentName.c_str(), info->mBufferID, info->mGraphicBuffer.get());
771
772    --mMetaDataBuffersToSubmit;
773    CHECK_EQ(mOMX->fillBuffer(mNode, info->mBufferID),
774             (status_t)OK);
775
776    info->mStatus = BufferInfo::OWNED_BY_COMPONENT;
777    return OK;
778}
779
780status_t ACodec::cancelBufferToNativeWindow(BufferInfo *info) {
781    CHECK_EQ((int)info->mStatus, (int)BufferInfo::OWNED_BY_US);
782
783    ALOGV("[%s] Calling cancelBuffer on buffer %p",
784         mComponentName.c_str(), info->mBufferID);
785
786    int err = mNativeWindow->cancelBuffer(
787        mNativeWindow.get(), info->mGraphicBuffer.get(), -1);
788
789    CHECK_EQ(err, 0);
790
791    info->mStatus = BufferInfo::OWNED_BY_NATIVE_WINDOW;
792
793    return OK;
794}
795
796ACodec::BufferInfo *ACodec::dequeueBufferFromNativeWindow() {
797    ANativeWindowBuffer *buf;
798    int fenceFd = -1;
799    CHECK(mNativeWindow.get() != NULL);
800    if (native_window_dequeue_buffer_and_wait(mNativeWindow.get(), &buf) != 0) {
801        ALOGE("dequeueBuffer failed.");
802        return NULL;
803    }
804
805    BufferInfo *oldest = NULL;
806    for (size_t i = mBuffers[kPortIndexOutput].size(); i-- > 0;) {
807        BufferInfo *info =
808            &mBuffers[kPortIndexOutput].editItemAt(i);
809
810        if (info->mGraphicBuffer != NULL &&
811            info->mGraphicBuffer->handle == buf->handle) {
812            CHECK_EQ((int)info->mStatus,
813                     (int)BufferInfo::OWNED_BY_NATIVE_WINDOW);
814
815            info->mStatus = BufferInfo::OWNED_BY_US;
816
817            return info;
818        }
819
820        if (info->mStatus == BufferInfo::OWNED_BY_NATIVE_WINDOW &&
821            (oldest == NULL ||
822             // avoid potential issues from counter rolling over
823             mDequeueCounter - info->mDequeuedAt >
824                    mDequeueCounter - oldest->mDequeuedAt)) {
825            oldest = info;
826        }
827    }
828
829    if (oldest) {
830        CHECK(mStoreMetaDataInOutputBuffers);
831
832        // discard buffer in LRU info and replace with new buffer
833        oldest->mGraphicBuffer = new GraphicBuffer(buf, false);
834        oldest->mStatus = BufferInfo::OWNED_BY_US;
835
836        struct VideoDecoderOutputMetaData metaData;
837        metaData.eType = kMetadataBufferTypeGrallocSource;
838        metaData.pHandle = oldest->mGraphicBuffer->handle;
839        memcpy(oldest->mData->base(), &metaData, sizeof(metaData));
840
841        ALOGV("replaced oldest buffer #%u with age %u (%p stored in %p)",
842                oldest - &mBuffers[kPortIndexOutput][0],
843                mDequeueCounter - oldest->mDequeuedAt,
844                metaData.pHandle, oldest->mData->base());
845
846        return oldest;
847    }
848
849    TRESPASS();
850
851    return NULL;
852}
853
854status_t ACodec::freeBuffersOnPort(OMX_U32 portIndex) {
855    for (size_t i = mBuffers[portIndex].size(); i-- > 0;) {
856        CHECK_EQ((status_t)OK, freeBuffer(portIndex, i));
857    }
858
859    mDealer[portIndex].clear();
860
861    return OK;
862}
863
864status_t ACodec::freeOutputBuffersNotOwnedByComponent() {
865    for (size_t i = mBuffers[kPortIndexOutput].size(); i-- > 0;) {
866        BufferInfo *info =
867            &mBuffers[kPortIndexOutput].editItemAt(i);
868
869        // At this time some buffers may still be with the component
870        // or being drained.
871        if (info->mStatus != BufferInfo::OWNED_BY_COMPONENT &&
872            info->mStatus != BufferInfo::OWNED_BY_DOWNSTREAM) {
873            CHECK_EQ((status_t)OK, freeBuffer(kPortIndexOutput, i));
874        }
875    }
876
877    return OK;
878}
879
880status_t ACodec::freeBuffer(OMX_U32 portIndex, size_t i) {
881    BufferInfo *info = &mBuffers[portIndex].editItemAt(i);
882
883    CHECK(info->mStatus == BufferInfo::OWNED_BY_US
884            || info->mStatus == BufferInfo::OWNED_BY_NATIVE_WINDOW);
885
886    if (portIndex == kPortIndexOutput && mNativeWindow != NULL
887            && info->mStatus == BufferInfo::OWNED_BY_US) {
888        CHECK_EQ((status_t)OK, cancelBufferToNativeWindow(info));
889    }
890
891    CHECK_EQ(mOMX->freeBuffer(
892                mNode, portIndex, info->mBufferID),
893             (status_t)OK);
894
895    mBuffers[portIndex].removeAt(i);
896
897    return OK;
898}
899
900ACodec::BufferInfo *ACodec::findBufferByID(
901        uint32_t portIndex, IOMX::buffer_id bufferID,
902        ssize_t *index) {
903    for (size_t i = 0; i < mBuffers[portIndex].size(); ++i) {
904        BufferInfo *info = &mBuffers[portIndex].editItemAt(i);
905
906        if (info->mBufferID == bufferID) {
907            if (index != NULL) {
908                *index = i;
909            }
910            return info;
911        }
912    }
913
914    TRESPASS();
915
916    return NULL;
917}
918
919status_t ACodec::setComponentRole(
920        bool isEncoder, const char *mime) {
921    struct MimeToRole {
922        const char *mime;
923        const char *decoderRole;
924        const char *encoderRole;
925    };
926
927    static const MimeToRole kMimeToRole[] = {
928        { MEDIA_MIMETYPE_AUDIO_MPEG,
929            "audio_decoder.mp3", "audio_encoder.mp3" },
930        { MEDIA_MIMETYPE_AUDIO_MPEG_LAYER_I,
931            "audio_decoder.mp1", "audio_encoder.mp1" },
932        { MEDIA_MIMETYPE_AUDIO_MPEG_LAYER_II,
933            "audio_decoder.mp2", "audio_encoder.mp2" },
934        { MEDIA_MIMETYPE_AUDIO_AMR_NB,
935            "audio_decoder.amrnb", "audio_encoder.amrnb" },
936        { MEDIA_MIMETYPE_AUDIO_AMR_WB,
937            "audio_decoder.amrwb", "audio_encoder.amrwb" },
938        { MEDIA_MIMETYPE_AUDIO_AAC,
939            "audio_decoder.aac", "audio_encoder.aac" },
940        { MEDIA_MIMETYPE_AUDIO_VORBIS,
941            "audio_decoder.vorbis", "audio_encoder.vorbis" },
942        { MEDIA_MIMETYPE_AUDIO_G711_MLAW,
943            "audio_decoder.g711mlaw", "audio_encoder.g711mlaw" },
944        { MEDIA_MIMETYPE_AUDIO_G711_ALAW,
945            "audio_decoder.g711alaw", "audio_encoder.g711alaw" },
946        { MEDIA_MIMETYPE_VIDEO_AVC,
947            "video_decoder.avc", "video_encoder.avc" },
948        { MEDIA_MIMETYPE_VIDEO_MPEG4,
949            "video_decoder.mpeg4", "video_encoder.mpeg4" },
950        { MEDIA_MIMETYPE_VIDEO_H263,
951            "video_decoder.h263", "video_encoder.h263" },
952        { MEDIA_MIMETYPE_VIDEO_VP8,
953            "video_decoder.vp8", "video_encoder.vp8" },
954        { MEDIA_MIMETYPE_VIDEO_VP9,
955            "video_decoder.vp9", "video_encoder.vp9" },
956        { MEDIA_MIMETYPE_AUDIO_RAW,
957            "audio_decoder.raw", "audio_encoder.raw" },
958        { MEDIA_MIMETYPE_AUDIO_FLAC,
959            "audio_decoder.flac", "audio_encoder.flac" },
960        { MEDIA_MIMETYPE_AUDIO_MSGSM,
961            "audio_decoder.gsm", "audio_encoder.gsm" },
962    };
963
964    static const size_t kNumMimeToRole =
965        sizeof(kMimeToRole) / sizeof(kMimeToRole[0]);
966
967    size_t i;
968    for (i = 0; i < kNumMimeToRole; ++i) {
969        if (!strcasecmp(mime, kMimeToRole[i].mime)) {
970            break;
971        }
972    }
973
974    if (i == kNumMimeToRole) {
975        return ERROR_UNSUPPORTED;
976    }
977
978    const char *role =
979        isEncoder ? kMimeToRole[i].encoderRole
980                  : kMimeToRole[i].decoderRole;
981
982    if (role != NULL) {
983        OMX_PARAM_COMPONENTROLETYPE roleParams;
984        InitOMXParams(&roleParams);
985
986        strncpy((char *)roleParams.cRole,
987                role, OMX_MAX_STRINGNAME_SIZE - 1);
988
989        roleParams.cRole[OMX_MAX_STRINGNAME_SIZE - 1] = '\0';
990
991        status_t err = mOMX->setParameter(
992                mNode, OMX_IndexParamStandardComponentRole,
993                &roleParams, sizeof(roleParams));
994
995        if (err != OK) {
996            ALOGW("[%s] Failed to set standard component role '%s'.",
997                 mComponentName.c_str(), role);
998
999            return err;
1000        }
1001    }
1002
1003    return OK;
1004}
1005
1006status_t ACodec::configureCodec(
1007        const char *mime, const sp<AMessage> &msg) {
1008    int32_t encoder;
1009    if (!msg->findInt32("encoder", &encoder)) {
1010        encoder = false;
1011    }
1012
1013    mIsEncoder = encoder;
1014
1015    status_t err = setComponentRole(encoder /* isEncoder */, mime);
1016
1017    if (err != OK) {
1018        return err;
1019    }
1020
1021    int32_t bitRate = 0;
1022    // FLAC encoder doesn't need a bitrate, other encoders do
1023    if (encoder && strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_FLAC)
1024            && !msg->findInt32("bitrate", &bitRate)) {
1025        return INVALID_OPERATION;
1026    }
1027
1028    int32_t storeMeta;
1029    if (encoder
1030            && msg->findInt32("store-metadata-in-buffers", &storeMeta)
1031            && storeMeta != 0) {
1032        err = mOMX->storeMetaDataInBuffers(mNode, kPortIndexInput, OMX_TRUE);
1033
1034        if (err != OK) {
1035              ALOGE("[%s] storeMetaDataInBuffers (input) failed w/ err %d",
1036                    mComponentName.c_str(), err);
1037
1038              return err;
1039          }
1040      }
1041
1042    int32_t prependSPSPPS = 0;
1043    if (encoder
1044            && msg->findInt32("prepend-sps-pps-to-idr-frames", &prependSPSPPS)
1045            && prependSPSPPS != 0) {
1046        OMX_INDEXTYPE index;
1047        err = mOMX->getExtensionIndex(
1048                mNode,
1049                "OMX.google.android.index.prependSPSPPSToIDRFrames",
1050                &index);
1051
1052        if (err == OK) {
1053            PrependSPSPPSToIDRFramesParams params;
1054            InitOMXParams(&params);
1055            params.bEnable = OMX_TRUE;
1056
1057            err = mOMX->setParameter(
1058                    mNode, index, &params, sizeof(params));
1059        }
1060
1061        if (err != OK) {
1062            ALOGE("Encoder could not be configured to emit SPS/PPS before "
1063                  "IDR frames. (err %d)", err);
1064
1065            return err;
1066        }
1067    }
1068
1069    // Only enable metadata mode on encoder output if encoder can prepend
1070    // sps/pps to idr frames, since in metadata mode the bitstream is in an
1071    // opaque handle, to which we don't have access.
1072    int32_t video = !strncasecmp(mime, "video/", 6);
1073    if (encoder && video) {
1074        OMX_BOOL enable = (OMX_BOOL) (prependSPSPPS
1075            && msg->findInt32("store-metadata-in-buffers-output", &storeMeta)
1076            && storeMeta != 0);
1077
1078        err = mOMX->storeMetaDataInBuffers(mNode, kPortIndexOutput, enable);
1079
1080        if (err != OK) {
1081            ALOGE("[%s] storeMetaDataInBuffers (output) failed w/ err %d",
1082                mComponentName.c_str(), err);
1083            mUseMetadataOnEncoderOutput = 0;
1084        } else {
1085            mUseMetadataOnEncoderOutput = enable;
1086        }
1087    }
1088
1089    // Always try to enable dynamic output buffers on native surface
1090    sp<RefBase> obj;
1091    int32_t haveNativeWindow = msg->findObject("native-window", &obj) &&
1092            obj != NULL;
1093    mStoreMetaDataInOutputBuffers = false;
1094    if (!encoder && video && haveNativeWindow) {
1095        err = mOMX->storeMetaDataInBuffers(mNode, kPortIndexOutput, OMX_TRUE);
1096        if (err != OK) {
1097            // allow failure
1098            ALOGE("[%s] storeMetaDataInBuffers failed w/ err %d",
1099                  mComponentName.c_str(), err);
1100            err = OK;
1101        } else {
1102            ALOGV("[%s] storeMetaDataInBuffers succeeded", mComponentName.c_str());
1103            mStoreMetaDataInOutputBuffers = true;
1104        }
1105    }
1106
1107    if (video) {
1108        if (encoder) {
1109            err = setupVideoEncoder(mime, msg);
1110        } else {
1111            int32_t width, height;
1112            if (!msg->findInt32("width", &width)
1113                    || !msg->findInt32("height", &height)) {
1114                err = INVALID_OPERATION;
1115            } else {
1116                err = setupVideoDecoder(mime, width, height);
1117            }
1118        }
1119    } else if (!strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_MPEG)) {
1120        int32_t numChannels, sampleRate;
1121        if (!msg->findInt32("channel-count", &numChannels)
1122                || !msg->findInt32("sample-rate", &sampleRate)) {
1123            // Since we did not always check for these, leave them optional
1124            // and have the decoder figure it all out.
1125            err = OK;
1126        } else {
1127            err = setupRawAudioFormat(
1128                    encoder ? kPortIndexInput : kPortIndexOutput,
1129                    sampleRate,
1130                    numChannels);
1131        }
1132    } else if (!strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_AAC)) {
1133        int32_t numChannels, sampleRate;
1134        if (!msg->findInt32("channel-count", &numChannels)
1135                || !msg->findInt32("sample-rate", &sampleRate)) {
1136            err = INVALID_OPERATION;
1137        } else {
1138            int32_t isADTS, aacProfile;
1139            if (!msg->findInt32("is-adts", &isADTS)) {
1140                isADTS = 0;
1141            }
1142            if (!msg->findInt32("aac-profile", &aacProfile)) {
1143                aacProfile = OMX_AUDIO_AACObjectNull;
1144            }
1145
1146            err = setupAACCodec(
1147                    encoder, numChannels, sampleRate, bitRate, aacProfile,
1148                    isADTS != 0);
1149        }
1150    } else if (!strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_AMR_NB)) {
1151        err = setupAMRCodec(encoder, false /* isWAMR */, bitRate);
1152    } else if (!strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_AMR_WB)) {
1153        err = setupAMRCodec(encoder, true /* isWAMR */, bitRate);
1154    } else if (!strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_G711_ALAW)
1155            || !strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_G711_MLAW)) {
1156        // These are PCM-like formats with a fixed sample rate but
1157        // a variable number of channels.
1158
1159        int32_t numChannels;
1160        if (!msg->findInt32("channel-count", &numChannels)) {
1161            err = INVALID_OPERATION;
1162        } else {
1163            err = setupG711Codec(encoder, numChannels);
1164        }
1165    } else if (!strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_FLAC)) {
1166        int32_t numChannels, sampleRate, compressionLevel = -1;
1167        if (encoder &&
1168                (!msg->findInt32("channel-count", &numChannels)
1169                        || !msg->findInt32("sample-rate", &sampleRate))) {
1170            ALOGE("missing channel count or sample rate for FLAC encoder");
1171            err = INVALID_OPERATION;
1172        } else {
1173            if (encoder) {
1174                if (!msg->findInt32(
1175                            "flac-compression-level", &compressionLevel)) {
1176                    compressionLevel = 5;// default FLAC compression level
1177                } else if (compressionLevel < 0) {
1178                    ALOGW("compression level %d outside [0..8] range, "
1179                          "using 0",
1180                          compressionLevel);
1181                    compressionLevel = 0;
1182                } else if (compressionLevel > 8) {
1183                    ALOGW("compression level %d outside [0..8] range, "
1184                          "using 8",
1185                          compressionLevel);
1186                    compressionLevel = 8;
1187                }
1188            }
1189            err = setupFlacCodec(
1190                    encoder, numChannels, sampleRate, compressionLevel);
1191        }
1192    } else if (!strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_RAW)) {
1193        int32_t numChannels, sampleRate;
1194        if (encoder
1195                || !msg->findInt32("channel-count", &numChannels)
1196                || !msg->findInt32("sample-rate", &sampleRate)) {
1197            err = INVALID_OPERATION;
1198        } else {
1199            err = setupRawAudioFormat(kPortIndexInput, sampleRate, numChannels);
1200        }
1201    }
1202
1203    if (err != OK) {
1204        return err;
1205    }
1206
1207    if (!msg->findInt32("encoder-delay", &mEncoderDelay)) {
1208        mEncoderDelay = 0;
1209    }
1210
1211    if (!msg->findInt32("encoder-padding", &mEncoderPadding)) {
1212        mEncoderPadding = 0;
1213    }
1214
1215    if (msg->findInt32("channel-mask", &mChannelMask)) {
1216        mChannelMaskPresent = true;
1217    } else {
1218        mChannelMaskPresent = false;
1219    }
1220
1221    int32_t maxInputSize;
1222    if (msg->findInt32("max-input-size", &maxInputSize)) {
1223        err = setMinBufferSize(kPortIndexInput, (size_t)maxInputSize);
1224    } else if (!strcmp("OMX.Nvidia.aac.decoder", mComponentName.c_str())) {
1225        err = setMinBufferSize(kPortIndexInput, 8192);  // XXX
1226    }
1227
1228    return err;
1229}
1230
1231status_t ACodec::setMinBufferSize(OMX_U32 portIndex, size_t size) {
1232    OMX_PARAM_PORTDEFINITIONTYPE def;
1233    InitOMXParams(&def);
1234    def.nPortIndex = portIndex;
1235
1236    status_t err = mOMX->getParameter(
1237            mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
1238
1239    if (err != OK) {
1240        return err;
1241    }
1242
1243    if (def.nBufferSize >= size) {
1244        return OK;
1245    }
1246
1247    def.nBufferSize = size;
1248
1249    err = mOMX->setParameter(
1250            mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
1251
1252    if (err != OK) {
1253        return err;
1254    }
1255
1256    err = mOMX->getParameter(
1257            mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
1258
1259    if (err != OK) {
1260        return err;
1261    }
1262
1263    CHECK(def.nBufferSize >= size);
1264
1265    return OK;
1266}
1267
1268status_t ACodec::selectAudioPortFormat(
1269        OMX_U32 portIndex, OMX_AUDIO_CODINGTYPE desiredFormat) {
1270    OMX_AUDIO_PARAM_PORTFORMATTYPE format;
1271    InitOMXParams(&format);
1272
1273    format.nPortIndex = portIndex;
1274    for (OMX_U32 index = 0;; ++index) {
1275        format.nIndex = index;
1276
1277        status_t err = mOMX->getParameter(
1278                mNode, OMX_IndexParamAudioPortFormat,
1279                &format, sizeof(format));
1280
1281        if (err != OK) {
1282            return err;
1283        }
1284
1285        if (format.eEncoding == desiredFormat) {
1286            break;
1287        }
1288    }
1289
1290    return mOMX->setParameter(
1291            mNode, OMX_IndexParamAudioPortFormat, &format, sizeof(format));
1292}
1293
1294status_t ACodec::setupAACCodec(
1295        bool encoder, int32_t numChannels, int32_t sampleRate,
1296        int32_t bitRate, int32_t aacProfile, bool isADTS) {
1297    if (encoder && isADTS) {
1298        return -EINVAL;
1299    }
1300
1301    status_t err = setupRawAudioFormat(
1302            encoder ? kPortIndexInput : kPortIndexOutput,
1303            sampleRate,
1304            numChannels);
1305
1306    if (err != OK) {
1307        return err;
1308    }
1309
1310    if (encoder) {
1311        err = selectAudioPortFormat(kPortIndexOutput, OMX_AUDIO_CodingAAC);
1312
1313        if (err != OK) {
1314            return err;
1315        }
1316
1317        OMX_PARAM_PORTDEFINITIONTYPE def;
1318        InitOMXParams(&def);
1319        def.nPortIndex = kPortIndexOutput;
1320
1321        err = mOMX->getParameter(
1322                mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
1323
1324        if (err != OK) {
1325            return err;
1326        }
1327
1328        def.format.audio.bFlagErrorConcealment = OMX_TRUE;
1329        def.format.audio.eEncoding = OMX_AUDIO_CodingAAC;
1330
1331        err = mOMX->setParameter(
1332                mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
1333
1334        if (err != OK) {
1335            return err;
1336        }
1337
1338        OMX_AUDIO_PARAM_AACPROFILETYPE profile;
1339        InitOMXParams(&profile);
1340        profile.nPortIndex = kPortIndexOutput;
1341
1342        err = mOMX->getParameter(
1343                mNode, OMX_IndexParamAudioAac, &profile, sizeof(profile));
1344
1345        if (err != OK) {
1346            return err;
1347        }
1348
1349        profile.nChannels = numChannels;
1350
1351        profile.eChannelMode =
1352            (numChannels == 1)
1353                ? OMX_AUDIO_ChannelModeMono: OMX_AUDIO_ChannelModeStereo;
1354
1355        profile.nSampleRate = sampleRate;
1356        profile.nBitRate = bitRate;
1357        profile.nAudioBandWidth = 0;
1358        profile.nFrameLength = 0;
1359        profile.nAACtools = OMX_AUDIO_AACToolAll;
1360        profile.nAACERtools = OMX_AUDIO_AACERNone;
1361        profile.eAACProfile = (OMX_AUDIO_AACPROFILETYPE) aacProfile;
1362        profile.eAACStreamFormat = OMX_AUDIO_AACStreamFormatMP4FF;
1363
1364        err = mOMX->setParameter(
1365                mNode, OMX_IndexParamAudioAac, &profile, sizeof(profile));
1366
1367        if (err != OK) {
1368            return err;
1369        }
1370
1371        return err;
1372    }
1373
1374    OMX_AUDIO_PARAM_AACPROFILETYPE profile;
1375    InitOMXParams(&profile);
1376    profile.nPortIndex = kPortIndexInput;
1377
1378    err = mOMX->getParameter(
1379            mNode, OMX_IndexParamAudioAac, &profile, sizeof(profile));
1380
1381    if (err != OK) {
1382        return err;
1383    }
1384
1385    profile.nChannels = numChannels;
1386    profile.nSampleRate = sampleRate;
1387
1388    profile.eAACStreamFormat =
1389        isADTS
1390            ? OMX_AUDIO_AACStreamFormatMP4ADTS
1391            : OMX_AUDIO_AACStreamFormatMP4FF;
1392
1393    return mOMX->setParameter(
1394            mNode, OMX_IndexParamAudioAac, &profile, sizeof(profile));
1395}
1396
1397static OMX_AUDIO_AMRBANDMODETYPE pickModeFromBitRate(
1398        bool isAMRWB, int32_t bps) {
1399    if (isAMRWB) {
1400        if (bps <= 6600) {
1401            return OMX_AUDIO_AMRBandModeWB0;
1402        } else if (bps <= 8850) {
1403            return OMX_AUDIO_AMRBandModeWB1;
1404        } else if (bps <= 12650) {
1405            return OMX_AUDIO_AMRBandModeWB2;
1406        } else if (bps <= 14250) {
1407            return OMX_AUDIO_AMRBandModeWB3;
1408        } else if (bps <= 15850) {
1409            return OMX_AUDIO_AMRBandModeWB4;
1410        } else if (bps <= 18250) {
1411            return OMX_AUDIO_AMRBandModeWB5;
1412        } else if (bps <= 19850) {
1413            return OMX_AUDIO_AMRBandModeWB6;
1414        } else if (bps <= 23050) {
1415            return OMX_AUDIO_AMRBandModeWB7;
1416        }
1417
1418        // 23850 bps
1419        return OMX_AUDIO_AMRBandModeWB8;
1420    } else {  // AMRNB
1421        if (bps <= 4750) {
1422            return OMX_AUDIO_AMRBandModeNB0;
1423        } else if (bps <= 5150) {
1424            return OMX_AUDIO_AMRBandModeNB1;
1425        } else if (bps <= 5900) {
1426            return OMX_AUDIO_AMRBandModeNB2;
1427        } else if (bps <= 6700) {
1428            return OMX_AUDIO_AMRBandModeNB3;
1429        } else if (bps <= 7400) {
1430            return OMX_AUDIO_AMRBandModeNB4;
1431        } else if (bps <= 7950) {
1432            return OMX_AUDIO_AMRBandModeNB5;
1433        } else if (bps <= 10200) {
1434            return OMX_AUDIO_AMRBandModeNB6;
1435        }
1436
1437        // 12200 bps
1438        return OMX_AUDIO_AMRBandModeNB7;
1439    }
1440}
1441
1442status_t ACodec::setupAMRCodec(bool encoder, bool isWAMR, int32_t bitrate) {
1443    OMX_AUDIO_PARAM_AMRTYPE def;
1444    InitOMXParams(&def);
1445    def.nPortIndex = encoder ? kPortIndexOutput : kPortIndexInput;
1446
1447    status_t err =
1448        mOMX->getParameter(mNode, OMX_IndexParamAudioAmr, &def, sizeof(def));
1449
1450    if (err != OK) {
1451        return err;
1452    }
1453
1454    def.eAMRFrameFormat = OMX_AUDIO_AMRFrameFormatFSF;
1455    def.eAMRBandMode = pickModeFromBitRate(isWAMR, bitrate);
1456
1457    err = mOMX->setParameter(
1458            mNode, OMX_IndexParamAudioAmr, &def, sizeof(def));
1459
1460    if (err != OK) {
1461        return err;
1462    }
1463
1464    return setupRawAudioFormat(
1465            encoder ? kPortIndexInput : kPortIndexOutput,
1466            isWAMR ? 16000 : 8000 /* sampleRate */,
1467            1 /* numChannels */);
1468}
1469
1470status_t ACodec::setupG711Codec(bool encoder, int32_t numChannels) {
1471    CHECK(!encoder);  // XXX TODO
1472
1473    return setupRawAudioFormat(
1474            kPortIndexInput, 8000 /* sampleRate */, numChannels);
1475}
1476
1477status_t ACodec::setupFlacCodec(
1478        bool encoder, int32_t numChannels, int32_t sampleRate, int32_t compressionLevel) {
1479
1480    if (encoder) {
1481        OMX_AUDIO_PARAM_FLACTYPE def;
1482        InitOMXParams(&def);
1483        def.nPortIndex = kPortIndexOutput;
1484
1485        // configure compression level
1486        status_t err = mOMX->getParameter(mNode, OMX_IndexParamAudioFlac, &def, sizeof(def));
1487        if (err != OK) {
1488            ALOGE("setupFlacCodec(): Error %d getting OMX_IndexParamAudioFlac parameter", err);
1489            return err;
1490        }
1491        def.nCompressionLevel = compressionLevel;
1492        err = mOMX->setParameter(mNode, OMX_IndexParamAudioFlac, &def, sizeof(def));
1493        if (err != OK) {
1494            ALOGE("setupFlacCodec(): Error %d setting OMX_IndexParamAudioFlac parameter", err);
1495            return err;
1496        }
1497    }
1498
1499    return setupRawAudioFormat(
1500            encoder ? kPortIndexInput : kPortIndexOutput,
1501            sampleRate,
1502            numChannels);
1503}
1504
1505status_t ACodec::setupRawAudioFormat(
1506        OMX_U32 portIndex, int32_t sampleRate, int32_t numChannels) {
1507    OMX_PARAM_PORTDEFINITIONTYPE def;
1508    InitOMXParams(&def);
1509    def.nPortIndex = portIndex;
1510
1511    status_t err = mOMX->getParameter(
1512            mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
1513
1514    if (err != OK) {
1515        return err;
1516    }
1517
1518    def.format.audio.eEncoding = OMX_AUDIO_CodingPCM;
1519
1520    err = mOMX->setParameter(
1521            mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
1522
1523    if (err != OK) {
1524        return err;
1525    }
1526
1527    OMX_AUDIO_PARAM_PCMMODETYPE pcmParams;
1528    InitOMXParams(&pcmParams);
1529    pcmParams.nPortIndex = portIndex;
1530
1531    err = mOMX->getParameter(
1532            mNode, OMX_IndexParamAudioPcm, &pcmParams, sizeof(pcmParams));
1533
1534    if (err != OK) {
1535        return err;
1536    }
1537
1538    pcmParams.nChannels = numChannels;
1539    pcmParams.eNumData = OMX_NumericalDataSigned;
1540    pcmParams.bInterleaved = OMX_TRUE;
1541    pcmParams.nBitPerSample = 16;
1542    pcmParams.nSamplingRate = sampleRate;
1543    pcmParams.ePCMMode = OMX_AUDIO_PCMModeLinear;
1544
1545    if (getOMXChannelMapping(numChannels, pcmParams.eChannelMapping) != OK) {
1546        return OMX_ErrorNone;
1547    }
1548
1549    return mOMX->setParameter(
1550            mNode, OMX_IndexParamAudioPcm, &pcmParams, sizeof(pcmParams));
1551}
1552
1553status_t ACodec::setVideoPortFormatType(
1554        OMX_U32 portIndex,
1555        OMX_VIDEO_CODINGTYPE compressionFormat,
1556        OMX_COLOR_FORMATTYPE colorFormat) {
1557    OMX_VIDEO_PARAM_PORTFORMATTYPE format;
1558    InitOMXParams(&format);
1559    format.nPortIndex = portIndex;
1560    format.nIndex = 0;
1561    bool found = false;
1562
1563    OMX_U32 index = 0;
1564    for (;;) {
1565        format.nIndex = index;
1566        status_t err = mOMX->getParameter(
1567                mNode, OMX_IndexParamVideoPortFormat,
1568                &format, sizeof(format));
1569
1570        if (err != OK) {
1571            return err;
1572        }
1573
1574        // The following assertion is violated by TI's video decoder.
1575        // CHECK_EQ(format.nIndex, index);
1576
1577        if (!strcmp("OMX.TI.Video.encoder", mComponentName.c_str())) {
1578            if (portIndex == kPortIndexInput
1579                    && colorFormat == format.eColorFormat) {
1580                // eCompressionFormat does not seem right.
1581                found = true;
1582                break;
1583            }
1584            if (portIndex == kPortIndexOutput
1585                    && compressionFormat == format.eCompressionFormat) {
1586                // eColorFormat does not seem right.
1587                found = true;
1588                break;
1589            }
1590        }
1591
1592        if (format.eCompressionFormat == compressionFormat
1593            && format.eColorFormat == colorFormat) {
1594            found = true;
1595            break;
1596        }
1597
1598        ++index;
1599    }
1600
1601    if (!found) {
1602        return UNKNOWN_ERROR;
1603    }
1604
1605    status_t err = mOMX->setParameter(
1606            mNode, OMX_IndexParamVideoPortFormat,
1607            &format, sizeof(format));
1608
1609    return err;
1610}
1611
1612status_t ACodec::setSupportedOutputFormat() {
1613    OMX_VIDEO_PARAM_PORTFORMATTYPE format;
1614    InitOMXParams(&format);
1615    format.nPortIndex = kPortIndexOutput;
1616    format.nIndex = 0;
1617
1618    status_t err = mOMX->getParameter(
1619            mNode, OMX_IndexParamVideoPortFormat,
1620            &format, sizeof(format));
1621    CHECK_EQ(err, (status_t)OK);
1622    CHECK_EQ((int)format.eCompressionFormat, (int)OMX_VIDEO_CodingUnused);
1623
1624    return mOMX->setParameter(
1625            mNode, OMX_IndexParamVideoPortFormat,
1626            &format, sizeof(format));
1627}
1628
1629static const struct VideoCodingMapEntry {
1630    const char *mMime;
1631    OMX_VIDEO_CODINGTYPE mVideoCodingType;
1632} kVideoCodingMapEntry[] = {
1633    { MEDIA_MIMETYPE_VIDEO_AVC, OMX_VIDEO_CodingAVC },
1634    { MEDIA_MIMETYPE_VIDEO_MPEG4, OMX_VIDEO_CodingMPEG4 },
1635    { MEDIA_MIMETYPE_VIDEO_H263, OMX_VIDEO_CodingH263 },
1636    { MEDIA_MIMETYPE_VIDEO_MPEG2, OMX_VIDEO_CodingMPEG2 },
1637    { MEDIA_MIMETYPE_VIDEO_VP8, OMX_VIDEO_CodingVP8 },
1638    { MEDIA_MIMETYPE_VIDEO_VP9, OMX_VIDEO_CodingVP9 },
1639};
1640
1641static status_t GetVideoCodingTypeFromMime(
1642        const char *mime, OMX_VIDEO_CODINGTYPE *codingType) {
1643    for (size_t i = 0;
1644         i < sizeof(kVideoCodingMapEntry) / sizeof(kVideoCodingMapEntry[0]);
1645         ++i) {
1646        if (!strcasecmp(mime, kVideoCodingMapEntry[i].mMime)) {
1647            *codingType = kVideoCodingMapEntry[i].mVideoCodingType;
1648            return OK;
1649        }
1650    }
1651
1652    *codingType = OMX_VIDEO_CodingUnused;
1653
1654    return ERROR_UNSUPPORTED;
1655}
1656
1657static status_t GetMimeTypeForVideoCoding(
1658        OMX_VIDEO_CODINGTYPE codingType, AString *mime) {
1659    for (size_t i = 0;
1660         i < sizeof(kVideoCodingMapEntry) / sizeof(kVideoCodingMapEntry[0]);
1661         ++i) {
1662        if (codingType == kVideoCodingMapEntry[i].mVideoCodingType) {
1663            *mime = kVideoCodingMapEntry[i].mMime;
1664            return OK;
1665        }
1666    }
1667
1668    mime->clear();
1669
1670    return ERROR_UNSUPPORTED;
1671}
1672
1673status_t ACodec::setupVideoDecoder(
1674        const char *mime, int32_t width, int32_t height) {
1675    OMX_VIDEO_CODINGTYPE compressionFormat;
1676    status_t err = GetVideoCodingTypeFromMime(mime, &compressionFormat);
1677
1678    if (err != OK) {
1679        return err;
1680    }
1681
1682    err = setVideoPortFormatType(
1683            kPortIndexInput, compressionFormat, OMX_COLOR_FormatUnused);
1684
1685    if (err != OK) {
1686        return err;
1687    }
1688
1689    err = setSupportedOutputFormat();
1690
1691    if (err != OK) {
1692        return err;
1693    }
1694
1695    err = setVideoFormatOnPort(
1696            kPortIndexInput, width, height, compressionFormat);
1697
1698    if (err != OK) {
1699        return err;
1700    }
1701
1702    err = setVideoFormatOnPort(
1703            kPortIndexOutput, width, height, OMX_VIDEO_CodingUnused);
1704
1705    if (err != OK) {
1706        return err;
1707    }
1708
1709    return OK;
1710}
1711
1712status_t ACodec::setupVideoEncoder(const char *mime, const sp<AMessage> &msg) {
1713    int32_t tmp;
1714    if (!msg->findInt32("color-format", &tmp)) {
1715        return INVALID_OPERATION;
1716    }
1717
1718    OMX_COLOR_FORMATTYPE colorFormat =
1719        static_cast<OMX_COLOR_FORMATTYPE>(tmp);
1720
1721    status_t err = setVideoPortFormatType(
1722            kPortIndexInput, OMX_VIDEO_CodingUnused, colorFormat);
1723
1724    if (err != OK) {
1725        ALOGE("[%s] does not support color format %d",
1726              mComponentName.c_str(), colorFormat);
1727
1728        return err;
1729    }
1730
1731    /* Input port configuration */
1732
1733    OMX_PARAM_PORTDEFINITIONTYPE def;
1734    InitOMXParams(&def);
1735
1736    OMX_VIDEO_PORTDEFINITIONTYPE *video_def = &def.format.video;
1737
1738    def.nPortIndex = kPortIndexInput;
1739
1740    err = mOMX->getParameter(
1741            mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
1742
1743    if (err != OK) {
1744        return err;
1745    }
1746
1747    int32_t width, height, bitrate;
1748    if (!msg->findInt32("width", &width)
1749            || !msg->findInt32("height", &height)
1750            || !msg->findInt32("bitrate", &bitrate)) {
1751        return INVALID_OPERATION;
1752    }
1753
1754    video_def->nFrameWidth = width;
1755    video_def->nFrameHeight = height;
1756
1757    int32_t stride;
1758    if (!msg->findInt32("stride", &stride)) {
1759        stride = width;
1760    }
1761
1762    video_def->nStride = stride;
1763
1764    int32_t sliceHeight;
1765    if (!msg->findInt32("slice-height", &sliceHeight)) {
1766        sliceHeight = height;
1767    }
1768
1769    video_def->nSliceHeight = sliceHeight;
1770
1771    def.nBufferSize = (video_def->nStride * video_def->nSliceHeight * 3) / 2;
1772
1773    float frameRate;
1774    if (!msg->findFloat("frame-rate", &frameRate)) {
1775        int32_t tmp;
1776        if (!msg->findInt32("frame-rate", &tmp)) {
1777            return INVALID_OPERATION;
1778        }
1779        frameRate = (float)tmp;
1780    }
1781
1782    video_def->xFramerate = (OMX_U32)(frameRate * 65536.0f);
1783    video_def->eCompressionFormat = OMX_VIDEO_CodingUnused;
1784    video_def->eColorFormat = colorFormat;
1785
1786    err = mOMX->setParameter(
1787            mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
1788
1789    if (err != OK) {
1790        ALOGE("[%s] failed to set input port definition parameters.",
1791              mComponentName.c_str());
1792
1793        return err;
1794    }
1795
1796    /* Output port configuration */
1797
1798    OMX_VIDEO_CODINGTYPE compressionFormat;
1799    err = GetVideoCodingTypeFromMime(mime, &compressionFormat);
1800
1801    if (err != OK) {
1802        return err;
1803    }
1804
1805    err = setVideoPortFormatType(
1806            kPortIndexOutput, compressionFormat, OMX_COLOR_FormatUnused);
1807
1808    if (err != OK) {
1809        ALOGE("[%s] does not support compression format %d",
1810             mComponentName.c_str(), compressionFormat);
1811
1812        return err;
1813    }
1814
1815    def.nPortIndex = kPortIndexOutput;
1816
1817    err = mOMX->getParameter(
1818            mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
1819
1820    if (err != OK) {
1821        return err;
1822    }
1823
1824    video_def->nFrameWidth = width;
1825    video_def->nFrameHeight = height;
1826    video_def->xFramerate = 0;
1827    video_def->nBitrate = bitrate;
1828    video_def->eCompressionFormat = compressionFormat;
1829    video_def->eColorFormat = OMX_COLOR_FormatUnused;
1830
1831    err = mOMX->setParameter(
1832            mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
1833
1834    if (err != OK) {
1835        ALOGE("[%s] failed to set output port definition parameters.",
1836              mComponentName.c_str());
1837
1838        return err;
1839    }
1840
1841    switch (compressionFormat) {
1842        case OMX_VIDEO_CodingMPEG4:
1843            err = setupMPEG4EncoderParameters(msg);
1844            break;
1845
1846        case OMX_VIDEO_CodingH263:
1847            err = setupH263EncoderParameters(msg);
1848            break;
1849
1850        case OMX_VIDEO_CodingAVC:
1851            err = setupAVCEncoderParameters(msg);
1852            break;
1853
1854        default:
1855            break;
1856    }
1857
1858    ALOGI("setupVideoEncoder succeeded");
1859
1860    return err;
1861}
1862
1863status_t ACodec::setCyclicIntraMacroblockRefresh(const sp<AMessage> &msg, int32_t mode) {
1864    OMX_VIDEO_PARAM_INTRAREFRESHTYPE params;
1865    InitOMXParams(&params);
1866    params.nPortIndex = kPortIndexOutput;
1867
1868    params.eRefreshMode = static_cast<OMX_VIDEO_INTRAREFRESHTYPE>(mode);
1869
1870    if (params.eRefreshMode == OMX_VIDEO_IntraRefreshCyclic ||
1871            params.eRefreshMode == OMX_VIDEO_IntraRefreshBoth) {
1872        int32_t mbs;
1873        if (!msg->findInt32("intra-refresh-CIR-mbs", &mbs)) {
1874            return INVALID_OPERATION;
1875        }
1876        params.nCirMBs = mbs;
1877    }
1878
1879    if (params.eRefreshMode == OMX_VIDEO_IntraRefreshAdaptive ||
1880            params.eRefreshMode == OMX_VIDEO_IntraRefreshBoth) {
1881        int32_t mbs;
1882        if (!msg->findInt32("intra-refresh-AIR-mbs", &mbs)) {
1883            return INVALID_OPERATION;
1884        }
1885        params.nAirMBs = mbs;
1886
1887        int32_t ref;
1888        if (!msg->findInt32("intra-refresh-AIR-ref", &ref)) {
1889            return INVALID_OPERATION;
1890        }
1891        params.nAirRef = ref;
1892    }
1893
1894    status_t err = mOMX->setParameter(
1895            mNode, OMX_IndexParamVideoIntraRefresh,
1896            &params, sizeof(params));
1897    return err;
1898}
1899
1900static OMX_U32 setPFramesSpacing(int32_t iFramesInterval, int32_t frameRate) {
1901    if (iFramesInterval < 0) {
1902        return 0xFFFFFFFF;
1903    } else if (iFramesInterval == 0) {
1904        return 0;
1905    }
1906    OMX_U32 ret = frameRate * iFramesInterval;
1907    CHECK(ret > 1);
1908    return ret;
1909}
1910
1911static OMX_VIDEO_CONTROLRATETYPE getBitrateMode(const sp<AMessage> &msg) {
1912    int32_t tmp;
1913    if (!msg->findInt32("bitrate-mode", &tmp)) {
1914        return OMX_Video_ControlRateVariable;
1915    }
1916
1917    return static_cast<OMX_VIDEO_CONTROLRATETYPE>(tmp);
1918}
1919
1920status_t ACodec::setupMPEG4EncoderParameters(const sp<AMessage> &msg) {
1921    int32_t bitrate, iFrameInterval;
1922    if (!msg->findInt32("bitrate", &bitrate)
1923            || !msg->findInt32("i-frame-interval", &iFrameInterval)) {
1924        return INVALID_OPERATION;
1925    }
1926
1927    OMX_VIDEO_CONTROLRATETYPE bitrateMode = getBitrateMode(msg);
1928
1929    float frameRate;
1930    if (!msg->findFloat("frame-rate", &frameRate)) {
1931        int32_t tmp;
1932        if (!msg->findInt32("frame-rate", &tmp)) {
1933            return INVALID_OPERATION;
1934        }
1935        frameRate = (float)tmp;
1936    }
1937
1938    OMX_VIDEO_PARAM_MPEG4TYPE mpeg4type;
1939    InitOMXParams(&mpeg4type);
1940    mpeg4type.nPortIndex = kPortIndexOutput;
1941
1942    status_t err = mOMX->getParameter(
1943            mNode, OMX_IndexParamVideoMpeg4, &mpeg4type, sizeof(mpeg4type));
1944
1945    if (err != OK) {
1946        return err;
1947    }
1948
1949    mpeg4type.nSliceHeaderSpacing = 0;
1950    mpeg4type.bSVH = OMX_FALSE;
1951    mpeg4type.bGov = OMX_FALSE;
1952
1953    mpeg4type.nAllowedPictureTypes =
1954        OMX_VIDEO_PictureTypeI | OMX_VIDEO_PictureTypeP;
1955
1956    mpeg4type.nPFrames = setPFramesSpacing(iFrameInterval, frameRate);
1957    if (mpeg4type.nPFrames == 0) {
1958        mpeg4type.nAllowedPictureTypes = OMX_VIDEO_PictureTypeI;
1959    }
1960    mpeg4type.nBFrames = 0;
1961    mpeg4type.nIDCVLCThreshold = 0;
1962    mpeg4type.bACPred = OMX_TRUE;
1963    mpeg4type.nMaxPacketSize = 256;
1964    mpeg4type.nTimeIncRes = 1000;
1965    mpeg4type.nHeaderExtension = 0;
1966    mpeg4type.bReversibleVLC = OMX_FALSE;
1967
1968    int32_t profile;
1969    if (msg->findInt32("profile", &profile)) {
1970        int32_t level;
1971        if (!msg->findInt32("level", &level)) {
1972            return INVALID_OPERATION;
1973        }
1974
1975        err = verifySupportForProfileAndLevel(profile, level);
1976
1977        if (err != OK) {
1978            return err;
1979        }
1980
1981        mpeg4type.eProfile = static_cast<OMX_VIDEO_MPEG4PROFILETYPE>(profile);
1982        mpeg4type.eLevel = static_cast<OMX_VIDEO_MPEG4LEVELTYPE>(level);
1983    }
1984
1985    err = mOMX->setParameter(
1986            mNode, OMX_IndexParamVideoMpeg4, &mpeg4type, sizeof(mpeg4type));
1987
1988    if (err != OK) {
1989        return err;
1990    }
1991
1992    err = configureBitrate(bitrate, bitrateMode);
1993
1994    if (err != OK) {
1995        return err;
1996    }
1997
1998    return setupErrorCorrectionParameters();
1999}
2000
2001status_t ACodec::setupH263EncoderParameters(const sp<AMessage> &msg) {
2002    int32_t bitrate, iFrameInterval;
2003    if (!msg->findInt32("bitrate", &bitrate)
2004            || !msg->findInt32("i-frame-interval", &iFrameInterval)) {
2005        return INVALID_OPERATION;
2006    }
2007
2008    OMX_VIDEO_CONTROLRATETYPE bitrateMode = getBitrateMode(msg);
2009
2010    float frameRate;
2011    if (!msg->findFloat("frame-rate", &frameRate)) {
2012        int32_t tmp;
2013        if (!msg->findInt32("frame-rate", &tmp)) {
2014            return INVALID_OPERATION;
2015        }
2016        frameRate = (float)tmp;
2017    }
2018
2019    OMX_VIDEO_PARAM_H263TYPE h263type;
2020    InitOMXParams(&h263type);
2021    h263type.nPortIndex = kPortIndexOutput;
2022
2023    status_t err = mOMX->getParameter(
2024            mNode, OMX_IndexParamVideoH263, &h263type, sizeof(h263type));
2025
2026    if (err != OK) {
2027        return err;
2028    }
2029
2030    h263type.nAllowedPictureTypes =
2031        OMX_VIDEO_PictureTypeI | OMX_VIDEO_PictureTypeP;
2032
2033    h263type.nPFrames = setPFramesSpacing(iFrameInterval, frameRate);
2034    if (h263type.nPFrames == 0) {
2035        h263type.nAllowedPictureTypes = OMX_VIDEO_PictureTypeI;
2036    }
2037    h263type.nBFrames = 0;
2038
2039    int32_t profile;
2040    if (msg->findInt32("profile", &profile)) {
2041        int32_t level;
2042        if (!msg->findInt32("level", &level)) {
2043            return INVALID_OPERATION;
2044        }
2045
2046        err = verifySupportForProfileAndLevel(profile, level);
2047
2048        if (err != OK) {
2049            return err;
2050        }
2051
2052        h263type.eProfile = static_cast<OMX_VIDEO_H263PROFILETYPE>(profile);
2053        h263type.eLevel = static_cast<OMX_VIDEO_H263LEVELTYPE>(level);
2054    }
2055
2056    h263type.bPLUSPTYPEAllowed = OMX_FALSE;
2057    h263type.bForceRoundingTypeToZero = OMX_FALSE;
2058    h263type.nPictureHeaderRepetition = 0;
2059    h263type.nGOBHeaderInterval = 0;
2060
2061    err = mOMX->setParameter(
2062            mNode, OMX_IndexParamVideoH263, &h263type, sizeof(h263type));
2063
2064    if (err != OK) {
2065        return err;
2066    }
2067
2068    err = configureBitrate(bitrate, bitrateMode);
2069
2070    if (err != OK) {
2071        return err;
2072    }
2073
2074    return setupErrorCorrectionParameters();
2075}
2076
2077status_t ACodec::setupAVCEncoderParameters(const sp<AMessage> &msg) {
2078    int32_t bitrate, iFrameInterval;
2079    if (!msg->findInt32("bitrate", &bitrate)
2080            || !msg->findInt32("i-frame-interval", &iFrameInterval)) {
2081        return INVALID_OPERATION;
2082    }
2083
2084    OMX_VIDEO_CONTROLRATETYPE bitrateMode = getBitrateMode(msg);
2085
2086    float frameRate;
2087    if (!msg->findFloat("frame-rate", &frameRate)) {
2088        int32_t tmp;
2089        if (!msg->findInt32("frame-rate", &tmp)) {
2090            return INVALID_OPERATION;
2091        }
2092        frameRate = (float)tmp;
2093    }
2094
2095    status_t err = OK;
2096    int32_t intraRefreshMode = 0;
2097    if (msg->findInt32("intra-refresh-mode", &intraRefreshMode)) {
2098        err = setCyclicIntraMacroblockRefresh(msg, intraRefreshMode);
2099        if (err != OK) {
2100            ALOGE("Setting intra macroblock refresh mode (%d) failed: 0x%x",
2101                    err, intraRefreshMode);
2102            return err;
2103        }
2104    }
2105
2106    OMX_VIDEO_PARAM_AVCTYPE h264type;
2107    InitOMXParams(&h264type);
2108    h264type.nPortIndex = kPortIndexOutput;
2109
2110    err = mOMX->getParameter(
2111            mNode, OMX_IndexParamVideoAvc, &h264type, sizeof(h264type));
2112
2113    if (err != OK) {
2114        return err;
2115    }
2116
2117    h264type.nAllowedPictureTypes =
2118        OMX_VIDEO_PictureTypeI | OMX_VIDEO_PictureTypeP;
2119
2120    int32_t profile;
2121    if (msg->findInt32("profile", &profile)) {
2122        int32_t level;
2123        if (!msg->findInt32("level", &level)) {
2124            return INVALID_OPERATION;
2125        }
2126
2127        err = verifySupportForProfileAndLevel(profile, level);
2128
2129        if (err != OK) {
2130            return err;
2131        }
2132
2133        h264type.eProfile = static_cast<OMX_VIDEO_AVCPROFILETYPE>(profile);
2134        h264type.eLevel = static_cast<OMX_VIDEO_AVCLEVELTYPE>(level);
2135    }
2136
2137    // XXX
2138    if (h264type.eProfile != OMX_VIDEO_AVCProfileBaseline) {
2139        ALOGW("Use baseline profile instead of %d for AVC recording",
2140            h264type.eProfile);
2141        h264type.eProfile = OMX_VIDEO_AVCProfileBaseline;
2142    }
2143
2144    if (h264type.eProfile == OMX_VIDEO_AVCProfileBaseline) {
2145        h264type.nSliceHeaderSpacing = 0;
2146        h264type.bUseHadamard = OMX_TRUE;
2147        h264type.nRefFrames = 1;
2148        h264type.nBFrames = 0;
2149        h264type.nPFrames = setPFramesSpacing(iFrameInterval, frameRate);
2150        if (h264type.nPFrames == 0) {
2151            h264type.nAllowedPictureTypes = OMX_VIDEO_PictureTypeI;
2152        }
2153        h264type.nRefIdx10ActiveMinus1 = 0;
2154        h264type.nRefIdx11ActiveMinus1 = 0;
2155        h264type.bEntropyCodingCABAC = OMX_FALSE;
2156        h264type.bWeightedPPrediction = OMX_FALSE;
2157        h264type.bconstIpred = OMX_FALSE;
2158        h264type.bDirect8x8Inference = OMX_FALSE;
2159        h264type.bDirectSpatialTemporal = OMX_FALSE;
2160        h264type.nCabacInitIdc = 0;
2161    }
2162
2163    if (h264type.nBFrames != 0) {
2164        h264type.nAllowedPictureTypes |= OMX_VIDEO_PictureTypeB;
2165    }
2166
2167    h264type.bEnableUEP = OMX_FALSE;
2168    h264type.bEnableFMO = OMX_FALSE;
2169    h264type.bEnableASO = OMX_FALSE;
2170    h264type.bEnableRS = OMX_FALSE;
2171    h264type.bFrameMBsOnly = OMX_TRUE;
2172    h264type.bMBAFF = OMX_FALSE;
2173    h264type.eLoopFilterMode = OMX_VIDEO_AVCLoopFilterEnable;
2174
2175    err = mOMX->setParameter(
2176            mNode, OMX_IndexParamVideoAvc, &h264type, sizeof(h264type));
2177
2178    if (err != OK) {
2179        return err;
2180    }
2181
2182    return configureBitrate(bitrate, bitrateMode);
2183}
2184
2185status_t ACodec::verifySupportForProfileAndLevel(
2186        int32_t profile, int32_t level) {
2187    OMX_VIDEO_PARAM_PROFILELEVELTYPE params;
2188    InitOMXParams(&params);
2189    params.nPortIndex = kPortIndexOutput;
2190
2191    for (params.nProfileIndex = 0;; ++params.nProfileIndex) {
2192        status_t err = mOMX->getParameter(
2193                mNode,
2194                OMX_IndexParamVideoProfileLevelQuerySupported,
2195                &params,
2196                sizeof(params));
2197
2198        if (err != OK) {
2199            return err;
2200        }
2201
2202        int32_t supportedProfile = static_cast<int32_t>(params.eProfile);
2203        int32_t supportedLevel = static_cast<int32_t>(params.eLevel);
2204
2205        if (profile == supportedProfile && level <= supportedLevel) {
2206            return OK;
2207        }
2208    }
2209}
2210
2211status_t ACodec::configureBitrate(
2212        int32_t bitrate, OMX_VIDEO_CONTROLRATETYPE bitrateMode) {
2213    OMX_VIDEO_PARAM_BITRATETYPE bitrateType;
2214    InitOMXParams(&bitrateType);
2215    bitrateType.nPortIndex = kPortIndexOutput;
2216
2217    status_t err = mOMX->getParameter(
2218            mNode, OMX_IndexParamVideoBitrate,
2219            &bitrateType, sizeof(bitrateType));
2220
2221    if (err != OK) {
2222        return err;
2223    }
2224
2225    bitrateType.eControlRate = bitrateMode;
2226    bitrateType.nTargetBitrate = bitrate;
2227
2228    return mOMX->setParameter(
2229            mNode, OMX_IndexParamVideoBitrate,
2230            &bitrateType, sizeof(bitrateType));
2231}
2232
2233status_t ACodec::setupErrorCorrectionParameters() {
2234    OMX_VIDEO_PARAM_ERRORCORRECTIONTYPE errorCorrectionType;
2235    InitOMXParams(&errorCorrectionType);
2236    errorCorrectionType.nPortIndex = kPortIndexOutput;
2237
2238    status_t err = mOMX->getParameter(
2239            mNode, OMX_IndexParamVideoErrorCorrection,
2240            &errorCorrectionType, sizeof(errorCorrectionType));
2241
2242    if (err != OK) {
2243        return OK;  // Optional feature. Ignore this failure
2244    }
2245
2246    errorCorrectionType.bEnableHEC = OMX_FALSE;
2247    errorCorrectionType.bEnableResync = OMX_TRUE;
2248    errorCorrectionType.nResynchMarkerSpacing = 256;
2249    errorCorrectionType.bEnableDataPartitioning = OMX_FALSE;
2250    errorCorrectionType.bEnableRVLC = OMX_FALSE;
2251
2252    return mOMX->setParameter(
2253            mNode, OMX_IndexParamVideoErrorCorrection,
2254            &errorCorrectionType, sizeof(errorCorrectionType));
2255}
2256
2257status_t ACodec::setVideoFormatOnPort(
2258        OMX_U32 portIndex,
2259        int32_t width, int32_t height, OMX_VIDEO_CODINGTYPE compressionFormat) {
2260    OMX_PARAM_PORTDEFINITIONTYPE def;
2261    InitOMXParams(&def);
2262    def.nPortIndex = portIndex;
2263
2264    OMX_VIDEO_PORTDEFINITIONTYPE *video_def = &def.format.video;
2265
2266    status_t err = mOMX->getParameter(
2267            mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
2268
2269    CHECK_EQ(err, (status_t)OK);
2270
2271    if (portIndex == kPortIndexInput) {
2272        // XXX Need a (much) better heuristic to compute input buffer sizes.
2273        const size_t X = 64 * 1024;
2274        if (def.nBufferSize < X) {
2275            def.nBufferSize = X;
2276        }
2277    }
2278
2279    CHECK_EQ((int)def.eDomain, (int)OMX_PortDomainVideo);
2280
2281    video_def->nFrameWidth = width;
2282    video_def->nFrameHeight = height;
2283
2284    if (portIndex == kPortIndexInput) {
2285        video_def->eCompressionFormat = compressionFormat;
2286        video_def->eColorFormat = OMX_COLOR_FormatUnused;
2287    }
2288
2289    err = mOMX->setParameter(
2290            mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
2291
2292    return err;
2293}
2294
2295status_t ACodec::initNativeWindow() {
2296    if (mNativeWindow != NULL) {
2297        return mOMX->enableGraphicBuffers(mNode, kPortIndexOutput, OMX_TRUE);
2298    }
2299
2300    mOMX->enableGraphicBuffers(mNode, kPortIndexOutput, OMX_FALSE);
2301    return OK;
2302}
2303
2304size_t ACodec::countBuffersOwnedByComponent(OMX_U32 portIndex) const {
2305    size_t n = 0;
2306
2307    for (size_t i = 0; i < mBuffers[portIndex].size(); ++i) {
2308        const BufferInfo &info = mBuffers[portIndex].itemAt(i);
2309
2310        if (info.mStatus == BufferInfo::OWNED_BY_COMPONENT) {
2311            ++n;
2312        }
2313    }
2314
2315    return n;
2316}
2317
2318size_t ACodec::countBuffersOwnedByNativeWindow() const {
2319    size_t n = 0;
2320
2321    for (size_t i = 0; i < mBuffers[kPortIndexOutput].size(); ++i) {
2322        const BufferInfo &info = mBuffers[kPortIndexOutput].itemAt(i);
2323
2324        if (info.mStatus == BufferInfo::OWNED_BY_NATIVE_WINDOW) {
2325            ++n;
2326        }
2327    }
2328
2329    return n;
2330}
2331
2332void ACodec::waitUntilAllPossibleNativeWindowBuffersAreReturnedToUs() {
2333    if (mNativeWindow == NULL) {
2334        return;
2335    }
2336
2337    int minUndequeuedBufs = 0;
2338    status_t err = mNativeWindow->query(
2339            mNativeWindow.get(), NATIVE_WINDOW_MIN_UNDEQUEUED_BUFFERS,
2340            &minUndequeuedBufs);
2341
2342    if (err != OK) {
2343        ALOGE("[%s] NATIVE_WINDOW_MIN_UNDEQUEUED_BUFFERS query failed: %s (%d)",
2344                mComponentName.c_str(), strerror(-err), -err);
2345
2346        minUndequeuedBufs = 0;
2347    }
2348
2349    while (countBuffersOwnedByNativeWindow() > (size_t)minUndequeuedBufs
2350            && dequeueBufferFromNativeWindow() != NULL) {
2351    }
2352}
2353
2354bool ACodec::allYourBuffersAreBelongToUs(
2355        OMX_U32 portIndex) {
2356    for (size_t i = 0; i < mBuffers[portIndex].size(); ++i) {
2357        BufferInfo *info = &mBuffers[portIndex].editItemAt(i);
2358
2359        if (info->mStatus != BufferInfo::OWNED_BY_US
2360                && info->mStatus != BufferInfo::OWNED_BY_NATIVE_WINDOW) {
2361            ALOGV("[%s] Buffer %p on port %ld still has status %d",
2362                    mComponentName.c_str(),
2363                    info->mBufferID, portIndex, info->mStatus);
2364            return false;
2365        }
2366    }
2367
2368    return true;
2369}
2370
2371bool ACodec::allYourBuffersAreBelongToUs() {
2372    return allYourBuffersAreBelongToUs(kPortIndexInput)
2373        && allYourBuffersAreBelongToUs(kPortIndexOutput);
2374}
2375
2376void ACodec::deferMessage(const sp<AMessage> &msg) {
2377    bool wasEmptyBefore = mDeferredQueue.empty();
2378    mDeferredQueue.push_back(msg);
2379}
2380
2381void ACodec::processDeferredMessages() {
2382    List<sp<AMessage> > queue = mDeferredQueue;
2383    mDeferredQueue.clear();
2384
2385    List<sp<AMessage> >::iterator it = queue.begin();
2386    while (it != queue.end()) {
2387        onMessageReceived(*it++);
2388    }
2389}
2390
2391void ACodec::sendFormatChange(const sp<AMessage> &reply) {
2392    sp<AMessage> notify = mNotify->dup();
2393    notify->setInt32("what", kWhatOutputFormatChanged);
2394
2395    OMX_PARAM_PORTDEFINITIONTYPE def;
2396    InitOMXParams(&def);
2397    def.nPortIndex = kPortIndexOutput;
2398
2399    CHECK_EQ(mOMX->getParameter(
2400                mNode, OMX_IndexParamPortDefinition, &def, sizeof(def)),
2401             (status_t)OK);
2402
2403    CHECK_EQ((int)def.eDir, (int)OMX_DirOutput);
2404
2405    switch (def.eDomain) {
2406        case OMX_PortDomainVideo:
2407        {
2408            OMX_VIDEO_PORTDEFINITIONTYPE *videoDef = &def.format.video;
2409
2410            AString mime;
2411            if (!mIsEncoder) {
2412                notify->setString("mime", MEDIA_MIMETYPE_VIDEO_RAW);
2413            } else if (GetMimeTypeForVideoCoding(
2414                        videoDef->eCompressionFormat, &mime) != OK) {
2415                notify->setString("mime", "application/octet-stream");
2416            } else {
2417                notify->setString("mime", mime.c_str());
2418            }
2419
2420            notify->setInt32("width", videoDef->nFrameWidth);
2421            notify->setInt32("height", videoDef->nFrameHeight);
2422
2423            if (!mIsEncoder) {
2424                notify->setInt32("stride", videoDef->nStride);
2425                notify->setInt32("slice-height", videoDef->nSliceHeight);
2426                notify->setInt32("color-format", videoDef->eColorFormat);
2427
2428                OMX_CONFIG_RECTTYPE rect;
2429                InitOMXParams(&rect);
2430                rect.nPortIndex = kPortIndexOutput;
2431
2432                if (mOMX->getConfig(
2433                            mNode, OMX_IndexConfigCommonOutputCrop,
2434                            &rect, sizeof(rect)) != OK) {
2435                    rect.nLeft = 0;
2436                    rect.nTop = 0;
2437                    rect.nWidth = videoDef->nFrameWidth;
2438                    rect.nHeight = videoDef->nFrameHeight;
2439                }
2440
2441                CHECK_GE(rect.nLeft, 0);
2442                CHECK_GE(rect.nTop, 0);
2443                CHECK_GE(rect.nWidth, 0u);
2444                CHECK_GE(rect.nHeight, 0u);
2445                CHECK_LE(rect.nLeft + rect.nWidth - 1, videoDef->nFrameWidth);
2446                CHECK_LE(rect.nTop + rect.nHeight - 1, videoDef->nFrameHeight);
2447
2448                notify->setRect(
2449                        "crop",
2450                        rect.nLeft,
2451                        rect.nTop,
2452                        rect.nLeft + rect.nWidth - 1,
2453                        rect.nTop + rect.nHeight - 1);
2454
2455                if (mNativeWindow != NULL) {
2456                    reply->setRect(
2457                            "crop",
2458                            rect.nLeft,
2459                            rect.nTop,
2460                            rect.nLeft + rect.nWidth,
2461                            rect.nTop + rect.nHeight);
2462                }
2463            }
2464            break;
2465        }
2466
2467        case OMX_PortDomainAudio:
2468        {
2469            OMX_AUDIO_PORTDEFINITIONTYPE *audioDef = &def.format.audio;
2470
2471            switch (audioDef->eEncoding) {
2472                case OMX_AUDIO_CodingPCM:
2473                {
2474                    OMX_AUDIO_PARAM_PCMMODETYPE params;
2475                    InitOMXParams(&params);
2476                    params.nPortIndex = kPortIndexOutput;
2477
2478                    CHECK_EQ(mOMX->getParameter(
2479                                mNode, OMX_IndexParamAudioPcm,
2480                                &params, sizeof(params)),
2481                             (status_t)OK);
2482
2483                    CHECK_GT(params.nChannels, 0);
2484                    CHECK(params.nChannels == 1 || params.bInterleaved);
2485                    CHECK_EQ(params.nBitPerSample, 16u);
2486
2487                    CHECK_EQ((int)params.eNumData,
2488                             (int)OMX_NumericalDataSigned);
2489
2490                    CHECK_EQ((int)params.ePCMMode,
2491                             (int)OMX_AUDIO_PCMModeLinear);
2492
2493                    notify->setString("mime", MEDIA_MIMETYPE_AUDIO_RAW);
2494                    notify->setInt32("channel-count", params.nChannels);
2495                    notify->setInt32("sample-rate", params.nSamplingRate);
2496                    if (mEncoderDelay + mEncoderPadding) {
2497                        size_t frameSize = params.nChannels * sizeof(int16_t);
2498                        if (mSkipCutBuffer != NULL) {
2499                            size_t prevbufsize = mSkipCutBuffer->size();
2500                            if (prevbufsize != 0) {
2501                                ALOGW("Replacing SkipCutBuffer holding %d "
2502                                      "bytes",
2503                                      prevbufsize);
2504                            }
2505                        }
2506                        mSkipCutBuffer = new SkipCutBuffer(
2507                                mEncoderDelay * frameSize,
2508                                mEncoderPadding * frameSize);
2509                    }
2510
2511                    if (mChannelMaskPresent) {
2512                        notify->setInt32("channel-mask", mChannelMask);
2513                    }
2514                    break;
2515                }
2516
2517                case OMX_AUDIO_CodingAAC:
2518                {
2519                    OMX_AUDIO_PARAM_AACPROFILETYPE params;
2520                    InitOMXParams(&params);
2521                    params.nPortIndex = kPortIndexOutput;
2522
2523                    CHECK_EQ(mOMX->getParameter(
2524                                mNode, OMX_IndexParamAudioAac,
2525                                &params, sizeof(params)),
2526                             (status_t)OK);
2527
2528                    notify->setString("mime", MEDIA_MIMETYPE_AUDIO_AAC);
2529                    notify->setInt32("channel-count", params.nChannels);
2530                    notify->setInt32("sample-rate", params.nSampleRate);
2531                    break;
2532                }
2533
2534                case OMX_AUDIO_CodingAMR:
2535                {
2536                    OMX_AUDIO_PARAM_AMRTYPE params;
2537                    InitOMXParams(&params);
2538                    params.nPortIndex = kPortIndexOutput;
2539
2540                    CHECK_EQ(mOMX->getParameter(
2541                                mNode, OMX_IndexParamAudioAmr,
2542                                &params, sizeof(params)),
2543                             (status_t)OK);
2544
2545                    notify->setInt32("channel-count", 1);
2546                    if (params.eAMRBandMode >= OMX_AUDIO_AMRBandModeWB0) {
2547                        notify->setString(
2548                                "mime", MEDIA_MIMETYPE_AUDIO_AMR_WB);
2549
2550                        notify->setInt32("sample-rate", 16000);
2551                    } else {
2552                        notify->setString(
2553                                "mime", MEDIA_MIMETYPE_AUDIO_AMR_NB);
2554
2555                        notify->setInt32("sample-rate", 8000);
2556                    }
2557                    break;
2558                }
2559
2560                case OMX_AUDIO_CodingFLAC:
2561                {
2562                    OMX_AUDIO_PARAM_FLACTYPE params;
2563                    InitOMXParams(&params);
2564                    params.nPortIndex = kPortIndexOutput;
2565
2566                    CHECK_EQ(mOMX->getParameter(
2567                                mNode, OMX_IndexParamAudioFlac,
2568                                &params, sizeof(params)),
2569                             (status_t)OK);
2570
2571                    notify->setString("mime", MEDIA_MIMETYPE_AUDIO_FLAC);
2572                    notify->setInt32("channel-count", params.nChannels);
2573                    notify->setInt32("sample-rate", params.nSampleRate);
2574                    break;
2575                }
2576
2577                default:
2578                    TRESPASS();
2579            }
2580            break;
2581        }
2582
2583        default:
2584            TRESPASS();
2585    }
2586
2587    notify->post();
2588
2589    mSentFormat = true;
2590}
2591
2592void ACodec::signalError(OMX_ERRORTYPE error, status_t internalError) {
2593    sp<AMessage> notify = mNotify->dup();
2594    notify->setInt32("what", ACodec::kWhatError);
2595    notify->setInt32("omx-error", error);
2596    notify->setInt32("err", internalError);
2597    notify->post();
2598}
2599
2600status_t ACodec::pushBlankBuffersToNativeWindow() {
2601    status_t err = NO_ERROR;
2602    ANativeWindowBuffer* anb = NULL;
2603    int numBufs = 0;
2604    int minUndequeuedBufs = 0;
2605
2606    // We need to reconnect to the ANativeWindow as a CPU client to ensure that
2607    // no frames get dropped by SurfaceFlinger assuming that these are video
2608    // frames.
2609    err = native_window_api_disconnect(mNativeWindow.get(),
2610            NATIVE_WINDOW_API_MEDIA);
2611    if (err != NO_ERROR) {
2612        ALOGE("error pushing blank frames: api_disconnect failed: %s (%d)",
2613                strerror(-err), -err);
2614        return err;
2615    }
2616
2617    err = native_window_api_connect(mNativeWindow.get(),
2618            NATIVE_WINDOW_API_CPU);
2619    if (err != NO_ERROR) {
2620        ALOGE("error pushing blank frames: api_connect failed: %s (%d)",
2621                strerror(-err), -err);
2622        return err;
2623    }
2624
2625    err = native_window_set_buffers_geometry(mNativeWindow.get(), 1, 1,
2626            HAL_PIXEL_FORMAT_RGBX_8888);
2627    if (err != NO_ERROR) {
2628        ALOGE("error pushing blank frames: set_buffers_geometry failed: %s (%d)",
2629                strerror(-err), -err);
2630        goto error;
2631    }
2632
2633    err = native_window_set_usage(mNativeWindow.get(),
2634            GRALLOC_USAGE_SW_WRITE_OFTEN);
2635    if (err != NO_ERROR) {
2636        ALOGE("error pushing blank frames: set_usage failed: %s (%d)",
2637                strerror(-err), -err);
2638        goto error;
2639    }
2640
2641    err = mNativeWindow->query(mNativeWindow.get(),
2642            NATIVE_WINDOW_MIN_UNDEQUEUED_BUFFERS, &minUndequeuedBufs);
2643    if (err != NO_ERROR) {
2644        ALOGE("error pushing blank frames: MIN_UNDEQUEUED_BUFFERS query "
2645                "failed: %s (%d)", strerror(-err), -err);
2646        goto error;
2647    }
2648
2649    numBufs = minUndequeuedBufs + 1;
2650    err = native_window_set_buffer_count(mNativeWindow.get(), numBufs);
2651    if (err != NO_ERROR) {
2652        ALOGE("error pushing blank frames: set_buffer_count failed: %s (%d)",
2653                strerror(-err), -err);
2654        goto error;
2655    }
2656
2657    // We  push numBufs + 1 buffers to ensure that we've drawn into the same
2658    // buffer twice.  This should guarantee that the buffer has been displayed
2659    // on the screen and then been replaced, so an previous video frames are
2660    // guaranteed NOT to be currently displayed.
2661    for (int i = 0; i < numBufs + 1; i++) {
2662        int fenceFd = -1;
2663        err = native_window_dequeue_buffer_and_wait(mNativeWindow.get(), &anb);
2664        if (err != NO_ERROR) {
2665            ALOGE("error pushing blank frames: dequeueBuffer failed: %s (%d)",
2666                    strerror(-err), -err);
2667            goto error;
2668        }
2669
2670        sp<GraphicBuffer> buf(new GraphicBuffer(anb, false));
2671
2672        // Fill the buffer with the a 1x1 checkerboard pattern ;)
2673        uint32_t* img = NULL;
2674        err = buf->lock(GRALLOC_USAGE_SW_WRITE_OFTEN, (void**)(&img));
2675        if (err != NO_ERROR) {
2676            ALOGE("error pushing blank frames: lock failed: %s (%d)",
2677                    strerror(-err), -err);
2678            goto error;
2679        }
2680
2681        *img = 0;
2682
2683        err = buf->unlock();
2684        if (err != NO_ERROR) {
2685            ALOGE("error pushing blank frames: unlock failed: %s (%d)",
2686                    strerror(-err), -err);
2687            goto error;
2688        }
2689
2690        err = mNativeWindow->queueBuffer(mNativeWindow.get(),
2691                buf->getNativeBuffer(), -1);
2692        if (err != NO_ERROR) {
2693            ALOGE("error pushing blank frames: queueBuffer failed: %s (%d)",
2694                    strerror(-err), -err);
2695            goto error;
2696        }
2697
2698        anb = NULL;
2699    }
2700
2701error:
2702
2703    if (err != NO_ERROR) {
2704        // Clean up after an error.
2705        if (anb != NULL) {
2706            mNativeWindow->cancelBuffer(mNativeWindow.get(), anb, -1);
2707        }
2708
2709        native_window_api_disconnect(mNativeWindow.get(),
2710                NATIVE_WINDOW_API_CPU);
2711        native_window_api_connect(mNativeWindow.get(),
2712                NATIVE_WINDOW_API_MEDIA);
2713
2714        return err;
2715    } else {
2716        // Clean up after success.
2717        err = native_window_api_disconnect(mNativeWindow.get(),
2718                NATIVE_WINDOW_API_CPU);
2719        if (err != NO_ERROR) {
2720            ALOGE("error pushing blank frames: api_disconnect failed: %s (%d)",
2721                    strerror(-err), -err);
2722            return err;
2723        }
2724
2725        err = native_window_api_connect(mNativeWindow.get(),
2726                NATIVE_WINDOW_API_MEDIA);
2727        if (err != NO_ERROR) {
2728            ALOGE("error pushing blank frames: api_connect failed: %s (%d)",
2729                    strerror(-err), -err);
2730            return err;
2731        }
2732
2733        return NO_ERROR;
2734    }
2735}
2736
2737////////////////////////////////////////////////////////////////////////////////
2738
2739ACodec::PortDescription::PortDescription() {
2740}
2741
2742status_t ACodec::requestIDRFrame() {
2743    if (!mIsEncoder) {
2744        return ERROR_UNSUPPORTED;
2745    }
2746
2747    OMX_CONFIG_INTRAREFRESHVOPTYPE params;
2748    InitOMXParams(&params);
2749
2750    params.nPortIndex = kPortIndexOutput;
2751    params.IntraRefreshVOP = OMX_TRUE;
2752
2753    return mOMX->setConfig(
2754            mNode,
2755            OMX_IndexConfigVideoIntraVOPRefresh,
2756            &params,
2757            sizeof(params));
2758}
2759
2760void ACodec::PortDescription::addBuffer(
2761        IOMX::buffer_id id, const sp<ABuffer> &buffer) {
2762    mBufferIDs.push_back(id);
2763    mBuffers.push_back(buffer);
2764}
2765
2766size_t ACodec::PortDescription::countBuffers() {
2767    return mBufferIDs.size();
2768}
2769
2770IOMX::buffer_id ACodec::PortDescription::bufferIDAt(size_t index) const {
2771    return mBufferIDs.itemAt(index);
2772}
2773
2774sp<ABuffer> ACodec::PortDescription::bufferAt(size_t index) const {
2775    return mBuffers.itemAt(index);
2776}
2777
2778////////////////////////////////////////////////////////////////////////////////
2779
2780ACodec::BaseState::BaseState(ACodec *codec, const sp<AState> &parentState)
2781    : AState(parentState),
2782      mCodec(codec) {
2783}
2784
2785ACodec::BaseState::PortMode ACodec::BaseState::getPortMode(OMX_U32 portIndex) {
2786    return KEEP_BUFFERS;
2787}
2788
2789bool ACodec::BaseState::onMessageReceived(const sp<AMessage> &msg) {
2790    switch (msg->what()) {
2791        case kWhatInputBufferFilled:
2792        {
2793            onInputBufferFilled(msg);
2794            break;
2795        }
2796
2797        case kWhatOutputBufferDrained:
2798        {
2799            onOutputBufferDrained(msg);
2800            break;
2801        }
2802
2803        case ACodec::kWhatOMXMessage:
2804        {
2805            return onOMXMessage(msg);
2806        }
2807
2808        case ACodec::kWhatCreateInputSurface:
2809        case ACodec::kWhatSignalEndOfInputStream:
2810        {
2811            ALOGE("Message 0x%x was not handled", msg->what());
2812            mCodec->signalError(OMX_ErrorUndefined, INVALID_OPERATION);
2813            return true;
2814        }
2815
2816        case ACodec::kWhatOMXDied:
2817        {
2818            ALOGE("OMX/mediaserver died, signalling error!");
2819            mCodec->signalError(OMX_ErrorResourcesLost, DEAD_OBJECT);
2820            break;
2821        }
2822
2823        default:
2824            return false;
2825    }
2826
2827    return true;
2828}
2829
2830bool ACodec::BaseState::onOMXMessage(const sp<AMessage> &msg) {
2831    int32_t type;
2832    CHECK(msg->findInt32("type", &type));
2833
2834    IOMX::node_id nodeID;
2835    CHECK(msg->findPointer("node", &nodeID));
2836    CHECK_EQ(nodeID, mCodec->mNode);
2837
2838    switch (type) {
2839        case omx_message::EVENT:
2840        {
2841            int32_t event, data1, data2;
2842            CHECK(msg->findInt32("event", &event));
2843            CHECK(msg->findInt32("data1", &data1));
2844            CHECK(msg->findInt32("data2", &data2));
2845
2846            if (event == OMX_EventCmdComplete
2847                    && data1 == OMX_CommandFlush
2848                    && data2 == (int32_t)OMX_ALL) {
2849                // Use of this notification is not consistent across
2850                // implementations. We'll drop this notification and rely
2851                // on flush-complete notifications on the individual port
2852                // indices instead.
2853
2854                return true;
2855            }
2856
2857            return onOMXEvent(
2858                    static_cast<OMX_EVENTTYPE>(event),
2859                    static_cast<OMX_U32>(data1),
2860                    static_cast<OMX_U32>(data2));
2861        }
2862
2863        case omx_message::EMPTY_BUFFER_DONE:
2864        {
2865            IOMX::buffer_id bufferID;
2866            CHECK(msg->findPointer("buffer", &bufferID));
2867
2868            return onOMXEmptyBufferDone(bufferID);
2869        }
2870
2871        case omx_message::FILL_BUFFER_DONE:
2872        {
2873            IOMX::buffer_id bufferID;
2874            CHECK(msg->findPointer("buffer", &bufferID));
2875
2876            int32_t rangeOffset, rangeLength, flags;
2877            int64_t timeUs;
2878            void *platformPrivate;
2879            void *dataPtr;
2880
2881            CHECK(msg->findInt32("range_offset", &rangeOffset));
2882            CHECK(msg->findInt32("range_length", &rangeLength));
2883            CHECK(msg->findInt32("flags", &flags));
2884            CHECK(msg->findInt64("timestamp", &timeUs));
2885            CHECK(msg->findPointer("platform_private", &platformPrivate));
2886            CHECK(msg->findPointer("data_ptr", &dataPtr));
2887
2888            return onOMXFillBufferDone(
2889                    bufferID,
2890                    (size_t)rangeOffset, (size_t)rangeLength,
2891                    (OMX_U32)flags,
2892                    timeUs,
2893                    platformPrivate,
2894                    dataPtr);
2895        }
2896
2897        default:
2898            TRESPASS();
2899            break;
2900    }
2901}
2902
2903bool ACodec::BaseState::onOMXEvent(
2904        OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2) {
2905    if (event != OMX_EventError) {
2906        ALOGV("[%s] EVENT(%d, 0x%08lx, 0x%08lx)",
2907             mCodec->mComponentName.c_str(), event, data1, data2);
2908
2909        return false;
2910    }
2911
2912    ALOGE("[%s] ERROR(0x%08lx)", mCodec->mComponentName.c_str(), data1);
2913
2914    mCodec->signalError((OMX_ERRORTYPE)data1);
2915
2916    return true;
2917}
2918
2919bool ACodec::BaseState::onOMXEmptyBufferDone(IOMX::buffer_id bufferID) {
2920    ALOGV("[%s] onOMXEmptyBufferDone %p",
2921         mCodec->mComponentName.c_str(), bufferID);
2922
2923    BufferInfo *info =
2924        mCodec->findBufferByID(kPortIndexInput, bufferID);
2925
2926    CHECK_EQ((int)info->mStatus, (int)BufferInfo::OWNED_BY_COMPONENT);
2927    info->mStatus = BufferInfo::OWNED_BY_US;
2928
2929    const sp<AMessage> &bufferMeta = info->mData->meta();
2930    void *mediaBuffer;
2931    if (bufferMeta->findPointer("mediaBuffer", &mediaBuffer)
2932            && mediaBuffer != NULL) {
2933        // We're in "store-metadata-in-buffers" mode, the underlying
2934        // OMX component had access to data that's implicitly refcounted
2935        // by this "mediaBuffer" object. Now that the OMX component has
2936        // told us that it's done with the input buffer, we can decrement
2937        // the mediaBuffer's reference count.
2938
2939        ALOGV("releasing mbuf %p", mediaBuffer);
2940
2941        ((MediaBuffer *)mediaBuffer)->release();
2942        mediaBuffer = NULL;
2943
2944        bufferMeta->setPointer("mediaBuffer", NULL);
2945    }
2946
2947    PortMode mode = getPortMode(kPortIndexInput);
2948
2949    switch (mode) {
2950        case KEEP_BUFFERS:
2951            break;
2952
2953        case RESUBMIT_BUFFERS:
2954            postFillThisBuffer(info);
2955            break;
2956
2957        default:
2958        {
2959            CHECK_EQ((int)mode, (int)FREE_BUFFERS);
2960            TRESPASS();  // Not currently used
2961            break;
2962        }
2963    }
2964
2965    return true;
2966}
2967
2968void ACodec::BaseState::postFillThisBuffer(BufferInfo *info) {
2969    if (mCodec->mPortEOS[kPortIndexInput]) {
2970        return;
2971    }
2972
2973    CHECK_EQ((int)info->mStatus, (int)BufferInfo::OWNED_BY_US);
2974
2975    sp<AMessage> notify = mCodec->mNotify->dup();
2976    notify->setInt32("what", ACodec::kWhatFillThisBuffer);
2977    notify->setPointer("buffer-id", info->mBufferID);
2978
2979    info->mData->meta()->clear();
2980    notify->setBuffer("buffer", info->mData);
2981
2982    sp<AMessage> reply = new AMessage(kWhatInputBufferFilled, mCodec->id());
2983    reply->setPointer("buffer-id", info->mBufferID);
2984
2985    notify->setMessage("reply", reply);
2986
2987    notify->post();
2988
2989    info->mStatus = BufferInfo::OWNED_BY_UPSTREAM;
2990}
2991
2992void ACodec::BaseState::onInputBufferFilled(const sp<AMessage> &msg) {
2993    IOMX::buffer_id bufferID;
2994    CHECK(msg->findPointer("buffer-id", &bufferID));
2995
2996    sp<ABuffer> buffer;
2997    int32_t err = OK;
2998    bool eos = false;
2999
3000    if (!msg->findBuffer("buffer", &buffer)) {
3001        CHECK(msg->findInt32("err", &err));
3002
3003        ALOGV("[%s] saw error %d instead of an input buffer",
3004             mCodec->mComponentName.c_str(), err);
3005
3006        buffer.clear();
3007
3008        eos = true;
3009    }
3010
3011    int32_t tmp;
3012    if (buffer != NULL && buffer->meta()->findInt32("eos", &tmp) && tmp) {
3013        eos = true;
3014        err = ERROR_END_OF_STREAM;
3015    }
3016
3017    BufferInfo *info = mCodec->findBufferByID(kPortIndexInput, bufferID);
3018    CHECK_EQ((int)info->mStatus, (int)BufferInfo::OWNED_BY_UPSTREAM);
3019
3020    info->mStatus = BufferInfo::OWNED_BY_US;
3021
3022    PortMode mode = getPortMode(kPortIndexInput);
3023
3024    switch (mode) {
3025        case KEEP_BUFFERS:
3026        {
3027            if (eos) {
3028                if (!mCodec->mPortEOS[kPortIndexInput]) {
3029                    mCodec->mPortEOS[kPortIndexInput] = true;
3030                    mCodec->mInputEOSResult = err;
3031                }
3032            }
3033            break;
3034        }
3035
3036        case RESUBMIT_BUFFERS:
3037        {
3038            if (buffer != NULL && !mCodec->mPortEOS[kPortIndexInput]) {
3039                int64_t timeUs;
3040                CHECK(buffer->meta()->findInt64("timeUs", &timeUs));
3041
3042                OMX_U32 flags = OMX_BUFFERFLAG_ENDOFFRAME;
3043
3044                int32_t isCSD;
3045                if (buffer->meta()->findInt32("csd", &isCSD) && isCSD != 0) {
3046                    flags |= OMX_BUFFERFLAG_CODECCONFIG;
3047                }
3048
3049                if (eos) {
3050                    flags |= OMX_BUFFERFLAG_EOS;
3051                }
3052
3053                if (buffer != info->mData) {
3054                    ALOGV("[%s] Needs to copy input data for buffer %p. (%p != %p)",
3055                         mCodec->mComponentName.c_str(),
3056                         bufferID,
3057                         buffer.get(), info->mData.get());
3058
3059                    CHECK_LE(buffer->size(), info->mData->capacity());
3060                    memcpy(info->mData->data(), buffer->data(), buffer->size());
3061                }
3062
3063                if (flags & OMX_BUFFERFLAG_CODECCONFIG) {
3064                    ALOGV("[%s] calling emptyBuffer %p w/ codec specific data",
3065                         mCodec->mComponentName.c_str(), bufferID);
3066                } else if (flags & OMX_BUFFERFLAG_EOS) {
3067                    ALOGV("[%s] calling emptyBuffer %p w/ EOS",
3068                         mCodec->mComponentName.c_str(), bufferID);
3069                } else {
3070#if TRACK_BUFFER_TIMING
3071                    ALOGI("[%s] calling emptyBuffer %p w/ time %lld us",
3072                         mCodec->mComponentName.c_str(), bufferID, timeUs);
3073#else
3074                    ALOGV("[%s] calling emptyBuffer %p w/ time %lld us",
3075                         mCodec->mComponentName.c_str(), bufferID, timeUs);
3076#endif
3077                }
3078
3079#if TRACK_BUFFER_TIMING
3080                ACodec::BufferStats stats;
3081                stats.mEmptyBufferTimeUs = ALooper::GetNowUs();
3082                stats.mFillBufferDoneTimeUs = -1ll;
3083                mCodec->mBufferStats.add(timeUs, stats);
3084#endif
3085
3086                if (mCodec->mStoreMetaDataInOutputBuffers) {
3087                    // try to submit an output buffer for each input buffer
3088                    PortMode outputMode = getPortMode(kPortIndexOutput);
3089
3090                    ALOGV("MetaDataBuffersToSubmit=%u portMode=%s",
3091                            mCodec->mMetaDataBuffersToSubmit,
3092                            (outputMode == FREE_BUFFERS ? "FREE" :
3093                             outputMode == KEEP_BUFFERS ? "KEEP" : "RESUBMIT"));
3094                    if (outputMode == RESUBMIT_BUFFERS) {
3095                        CHECK_EQ(mCodec->submitOutputMetaDataBuffer(),
3096                                (status_t)OK);
3097                    }
3098                }
3099
3100                CHECK_EQ(mCodec->mOMX->emptyBuffer(
3101                            mCodec->mNode,
3102                            bufferID,
3103                            0,
3104                            buffer->size(),
3105                            flags,
3106                            timeUs),
3107                         (status_t)OK);
3108
3109                info->mStatus = BufferInfo::OWNED_BY_COMPONENT;
3110
3111                if (!eos) {
3112                    getMoreInputDataIfPossible();
3113                } else {
3114                    ALOGV("[%s] Signalled EOS on the input port",
3115                         mCodec->mComponentName.c_str());
3116
3117                    mCodec->mPortEOS[kPortIndexInput] = true;
3118                    mCodec->mInputEOSResult = err;
3119                }
3120            } else if (!mCodec->mPortEOS[kPortIndexInput]) {
3121                if (err != ERROR_END_OF_STREAM) {
3122                    ALOGV("[%s] Signalling EOS on the input port "
3123                         "due to error %d",
3124                         mCodec->mComponentName.c_str(), err);
3125                } else {
3126                    ALOGV("[%s] Signalling EOS on the input port",
3127                         mCodec->mComponentName.c_str());
3128                }
3129
3130                ALOGV("[%s] calling emptyBuffer %p signalling EOS",
3131                     mCodec->mComponentName.c_str(), bufferID);
3132
3133                CHECK_EQ(mCodec->mOMX->emptyBuffer(
3134                            mCodec->mNode,
3135                            bufferID,
3136                            0,
3137                            0,
3138                            OMX_BUFFERFLAG_EOS,
3139                            0),
3140                         (status_t)OK);
3141
3142                info->mStatus = BufferInfo::OWNED_BY_COMPONENT;
3143
3144                mCodec->mPortEOS[kPortIndexInput] = true;
3145                mCodec->mInputEOSResult = err;
3146            }
3147            break;
3148
3149            default:
3150                CHECK_EQ((int)mode, (int)FREE_BUFFERS);
3151                break;
3152        }
3153    }
3154}
3155
3156void ACodec::BaseState::getMoreInputDataIfPossible() {
3157    if (mCodec->mPortEOS[kPortIndexInput]) {
3158        return;
3159    }
3160
3161    BufferInfo *eligible = NULL;
3162
3163    for (size_t i = 0; i < mCodec->mBuffers[kPortIndexInput].size(); ++i) {
3164        BufferInfo *info = &mCodec->mBuffers[kPortIndexInput].editItemAt(i);
3165
3166#if 0
3167        if (info->mStatus == BufferInfo::OWNED_BY_UPSTREAM) {
3168            // There's already a "read" pending.
3169            return;
3170        }
3171#endif
3172
3173        if (info->mStatus == BufferInfo::OWNED_BY_US) {
3174            eligible = info;
3175        }
3176    }
3177
3178    if (eligible == NULL) {
3179        return;
3180    }
3181
3182    postFillThisBuffer(eligible);
3183}
3184
3185bool ACodec::BaseState::onOMXFillBufferDone(
3186        IOMX::buffer_id bufferID,
3187        size_t rangeOffset, size_t rangeLength,
3188        OMX_U32 flags,
3189        int64_t timeUs,
3190        void *platformPrivate,
3191        void *dataPtr) {
3192    ALOGV("[%s] onOMXFillBufferDone %p time %lld us, flags = 0x%08lx",
3193         mCodec->mComponentName.c_str(), bufferID, timeUs, flags);
3194
3195    ssize_t index;
3196
3197#if TRACK_BUFFER_TIMING
3198    index = mCodec->mBufferStats.indexOfKey(timeUs);
3199    if (index >= 0) {
3200        ACodec::BufferStats *stats = &mCodec->mBufferStats.editValueAt(index);
3201        stats->mFillBufferDoneTimeUs = ALooper::GetNowUs();
3202
3203        ALOGI("frame PTS %lld: %lld",
3204                timeUs,
3205                stats->mFillBufferDoneTimeUs - stats->mEmptyBufferTimeUs);
3206
3207        mCodec->mBufferStats.removeItemsAt(index);
3208        stats = NULL;
3209    }
3210#endif
3211
3212    BufferInfo *info =
3213        mCodec->findBufferByID(kPortIndexOutput, bufferID, &index);
3214
3215    CHECK_EQ((int)info->mStatus, (int)BufferInfo::OWNED_BY_COMPONENT);
3216
3217    info->mDequeuedAt = ++mCodec->mDequeueCounter;
3218    info->mStatus = BufferInfo::OWNED_BY_US;
3219
3220    PortMode mode = getPortMode(kPortIndexOutput);
3221
3222    switch (mode) {
3223        case KEEP_BUFFERS:
3224            break;
3225
3226        case RESUBMIT_BUFFERS:
3227        {
3228            if (rangeLength == 0 && !(flags & OMX_BUFFERFLAG_EOS)) {
3229                ALOGV("[%s] calling fillBuffer %p",
3230                     mCodec->mComponentName.c_str(), info->mBufferID);
3231
3232                CHECK_EQ(mCodec->mOMX->fillBuffer(
3233                            mCodec->mNode, info->mBufferID),
3234                         (status_t)OK);
3235
3236                info->mStatus = BufferInfo::OWNED_BY_COMPONENT;
3237                break;
3238            }
3239
3240            sp<AMessage> reply =
3241                new AMessage(kWhatOutputBufferDrained, mCodec->id());
3242
3243            if (!mCodec->mSentFormat) {
3244                mCodec->sendFormatChange(reply);
3245            }
3246
3247            if (mCodec->mUseMetadataOnEncoderOutput) {
3248                native_handle_t* handle =
3249                        *(native_handle_t**)(info->mData->data() + 4);
3250                info->mData->meta()->setPointer("handle", handle);
3251                info->mData->meta()->setInt32("rangeOffset", rangeOffset);
3252                info->mData->meta()->setInt32("rangeLength", rangeLength);
3253            } else {
3254                info->mData->setRange(rangeOffset, rangeLength);
3255            }
3256#if 0
3257            if (mCodec->mNativeWindow == NULL) {
3258                if (IsIDR(info->mData)) {
3259                    ALOGI("IDR frame");
3260                }
3261            }
3262#endif
3263
3264            if (mCodec->mSkipCutBuffer != NULL) {
3265                mCodec->mSkipCutBuffer->submit(info->mData);
3266            }
3267            info->mData->meta()->setInt64("timeUs", timeUs);
3268
3269            sp<AMessage> notify = mCodec->mNotify->dup();
3270            notify->setInt32("what", ACodec::kWhatDrainThisBuffer);
3271            notify->setPointer("buffer-id", info->mBufferID);
3272            notify->setBuffer("buffer", info->mData);
3273            notify->setInt32("flags", flags);
3274
3275            reply->setPointer("buffer-id", info->mBufferID);
3276
3277            notify->setMessage("reply", reply);
3278
3279            notify->post();
3280
3281            info->mStatus = BufferInfo::OWNED_BY_DOWNSTREAM;
3282
3283            if (flags & OMX_BUFFERFLAG_EOS) {
3284                ALOGV("[%s] saw output EOS", mCodec->mComponentName.c_str());
3285
3286                sp<AMessage> notify = mCodec->mNotify->dup();
3287                notify->setInt32("what", ACodec::kWhatEOS);
3288                notify->setInt32("err", mCodec->mInputEOSResult);
3289                notify->post();
3290
3291                mCodec->mPortEOS[kPortIndexOutput] = true;
3292            }
3293            break;
3294        }
3295
3296        default:
3297        {
3298            CHECK_EQ((int)mode, (int)FREE_BUFFERS);
3299
3300            CHECK_EQ((status_t)OK,
3301                     mCodec->freeBuffer(kPortIndexOutput, index));
3302            break;
3303        }
3304    }
3305
3306    return true;
3307}
3308
3309void ACodec::BaseState::onOutputBufferDrained(const sp<AMessage> &msg) {
3310    IOMX::buffer_id bufferID;
3311    CHECK(msg->findPointer("buffer-id", &bufferID));
3312
3313    ssize_t index;
3314    BufferInfo *info =
3315        mCodec->findBufferByID(kPortIndexOutput, bufferID, &index);
3316    CHECK_EQ((int)info->mStatus, (int)BufferInfo::OWNED_BY_DOWNSTREAM);
3317
3318    android_native_rect_t crop;
3319    if (msg->findRect("crop",
3320            &crop.left, &crop.top, &crop.right, &crop.bottom)) {
3321        CHECK_EQ(0, native_window_set_crop(
3322                mCodec->mNativeWindow.get(), &crop));
3323    }
3324
3325    int32_t render;
3326    if (mCodec->mNativeWindow != NULL
3327            && msg->findInt32("render", &render) && render != 0
3328            && (info->mData == NULL || info->mData->size() != 0)) {
3329        // The client wants this buffer to be rendered.
3330
3331        status_t err;
3332        if ((err = mCodec->mNativeWindow->queueBuffer(
3333                    mCodec->mNativeWindow.get(),
3334                    info->mGraphicBuffer.get(), -1)) == OK) {
3335            info->mStatus = BufferInfo::OWNED_BY_NATIVE_WINDOW;
3336        } else {
3337            mCodec->signalError(OMX_ErrorUndefined, err);
3338            info->mStatus = BufferInfo::OWNED_BY_US;
3339        }
3340    } else {
3341        info->mStatus = BufferInfo::OWNED_BY_US;
3342    }
3343
3344    PortMode mode = getPortMode(kPortIndexOutput);
3345
3346    switch (mode) {
3347        case KEEP_BUFFERS:
3348        {
3349            // XXX fishy, revisit!!! What about the FREE_BUFFERS case below?
3350
3351            if (info->mStatus == BufferInfo::OWNED_BY_NATIVE_WINDOW) {
3352                // We cannot resubmit the buffer we just rendered, dequeue
3353                // the spare instead.
3354
3355                info = mCodec->dequeueBufferFromNativeWindow();
3356            }
3357            break;
3358        }
3359
3360        case RESUBMIT_BUFFERS:
3361        {
3362            if (!mCodec->mPortEOS[kPortIndexOutput]) {
3363                if (info->mStatus == BufferInfo::OWNED_BY_NATIVE_WINDOW) {
3364                    // We cannot resubmit the buffer we just rendered, dequeue
3365                    // the spare instead.
3366
3367                    info = mCodec->dequeueBufferFromNativeWindow();
3368                }
3369
3370                if (info != NULL) {
3371                    ALOGV("[%s] calling fillBuffer %p",
3372                         mCodec->mComponentName.c_str(), info->mBufferID);
3373
3374                    CHECK_EQ(mCodec->mOMX->fillBuffer(mCodec->mNode, info->mBufferID),
3375                             (status_t)OK);
3376
3377                    info->mStatus = BufferInfo::OWNED_BY_COMPONENT;
3378                }
3379            }
3380            break;
3381        }
3382
3383        default:
3384        {
3385            CHECK_EQ((int)mode, (int)FREE_BUFFERS);
3386
3387            CHECK_EQ((status_t)OK,
3388                     mCodec->freeBuffer(kPortIndexOutput, index));
3389            break;
3390        }
3391    }
3392}
3393
3394////////////////////////////////////////////////////////////////////////////////
3395
3396ACodec::UninitializedState::UninitializedState(ACodec *codec)
3397    : BaseState(codec) {
3398}
3399
3400void ACodec::UninitializedState::stateEntered() {
3401    ALOGV("Now uninitialized");
3402
3403    if (mDeathNotifier != NULL) {
3404        mCodec->mOMX->asBinder()->unlinkToDeath(mDeathNotifier);
3405        mDeathNotifier.clear();
3406    }
3407
3408    mCodec->mNativeWindow.clear();
3409    mCodec->mNode = NULL;
3410    mCodec->mOMX.clear();
3411    mCodec->mQuirks = 0;
3412    mCodec->mFlags = 0;
3413    mCodec->mUseMetadataOnEncoderOutput = 0;
3414    mCodec->mComponentName.clear();
3415}
3416
3417bool ACodec::UninitializedState::onMessageReceived(const sp<AMessage> &msg) {
3418    bool handled = false;
3419
3420    switch (msg->what()) {
3421        case ACodec::kWhatSetup:
3422        {
3423            onSetup(msg);
3424
3425            handled = true;
3426            break;
3427        }
3428
3429        case ACodec::kWhatAllocateComponent:
3430        {
3431            onAllocateComponent(msg);
3432            handled = true;
3433            break;
3434        }
3435
3436        case ACodec::kWhatShutdown:
3437        {
3438            int32_t keepComponentAllocated;
3439            CHECK(msg->findInt32(
3440                        "keepComponentAllocated", &keepComponentAllocated));
3441            CHECK(!keepComponentAllocated);
3442
3443            sp<AMessage> notify = mCodec->mNotify->dup();
3444            notify->setInt32("what", ACodec::kWhatShutdownCompleted);
3445            notify->post();
3446
3447            handled = true;
3448            break;
3449        }
3450
3451        case ACodec::kWhatFlush:
3452        {
3453            sp<AMessage> notify = mCodec->mNotify->dup();
3454            notify->setInt32("what", ACodec::kWhatFlushCompleted);
3455            notify->post();
3456
3457            handled = true;
3458            break;
3459        }
3460
3461        default:
3462            return BaseState::onMessageReceived(msg);
3463    }
3464
3465    return handled;
3466}
3467
3468void ACodec::UninitializedState::onSetup(
3469        const sp<AMessage> &msg) {
3470    if (onAllocateComponent(msg)
3471            && mCodec->mLoadedState->onConfigureComponent(msg)) {
3472        mCodec->mLoadedState->onStart();
3473    }
3474}
3475
3476bool ACodec::UninitializedState::onAllocateComponent(const sp<AMessage> &msg) {
3477    ALOGV("onAllocateComponent");
3478
3479    CHECK(mCodec->mNode == NULL);
3480
3481    OMXClient client;
3482    CHECK_EQ(client.connect(), (status_t)OK);
3483
3484    sp<IOMX> omx = client.interface();
3485
3486    sp<AMessage> notify = new AMessage(kWhatOMXDied, mCodec->id());
3487
3488    mDeathNotifier = new DeathNotifier(notify);
3489    if (omx->asBinder()->linkToDeath(mDeathNotifier) != OK) {
3490        // This was a local binder, if it dies so do we, we won't care
3491        // about any notifications in the afterlife.
3492        mDeathNotifier.clear();
3493    }
3494
3495    Vector<OMXCodec::CodecNameAndQuirks> matchingCodecs;
3496
3497    AString mime;
3498
3499    AString componentName;
3500    uint32_t quirks = 0;
3501    if (msg->findString("componentName", &componentName)) {
3502        ssize_t index = matchingCodecs.add();
3503        OMXCodec::CodecNameAndQuirks *entry = &matchingCodecs.editItemAt(index);
3504        entry->mName = String8(componentName.c_str());
3505
3506        if (!OMXCodec::findCodecQuirks(
3507                    componentName.c_str(), &entry->mQuirks)) {
3508            entry->mQuirks = 0;
3509        }
3510    } else {
3511        CHECK(msg->findString("mime", &mime));
3512
3513        int32_t encoder;
3514        if (!msg->findInt32("encoder", &encoder)) {
3515            encoder = false;
3516        }
3517
3518        OMXCodec::findMatchingCodecs(
3519                mime.c_str(),
3520                encoder, // createEncoder
3521                NULL,  // matchComponentName
3522                0,     // flags
3523                &matchingCodecs);
3524    }
3525
3526    sp<CodecObserver> observer = new CodecObserver;
3527    IOMX::node_id node = NULL;
3528
3529    for (size_t matchIndex = 0; matchIndex < matchingCodecs.size();
3530            ++matchIndex) {
3531        componentName = matchingCodecs.itemAt(matchIndex).mName.string();
3532        quirks = matchingCodecs.itemAt(matchIndex).mQuirks;
3533
3534        pid_t tid = androidGetTid();
3535        int prevPriority = androidGetThreadPriority(tid);
3536        androidSetThreadPriority(tid, ANDROID_PRIORITY_FOREGROUND);
3537        status_t err = omx->allocateNode(componentName.c_str(), observer, &node);
3538        androidSetThreadPriority(tid, prevPriority);
3539
3540        if (err == OK) {
3541            break;
3542        }
3543
3544        node = NULL;
3545    }
3546
3547    if (node == NULL) {
3548        if (!mime.empty()) {
3549            ALOGE("Unable to instantiate a decoder for type '%s'.",
3550                 mime.c_str());
3551        } else {
3552            ALOGE("Unable to instantiate decoder '%s'.", componentName.c_str());
3553        }
3554
3555        mCodec->signalError(OMX_ErrorComponentNotFound);
3556        return false;
3557    }
3558
3559    notify = new AMessage(kWhatOMXMessage, mCodec->id());
3560    observer->setNotificationMessage(notify);
3561
3562    mCodec->mComponentName = componentName;
3563    mCodec->mFlags = 0;
3564
3565    if (componentName.endsWith(".secure")) {
3566        mCodec->mFlags |= kFlagIsSecure;
3567    }
3568
3569    mCodec->mQuirks = quirks;
3570    mCodec->mOMX = omx;
3571    mCodec->mNode = node;
3572
3573    {
3574        sp<AMessage> notify = mCodec->mNotify->dup();
3575        notify->setInt32("what", ACodec::kWhatComponentAllocated);
3576        notify->setString("componentName", mCodec->mComponentName.c_str());
3577        notify->post();
3578    }
3579
3580    mCodec->changeState(mCodec->mLoadedState);
3581
3582    return true;
3583}
3584
3585////////////////////////////////////////////////////////////////////////////////
3586
3587ACodec::LoadedState::LoadedState(ACodec *codec)
3588    : BaseState(codec) {
3589}
3590
3591void ACodec::LoadedState::stateEntered() {
3592    ALOGV("[%s] Now Loaded", mCodec->mComponentName.c_str());
3593
3594    mCodec->mPortEOS[kPortIndexInput] =
3595        mCodec->mPortEOS[kPortIndexOutput] = false;
3596
3597    mCodec->mInputEOSResult = OK;
3598
3599    mCodec->mDequeueCounter = 0;
3600    mCodec->mMetaDataBuffersToSubmit = 0;
3601
3602    if (mCodec->mShutdownInProgress) {
3603        bool keepComponentAllocated = mCodec->mKeepComponentAllocated;
3604
3605        mCodec->mShutdownInProgress = false;
3606        mCodec->mKeepComponentAllocated = false;
3607
3608        onShutdown(keepComponentAllocated);
3609    }
3610}
3611
3612void ACodec::LoadedState::onShutdown(bool keepComponentAllocated) {
3613    if (!keepComponentAllocated) {
3614        CHECK_EQ(mCodec->mOMX->freeNode(mCodec->mNode), (status_t)OK);
3615
3616        mCodec->changeState(mCodec->mUninitializedState);
3617    }
3618
3619    sp<AMessage> notify = mCodec->mNotify->dup();
3620    notify->setInt32("what", ACodec::kWhatShutdownCompleted);
3621    notify->post();
3622}
3623
3624bool ACodec::LoadedState::onMessageReceived(const sp<AMessage> &msg) {
3625    bool handled = false;
3626
3627    switch (msg->what()) {
3628        case ACodec::kWhatConfigureComponent:
3629        {
3630            onConfigureComponent(msg);
3631            handled = true;
3632            break;
3633        }
3634
3635        case ACodec::kWhatCreateInputSurface:
3636        {
3637            onCreateInputSurface(msg);
3638            handled = true;
3639            break;
3640        }
3641
3642        case ACodec::kWhatStart:
3643        {
3644            onStart();
3645            handled = true;
3646            break;
3647        }
3648
3649        case ACodec::kWhatShutdown:
3650        {
3651            int32_t keepComponentAllocated;
3652            CHECK(msg->findInt32(
3653                        "keepComponentAllocated", &keepComponentAllocated));
3654
3655            onShutdown(keepComponentAllocated);
3656
3657            handled = true;
3658            break;
3659        }
3660
3661        case ACodec::kWhatFlush:
3662        {
3663            sp<AMessage> notify = mCodec->mNotify->dup();
3664            notify->setInt32("what", ACodec::kWhatFlushCompleted);
3665            notify->post();
3666
3667            handled = true;
3668            break;
3669        }
3670
3671        default:
3672            return BaseState::onMessageReceived(msg);
3673    }
3674
3675    return handled;
3676}
3677
3678bool ACodec::LoadedState::onConfigureComponent(
3679        const sp<AMessage> &msg) {
3680    ALOGV("onConfigureComponent");
3681
3682    CHECK(mCodec->mNode != NULL);
3683
3684    AString mime;
3685    CHECK(msg->findString("mime", &mime));
3686
3687    status_t err = mCodec->configureCodec(mime.c_str(), msg);
3688
3689    if (err != OK) {
3690        ALOGE("[%s] configureCodec returning error %d",
3691              mCodec->mComponentName.c_str(), err);
3692
3693        mCodec->signalError(OMX_ErrorUndefined, err);
3694        return false;
3695    }
3696
3697    sp<RefBase> obj;
3698    if (msg->findObject("native-window", &obj)
3699            && strncmp("OMX.google.", mCodec->mComponentName.c_str(), 11)) {
3700        sp<NativeWindowWrapper> nativeWindow(
3701                static_cast<NativeWindowWrapper *>(obj.get()));
3702        CHECK(nativeWindow != NULL);
3703        mCodec->mNativeWindow = nativeWindow->getNativeWindow();
3704
3705        native_window_set_scaling_mode(
3706                mCodec->mNativeWindow.get(),
3707                NATIVE_WINDOW_SCALING_MODE_SCALE_TO_WINDOW);
3708    }
3709    CHECK_EQ((status_t)OK, mCodec->initNativeWindow());
3710
3711    {
3712        sp<AMessage> notify = mCodec->mNotify->dup();
3713        notify->setInt32("what", ACodec::kWhatComponentConfigured);
3714        notify->post();
3715    }
3716
3717    return true;
3718}
3719
3720void ACodec::LoadedState::onCreateInputSurface(
3721        const sp<AMessage> &msg) {
3722    ALOGV("onCreateInputSurface");
3723
3724    sp<AMessage> notify = mCodec->mNotify->dup();
3725    notify->setInt32("what", ACodec::kWhatInputSurfaceCreated);
3726
3727    sp<IGraphicBufferProducer> bufferProducer;
3728    status_t err;
3729
3730    err = mCodec->mOMX->createInputSurface(mCodec->mNode, kPortIndexInput,
3731            &bufferProducer);
3732    if (err == OK) {
3733        notify->setObject("input-surface",
3734                new BufferProducerWrapper(bufferProducer));
3735    } else {
3736        // Can't use mCodec->signalError() here -- MediaCodec won't forward
3737        // the error through because it's in the "configured" state.  We
3738        // send a kWhatInputSurfaceCreated with an error value instead.
3739        ALOGE("[%s] onCreateInputSurface returning error %d",
3740                mCodec->mComponentName.c_str(), err);
3741        notify->setInt32("err", err);
3742    }
3743    notify->post();
3744}
3745
3746void ACodec::LoadedState::onStart() {
3747    ALOGV("onStart");
3748
3749    CHECK_EQ(mCodec->mOMX->sendCommand(
3750                mCodec->mNode, OMX_CommandStateSet, OMX_StateIdle),
3751             (status_t)OK);
3752
3753    mCodec->changeState(mCodec->mLoadedToIdleState);
3754}
3755
3756////////////////////////////////////////////////////////////////////////////////
3757
3758ACodec::LoadedToIdleState::LoadedToIdleState(ACodec *codec)
3759    : BaseState(codec) {
3760}
3761
3762void ACodec::LoadedToIdleState::stateEntered() {
3763    ALOGV("[%s] Now Loaded->Idle", mCodec->mComponentName.c_str());
3764
3765    status_t err;
3766    if ((err = allocateBuffers()) != OK) {
3767        ALOGE("Failed to allocate buffers after transitioning to IDLE state "
3768             "(error 0x%08x)",
3769             err);
3770
3771        mCodec->signalError(OMX_ErrorUndefined, err);
3772
3773        mCodec->changeState(mCodec->mLoadedState);
3774    }
3775}
3776
3777status_t ACodec::LoadedToIdleState::allocateBuffers() {
3778    status_t err = mCodec->allocateBuffersOnPort(kPortIndexInput);
3779
3780    if (err != OK) {
3781        return err;
3782    }
3783
3784    return mCodec->allocateBuffersOnPort(kPortIndexOutput);
3785}
3786
3787bool ACodec::LoadedToIdleState::onMessageReceived(const sp<AMessage> &msg) {
3788    switch (msg->what()) {
3789        case kWhatShutdown:
3790        {
3791            mCodec->deferMessage(msg);
3792            return true;
3793        }
3794
3795        case kWhatSignalEndOfInputStream:
3796        {
3797            mCodec->onSignalEndOfInputStream();
3798            return true;
3799        }
3800
3801        case kWhatResume:
3802        {
3803            // We'll be active soon enough.
3804            return true;
3805        }
3806
3807        case kWhatFlush:
3808        {
3809            // We haven't even started yet, so we're flushed alright...
3810            sp<AMessage> notify = mCodec->mNotify->dup();
3811            notify->setInt32("what", ACodec::kWhatFlushCompleted);
3812            notify->post();
3813            return true;
3814        }
3815
3816        default:
3817            return BaseState::onMessageReceived(msg);
3818    }
3819}
3820
3821bool ACodec::LoadedToIdleState::onOMXEvent(
3822        OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2) {
3823    switch (event) {
3824        case OMX_EventCmdComplete:
3825        {
3826            CHECK_EQ(data1, (OMX_U32)OMX_CommandStateSet);
3827            CHECK_EQ(data2, (OMX_U32)OMX_StateIdle);
3828
3829            CHECK_EQ(mCodec->mOMX->sendCommand(
3830                        mCodec->mNode, OMX_CommandStateSet, OMX_StateExecuting),
3831                     (status_t)OK);
3832
3833            mCodec->changeState(mCodec->mIdleToExecutingState);
3834
3835            return true;
3836        }
3837
3838        default:
3839            return BaseState::onOMXEvent(event, data1, data2);
3840    }
3841}
3842
3843////////////////////////////////////////////////////////////////////////////////
3844
3845ACodec::IdleToExecutingState::IdleToExecutingState(ACodec *codec)
3846    : BaseState(codec) {
3847}
3848
3849void ACodec::IdleToExecutingState::stateEntered() {
3850    ALOGV("[%s] Now Idle->Executing", mCodec->mComponentName.c_str());
3851}
3852
3853bool ACodec::IdleToExecutingState::onMessageReceived(const sp<AMessage> &msg) {
3854    switch (msg->what()) {
3855        case kWhatShutdown:
3856        {
3857            mCodec->deferMessage(msg);
3858            return true;
3859        }
3860
3861        case kWhatResume:
3862        {
3863            // We'll be active soon enough.
3864            return true;
3865        }
3866
3867        case kWhatFlush:
3868        {
3869            // We haven't even started yet, so we're flushed alright...
3870            sp<AMessage> notify = mCodec->mNotify->dup();
3871            notify->setInt32("what", ACodec::kWhatFlushCompleted);
3872            notify->post();
3873
3874            return true;
3875        }
3876
3877        case kWhatSignalEndOfInputStream:
3878        {
3879            mCodec->onSignalEndOfInputStream();
3880            return true;
3881        }
3882
3883        default:
3884            return BaseState::onMessageReceived(msg);
3885    }
3886}
3887
3888bool ACodec::IdleToExecutingState::onOMXEvent(
3889        OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2) {
3890    switch (event) {
3891        case OMX_EventCmdComplete:
3892        {
3893            CHECK_EQ(data1, (OMX_U32)OMX_CommandStateSet);
3894            CHECK_EQ(data2, (OMX_U32)OMX_StateExecuting);
3895
3896            mCodec->mExecutingState->resume();
3897            mCodec->changeState(mCodec->mExecutingState);
3898
3899            return true;
3900        }
3901
3902        default:
3903            return BaseState::onOMXEvent(event, data1, data2);
3904    }
3905}
3906
3907////////////////////////////////////////////////////////////////////////////////
3908
3909ACodec::ExecutingState::ExecutingState(ACodec *codec)
3910    : BaseState(codec),
3911      mActive(false) {
3912}
3913
3914ACodec::BaseState::PortMode ACodec::ExecutingState::getPortMode(
3915        OMX_U32 portIndex) {
3916    return RESUBMIT_BUFFERS;
3917}
3918
3919void ACodec::ExecutingState::submitOutputMetaBuffers() {
3920    // submit as many buffers as there are input buffers with the codec
3921    // in case we are in port reconfiguring
3922    for (size_t i = 0; i < mCodec->mBuffers[kPortIndexInput].size(); ++i) {
3923        BufferInfo *info = &mCodec->mBuffers[kPortIndexInput].editItemAt(i);
3924
3925        if (info->mStatus == BufferInfo::OWNED_BY_COMPONENT) {
3926            if (mCodec->submitOutputMetaDataBuffer() != OK)
3927                break;
3928        }
3929    }
3930}
3931
3932void ACodec::ExecutingState::submitRegularOutputBuffers() {
3933    for (size_t i = 0; i < mCodec->mBuffers[kPortIndexOutput].size(); ++i) {
3934        BufferInfo *info = &mCodec->mBuffers[kPortIndexOutput].editItemAt(i);
3935
3936        if (mCodec->mNativeWindow != NULL) {
3937            CHECK(info->mStatus == BufferInfo::OWNED_BY_US
3938                    || info->mStatus == BufferInfo::OWNED_BY_NATIVE_WINDOW);
3939
3940            if (info->mStatus == BufferInfo::OWNED_BY_NATIVE_WINDOW) {
3941                continue;
3942            }
3943        } else {
3944            CHECK_EQ((int)info->mStatus, (int)BufferInfo::OWNED_BY_US);
3945        }
3946
3947        ALOGV("[%s] calling fillBuffer %p",
3948             mCodec->mComponentName.c_str(), info->mBufferID);
3949
3950        CHECK_EQ(mCodec->mOMX->fillBuffer(mCodec->mNode, info->mBufferID),
3951                 (status_t)OK);
3952
3953        info->mStatus = BufferInfo::OWNED_BY_COMPONENT;
3954    }
3955}
3956
3957void ACodec::ExecutingState::submitOutputBuffers() {
3958    if (mCodec->mStoreMetaDataInOutputBuffers) {
3959        submitOutputMetaBuffers();
3960    } else {
3961        submitRegularOutputBuffers();
3962    }
3963}
3964
3965void ACodec::ExecutingState::resume() {
3966    if (mActive) {
3967        ALOGV("[%s] We're already active, no need to resume.",
3968             mCodec->mComponentName.c_str());
3969
3970        return;
3971    }
3972
3973    submitOutputBuffers();
3974
3975    // Post the first input buffer.
3976    CHECK_GT(mCodec->mBuffers[kPortIndexInput].size(), 0u);
3977    BufferInfo *info = &mCodec->mBuffers[kPortIndexInput].editItemAt(0);
3978
3979    postFillThisBuffer(info);
3980
3981    mActive = true;
3982}
3983
3984void ACodec::ExecutingState::stateEntered() {
3985    ALOGV("[%s] Now Executing", mCodec->mComponentName.c_str());
3986
3987    mCodec->processDeferredMessages();
3988}
3989
3990bool ACodec::ExecutingState::onMessageReceived(const sp<AMessage> &msg) {
3991    bool handled = false;
3992
3993    switch (msg->what()) {
3994        case kWhatShutdown:
3995        {
3996            int32_t keepComponentAllocated;
3997            CHECK(msg->findInt32(
3998                        "keepComponentAllocated", &keepComponentAllocated));
3999
4000            mCodec->mShutdownInProgress = true;
4001            mCodec->mKeepComponentAllocated = keepComponentAllocated;
4002
4003            mActive = false;
4004
4005            CHECK_EQ(mCodec->mOMX->sendCommand(
4006                        mCodec->mNode, OMX_CommandStateSet, OMX_StateIdle),
4007                     (status_t)OK);
4008
4009            mCodec->changeState(mCodec->mExecutingToIdleState);
4010
4011            handled = true;
4012            break;
4013        }
4014
4015        case kWhatFlush:
4016        {
4017            ALOGV("[%s] ExecutingState flushing now "
4018                 "(codec owns %d/%d input, %d/%d output).",
4019                    mCodec->mComponentName.c_str(),
4020                    mCodec->countBuffersOwnedByComponent(kPortIndexInput),
4021                    mCodec->mBuffers[kPortIndexInput].size(),
4022                    mCodec->countBuffersOwnedByComponent(kPortIndexOutput),
4023                    mCodec->mBuffers[kPortIndexOutput].size());
4024
4025            mActive = false;
4026
4027            CHECK_EQ(mCodec->mOMX->sendCommand(
4028                        mCodec->mNode, OMX_CommandFlush, OMX_ALL),
4029                     (status_t)OK);
4030
4031            mCodec->changeState(mCodec->mFlushingState);
4032            handled = true;
4033            break;
4034        }
4035
4036        case kWhatResume:
4037        {
4038            resume();
4039
4040            handled = true;
4041            break;
4042        }
4043
4044        case kWhatRequestIDRFrame:
4045        {
4046            status_t err = mCodec->requestIDRFrame();
4047            if (err != OK) {
4048                ALOGW("Requesting an IDR frame failed.");
4049            }
4050
4051            handled = true;
4052            break;
4053        }
4054
4055        case kWhatSetParameters:
4056        {
4057            sp<AMessage> params;
4058            CHECK(msg->findMessage("params", &params));
4059
4060            status_t err = mCodec->setParameters(params);
4061
4062            sp<AMessage> reply;
4063            if (msg->findMessage("reply", &reply)) {
4064                reply->setInt32("err", err);
4065                reply->post();
4066            }
4067
4068            handled = true;
4069            break;
4070        }
4071
4072        case ACodec::kWhatSignalEndOfInputStream:
4073        {
4074            mCodec->onSignalEndOfInputStream();
4075            handled = true;
4076            break;
4077        }
4078
4079        default:
4080            handled = BaseState::onMessageReceived(msg);
4081            break;
4082    }
4083
4084    return handled;
4085}
4086
4087status_t ACodec::setParameters(const sp<AMessage> &params) {
4088    int32_t videoBitrate;
4089    if (params->findInt32("videoBitrate", &videoBitrate)) {
4090        OMX_VIDEO_CONFIG_BITRATETYPE configParams;
4091        InitOMXParams(&configParams);
4092        configParams.nPortIndex = kPortIndexOutput;
4093        configParams.nEncodeBitrate = videoBitrate;
4094
4095        status_t err = mOMX->setConfig(
4096                mNode,
4097                OMX_IndexConfigVideoBitrate,
4098                &configParams,
4099                sizeof(configParams));
4100
4101        if (err != OK) {
4102            ALOGE("setConfig(OMX_IndexConfigVideoBitrate, %d) failed w/ err %d",
4103                   videoBitrate, err);
4104
4105            return err;
4106        }
4107    }
4108
4109    int32_t dropInputFrames;
4110    if (params->findInt32("drop-input-frames", &dropInputFrames)) {
4111        bool suspend = dropInputFrames != 0;
4112
4113        CHECK_EQ((status_t)OK,
4114                 mOMX->setInternalOption(
4115                     mNode,
4116                     kPortIndexInput,
4117                     IOMX::INTERNAL_OPTION_SUSPEND,
4118                     &suspend,
4119                     sizeof(suspend)));
4120    }
4121
4122    return OK;
4123}
4124
4125void ACodec::onSignalEndOfInputStream() {
4126    sp<AMessage> notify = mNotify->dup();
4127    notify->setInt32("what", ACodec::kWhatSignaledInputEOS);
4128
4129    status_t err = mOMX->signalEndOfInputStream(mNode);
4130    if (err != OK) {
4131        notify->setInt32("err", err);
4132    }
4133    notify->post();
4134}
4135
4136bool ACodec::ExecutingState::onOMXEvent(
4137        OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2) {
4138    switch (event) {
4139        case OMX_EventPortSettingsChanged:
4140        {
4141            CHECK_EQ(data1, (OMX_U32)kPortIndexOutput);
4142
4143            if (data2 == 0 || data2 == OMX_IndexParamPortDefinition) {
4144                mCodec->mMetaDataBuffersToSubmit = 0;
4145                CHECK_EQ(mCodec->mOMX->sendCommand(
4146                            mCodec->mNode,
4147                            OMX_CommandPortDisable, kPortIndexOutput),
4148                         (status_t)OK);
4149
4150                mCodec->freeOutputBuffersNotOwnedByComponent();
4151
4152                mCodec->changeState(mCodec->mOutputPortSettingsChangedState);
4153            } else if (data2 == OMX_IndexConfigCommonOutputCrop) {
4154                mCodec->mSentFormat = false;
4155            } else {
4156                ALOGV("[%s] OMX_EventPortSettingsChanged 0x%08lx",
4157                     mCodec->mComponentName.c_str(), data2);
4158            }
4159
4160            return true;
4161        }
4162
4163        case OMX_EventBufferFlag:
4164        {
4165            return true;
4166        }
4167
4168        default:
4169            return BaseState::onOMXEvent(event, data1, data2);
4170    }
4171}
4172
4173////////////////////////////////////////////////////////////////////////////////
4174
4175ACodec::OutputPortSettingsChangedState::OutputPortSettingsChangedState(
4176        ACodec *codec)
4177    : BaseState(codec) {
4178}
4179
4180ACodec::BaseState::PortMode ACodec::OutputPortSettingsChangedState::getPortMode(
4181        OMX_U32 portIndex) {
4182    if (portIndex == kPortIndexOutput) {
4183        return FREE_BUFFERS;
4184    }
4185
4186    CHECK_EQ(portIndex, (OMX_U32)kPortIndexInput);
4187
4188    return RESUBMIT_BUFFERS;
4189}
4190
4191bool ACodec::OutputPortSettingsChangedState::onMessageReceived(
4192        const sp<AMessage> &msg) {
4193    bool handled = false;
4194
4195    switch (msg->what()) {
4196        case kWhatFlush:
4197        case kWhatShutdown:
4198        case kWhatResume:
4199        {
4200            if (msg->what() == kWhatResume) {
4201                ALOGV("[%s] Deferring resume", mCodec->mComponentName.c_str());
4202            }
4203
4204            mCodec->deferMessage(msg);
4205            handled = true;
4206            break;
4207        }
4208
4209        default:
4210            handled = BaseState::onMessageReceived(msg);
4211            break;
4212    }
4213
4214    return handled;
4215}
4216
4217void ACodec::OutputPortSettingsChangedState::stateEntered() {
4218    ALOGV("[%s] Now handling output port settings change",
4219         mCodec->mComponentName.c_str());
4220}
4221
4222bool ACodec::OutputPortSettingsChangedState::onOMXEvent(
4223        OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2) {
4224    switch (event) {
4225        case OMX_EventCmdComplete:
4226        {
4227            if (data1 == (OMX_U32)OMX_CommandPortDisable) {
4228                CHECK_EQ(data2, (OMX_U32)kPortIndexOutput);
4229
4230                ALOGV("[%s] Output port now disabled.",
4231                        mCodec->mComponentName.c_str());
4232
4233                CHECK(mCodec->mBuffers[kPortIndexOutput].isEmpty());
4234                mCodec->mDealer[kPortIndexOutput].clear();
4235
4236                CHECK_EQ(mCodec->mOMX->sendCommand(
4237                            mCodec->mNode, OMX_CommandPortEnable, kPortIndexOutput),
4238                         (status_t)OK);
4239
4240                status_t err;
4241                if ((err = mCodec->allocateBuffersOnPort(
4242                                kPortIndexOutput)) != OK) {
4243                    ALOGE("Failed to allocate output port buffers after "
4244                         "port reconfiguration (error 0x%08x)",
4245                         err);
4246
4247                    mCodec->signalError(OMX_ErrorUndefined, err);
4248
4249                    // This is technically not correct, but appears to be
4250                    // the only way to free the component instance.
4251                    // Controlled transitioning from excecuting->idle
4252                    // and idle->loaded seem impossible probably because
4253                    // the output port never finishes re-enabling.
4254                    mCodec->mShutdownInProgress = true;
4255                    mCodec->mKeepComponentAllocated = false;
4256                    mCodec->changeState(mCodec->mLoadedState);
4257                }
4258
4259                return true;
4260            } else if (data1 == (OMX_U32)OMX_CommandPortEnable) {
4261                CHECK_EQ(data2, (OMX_U32)kPortIndexOutput);
4262
4263                mCodec->mSentFormat = false;
4264
4265                ALOGV("[%s] Output port now reenabled.",
4266                        mCodec->mComponentName.c_str());
4267
4268                if (mCodec->mExecutingState->active()) {
4269                    mCodec->mExecutingState->submitOutputBuffers();
4270                }
4271
4272                mCodec->changeState(mCodec->mExecutingState);
4273
4274                return true;
4275            }
4276
4277            return false;
4278        }
4279
4280        default:
4281            return false;
4282    }
4283}
4284
4285////////////////////////////////////////////////////////////////////////////////
4286
4287ACodec::ExecutingToIdleState::ExecutingToIdleState(ACodec *codec)
4288    : BaseState(codec),
4289      mComponentNowIdle(false) {
4290}
4291
4292bool ACodec::ExecutingToIdleState::onMessageReceived(const sp<AMessage> &msg) {
4293    bool handled = false;
4294
4295    switch (msg->what()) {
4296        case kWhatFlush:
4297        {
4298            // Don't send me a flush request if you previously wanted me
4299            // to shutdown.
4300            TRESPASS();
4301            break;
4302        }
4303
4304        case kWhatShutdown:
4305        {
4306            // We're already doing that...
4307
4308            handled = true;
4309            break;
4310        }
4311
4312        default:
4313            handled = BaseState::onMessageReceived(msg);
4314            break;
4315    }
4316
4317    return handled;
4318}
4319
4320void ACodec::ExecutingToIdleState::stateEntered() {
4321    ALOGV("[%s] Now Executing->Idle", mCodec->mComponentName.c_str());
4322
4323    mComponentNowIdle = false;
4324    mCodec->mSentFormat = false;
4325}
4326
4327bool ACodec::ExecutingToIdleState::onOMXEvent(
4328        OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2) {
4329    switch (event) {
4330        case OMX_EventCmdComplete:
4331        {
4332            CHECK_EQ(data1, (OMX_U32)OMX_CommandStateSet);
4333            CHECK_EQ(data2, (OMX_U32)OMX_StateIdle);
4334
4335            mComponentNowIdle = true;
4336
4337            changeStateIfWeOwnAllBuffers();
4338
4339            return true;
4340        }
4341
4342        case OMX_EventPortSettingsChanged:
4343        case OMX_EventBufferFlag:
4344        {
4345            // We're shutting down and don't care about this anymore.
4346            return true;
4347        }
4348
4349        default:
4350            return BaseState::onOMXEvent(event, data1, data2);
4351    }
4352}
4353
4354void ACodec::ExecutingToIdleState::changeStateIfWeOwnAllBuffers() {
4355    if (mComponentNowIdle && mCodec->allYourBuffersAreBelongToUs()) {
4356        CHECK_EQ(mCodec->mOMX->sendCommand(
4357                    mCodec->mNode, OMX_CommandStateSet, OMX_StateLoaded),
4358                 (status_t)OK);
4359
4360        CHECK_EQ(mCodec->freeBuffersOnPort(kPortIndexInput), (status_t)OK);
4361        CHECK_EQ(mCodec->freeBuffersOnPort(kPortIndexOutput), (status_t)OK);
4362
4363        if (mCodec->mFlags & kFlagIsSecure && mCodec->mNativeWindow != NULL) {
4364            // We push enough 1x1 blank buffers to ensure that one of
4365            // them has made it to the display.  This allows the OMX
4366            // component teardown to zero out any protected buffers
4367            // without the risk of scanning out one of those buffers.
4368            mCodec->pushBlankBuffersToNativeWindow();
4369        }
4370
4371        mCodec->changeState(mCodec->mIdleToLoadedState);
4372    }
4373}
4374
4375void ACodec::ExecutingToIdleState::onInputBufferFilled(
4376        const sp<AMessage> &msg) {
4377    BaseState::onInputBufferFilled(msg);
4378
4379    changeStateIfWeOwnAllBuffers();
4380}
4381
4382void ACodec::ExecutingToIdleState::onOutputBufferDrained(
4383        const sp<AMessage> &msg) {
4384    BaseState::onOutputBufferDrained(msg);
4385
4386    changeStateIfWeOwnAllBuffers();
4387}
4388
4389////////////////////////////////////////////////////////////////////////////////
4390
4391ACodec::IdleToLoadedState::IdleToLoadedState(ACodec *codec)
4392    : BaseState(codec) {
4393}
4394
4395bool ACodec::IdleToLoadedState::onMessageReceived(const sp<AMessage> &msg) {
4396    bool handled = false;
4397
4398    switch (msg->what()) {
4399        case kWhatShutdown:
4400        {
4401            // We're already doing that...
4402
4403            handled = true;
4404            break;
4405        }
4406
4407        case kWhatFlush:
4408        {
4409            // Don't send me a flush request if you previously wanted me
4410            // to shutdown.
4411            TRESPASS();
4412            break;
4413        }
4414
4415        default:
4416            handled = BaseState::onMessageReceived(msg);
4417            break;
4418    }
4419
4420    return handled;
4421}
4422
4423void ACodec::IdleToLoadedState::stateEntered() {
4424    ALOGV("[%s] Now Idle->Loaded", mCodec->mComponentName.c_str());
4425}
4426
4427bool ACodec::IdleToLoadedState::onOMXEvent(
4428        OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2) {
4429    switch (event) {
4430        case OMX_EventCmdComplete:
4431        {
4432            CHECK_EQ(data1, (OMX_U32)OMX_CommandStateSet);
4433            CHECK_EQ(data2, (OMX_U32)OMX_StateLoaded);
4434
4435            mCodec->changeState(mCodec->mLoadedState);
4436
4437            return true;
4438        }
4439
4440        default:
4441            return BaseState::onOMXEvent(event, data1, data2);
4442    }
4443}
4444
4445////////////////////////////////////////////////////////////////////////////////
4446
4447ACodec::FlushingState::FlushingState(ACodec *codec)
4448    : BaseState(codec) {
4449}
4450
4451void ACodec::FlushingState::stateEntered() {
4452    ALOGV("[%s] Now Flushing", mCodec->mComponentName.c_str());
4453
4454    mFlushComplete[kPortIndexInput] = mFlushComplete[kPortIndexOutput] = false;
4455}
4456
4457bool ACodec::FlushingState::onMessageReceived(const sp<AMessage> &msg) {
4458    bool handled = false;
4459
4460    switch (msg->what()) {
4461        case kWhatShutdown:
4462        {
4463            mCodec->deferMessage(msg);
4464            break;
4465        }
4466
4467        case kWhatFlush:
4468        {
4469            // We're already doing this right now.
4470            handled = true;
4471            break;
4472        }
4473
4474        default:
4475            handled = BaseState::onMessageReceived(msg);
4476            break;
4477    }
4478
4479    return handled;
4480}
4481
4482bool ACodec::FlushingState::onOMXEvent(
4483        OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2) {
4484    ALOGV("[%s] FlushingState onOMXEvent(%d,%ld)",
4485            mCodec->mComponentName.c_str(), event, data1);
4486
4487    switch (event) {
4488        case OMX_EventCmdComplete:
4489        {
4490            CHECK_EQ(data1, (OMX_U32)OMX_CommandFlush);
4491
4492            if (data2 == kPortIndexInput || data2 == kPortIndexOutput) {
4493                CHECK(!mFlushComplete[data2]);
4494                mFlushComplete[data2] = true;
4495
4496                if (mFlushComplete[kPortIndexInput]
4497                        && mFlushComplete[kPortIndexOutput]) {
4498                    changeStateIfWeOwnAllBuffers();
4499                }
4500            } else {
4501                CHECK_EQ(data2, OMX_ALL);
4502                CHECK(mFlushComplete[kPortIndexInput]);
4503                CHECK(mFlushComplete[kPortIndexOutput]);
4504
4505                changeStateIfWeOwnAllBuffers();
4506            }
4507
4508            return true;
4509        }
4510
4511        case OMX_EventPortSettingsChanged:
4512        {
4513            sp<AMessage> msg = new AMessage(kWhatOMXMessage, mCodec->id());
4514            msg->setInt32("type", omx_message::EVENT);
4515            msg->setPointer("node", mCodec->mNode);
4516            msg->setInt32("event", event);
4517            msg->setInt32("data1", data1);
4518            msg->setInt32("data2", data2);
4519
4520            ALOGV("[%s] Deferring OMX_EventPortSettingsChanged",
4521                 mCodec->mComponentName.c_str());
4522
4523            mCodec->deferMessage(msg);
4524
4525            return true;
4526        }
4527
4528        default:
4529            return BaseState::onOMXEvent(event, data1, data2);
4530    }
4531
4532    return true;
4533}
4534
4535void ACodec::FlushingState::onOutputBufferDrained(const sp<AMessage> &msg) {
4536    BaseState::onOutputBufferDrained(msg);
4537
4538    changeStateIfWeOwnAllBuffers();
4539}
4540
4541void ACodec::FlushingState::onInputBufferFilled(const sp<AMessage> &msg) {
4542    BaseState::onInputBufferFilled(msg);
4543
4544    changeStateIfWeOwnAllBuffers();
4545}
4546
4547void ACodec::FlushingState::changeStateIfWeOwnAllBuffers() {
4548    if (mFlushComplete[kPortIndexInput]
4549            && mFlushComplete[kPortIndexOutput]
4550            && mCodec->allYourBuffersAreBelongToUs()) {
4551        // We now own all buffers except possibly those still queued with
4552        // the native window for rendering. Let's get those back as well.
4553        mCodec->waitUntilAllPossibleNativeWindowBuffersAreReturnedToUs();
4554
4555        sp<AMessage> notify = mCodec->mNotify->dup();
4556        notify->setInt32("what", ACodec::kWhatFlushCompleted);
4557        notify->post();
4558
4559        mCodec->mPortEOS[kPortIndexInput] =
4560            mCodec->mPortEOS[kPortIndexOutput] = false;
4561
4562        mCodec->mInputEOSResult = OK;
4563
4564        if (mCodec->mSkipCutBuffer != NULL) {
4565            mCodec->mSkipCutBuffer->clear();
4566        }
4567
4568        mCodec->changeState(mCodec->mExecutingState);
4569    }
4570}
4571
4572}  // namespace android
4573