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