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