MediaCodec.cpp revision 6b5d15099579c179d8e7531bb5abfb272614513a
1/*
2 * Copyright 2012, 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 "MediaCodec"
19#include <utils/Log.h>
20
21#include <media/stagefright/MediaCodec.h>
22
23#include "include/SoftwareRenderer.h"
24
25#include <gui/Surface.h>
26#include <media/ICrypto.h>
27#include <media/stagefright/foundation/ABuffer.h>
28#include <media/stagefright/foundation/ADebug.h>
29#include <media/stagefright/foundation/AMessage.h>
30#include <media/stagefright/foundation/AString.h>
31#include <media/stagefright/foundation/hexdump.h>
32#include <media/stagefright/ACodec.h>
33#include <media/stagefright/BufferProducerWrapper.h>
34#include <media/stagefright/MediaErrors.h>
35#include <media/stagefright/MetaData.h>
36#include <media/stagefright/NativeWindowWrapper.h>
37
38namespace android {
39
40// static
41sp<MediaCodec> MediaCodec::CreateByType(
42        const sp<ALooper> &looper, const char *mime, bool encoder) {
43    sp<MediaCodec> codec = new MediaCodec(looper);
44    if (codec->init(mime, true /* nameIsType */, encoder) != OK) {
45        return NULL;
46    }
47
48    return codec;
49}
50
51// static
52sp<MediaCodec> MediaCodec::CreateByComponentName(
53        const sp<ALooper> &looper, const char *name) {
54    sp<MediaCodec> codec = new MediaCodec(looper);
55    if (codec->init(name, false /* nameIsType */, false /* encoder */) != OK) {
56        return NULL;
57    }
58
59    return codec;
60}
61
62MediaCodec::MediaCodec(const sp<ALooper> &looper)
63    : mState(UNINITIALIZED),
64      mLooper(looper),
65      mCodec(new ACodec),
66      mReplyID(0),
67      mFlags(0),
68      mSoftRenderer(NULL),
69      mDequeueInputTimeoutGeneration(0),
70      mDequeueInputReplyID(0),
71      mDequeueOutputTimeoutGeneration(0),
72      mDequeueOutputReplyID(0),
73      mHaveInputSurface(false) {
74}
75
76MediaCodec::~MediaCodec() {
77    CHECK_EQ(mState, UNINITIALIZED);
78}
79
80// static
81status_t MediaCodec::PostAndAwaitResponse(
82        const sp<AMessage> &msg, sp<AMessage> *response) {
83    status_t err = msg->postAndAwaitResponse(response);
84
85    if (err != OK) {
86        return err;
87    }
88
89    if (!(*response)->findInt32("err", &err)) {
90        err = OK;
91    }
92
93    return err;
94}
95
96status_t MediaCodec::init(const char *name, bool nameIsType, bool encoder) {
97    // Current video decoders do not return from OMX_FillThisBuffer
98    // quickly, violating the OpenMAX specs, until that is remedied
99    // we need to invest in an extra looper to free the main event
100    // queue.
101    bool needDedicatedLooper = false;
102    if (nameIsType && !strncasecmp(name, "video/", 6)) {
103        needDedicatedLooper = true;
104    } else if (!nameIsType && !strncmp(name, "OMX.TI.DUCATI1.VIDEO.", 21)) {
105        needDedicatedLooper = true;
106    }
107
108    if (needDedicatedLooper) {
109        if (mCodecLooper == NULL) {
110            mCodecLooper = new ALooper;
111            mCodecLooper->setName("CodecLooper");
112            mCodecLooper->start(false, false, ANDROID_PRIORITY_AUDIO);
113        }
114
115        mCodecLooper->registerHandler(mCodec);
116    } else {
117        mLooper->registerHandler(mCodec);
118    }
119
120    mLooper->registerHandler(this);
121
122    mCodec->setNotificationMessage(new AMessage(kWhatCodecNotify, id()));
123
124    sp<AMessage> msg = new AMessage(kWhatInit, id());
125    msg->setString("name", name);
126    msg->setInt32("nameIsType", nameIsType);
127
128    if (nameIsType) {
129        msg->setInt32("encoder", encoder);
130    }
131
132    sp<AMessage> response;
133    return PostAndAwaitResponse(msg, &response);
134}
135
136status_t MediaCodec::configure(
137        const sp<AMessage> &format,
138        const sp<Surface> &nativeWindow,
139        const sp<ICrypto> &crypto,
140        uint32_t flags) {
141    sp<AMessage> msg = new AMessage(kWhatConfigure, id());
142
143    msg->setMessage("format", format);
144    msg->setInt32("flags", flags);
145
146    if (nativeWindow != NULL) {
147        msg->setObject(
148                "native-window",
149                new NativeWindowWrapper(nativeWindow));
150    }
151
152    if (crypto != NULL) {
153        msg->setPointer("crypto", crypto.get());
154    }
155
156    sp<AMessage> response;
157    return PostAndAwaitResponse(msg, &response);
158}
159
160status_t MediaCodec::createInputSurface(
161        sp<IGraphicBufferProducer>* bufferProducer) {
162    sp<AMessage> msg = new AMessage(kWhatCreateInputSurface, id());
163
164    sp<AMessage> response;
165    status_t err = PostAndAwaitResponse(msg, &response);
166    if (err == NO_ERROR) {
167        // unwrap the sp<IGraphicBufferProducer>
168        sp<RefBase> obj;
169        bool found = response->findObject("input-surface", &obj);
170        CHECK(found);
171        sp<BufferProducerWrapper> wrapper(
172                static_cast<BufferProducerWrapper*>(obj.get()));
173        *bufferProducer = wrapper->getBufferProducer();
174    } else {
175        ALOGW("createInputSurface failed, err=%d", err);
176    }
177    return err;
178}
179
180status_t MediaCodec::start() {
181    sp<AMessage> msg = new AMessage(kWhatStart, id());
182
183    sp<AMessage> response;
184    return PostAndAwaitResponse(msg, &response);
185}
186
187status_t MediaCodec::stop() {
188    sp<AMessage> msg = new AMessage(kWhatStop, id());
189
190    sp<AMessage> response;
191    return PostAndAwaitResponse(msg, &response);
192}
193
194status_t MediaCodec::release() {
195    sp<AMessage> msg = new AMessage(kWhatRelease, id());
196
197    sp<AMessage> response;
198    return PostAndAwaitResponse(msg, &response);
199}
200
201status_t MediaCodec::queueInputBuffer(
202        size_t index,
203        size_t offset,
204        size_t size,
205        int64_t presentationTimeUs,
206        uint32_t flags,
207        AString *errorDetailMsg) {
208    if (errorDetailMsg != NULL) {
209        errorDetailMsg->clear();
210    }
211
212    sp<AMessage> msg = new AMessage(kWhatQueueInputBuffer, id());
213    msg->setSize("index", index);
214    msg->setSize("offset", offset);
215    msg->setSize("size", size);
216    msg->setInt64("timeUs", presentationTimeUs);
217    msg->setInt32("flags", flags);
218    msg->setPointer("errorDetailMsg", errorDetailMsg);
219
220    sp<AMessage> response;
221    return PostAndAwaitResponse(msg, &response);
222}
223
224status_t MediaCodec::queueSecureInputBuffer(
225        size_t index,
226        size_t offset,
227        const CryptoPlugin::SubSample *subSamples,
228        size_t numSubSamples,
229        const uint8_t key[16],
230        const uint8_t iv[16],
231        CryptoPlugin::Mode mode,
232        int64_t presentationTimeUs,
233        uint32_t flags,
234        AString *errorDetailMsg) {
235    if (errorDetailMsg != NULL) {
236        errorDetailMsg->clear();
237    }
238
239    sp<AMessage> msg = new AMessage(kWhatQueueInputBuffer, id());
240    msg->setSize("index", index);
241    msg->setSize("offset", offset);
242    msg->setPointer("subSamples", (void *)subSamples);
243    msg->setSize("numSubSamples", numSubSamples);
244    msg->setPointer("key", (void *)key);
245    msg->setPointer("iv", (void *)iv);
246    msg->setInt32("mode", mode);
247    msg->setInt64("timeUs", presentationTimeUs);
248    msg->setInt32("flags", flags);
249    msg->setPointer("errorDetailMsg", errorDetailMsg);
250
251    sp<AMessage> response;
252    status_t err = PostAndAwaitResponse(msg, &response);
253
254    return err;
255}
256
257status_t MediaCodec::dequeueInputBuffer(size_t *index, int64_t timeoutUs) {
258    sp<AMessage> msg = new AMessage(kWhatDequeueInputBuffer, id());
259    msg->setInt64("timeoutUs", timeoutUs);
260
261    sp<AMessage> response;
262    status_t err;
263    if ((err = PostAndAwaitResponse(msg, &response)) != OK) {
264        return err;
265    }
266
267    CHECK(response->findSize("index", index));
268
269    return OK;
270}
271
272status_t MediaCodec::dequeueOutputBuffer(
273        size_t *index,
274        size_t *offset,
275        size_t *size,
276        int64_t *presentationTimeUs,
277        uint32_t *flags,
278        int64_t timeoutUs) {
279    sp<AMessage> msg = new AMessage(kWhatDequeueOutputBuffer, id());
280    msg->setInt64("timeoutUs", timeoutUs);
281
282    sp<AMessage> response;
283    status_t err;
284    if ((err = PostAndAwaitResponse(msg, &response)) != OK) {
285        return err;
286    }
287
288    CHECK(response->findSize("index", index));
289    CHECK(response->findSize("offset", offset));
290    CHECK(response->findSize("size", size));
291    CHECK(response->findInt64("timeUs", presentationTimeUs));
292    CHECK(response->findInt32("flags", (int32_t *)flags));
293
294    return OK;
295}
296
297status_t MediaCodec::renderOutputBufferAndRelease(size_t index) {
298    sp<AMessage> msg = new AMessage(kWhatReleaseOutputBuffer, id());
299    msg->setSize("index", index);
300    msg->setInt32("render", true);
301
302    sp<AMessage> response;
303    return PostAndAwaitResponse(msg, &response);
304}
305
306status_t MediaCodec::releaseOutputBuffer(size_t index) {
307    sp<AMessage> msg = new AMessage(kWhatReleaseOutputBuffer, id());
308    msg->setSize("index", index);
309
310    sp<AMessage> response;
311    return PostAndAwaitResponse(msg, &response);
312}
313
314status_t MediaCodec::signalEndOfInputStream() {
315    sp<AMessage> msg = new AMessage(kWhatSignalEndOfInputStream, id());
316
317    sp<AMessage> response;
318    return PostAndAwaitResponse(msg, &response);
319}
320
321status_t MediaCodec::getOutputFormat(sp<AMessage> *format) const {
322    sp<AMessage> msg = new AMessage(kWhatGetOutputFormat, id());
323
324    sp<AMessage> response;
325    status_t err;
326    if ((err = PostAndAwaitResponse(msg, &response)) != OK) {
327        return err;
328    }
329
330    CHECK(response->findMessage("format", format));
331
332    return OK;
333}
334
335status_t MediaCodec::getName(AString *name) const {
336    sp<AMessage> msg = new AMessage(kWhatGetName, id());
337
338    sp<AMessage> response;
339    status_t err;
340    if ((err = PostAndAwaitResponse(msg, &response)) != OK) {
341        return err;
342    }
343
344    CHECK(response->findString("name", name));
345
346    return OK;
347}
348
349status_t MediaCodec::getInputBuffers(Vector<sp<ABuffer> > *buffers) const {
350    sp<AMessage> msg = new AMessage(kWhatGetBuffers, id());
351    msg->setInt32("portIndex", kPortIndexInput);
352    msg->setPointer("buffers", buffers);
353
354    sp<AMessage> response;
355    return PostAndAwaitResponse(msg, &response);
356}
357
358status_t MediaCodec::getOutputBuffers(Vector<sp<ABuffer> > *buffers) const {
359    sp<AMessage> msg = new AMessage(kWhatGetBuffers, id());
360    msg->setInt32("portIndex", kPortIndexOutput);
361    msg->setPointer("buffers", buffers);
362
363    sp<AMessage> response;
364    return PostAndAwaitResponse(msg, &response);
365}
366
367status_t MediaCodec::flush() {
368    sp<AMessage> msg = new AMessage(kWhatFlush, id());
369
370    sp<AMessage> response;
371    return PostAndAwaitResponse(msg, &response);
372}
373
374status_t MediaCodec::requestIDRFrame() {
375    (new AMessage(kWhatRequestIDRFrame, id()))->post();
376
377    return OK;
378}
379
380void MediaCodec::requestActivityNotification(const sp<AMessage> &notify) {
381    sp<AMessage> msg = new AMessage(kWhatRequestActivityNotification, id());
382    msg->setMessage("notify", notify);
383    msg->post();
384}
385
386////////////////////////////////////////////////////////////////////////////////
387
388void MediaCodec::cancelPendingDequeueOperations() {
389    if (mFlags & kFlagDequeueInputPending) {
390        sp<AMessage> response = new AMessage;
391        response->setInt32("err", INVALID_OPERATION);
392        response->postReply(mDequeueInputReplyID);
393
394        ++mDequeueInputTimeoutGeneration;
395        mDequeueInputReplyID = 0;
396        mFlags &= ~kFlagDequeueInputPending;
397    }
398
399    if (mFlags & kFlagDequeueOutputPending) {
400        sp<AMessage> response = new AMessage;
401        response->setInt32("err", INVALID_OPERATION);
402        response->postReply(mDequeueOutputReplyID);
403
404        ++mDequeueOutputTimeoutGeneration;
405        mDequeueOutputReplyID = 0;
406        mFlags &= ~kFlagDequeueOutputPending;
407    }
408}
409
410bool MediaCodec::handleDequeueInputBuffer(uint32_t replyID, bool newRequest) {
411    if (mState != STARTED
412            || (mFlags & kFlagStickyError)
413            || (newRequest && (mFlags & kFlagDequeueInputPending))) {
414        sp<AMessage> response = new AMessage;
415        response->setInt32("err", INVALID_OPERATION);
416
417        response->postReply(replyID);
418
419        return true;
420    }
421
422    ssize_t index = dequeuePortBuffer(kPortIndexInput);
423
424    if (index < 0) {
425        CHECK_EQ(index, -EAGAIN);
426        return false;
427    }
428
429    sp<AMessage> response = new AMessage;
430    response->setSize("index", index);
431    response->postReply(replyID);
432
433    return true;
434}
435
436bool MediaCodec::handleDequeueOutputBuffer(uint32_t replyID, bool newRequest) {
437    sp<AMessage> response = new AMessage;
438
439    if (mState != STARTED
440            || (mFlags & kFlagStickyError)
441            || (newRequest && (mFlags & kFlagDequeueOutputPending))) {
442        response->setInt32("err", INVALID_OPERATION);
443    } else if (mFlags & kFlagOutputBuffersChanged) {
444        response->setInt32("err", INFO_OUTPUT_BUFFERS_CHANGED);
445        mFlags &= ~kFlagOutputBuffersChanged;
446    } else if (mFlags & kFlagOutputFormatChanged) {
447        response->setInt32("err", INFO_FORMAT_CHANGED);
448        mFlags &= ~kFlagOutputFormatChanged;
449    } else {
450        ssize_t index = dequeuePortBuffer(kPortIndexOutput);
451
452        if (index < 0) {
453            CHECK_EQ(index, -EAGAIN);
454            return false;
455        }
456
457        const sp<ABuffer> &buffer =
458            mPortBuffers[kPortIndexOutput].itemAt(index).mData;
459
460        response->setSize("index", index);
461        response->setSize("offset", buffer->offset());
462        response->setSize("size", buffer->size());
463
464        int64_t timeUs;
465        CHECK(buffer->meta()->findInt64("timeUs", &timeUs));
466
467        response->setInt64("timeUs", timeUs);
468
469        int32_t omxFlags;
470        CHECK(buffer->meta()->findInt32("omxFlags", &omxFlags));
471
472        uint32_t flags = 0;
473        if (omxFlags & OMX_BUFFERFLAG_SYNCFRAME) {
474            flags |= BUFFER_FLAG_SYNCFRAME;
475        }
476        if (omxFlags & OMX_BUFFERFLAG_CODECCONFIG) {
477            flags |= BUFFER_FLAG_CODECCONFIG;
478        }
479        if (omxFlags & OMX_BUFFERFLAG_EOS) {
480            flags |= BUFFER_FLAG_EOS;
481        }
482
483        response->setInt32("flags", flags);
484    }
485
486    response->postReply(replyID);
487
488    return true;
489}
490
491void MediaCodec::onMessageReceived(const sp<AMessage> &msg) {
492    switch (msg->what()) {
493        case kWhatCodecNotify:
494        {
495            int32_t what;
496            CHECK(msg->findInt32("what", &what));
497
498            switch (what) {
499                case ACodec::kWhatError:
500                {
501                    int32_t omxError, internalError;
502                    CHECK(msg->findInt32("omx-error", &omxError));
503                    CHECK(msg->findInt32("err", &internalError));
504
505                    ALOGE("Codec reported an error. "
506                          "(omx error 0x%08x, internalError %d)",
507                          omxError, internalError);
508
509                    if (omxError == OMX_ErrorResourcesLost
510                            && internalError == DEAD_OBJECT) {
511                        mFlags |= kFlagSawMediaServerDie;
512                    }
513
514                    bool sendErrorReponse = true;
515
516                    switch (mState) {
517                        case INITIALIZING:
518                        {
519                            setState(UNINITIALIZED);
520                            break;
521                        }
522
523                        case CONFIGURING:
524                        {
525                            setState(INITIALIZED);
526                            break;
527                        }
528
529                        case STARTING:
530                        {
531                            setState(CONFIGURED);
532                            break;
533                        }
534
535                        case STOPPING:
536                        case RELEASING:
537                        {
538                            // Ignore the error, assuming we'll still get
539                            // the shutdown complete notification.
540
541                            sendErrorReponse = false;
542
543                            if (mFlags & kFlagSawMediaServerDie) {
544                                // MediaServer died, there definitely won't
545                                // be a shutdown complete notification after
546                                // all.
547
548                                // note that we're directly going from
549                                // STOPPING->UNINITIALIZED, instead of the
550                                // usual STOPPING->INITIALIZED state.
551                                setState(UNINITIALIZED);
552
553                                (new AMessage)->postReply(mReplyID);
554                            }
555                            break;
556                        }
557
558                        case FLUSHING:
559                        {
560                            setState(STARTED);
561                            break;
562                        }
563
564                        case STARTED:
565                        {
566                            sendErrorReponse = false;
567
568                            mFlags |= kFlagStickyError;
569                            postActivityNotificationIfPossible();
570
571                            cancelPendingDequeueOperations();
572                            break;
573                        }
574
575                        default:
576                        {
577                            sendErrorReponse = false;
578
579                            mFlags |= kFlagStickyError;
580                            postActivityNotificationIfPossible();
581                            break;
582                        }
583                    }
584
585                    if (sendErrorReponse) {
586                        sp<AMessage> response = new AMessage;
587                        response->setInt32("err", UNKNOWN_ERROR);
588
589                        response->postReply(mReplyID);
590                    }
591                    break;
592                }
593
594                case ACodec::kWhatComponentAllocated:
595                {
596                    CHECK_EQ(mState, INITIALIZING);
597                    setState(INITIALIZED);
598
599                    CHECK(msg->findString("componentName", &mComponentName));
600
601                    if (mComponentName.startsWith("OMX.google.")) {
602                        mFlags |= kFlagIsSoftwareCodec;
603                    } else {
604                        mFlags &= ~kFlagIsSoftwareCodec;
605                    }
606
607                    if (mComponentName.endsWith(".secure")) {
608                        mFlags |= kFlagIsSecure;
609                    } else {
610                        mFlags &= ~kFlagIsSecure;
611                    }
612
613                    (new AMessage)->postReply(mReplyID);
614                    break;
615                }
616
617                case ACodec::kWhatComponentConfigured:
618                {
619                    CHECK_EQ(mState, CONFIGURING);
620                    setState(CONFIGURED);
621
622                    // reset input surface flag
623                    mHaveInputSurface = false;
624
625                    (new AMessage)->postReply(mReplyID);
626                    break;
627                }
628
629                case ACodec::kWhatInputSurfaceCreated:
630                {
631                    // response to ACodec::kWhatCreateInputSurface
632                    status_t err = NO_ERROR;
633                    sp<AMessage> response = new AMessage();
634                    if (!msg->findInt32("err", &err)) {
635                        sp<RefBase> obj;
636                        msg->findObject("input-surface", &obj);
637                        CHECK(obj != NULL);
638                        response->setObject("input-surface", obj);
639                        mHaveInputSurface = true;
640                    } else {
641                        response->setInt32("err", err);
642                    }
643                    response->postReply(mReplyID);
644                    break;
645                }
646
647                case ACodec::kWhatSignaledInputEOS:
648                {
649                    // response to ACodec::kWhatSignalEndOfInputStream
650                    sp<AMessage> response = new AMessage();
651                    status_t err;
652                    if (msg->findInt32("err", &err)) {
653                        response->setInt32("err", err);
654                    }
655                    response->postReply(mReplyID);
656                    break;
657                }
658
659
660                case ACodec::kWhatBuffersAllocated:
661                {
662                    int32_t portIndex;
663                    CHECK(msg->findInt32("portIndex", &portIndex));
664
665                    ALOGV("%s buffers allocated",
666                          portIndex == kPortIndexInput ? "input" : "output");
667
668                    CHECK(portIndex == kPortIndexInput
669                            || portIndex == kPortIndexOutput);
670
671                    mPortBuffers[portIndex].clear();
672
673                    Vector<BufferInfo> *buffers = &mPortBuffers[portIndex];
674
675                    sp<RefBase> obj;
676                    CHECK(msg->findObject("portDesc", &obj));
677
678                    sp<ACodec::PortDescription> portDesc =
679                        static_cast<ACodec::PortDescription *>(obj.get());
680
681                    size_t numBuffers = portDesc->countBuffers();
682
683                    for (size_t i = 0; i < numBuffers; ++i) {
684                        BufferInfo info;
685                        info.mBufferID = portDesc->bufferIDAt(i);
686                        info.mOwnedByClient = false;
687                        info.mData = portDesc->bufferAt(i);
688
689                        if (portIndex == kPortIndexInput && mCrypto != NULL) {
690                            info.mEncryptedData =
691                                new ABuffer(info.mData->capacity());
692                        }
693
694                        buffers->push_back(info);
695                    }
696
697                    if (portIndex == kPortIndexOutput) {
698                        if (mState == STARTING) {
699                            // We're always allocating output buffers after
700                            // allocating input buffers, so this is a good
701                            // indication that now all buffers are allocated.
702                            setState(STARTED);
703                            (new AMessage)->postReply(mReplyID);
704                        } else {
705                            mFlags |= kFlagOutputBuffersChanged;
706                            postActivityNotificationIfPossible();
707                        }
708                    }
709                    break;
710                }
711
712                case ACodec::kWhatOutputFormatChanged:
713                {
714                    ALOGV("codec output format changed");
715
716                    if ((mFlags & kFlagIsSoftwareCodec)
717                            && mNativeWindow != NULL) {
718                        AString mime;
719                        CHECK(msg->findString("mime", &mime));
720
721                        if (!strncasecmp("video/", mime.c_str(), 6)) {
722                            delete mSoftRenderer;
723                            mSoftRenderer = NULL;
724
725                            int32_t width, height;
726                            CHECK(msg->findInt32("width", &width));
727                            CHECK(msg->findInt32("height", &height));
728
729                            int32_t colorFormat;
730                            CHECK(msg->findInt32(
731                                        "color-format", &colorFormat));
732
733                            sp<MetaData> meta = new MetaData;
734                            meta->setInt32(kKeyWidth, width);
735                            meta->setInt32(kKeyHeight, height);
736                            meta->setInt32(kKeyColorFormat, colorFormat);
737
738                            mSoftRenderer =
739                                new SoftwareRenderer(mNativeWindow, meta);
740                        }
741                    }
742
743                    mOutputFormat = msg;
744                    mFlags |= kFlagOutputFormatChanged;
745                    postActivityNotificationIfPossible();
746                    break;
747                }
748
749                case ACodec::kWhatFillThisBuffer:
750                {
751                    /* size_t index = */updateBuffers(kPortIndexInput, msg);
752
753                    if (mState == FLUSHING
754                            || mState == STOPPING
755                            || mState == RELEASING) {
756                        returnBuffersToCodecOnPort(kPortIndexInput);
757                        break;
758                    }
759
760                    if (!mCSD.empty()) {
761                        ssize_t index = dequeuePortBuffer(kPortIndexInput);
762                        CHECK_GE(index, 0);
763
764                        // If codec specific data had been specified as
765                        // part of the format in the call to configure and
766                        // if there's more csd left, we submit it here
767                        // clients only get access to input buffers once
768                        // this data has been exhausted.
769
770                        status_t err = queueCSDInputBuffer(index);
771
772                        if (err != OK) {
773                            ALOGE("queueCSDInputBuffer failed w/ error %d",
774                                  err);
775
776                            mFlags |= kFlagStickyError;
777                            postActivityNotificationIfPossible();
778
779                            cancelPendingDequeueOperations();
780                        }
781                        break;
782                    }
783
784                    if (mFlags & kFlagDequeueInputPending) {
785                        CHECK(handleDequeueInputBuffer(mDequeueInputReplyID));
786
787                        ++mDequeueInputTimeoutGeneration;
788                        mFlags &= ~kFlagDequeueInputPending;
789                        mDequeueInputReplyID = 0;
790                    } else {
791                        postActivityNotificationIfPossible();
792                    }
793                    break;
794                }
795
796                case ACodec::kWhatDrainThisBuffer:
797                {
798                    /* size_t index = */updateBuffers(kPortIndexOutput, msg);
799
800                    if (mState == FLUSHING
801                            || mState == STOPPING
802                            || mState == RELEASING) {
803                        returnBuffersToCodecOnPort(kPortIndexOutput);
804                        break;
805                    }
806
807                    sp<ABuffer> buffer;
808                    CHECK(msg->findBuffer("buffer", &buffer));
809
810                    int32_t omxFlags;
811                    CHECK(msg->findInt32("flags", &omxFlags));
812
813                    buffer->meta()->setInt32("omxFlags", omxFlags);
814
815                    if (mFlags & kFlagDequeueOutputPending) {
816                        CHECK(handleDequeueOutputBuffer(mDequeueOutputReplyID));
817
818                        ++mDequeueOutputTimeoutGeneration;
819                        mFlags &= ~kFlagDequeueOutputPending;
820                        mDequeueOutputReplyID = 0;
821                    } else {
822                        postActivityNotificationIfPossible();
823                    }
824
825                    break;
826                }
827
828                case ACodec::kWhatEOS:
829                {
830                    // We already notify the client of this by using the
831                    // corresponding flag in "onOutputBufferReady".
832                    break;
833                }
834
835                case ACodec::kWhatShutdownCompleted:
836                {
837                    if (mState == STOPPING) {
838                        setState(INITIALIZED);
839                    } else {
840                        CHECK_EQ(mState, RELEASING);
841                        setState(UNINITIALIZED);
842                    }
843
844                    (new AMessage)->postReply(mReplyID);
845                    break;
846                }
847
848                case ACodec::kWhatFlushCompleted:
849                {
850                    CHECK_EQ(mState, FLUSHING);
851                    setState(STARTED);
852
853                    mCodec->signalResume();
854
855                    (new AMessage)->postReply(mReplyID);
856                    break;
857                }
858
859                default:
860                    TRESPASS();
861            }
862            break;
863        }
864
865        case kWhatInit:
866        {
867            uint32_t replyID;
868            CHECK(msg->senderAwaitsResponse(&replyID));
869
870            if (mState != UNINITIALIZED) {
871                sp<AMessage> response = new AMessage;
872                response->setInt32("err", INVALID_OPERATION);
873
874                response->postReply(replyID);
875                break;
876            }
877
878            mReplyID = replyID;
879            setState(INITIALIZING);
880
881            AString name;
882            CHECK(msg->findString("name", &name));
883
884            int32_t nameIsType;
885            int32_t encoder = false;
886            CHECK(msg->findInt32("nameIsType", &nameIsType));
887            if (nameIsType) {
888                CHECK(msg->findInt32("encoder", &encoder));
889            }
890
891            sp<AMessage> format = new AMessage;
892
893            if (nameIsType) {
894                format->setString("mime", name.c_str());
895                format->setInt32("encoder", encoder);
896            } else {
897                format->setString("componentName", name.c_str());
898            }
899
900            mCodec->initiateAllocateComponent(format);
901            break;
902        }
903
904        case kWhatConfigure:
905        {
906            uint32_t replyID;
907            CHECK(msg->senderAwaitsResponse(&replyID));
908
909            if (mState != INITIALIZED) {
910                sp<AMessage> response = new AMessage;
911                response->setInt32("err", INVALID_OPERATION);
912
913                response->postReply(replyID);
914                break;
915            }
916
917            sp<RefBase> obj;
918            if (!msg->findObject("native-window", &obj)) {
919                obj.clear();
920            }
921
922            sp<AMessage> format;
923            CHECK(msg->findMessage("format", &format));
924
925            if (obj != NULL) {
926                format->setObject("native-window", obj);
927
928                status_t err = setNativeWindow(
929                    static_cast<NativeWindowWrapper *>(obj.get())
930                        ->getSurfaceTextureClient());
931
932                if (err != OK) {
933                    sp<AMessage> response = new AMessage;
934                    response->setInt32("err", err);
935
936                    response->postReply(replyID);
937                    break;
938                }
939            } else {
940                setNativeWindow(NULL);
941            }
942
943            mReplyID = replyID;
944            setState(CONFIGURING);
945
946            void *crypto;
947            if (!msg->findPointer("crypto", &crypto)) {
948                crypto = NULL;
949            }
950
951            mCrypto = static_cast<ICrypto *>(crypto);
952
953            uint32_t flags;
954            CHECK(msg->findInt32("flags", (int32_t *)&flags));
955
956            if (flags & CONFIGURE_FLAG_ENCODE) {
957                format->setInt32("encoder", true);
958            }
959
960            extractCSD(format);
961
962            mCodec->initiateConfigureComponent(format);
963            break;
964        }
965
966        case kWhatCreateInputSurface:
967        {
968            uint32_t replyID;
969            CHECK(msg->senderAwaitsResponse(&replyID));
970
971            // Must be configured, but can't have been started yet.
972            if (mState != CONFIGURED) {
973                sp<AMessage> response = new AMessage;
974                response->setInt32("err", INVALID_OPERATION);
975
976                response->postReply(replyID);
977                break;
978            }
979
980            mReplyID = replyID;
981            mCodec->initiateCreateInputSurface();
982            break;
983        }
984
985        case kWhatStart:
986        {
987            uint32_t replyID;
988            CHECK(msg->senderAwaitsResponse(&replyID));
989
990            if (mState != CONFIGURED) {
991                sp<AMessage> response = new AMessage;
992                response->setInt32("err", INVALID_OPERATION);
993
994                response->postReply(replyID);
995                break;
996            }
997
998            mReplyID = replyID;
999            setState(STARTING);
1000
1001            mCodec->initiateStart();
1002            break;
1003        }
1004
1005        case kWhatStop:
1006        case kWhatRelease:
1007        {
1008            State targetState =
1009                (msg->what() == kWhatStop) ? INITIALIZED : UNINITIALIZED;
1010
1011            uint32_t replyID;
1012            CHECK(msg->senderAwaitsResponse(&replyID));
1013
1014            if (mState != INITIALIZED
1015                    && mState != CONFIGURED && mState != STARTED) {
1016                // We may be in "UNINITIALIZED" state already without the
1017                // client being aware of this if media server died while
1018                // we were being stopped. The client would assume that
1019                // after stop() returned, it would be safe to call release()
1020                // and it should be in this case, no harm to allow a release()
1021                // if we're already uninitialized.
1022                // Similarly stopping a stopped MediaCodec should be benign.
1023                sp<AMessage> response = new AMessage;
1024                response->setInt32(
1025                        "err",
1026                        mState == targetState ? OK : INVALID_OPERATION);
1027
1028                response->postReply(replyID);
1029                break;
1030            }
1031
1032            if (mFlags & kFlagSawMediaServerDie) {
1033                // It's dead, Jim. Don't expect initiateShutdown to yield
1034                // any useful results now...
1035                setState(UNINITIALIZED);
1036                (new AMessage)->postReply(replyID);
1037                break;
1038            }
1039
1040            mReplyID = replyID;
1041            setState(msg->what() == kWhatStop ? STOPPING : RELEASING);
1042
1043            mCodec->initiateShutdown(
1044                    msg->what() == kWhatStop /* keepComponentAllocated */);
1045
1046            returnBuffersToCodec();
1047            break;
1048        }
1049
1050        case kWhatDequeueInputBuffer:
1051        {
1052            uint32_t replyID;
1053            CHECK(msg->senderAwaitsResponse(&replyID));
1054
1055            if (mHaveInputSurface) {
1056                ALOGE("dequeueInputBuffer can't be used with input surface");
1057                sp<AMessage> response = new AMessage;
1058                response->setInt32("err", INVALID_OPERATION);
1059                response->postReply(replyID);
1060                break;
1061            }
1062
1063            if (handleDequeueInputBuffer(replyID, true /* new request */)) {
1064                break;
1065            }
1066
1067            int64_t timeoutUs;
1068            CHECK(msg->findInt64("timeoutUs", &timeoutUs));
1069
1070            if (timeoutUs == 0ll) {
1071                sp<AMessage> response = new AMessage;
1072                response->setInt32("err", -EAGAIN);
1073                response->postReply(replyID);
1074                break;
1075            }
1076
1077            mFlags |= kFlagDequeueInputPending;
1078            mDequeueInputReplyID = replyID;
1079
1080            if (timeoutUs > 0ll) {
1081                sp<AMessage> timeoutMsg =
1082                    new AMessage(kWhatDequeueInputTimedOut, id());
1083                timeoutMsg->setInt32(
1084                        "generation", ++mDequeueInputTimeoutGeneration);
1085                timeoutMsg->post(timeoutUs);
1086            }
1087            break;
1088        }
1089
1090        case kWhatDequeueInputTimedOut:
1091        {
1092            int32_t generation;
1093            CHECK(msg->findInt32("generation", &generation));
1094
1095            if (generation != mDequeueInputTimeoutGeneration) {
1096                // Obsolete
1097                break;
1098            }
1099
1100            CHECK(mFlags & kFlagDequeueInputPending);
1101
1102            sp<AMessage> response = new AMessage;
1103            response->setInt32("err", -EAGAIN);
1104            response->postReply(mDequeueInputReplyID);
1105
1106            mFlags &= ~kFlagDequeueInputPending;
1107            mDequeueInputReplyID = 0;
1108            break;
1109        }
1110
1111        case kWhatQueueInputBuffer:
1112        {
1113            uint32_t replyID;
1114            CHECK(msg->senderAwaitsResponse(&replyID));
1115
1116            if (mState != STARTED || (mFlags & kFlagStickyError)) {
1117                sp<AMessage> response = new AMessage;
1118                response->setInt32("err", INVALID_OPERATION);
1119
1120                response->postReply(replyID);
1121                break;
1122            }
1123
1124            status_t err = onQueueInputBuffer(msg);
1125
1126            sp<AMessage> response = new AMessage;
1127            response->setInt32("err", err);
1128            response->postReply(replyID);
1129            break;
1130        }
1131
1132        case kWhatDequeueOutputBuffer:
1133        {
1134            uint32_t replyID;
1135            CHECK(msg->senderAwaitsResponse(&replyID));
1136
1137            if (handleDequeueOutputBuffer(replyID, true /* new request */)) {
1138                break;
1139            }
1140
1141            int64_t timeoutUs;
1142            CHECK(msg->findInt64("timeoutUs", &timeoutUs));
1143
1144            if (timeoutUs == 0ll) {
1145                sp<AMessage> response = new AMessage;
1146                response->setInt32("err", -EAGAIN);
1147                response->postReply(replyID);
1148                break;
1149            }
1150
1151            mFlags |= kFlagDequeueOutputPending;
1152            mDequeueOutputReplyID = replyID;
1153
1154            if (timeoutUs > 0ll) {
1155                sp<AMessage> timeoutMsg =
1156                    new AMessage(kWhatDequeueOutputTimedOut, id());
1157                timeoutMsg->setInt32(
1158                        "generation", ++mDequeueOutputTimeoutGeneration);
1159                timeoutMsg->post(timeoutUs);
1160            }
1161            break;
1162        }
1163
1164        case kWhatDequeueOutputTimedOut:
1165        {
1166            int32_t generation;
1167            CHECK(msg->findInt32("generation", &generation));
1168
1169            if (generation != mDequeueOutputTimeoutGeneration) {
1170                // Obsolete
1171                break;
1172            }
1173
1174            CHECK(mFlags & kFlagDequeueOutputPending);
1175
1176            sp<AMessage> response = new AMessage;
1177            response->setInt32("err", -EAGAIN);
1178            response->postReply(mDequeueOutputReplyID);
1179
1180            mFlags &= ~kFlagDequeueOutputPending;
1181            mDequeueOutputReplyID = 0;
1182            break;
1183        }
1184
1185        case kWhatReleaseOutputBuffer:
1186        {
1187            uint32_t replyID;
1188            CHECK(msg->senderAwaitsResponse(&replyID));
1189
1190            if (mState != STARTED || (mFlags & kFlagStickyError)) {
1191                sp<AMessage> response = new AMessage;
1192                response->setInt32("err", INVALID_OPERATION);
1193
1194                response->postReply(replyID);
1195                break;
1196            }
1197
1198            status_t err = onReleaseOutputBuffer(msg);
1199
1200            sp<AMessage> response = new AMessage;
1201            response->setInt32("err", err);
1202            response->postReply(replyID);
1203            break;
1204        }
1205
1206        case kWhatSignalEndOfInputStream:
1207        {
1208            uint32_t replyID;
1209            CHECK(msg->senderAwaitsResponse(&replyID));
1210
1211            if (mState != STARTED || (mFlags & kFlagStickyError)) {
1212                sp<AMessage> response = new AMessage;
1213                response->setInt32("err", INVALID_OPERATION);
1214
1215                response->postReply(replyID);
1216                break;
1217            }
1218
1219            mReplyID = replyID;
1220            mCodec->signalEndOfInputStream();
1221            break;
1222        }
1223
1224        case kWhatGetBuffers:
1225        {
1226            uint32_t replyID;
1227            CHECK(msg->senderAwaitsResponse(&replyID));
1228
1229            if (mState != STARTED || (mFlags & kFlagStickyError)) {
1230                sp<AMessage> response = new AMessage;
1231                response->setInt32("err", INVALID_OPERATION);
1232
1233                response->postReply(replyID);
1234                break;
1235            }
1236
1237            int32_t portIndex;
1238            CHECK(msg->findInt32("portIndex", &portIndex));
1239
1240            Vector<sp<ABuffer> > *dstBuffers;
1241            CHECK(msg->findPointer("buffers", (void **)&dstBuffers));
1242
1243            dstBuffers->clear();
1244            const Vector<BufferInfo> &srcBuffers = mPortBuffers[portIndex];
1245
1246            for (size_t i = 0; i < srcBuffers.size(); ++i) {
1247                const BufferInfo &info = srcBuffers.itemAt(i);
1248
1249                dstBuffers->push_back(
1250                        (portIndex == kPortIndexInput && mCrypto != NULL)
1251                                ? info.mEncryptedData : info.mData);
1252            }
1253
1254            (new AMessage)->postReply(replyID);
1255            break;
1256        }
1257
1258        case kWhatFlush:
1259        {
1260            uint32_t replyID;
1261            CHECK(msg->senderAwaitsResponse(&replyID));
1262
1263            if (mState != STARTED || (mFlags & kFlagStickyError)) {
1264                sp<AMessage> response = new AMessage;
1265                response->setInt32("err", INVALID_OPERATION);
1266
1267                response->postReply(replyID);
1268                break;
1269            }
1270
1271            mReplyID = replyID;
1272            setState(FLUSHING);
1273
1274            mCodec->signalFlush();
1275            returnBuffersToCodec();
1276            break;
1277        }
1278
1279        case kWhatGetOutputFormat:
1280        {
1281            uint32_t replyID;
1282            CHECK(msg->senderAwaitsResponse(&replyID));
1283
1284            if ((mState != STARTED && mState != FLUSHING)
1285                    || (mFlags & kFlagStickyError)
1286                    || mOutputFormat == NULL) {
1287                sp<AMessage> response = new AMessage;
1288                response->setInt32("err", INVALID_OPERATION);
1289
1290                response->postReply(replyID);
1291                break;
1292            }
1293
1294            sp<AMessage> response = new AMessage;
1295            response->setMessage("format", mOutputFormat);
1296            response->postReply(replyID);
1297            break;
1298        }
1299
1300        case kWhatRequestIDRFrame:
1301        {
1302            mCodec->signalRequestIDRFrame();
1303            break;
1304        }
1305
1306        case kWhatRequestActivityNotification:
1307        {
1308            CHECK(mActivityNotify == NULL);
1309            CHECK(msg->findMessage("notify", &mActivityNotify));
1310
1311            postActivityNotificationIfPossible();
1312            break;
1313        }
1314
1315        case kWhatGetName:
1316        {
1317            uint32_t replyID;
1318            CHECK(msg->senderAwaitsResponse(&replyID));
1319
1320            if (mComponentName.empty()) {
1321                sp<AMessage> response = new AMessage;
1322                response->setInt32("err", INVALID_OPERATION);
1323
1324                response->postReply(replyID);
1325                break;
1326            }
1327
1328            sp<AMessage> response = new AMessage;
1329            response->setString("name", mComponentName.c_str());
1330            response->postReply(replyID);
1331            break;
1332        }
1333
1334        case kWhatSetParameters:
1335        {
1336            uint32_t replyID;
1337            CHECK(msg->senderAwaitsResponse(&replyID));
1338
1339            sp<AMessage> params;
1340            CHECK(msg->findMessage("params", &params));
1341
1342            status_t err = onSetParameters(params);
1343
1344            sp<AMessage> response = new AMessage;
1345            response->setInt32("err", err);
1346
1347            response->postReply(replyID);
1348            break;
1349        }
1350
1351        default:
1352            TRESPASS();
1353    }
1354}
1355
1356void MediaCodec::extractCSD(const sp<AMessage> &format) {
1357    mCSD.clear();
1358
1359    size_t i = 0;
1360    for (;;) {
1361        sp<ABuffer> csd;
1362        if (!format->findBuffer(StringPrintf("csd-%u", i).c_str(), &csd)) {
1363            break;
1364        }
1365
1366        mCSD.push_back(csd);
1367        ++i;
1368    }
1369
1370    ALOGV("Found %u pieces of codec specific data.", mCSD.size());
1371}
1372
1373status_t MediaCodec::queueCSDInputBuffer(size_t bufferIndex) {
1374    CHECK(!mCSD.empty());
1375
1376    BufferInfo *info =
1377        &mPortBuffers[kPortIndexInput].editItemAt(bufferIndex);
1378
1379    sp<ABuffer> csd = *mCSD.begin();
1380    mCSD.erase(mCSD.begin());
1381
1382    const sp<ABuffer> &codecInputData =
1383        (mCrypto != NULL) ? info->mEncryptedData : info->mData;
1384
1385    if (csd->size() > codecInputData->capacity()) {
1386        return -EINVAL;
1387    }
1388
1389    memcpy(codecInputData->data(), csd->data(), csd->size());
1390
1391    AString errorDetailMsg;
1392
1393    sp<AMessage> msg = new AMessage(kWhatQueueInputBuffer, id());
1394    msg->setSize("index", bufferIndex);
1395    msg->setSize("offset", 0);
1396    msg->setSize("size", csd->size());
1397    msg->setInt64("timeUs", 0ll);
1398    msg->setInt32("flags", BUFFER_FLAG_CODECCONFIG);
1399    msg->setPointer("errorDetailMsg", &errorDetailMsg);
1400
1401    return onQueueInputBuffer(msg);
1402}
1403
1404void MediaCodec::setState(State newState) {
1405    if (newState == INITIALIZED || newState == UNINITIALIZED) {
1406        delete mSoftRenderer;
1407        mSoftRenderer = NULL;
1408
1409        mCrypto.clear();
1410        setNativeWindow(NULL);
1411
1412        mOutputFormat.clear();
1413        mFlags &= ~kFlagOutputFormatChanged;
1414        mFlags &= ~kFlagOutputBuffersChanged;
1415        mFlags &= ~kFlagStickyError;
1416
1417        mActivityNotify.clear();
1418    }
1419
1420    if (newState == UNINITIALIZED) {
1421        mComponentName.clear();
1422
1423        // The component is gone, mediaserver's probably back up already
1424        // but should definitely be back up should we try to instantiate
1425        // another component.. and the cycle continues.
1426        mFlags &= ~kFlagSawMediaServerDie;
1427    }
1428
1429    mState = newState;
1430
1431    cancelPendingDequeueOperations();
1432}
1433
1434void MediaCodec::returnBuffersToCodec() {
1435    returnBuffersToCodecOnPort(kPortIndexInput);
1436    returnBuffersToCodecOnPort(kPortIndexOutput);
1437}
1438
1439void MediaCodec::returnBuffersToCodecOnPort(int32_t portIndex) {
1440    CHECK(portIndex == kPortIndexInput || portIndex == kPortIndexOutput);
1441
1442    Vector<BufferInfo> *buffers = &mPortBuffers[portIndex];
1443
1444    for (size_t i = 0; i < buffers->size(); ++i) {
1445        BufferInfo *info = &buffers->editItemAt(i);
1446
1447        if (info->mNotify != NULL) {
1448            sp<AMessage> msg = info->mNotify;
1449            info->mNotify = NULL;
1450            info->mOwnedByClient = false;
1451
1452            if (portIndex == kPortIndexInput) {
1453                msg->setInt32("err", ERROR_END_OF_STREAM);
1454            }
1455            msg->post();
1456        }
1457    }
1458
1459    mAvailPortBuffers[portIndex].clear();
1460}
1461
1462size_t MediaCodec::updateBuffers(
1463        int32_t portIndex, const sp<AMessage> &msg) {
1464    CHECK(portIndex == kPortIndexInput || portIndex == kPortIndexOutput);
1465
1466    void *bufferID;
1467    CHECK(msg->findPointer("buffer-id", &bufferID));
1468
1469    Vector<BufferInfo> *buffers = &mPortBuffers[portIndex];
1470
1471    for (size_t i = 0; i < buffers->size(); ++i) {
1472        BufferInfo *info = &buffers->editItemAt(i);
1473
1474        if (info->mBufferID == bufferID) {
1475            CHECK(info->mNotify == NULL);
1476            CHECK(msg->findMessage("reply", &info->mNotify));
1477
1478            mAvailPortBuffers[portIndex].push_back(i);
1479
1480            return i;
1481        }
1482    }
1483
1484    TRESPASS();
1485
1486    return 0;
1487}
1488
1489status_t MediaCodec::onQueueInputBuffer(const sp<AMessage> &msg) {
1490    size_t index;
1491    size_t offset;
1492    size_t size;
1493    int64_t timeUs;
1494    uint32_t flags;
1495    CHECK(msg->findSize("index", &index));
1496    CHECK(msg->findSize("offset", &offset));
1497    CHECK(msg->findInt64("timeUs", &timeUs));
1498    CHECK(msg->findInt32("flags", (int32_t *)&flags));
1499
1500    const CryptoPlugin::SubSample *subSamples;
1501    size_t numSubSamples;
1502    const uint8_t *key;
1503    const uint8_t *iv;
1504    CryptoPlugin::Mode mode = CryptoPlugin::kMode_Unencrypted;
1505
1506    // We allow the simpler queueInputBuffer API to be used even in
1507    // secure mode, by fabricating a single unencrypted subSample.
1508    CryptoPlugin::SubSample ss;
1509
1510    if (msg->findSize("size", &size)) {
1511        if (mCrypto != NULL) {
1512            ss.mNumBytesOfClearData = size;
1513            ss.mNumBytesOfEncryptedData = 0;
1514
1515            subSamples = &ss;
1516            numSubSamples = 1;
1517            key = NULL;
1518            iv = NULL;
1519        }
1520    } else {
1521        if (mCrypto == NULL) {
1522            return -EINVAL;
1523        }
1524
1525        CHECK(msg->findPointer("subSamples", (void **)&subSamples));
1526        CHECK(msg->findSize("numSubSamples", &numSubSamples));
1527        CHECK(msg->findPointer("key", (void **)&key));
1528        CHECK(msg->findPointer("iv", (void **)&iv));
1529
1530        int32_t tmp;
1531        CHECK(msg->findInt32("mode", &tmp));
1532
1533        mode = (CryptoPlugin::Mode)tmp;
1534
1535        size = 0;
1536        for (size_t i = 0; i < numSubSamples; ++i) {
1537            size += subSamples[i].mNumBytesOfClearData;
1538            size += subSamples[i].mNumBytesOfEncryptedData;
1539        }
1540    }
1541
1542    if (index >= mPortBuffers[kPortIndexInput].size()) {
1543        return -ERANGE;
1544    }
1545
1546    BufferInfo *info = &mPortBuffers[kPortIndexInput].editItemAt(index);
1547
1548    if (info->mNotify == NULL || !info->mOwnedByClient) {
1549        return -EACCES;
1550    }
1551
1552    if (offset + size > info->mData->capacity()) {
1553        return -EINVAL;
1554    }
1555
1556    sp<AMessage> reply = info->mNotify;
1557    info->mData->setRange(offset, size);
1558    info->mData->meta()->setInt64("timeUs", timeUs);
1559
1560    if (flags & BUFFER_FLAG_EOS) {
1561        info->mData->meta()->setInt32("eos", true);
1562    }
1563
1564    if (flags & BUFFER_FLAG_CODECCONFIG) {
1565        info->mData->meta()->setInt32("csd", true);
1566    }
1567
1568    if (mCrypto != NULL) {
1569        if (size > info->mEncryptedData->capacity()) {
1570            return -ERANGE;
1571        }
1572
1573        AString *errorDetailMsg;
1574        CHECK(msg->findPointer("errorDetailMsg", (void **)&errorDetailMsg));
1575
1576        ssize_t result = mCrypto->decrypt(
1577                (mFlags & kFlagIsSecure) != 0,
1578                key,
1579                iv,
1580                mode,
1581                info->mEncryptedData->base() + offset,
1582                subSamples,
1583                numSubSamples,
1584                info->mData->base(),
1585                errorDetailMsg);
1586
1587        if (result < 0) {
1588            return result;
1589        }
1590
1591        info->mData->setRange(0, result);
1592    }
1593
1594    reply->setBuffer("buffer", info->mData);
1595    reply->post();
1596
1597    info->mNotify = NULL;
1598    info->mOwnedByClient = false;
1599
1600    return OK;
1601}
1602
1603status_t MediaCodec::onReleaseOutputBuffer(const sp<AMessage> &msg) {
1604    size_t index;
1605    CHECK(msg->findSize("index", &index));
1606
1607    int32_t render;
1608    if (!msg->findInt32("render", &render)) {
1609        render = 0;
1610    }
1611
1612    if (mState != STARTED) {
1613        return -EINVAL;
1614    }
1615
1616    if (index >= mPortBuffers[kPortIndexOutput].size()) {
1617        return -ERANGE;
1618    }
1619
1620    BufferInfo *info = &mPortBuffers[kPortIndexOutput].editItemAt(index);
1621
1622    if (info->mNotify == NULL || !info->mOwnedByClient) {
1623        return -EACCES;
1624    }
1625
1626    if (render) {
1627        info->mNotify->setInt32("render", true);
1628
1629        if (mSoftRenderer != NULL) {
1630            mSoftRenderer->render(
1631                    info->mData->data(), info->mData->size(), NULL);
1632        }
1633    }
1634
1635    info->mNotify->post();
1636    info->mNotify = NULL;
1637    info->mOwnedByClient = false;
1638
1639    return OK;
1640}
1641
1642ssize_t MediaCodec::dequeuePortBuffer(int32_t portIndex) {
1643    CHECK(portIndex == kPortIndexInput || portIndex == kPortIndexOutput);
1644
1645    List<size_t> *availBuffers = &mAvailPortBuffers[portIndex];
1646
1647    if (availBuffers->empty()) {
1648        return -EAGAIN;
1649    }
1650
1651    size_t index = *availBuffers->begin();
1652    availBuffers->erase(availBuffers->begin());
1653
1654    BufferInfo *info = &mPortBuffers[portIndex].editItemAt(index);
1655    CHECK(!info->mOwnedByClient);
1656    info->mOwnedByClient = true;
1657
1658    return index;
1659}
1660
1661status_t MediaCodec::setNativeWindow(
1662        const sp<Surface> &surfaceTextureClient) {
1663    status_t err;
1664
1665    if (mNativeWindow != NULL) {
1666        err = native_window_api_disconnect(
1667                mNativeWindow.get(), NATIVE_WINDOW_API_MEDIA);
1668
1669        if (err != OK) {
1670            ALOGW("native_window_api_disconnect returned an error: %s (%d)",
1671                    strerror(-err), err);
1672        }
1673
1674        mNativeWindow.clear();
1675    }
1676
1677    if (surfaceTextureClient != NULL) {
1678        err = native_window_api_connect(
1679                surfaceTextureClient.get(), NATIVE_WINDOW_API_MEDIA);
1680
1681        if (err != OK) {
1682            ALOGE("native_window_api_connect returned an error: %s (%d)",
1683                    strerror(-err), err);
1684
1685            return err;
1686        }
1687
1688        mNativeWindow = surfaceTextureClient;
1689    }
1690
1691    return OK;
1692}
1693
1694void MediaCodec::postActivityNotificationIfPossible() {
1695    if (mActivityNotify == NULL) {
1696        return;
1697    }
1698
1699    if ((mFlags & (kFlagStickyError
1700                    | kFlagOutputBuffersChanged
1701                    | kFlagOutputFormatChanged))
1702            || !mAvailPortBuffers[kPortIndexInput].empty()
1703            || !mAvailPortBuffers[kPortIndexOutput].empty()) {
1704        mActivityNotify->post();
1705        mActivityNotify.clear();
1706    }
1707}
1708
1709status_t MediaCodec::setParameters(const sp<AMessage> &params) {
1710    sp<AMessage> msg = new AMessage(kWhatSetParameters, id());
1711    msg->setMessage("params", params);
1712
1713    sp<AMessage> response;
1714    return PostAndAwaitResponse(msg, &response);
1715}
1716
1717status_t MediaCodec::onSetParameters(const sp<AMessage> &params) {
1718    mCodec->signalSetParameters(params);
1719
1720    return OK;
1721}
1722
1723}  // namespace android
1724