MediaCodec.cpp revision 6507d14c6d10f93d390de62b9eed267f9b544985
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                    bool sendErrorReponse = true;
510
511                    switch (mState) {
512                        case INITIALIZING:
513                        {
514                            setState(UNINITIALIZED);
515                            break;
516                        }
517
518                        case CONFIGURING:
519                        {
520                            setState(INITIALIZED);
521                            break;
522                        }
523
524                        case STARTING:
525                        {
526                            setState(CONFIGURED);
527                            break;
528                        }
529
530                        case STOPPING:
531                        case RELEASING:
532                        {
533                            // Ignore the error, assuming we'll still get
534                            // the shutdown complete notification.
535
536                            sendErrorReponse = false;
537                            break;
538                        }
539
540                        case FLUSHING:
541                        {
542                            setState(STARTED);
543                            break;
544                        }
545
546                        case STARTED:
547                        {
548                            sendErrorReponse = false;
549
550                            mFlags |= kFlagStickyError;
551                            postActivityNotificationIfPossible();
552
553                            cancelPendingDequeueOperations();
554                            break;
555                        }
556
557                        default:
558                        {
559                            sendErrorReponse = false;
560
561                            mFlags |= kFlagStickyError;
562                            postActivityNotificationIfPossible();
563                            break;
564                        }
565                    }
566
567                    if (sendErrorReponse) {
568                        sp<AMessage> response = new AMessage;
569                        response->setInt32("err", UNKNOWN_ERROR);
570
571                        response->postReply(mReplyID);
572                    }
573                    break;
574                }
575
576                case ACodec::kWhatComponentAllocated:
577                {
578                    CHECK_EQ(mState, INITIALIZING);
579                    setState(INITIALIZED);
580
581                    CHECK(msg->findString("componentName", &mComponentName));
582
583                    if (mComponentName.startsWith("OMX.google.")) {
584                        mFlags |= kFlagIsSoftwareCodec;
585                    } else {
586                        mFlags &= ~kFlagIsSoftwareCodec;
587                    }
588
589                    if (mComponentName.endsWith(".secure")) {
590                        mFlags |= kFlagIsSecure;
591                    } else {
592                        mFlags &= ~kFlagIsSecure;
593                    }
594
595                    (new AMessage)->postReply(mReplyID);
596                    break;
597                }
598
599                case ACodec::kWhatComponentConfigured:
600                {
601                    CHECK_EQ(mState, CONFIGURING);
602                    setState(CONFIGURED);
603
604                    // reset input surface flag
605                    mHaveInputSurface = false;
606
607                    (new AMessage)->postReply(mReplyID);
608                    break;
609                }
610
611                case ACodec::kWhatInputSurfaceCreated:
612                {
613                    // response to ACodec::kWhatCreateInputSurface
614                    status_t err = NO_ERROR;
615                    sp<AMessage> response = new AMessage();
616                    if (!msg->findInt32("err", &err)) {
617                        sp<RefBase> obj;
618                        msg->findObject("input-surface", &obj);
619                        CHECK(obj != NULL);
620                        response->setObject("input-surface", obj);
621                        mHaveInputSurface = true;
622                    } else {
623                        response->setInt32("err", err);
624                    }
625                    response->postReply(mReplyID);
626                    break;
627                }
628
629                case ACodec::kWhatSignaledInputEOS:
630                {
631                    // response to ACodec::kWhatSignalEndOfInputStream
632                    sp<AMessage> response = new AMessage();
633                    status_t err;
634                    if (msg->findInt32("err", &err)) {
635                        response->setInt32("err", err);
636                    }
637                    response->postReply(mReplyID);
638                    break;
639                }
640
641
642                case ACodec::kWhatBuffersAllocated:
643                {
644                    int32_t portIndex;
645                    CHECK(msg->findInt32("portIndex", &portIndex));
646
647                    ALOGV("%s buffers allocated",
648                          portIndex == kPortIndexInput ? "input" : "output");
649
650                    CHECK(portIndex == kPortIndexInput
651                            || portIndex == kPortIndexOutput);
652
653                    mPortBuffers[portIndex].clear();
654
655                    Vector<BufferInfo> *buffers = &mPortBuffers[portIndex];
656
657                    sp<RefBase> obj;
658                    CHECK(msg->findObject("portDesc", &obj));
659
660                    sp<ACodec::PortDescription> portDesc =
661                        static_cast<ACodec::PortDescription *>(obj.get());
662
663                    size_t numBuffers = portDesc->countBuffers();
664
665                    for (size_t i = 0; i < numBuffers; ++i) {
666                        BufferInfo info;
667                        info.mBufferID = portDesc->bufferIDAt(i);
668                        info.mOwnedByClient = false;
669                        info.mData = portDesc->bufferAt(i);
670
671                        if (portIndex == kPortIndexInput && mCrypto != NULL) {
672                            info.mEncryptedData =
673                                new ABuffer(info.mData->capacity());
674                        }
675
676                        buffers->push_back(info);
677                    }
678
679                    if (portIndex == kPortIndexOutput) {
680                        if (mState == STARTING) {
681                            // We're always allocating output buffers after
682                            // allocating input buffers, so this is a good
683                            // indication that now all buffers are allocated.
684                            setState(STARTED);
685                            (new AMessage)->postReply(mReplyID);
686                        } else {
687                            mFlags |= kFlagOutputBuffersChanged;
688                            postActivityNotificationIfPossible();
689                        }
690                    }
691                    break;
692                }
693
694                case ACodec::kWhatOutputFormatChanged:
695                {
696                    ALOGV("codec output format changed");
697
698                    if ((mFlags & kFlagIsSoftwareCodec)
699                            && mNativeWindow != NULL) {
700                        AString mime;
701                        CHECK(msg->findString("mime", &mime));
702
703                        if (!strncasecmp("video/", mime.c_str(), 6)) {
704                            delete mSoftRenderer;
705                            mSoftRenderer = NULL;
706
707                            int32_t width, height;
708                            CHECK(msg->findInt32("width", &width));
709                            CHECK(msg->findInt32("height", &height));
710
711                            int32_t colorFormat;
712                            CHECK(msg->findInt32(
713                                        "color-format", &colorFormat));
714
715                            sp<MetaData> meta = new MetaData;
716                            meta->setInt32(kKeyWidth, width);
717                            meta->setInt32(kKeyHeight, height);
718                            meta->setInt32(kKeyColorFormat, colorFormat);
719
720                            mSoftRenderer =
721                                new SoftwareRenderer(mNativeWindow, meta);
722                        }
723                    }
724
725                    mOutputFormat = msg;
726                    mFlags |= kFlagOutputFormatChanged;
727                    postActivityNotificationIfPossible();
728                    break;
729                }
730
731                case ACodec::kWhatFillThisBuffer:
732                {
733                    /* size_t index = */updateBuffers(kPortIndexInput, msg);
734
735                    if (mState == FLUSHING
736                            || mState == STOPPING
737                            || mState == RELEASING) {
738                        returnBuffersToCodecOnPort(kPortIndexInput);
739                        break;
740                    }
741
742                    if (!mCSD.empty()) {
743                        ssize_t index = dequeuePortBuffer(kPortIndexInput);
744                        CHECK_GE(index, 0);
745
746                        // If codec specific data had been specified as
747                        // part of the format in the call to configure and
748                        // if there's more csd left, we submit it here
749                        // clients only get access to input buffers once
750                        // this data has been exhausted.
751
752                        status_t err = queueCSDInputBuffer(index);
753
754                        if (err != OK) {
755                            ALOGE("queueCSDInputBuffer failed w/ error %d",
756                                  err);
757
758                            mFlags |= kFlagStickyError;
759                            postActivityNotificationIfPossible();
760
761                            cancelPendingDequeueOperations();
762                        }
763                        break;
764                    }
765
766                    if (mFlags & kFlagDequeueInputPending) {
767                        CHECK(handleDequeueInputBuffer(mDequeueInputReplyID));
768
769                        ++mDequeueInputTimeoutGeneration;
770                        mFlags &= ~kFlagDequeueInputPending;
771                        mDequeueInputReplyID = 0;
772                    } else {
773                        postActivityNotificationIfPossible();
774                    }
775                    break;
776                }
777
778                case ACodec::kWhatDrainThisBuffer:
779                {
780                    /* size_t index = */updateBuffers(kPortIndexOutput, msg);
781
782                    if (mState == FLUSHING
783                            || mState == STOPPING
784                            || mState == RELEASING) {
785                        returnBuffersToCodecOnPort(kPortIndexOutput);
786                        break;
787                    }
788
789                    sp<ABuffer> buffer;
790                    CHECK(msg->findBuffer("buffer", &buffer));
791
792                    int32_t omxFlags;
793                    CHECK(msg->findInt32("flags", &omxFlags));
794
795                    buffer->meta()->setInt32("omxFlags", omxFlags);
796
797                    if (mFlags & kFlagDequeueOutputPending) {
798                        CHECK(handleDequeueOutputBuffer(mDequeueOutputReplyID));
799
800                        ++mDequeueOutputTimeoutGeneration;
801                        mFlags &= ~kFlagDequeueOutputPending;
802                        mDequeueOutputReplyID = 0;
803                    } else {
804                        postActivityNotificationIfPossible();
805                    }
806
807                    break;
808                }
809
810                case ACodec::kWhatEOS:
811                {
812                    // We already notify the client of this by using the
813                    // corresponding flag in "onOutputBufferReady".
814                    break;
815                }
816
817                case ACodec::kWhatShutdownCompleted:
818                {
819                    if (mState == STOPPING) {
820                        setState(INITIALIZED);
821                    } else {
822                        CHECK_EQ(mState, RELEASING);
823                        setState(UNINITIALIZED);
824                    }
825
826                    (new AMessage)->postReply(mReplyID);
827                    break;
828                }
829
830                case ACodec::kWhatFlushCompleted:
831                {
832                    CHECK_EQ(mState, FLUSHING);
833                    setState(STARTED);
834
835                    mCodec->signalResume();
836
837                    (new AMessage)->postReply(mReplyID);
838                    break;
839                }
840
841                default:
842                    TRESPASS();
843            }
844            break;
845        }
846
847        case kWhatInit:
848        {
849            uint32_t replyID;
850            CHECK(msg->senderAwaitsResponse(&replyID));
851
852            if (mState != UNINITIALIZED) {
853                sp<AMessage> response = new AMessage;
854                response->setInt32("err", INVALID_OPERATION);
855
856                response->postReply(replyID);
857                break;
858            }
859
860            mReplyID = replyID;
861            setState(INITIALIZING);
862
863            AString name;
864            CHECK(msg->findString("name", &name));
865
866            int32_t nameIsType;
867            int32_t encoder = false;
868            CHECK(msg->findInt32("nameIsType", &nameIsType));
869            if (nameIsType) {
870                CHECK(msg->findInt32("encoder", &encoder));
871            }
872
873            sp<AMessage> format = new AMessage;
874
875            if (nameIsType) {
876                format->setString("mime", name.c_str());
877                format->setInt32("encoder", encoder);
878            } else {
879                format->setString("componentName", name.c_str());
880            }
881
882            mCodec->initiateAllocateComponent(format);
883            break;
884        }
885
886        case kWhatConfigure:
887        {
888            uint32_t replyID;
889            CHECK(msg->senderAwaitsResponse(&replyID));
890
891            if (mState != INITIALIZED) {
892                sp<AMessage> response = new AMessage;
893                response->setInt32("err", INVALID_OPERATION);
894
895                response->postReply(replyID);
896                break;
897            }
898
899            sp<RefBase> obj;
900            if (!msg->findObject("native-window", &obj)) {
901                obj.clear();
902            }
903
904            sp<AMessage> format;
905            CHECK(msg->findMessage("format", &format));
906
907            if (obj != NULL) {
908                format->setObject("native-window", obj);
909
910                status_t err = setNativeWindow(
911                    static_cast<NativeWindowWrapper *>(obj.get())
912                        ->getSurfaceTextureClient());
913
914                if (err != OK) {
915                    sp<AMessage> response = new AMessage;
916                    response->setInt32("err", err);
917
918                    response->postReply(replyID);
919                    break;
920                }
921            } else {
922                setNativeWindow(NULL);
923            }
924
925            mReplyID = replyID;
926            setState(CONFIGURING);
927
928            void *crypto;
929            if (!msg->findPointer("crypto", &crypto)) {
930                crypto = NULL;
931            }
932
933            mCrypto = static_cast<ICrypto *>(crypto);
934
935            uint32_t flags;
936            CHECK(msg->findInt32("flags", (int32_t *)&flags));
937
938            if (flags & CONFIGURE_FLAG_ENCODE) {
939                format->setInt32("encoder", true);
940            }
941
942            extractCSD(format);
943
944            mCodec->initiateConfigureComponent(format);
945            break;
946        }
947
948        case kWhatCreateInputSurface:
949        {
950            uint32_t replyID;
951            CHECK(msg->senderAwaitsResponse(&replyID));
952
953            // Must be configured, but can't have been started yet.
954            if (mState != CONFIGURED) {
955                sp<AMessage> response = new AMessage;
956                response->setInt32("err", INVALID_OPERATION);
957
958                response->postReply(replyID);
959                break;
960            }
961
962            mReplyID = replyID;
963            mCodec->initiateCreateInputSurface();
964            break;
965        }
966
967        case kWhatStart:
968        {
969            uint32_t replyID;
970            CHECK(msg->senderAwaitsResponse(&replyID));
971
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            setState(STARTING);
982
983            mCodec->initiateStart();
984            break;
985        }
986
987        case kWhatStop:
988        {
989            uint32_t replyID;
990            CHECK(msg->senderAwaitsResponse(&replyID));
991
992            if (mState != INITIALIZED
993                    && mState != CONFIGURED && mState != STARTED) {
994                sp<AMessage> response = new AMessage;
995                response->setInt32("err", INVALID_OPERATION);
996
997                response->postReply(replyID);
998                break;
999            }
1000
1001            mReplyID = replyID;
1002            setState(STOPPING);
1003
1004            mCodec->initiateShutdown(true /* keepComponentAllocated */);
1005            returnBuffersToCodec();
1006            break;
1007        }
1008
1009        case kWhatRelease:
1010        {
1011            uint32_t replyID;
1012            CHECK(msg->senderAwaitsResponse(&replyID));
1013
1014            if (mState != INITIALIZED
1015                    && mState != CONFIGURED && mState != STARTED) {
1016                sp<AMessage> response = new AMessage;
1017                response->setInt32("err", INVALID_OPERATION);
1018
1019                response->postReply(replyID);
1020                break;
1021            }
1022
1023            mReplyID = replyID;
1024            setState(RELEASING);
1025
1026            mCodec->initiateShutdown();
1027            returnBuffersToCodec();
1028            break;
1029        }
1030
1031        case kWhatDequeueInputBuffer:
1032        {
1033            uint32_t replyID;
1034            CHECK(msg->senderAwaitsResponse(&replyID));
1035
1036            if (mHaveInputSurface) {
1037                ALOGE("dequeueInputBuffer can't be used with input surface");
1038                sp<AMessage> response = new AMessage;
1039                response->setInt32("err", INVALID_OPERATION);
1040                response->postReply(replyID);
1041                break;
1042            }
1043
1044            if (handleDequeueInputBuffer(replyID, true /* new request */)) {
1045                break;
1046            }
1047
1048            int64_t timeoutUs;
1049            CHECK(msg->findInt64("timeoutUs", &timeoutUs));
1050
1051            if (timeoutUs == 0ll) {
1052                sp<AMessage> response = new AMessage;
1053                response->setInt32("err", -EAGAIN);
1054                response->postReply(replyID);
1055                break;
1056            }
1057
1058            mFlags |= kFlagDequeueInputPending;
1059            mDequeueInputReplyID = replyID;
1060
1061            if (timeoutUs > 0ll) {
1062                sp<AMessage> timeoutMsg =
1063                    new AMessage(kWhatDequeueInputTimedOut, id());
1064                timeoutMsg->setInt32(
1065                        "generation", ++mDequeueInputTimeoutGeneration);
1066                timeoutMsg->post(timeoutUs);
1067            }
1068            break;
1069        }
1070
1071        case kWhatDequeueInputTimedOut:
1072        {
1073            int32_t generation;
1074            CHECK(msg->findInt32("generation", &generation));
1075
1076            if (generation != mDequeueInputTimeoutGeneration) {
1077                // Obsolete
1078                break;
1079            }
1080
1081            CHECK(mFlags & kFlagDequeueInputPending);
1082
1083            sp<AMessage> response = new AMessage;
1084            response->setInt32("err", -EAGAIN);
1085            response->postReply(mDequeueInputReplyID);
1086
1087            mFlags &= ~kFlagDequeueInputPending;
1088            mDequeueInputReplyID = 0;
1089            break;
1090        }
1091
1092        case kWhatQueueInputBuffer:
1093        {
1094            uint32_t replyID;
1095            CHECK(msg->senderAwaitsResponse(&replyID));
1096
1097            if (mState != STARTED || (mFlags & kFlagStickyError)) {
1098                sp<AMessage> response = new AMessage;
1099                response->setInt32("err", INVALID_OPERATION);
1100
1101                response->postReply(replyID);
1102                break;
1103            }
1104
1105            status_t err = onQueueInputBuffer(msg);
1106
1107            sp<AMessage> response = new AMessage;
1108            response->setInt32("err", err);
1109            response->postReply(replyID);
1110            break;
1111        }
1112
1113        case kWhatDequeueOutputBuffer:
1114        {
1115            uint32_t replyID;
1116            CHECK(msg->senderAwaitsResponse(&replyID));
1117
1118            if (handleDequeueOutputBuffer(replyID, true /* new request */)) {
1119                break;
1120            }
1121
1122            int64_t timeoutUs;
1123            CHECK(msg->findInt64("timeoutUs", &timeoutUs));
1124
1125            if (timeoutUs == 0ll) {
1126                sp<AMessage> response = new AMessage;
1127                response->setInt32("err", -EAGAIN);
1128                response->postReply(replyID);
1129                break;
1130            }
1131
1132            mFlags |= kFlagDequeueOutputPending;
1133            mDequeueOutputReplyID = replyID;
1134
1135            if (timeoutUs > 0ll) {
1136                sp<AMessage> timeoutMsg =
1137                    new AMessage(kWhatDequeueOutputTimedOut, id());
1138                timeoutMsg->setInt32(
1139                        "generation", ++mDequeueOutputTimeoutGeneration);
1140                timeoutMsg->post(timeoutUs);
1141            }
1142            break;
1143        }
1144
1145        case kWhatDequeueOutputTimedOut:
1146        {
1147            int32_t generation;
1148            CHECK(msg->findInt32("generation", &generation));
1149
1150            if (generation != mDequeueOutputTimeoutGeneration) {
1151                // Obsolete
1152                break;
1153            }
1154
1155            CHECK(mFlags & kFlagDequeueOutputPending);
1156
1157            sp<AMessage> response = new AMessage;
1158            response->setInt32("err", -EAGAIN);
1159            response->postReply(mDequeueOutputReplyID);
1160
1161            mFlags &= ~kFlagDequeueOutputPending;
1162            mDequeueOutputReplyID = 0;
1163            break;
1164        }
1165
1166        case kWhatReleaseOutputBuffer:
1167        {
1168            uint32_t replyID;
1169            CHECK(msg->senderAwaitsResponse(&replyID));
1170
1171            if (mState != STARTED || (mFlags & kFlagStickyError)) {
1172                sp<AMessage> response = new AMessage;
1173                response->setInt32("err", INVALID_OPERATION);
1174
1175                response->postReply(replyID);
1176                break;
1177            }
1178
1179            status_t err = onReleaseOutputBuffer(msg);
1180
1181            sp<AMessage> response = new AMessage;
1182            response->setInt32("err", err);
1183            response->postReply(replyID);
1184            break;
1185        }
1186
1187        case kWhatSignalEndOfInputStream:
1188        {
1189            uint32_t replyID;
1190            CHECK(msg->senderAwaitsResponse(&replyID));
1191
1192            if (mState != STARTED || (mFlags & kFlagStickyError)) {
1193                sp<AMessage> response = new AMessage;
1194                response->setInt32("err", INVALID_OPERATION);
1195
1196                response->postReply(replyID);
1197                break;
1198            }
1199
1200            mReplyID = replyID;
1201            mCodec->signalEndOfInputStream();
1202            break;
1203        }
1204
1205        case kWhatGetBuffers:
1206        {
1207            uint32_t replyID;
1208            CHECK(msg->senderAwaitsResponse(&replyID));
1209
1210            if (mState != STARTED || (mFlags & kFlagStickyError)) {
1211                sp<AMessage> response = new AMessage;
1212                response->setInt32("err", INVALID_OPERATION);
1213
1214                response->postReply(replyID);
1215                break;
1216            }
1217
1218            int32_t portIndex;
1219            CHECK(msg->findInt32("portIndex", &portIndex));
1220
1221            Vector<sp<ABuffer> > *dstBuffers;
1222            CHECK(msg->findPointer("buffers", (void **)&dstBuffers));
1223
1224            dstBuffers->clear();
1225            const Vector<BufferInfo> &srcBuffers = mPortBuffers[portIndex];
1226
1227            for (size_t i = 0; i < srcBuffers.size(); ++i) {
1228                const BufferInfo &info = srcBuffers.itemAt(i);
1229
1230                dstBuffers->push_back(
1231                        (portIndex == kPortIndexInput && mCrypto != NULL)
1232                                ? info.mEncryptedData : info.mData);
1233            }
1234
1235            (new AMessage)->postReply(replyID);
1236            break;
1237        }
1238
1239        case kWhatFlush:
1240        {
1241            uint32_t replyID;
1242            CHECK(msg->senderAwaitsResponse(&replyID));
1243
1244            if (mState != STARTED || (mFlags & kFlagStickyError)) {
1245                sp<AMessage> response = new AMessage;
1246                response->setInt32("err", INVALID_OPERATION);
1247
1248                response->postReply(replyID);
1249                break;
1250            }
1251
1252            mReplyID = replyID;
1253            setState(FLUSHING);
1254
1255            mCodec->signalFlush();
1256            returnBuffersToCodec();
1257            break;
1258        }
1259
1260        case kWhatGetOutputFormat:
1261        {
1262            uint32_t replyID;
1263            CHECK(msg->senderAwaitsResponse(&replyID));
1264
1265            if ((mState != STARTED && mState != FLUSHING)
1266                    || (mFlags & kFlagStickyError)
1267                    || mOutputFormat == NULL) {
1268                sp<AMessage> response = new AMessage;
1269                response->setInt32("err", INVALID_OPERATION);
1270
1271                response->postReply(replyID);
1272                break;
1273            }
1274
1275            sp<AMessage> response = new AMessage;
1276            response->setMessage("format", mOutputFormat);
1277            response->postReply(replyID);
1278            break;
1279        }
1280
1281        case kWhatRequestIDRFrame:
1282        {
1283            mCodec->signalRequestIDRFrame();
1284            break;
1285        }
1286
1287        case kWhatRequestActivityNotification:
1288        {
1289            CHECK(mActivityNotify == NULL);
1290            CHECK(msg->findMessage("notify", &mActivityNotify));
1291
1292            postActivityNotificationIfPossible();
1293            break;
1294        }
1295
1296        case kWhatGetName:
1297        {
1298            uint32_t replyID;
1299            CHECK(msg->senderAwaitsResponse(&replyID));
1300
1301            if (mComponentName.empty()) {
1302                sp<AMessage> response = new AMessage;
1303                response->setInt32("err", INVALID_OPERATION);
1304
1305                response->postReply(replyID);
1306                break;
1307            }
1308
1309            sp<AMessage> response = new AMessage;
1310            response->setString("name", mComponentName.c_str());
1311            response->postReply(replyID);
1312            break;
1313        }
1314
1315        case kWhatSetParameters:
1316        {
1317            uint32_t replyID;
1318            CHECK(msg->senderAwaitsResponse(&replyID));
1319
1320            sp<AMessage> params;
1321            CHECK(msg->findMessage("params", &params));
1322
1323            status_t err = onSetParameters(params);
1324
1325            sp<AMessage> response = new AMessage;
1326            response->setInt32("err", err);
1327
1328            response->postReply(replyID);
1329            break;
1330        }
1331
1332        default:
1333            TRESPASS();
1334    }
1335}
1336
1337void MediaCodec::extractCSD(const sp<AMessage> &format) {
1338    mCSD.clear();
1339
1340    size_t i = 0;
1341    for (;;) {
1342        sp<ABuffer> csd;
1343        if (!format->findBuffer(StringPrintf("csd-%u", i).c_str(), &csd)) {
1344            break;
1345        }
1346
1347        mCSD.push_back(csd);
1348        ++i;
1349    }
1350
1351    ALOGV("Found %u pieces of codec specific data.", mCSD.size());
1352}
1353
1354status_t MediaCodec::queueCSDInputBuffer(size_t bufferIndex) {
1355    CHECK(!mCSD.empty());
1356
1357    BufferInfo *info =
1358        &mPortBuffers[kPortIndexInput].editItemAt(bufferIndex);
1359
1360    sp<ABuffer> csd = *mCSD.begin();
1361    mCSD.erase(mCSD.begin());
1362
1363    const sp<ABuffer> &codecInputData =
1364        (mCrypto != NULL) ? info->mEncryptedData : info->mData;
1365
1366    if (csd->size() > codecInputData->capacity()) {
1367        return -EINVAL;
1368    }
1369
1370    memcpy(codecInputData->data(), csd->data(), csd->size());
1371
1372    AString errorDetailMsg;
1373
1374    sp<AMessage> msg = new AMessage(kWhatQueueInputBuffer, id());
1375    msg->setSize("index", bufferIndex);
1376    msg->setSize("offset", 0);
1377    msg->setSize("size", csd->size());
1378    msg->setInt64("timeUs", 0ll);
1379    msg->setInt32("flags", BUFFER_FLAG_CODECCONFIG);
1380    msg->setPointer("errorDetailMsg", &errorDetailMsg);
1381
1382    return onQueueInputBuffer(msg);
1383}
1384
1385void MediaCodec::setState(State newState) {
1386    if (newState == INITIALIZED || newState == UNINITIALIZED) {
1387        delete mSoftRenderer;
1388        mSoftRenderer = NULL;
1389
1390        mCrypto.clear();
1391        setNativeWindow(NULL);
1392
1393        mOutputFormat.clear();
1394        mFlags &= ~kFlagOutputFormatChanged;
1395        mFlags &= ~kFlagOutputBuffersChanged;
1396        mFlags &= ~kFlagStickyError;
1397
1398        mActivityNotify.clear();
1399    }
1400
1401    if (newState == UNINITIALIZED) {
1402        mComponentName.clear();
1403    }
1404
1405    mState = newState;
1406
1407    cancelPendingDequeueOperations();
1408}
1409
1410void MediaCodec::returnBuffersToCodec() {
1411    returnBuffersToCodecOnPort(kPortIndexInput);
1412    returnBuffersToCodecOnPort(kPortIndexOutput);
1413}
1414
1415void MediaCodec::returnBuffersToCodecOnPort(int32_t portIndex) {
1416    CHECK(portIndex == kPortIndexInput || portIndex == kPortIndexOutput);
1417
1418    Vector<BufferInfo> *buffers = &mPortBuffers[portIndex];
1419
1420    for (size_t i = 0; i < buffers->size(); ++i) {
1421        BufferInfo *info = &buffers->editItemAt(i);
1422
1423        if (info->mNotify != NULL) {
1424            sp<AMessage> msg = info->mNotify;
1425            info->mNotify = NULL;
1426            info->mOwnedByClient = false;
1427
1428            if (portIndex == kPortIndexInput) {
1429                msg->setInt32("err", ERROR_END_OF_STREAM);
1430            }
1431            msg->post();
1432        }
1433    }
1434
1435    mAvailPortBuffers[portIndex].clear();
1436}
1437
1438size_t MediaCodec::updateBuffers(
1439        int32_t portIndex, const sp<AMessage> &msg) {
1440    CHECK(portIndex == kPortIndexInput || portIndex == kPortIndexOutput);
1441
1442    void *bufferID;
1443    CHECK(msg->findPointer("buffer-id", &bufferID));
1444
1445    Vector<BufferInfo> *buffers = &mPortBuffers[portIndex];
1446
1447    for (size_t i = 0; i < buffers->size(); ++i) {
1448        BufferInfo *info = &buffers->editItemAt(i);
1449
1450        if (info->mBufferID == bufferID) {
1451            CHECK(info->mNotify == NULL);
1452            CHECK(msg->findMessage("reply", &info->mNotify));
1453
1454            mAvailPortBuffers[portIndex].push_back(i);
1455
1456            return i;
1457        }
1458    }
1459
1460    TRESPASS();
1461
1462    return 0;
1463}
1464
1465status_t MediaCodec::onQueueInputBuffer(const sp<AMessage> &msg) {
1466    size_t index;
1467    size_t offset;
1468    size_t size;
1469    int64_t timeUs;
1470    uint32_t flags;
1471    CHECK(msg->findSize("index", &index));
1472    CHECK(msg->findSize("offset", &offset));
1473    CHECK(msg->findInt64("timeUs", &timeUs));
1474    CHECK(msg->findInt32("flags", (int32_t *)&flags));
1475
1476    const CryptoPlugin::SubSample *subSamples;
1477    size_t numSubSamples;
1478    const uint8_t *key;
1479    const uint8_t *iv;
1480    CryptoPlugin::Mode mode = CryptoPlugin::kMode_Unencrypted;
1481
1482    // We allow the simpler queueInputBuffer API to be used even in
1483    // secure mode, by fabricating a single unencrypted subSample.
1484    CryptoPlugin::SubSample ss;
1485
1486    if (msg->findSize("size", &size)) {
1487        if (mCrypto != NULL) {
1488            ss.mNumBytesOfClearData = size;
1489            ss.mNumBytesOfEncryptedData = 0;
1490
1491            subSamples = &ss;
1492            numSubSamples = 1;
1493            key = NULL;
1494            iv = NULL;
1495        }
1496    } else {
1497        if (mCrypto == NULL) {
1498            return -EINVAL;
1499        }
1500
1501        CHECK(msg->findPointer("subSamples", (void **)&subSamples));
1502        CHECK(msg->findSize("numSubSamples", &numSubSamples));
1503        CHECK(msg->findPointer("key", (void **)&key));
1504        CHECK(msg->findPointer("iv", (void **)&iv));
1505
1506        int32_t tmp;
1507        CHECK(msg->findInt32("mode", &tmp));
1508
1509        mode = (CryptoPlugin::Mode)tmp;
1510
1511        size = 0;
1512        for (size_t i = 0; i < numSubSamples; ++i) {
1513            size += subSamples[i].mNumBytesOfClearData;
1514            size += subSamples[i].mNumBytesOfEncryptedData;
1515        }
1516    }
1517
1518    if (index >= mPortBuffers[kPortIndexInput].size()) {
1519        return -ERANGE;
1520    }
1521
1522    BufferInfo *info = &mPortBuffers[kPortIndexInput].editItemAt(index);
1523
1524    if (info->mNotify == NULL || !info->mOwnedByClient) {
1525        return -EACCES;
1526    }
1527
1528    if (offset + size > info->mData->capacity()) {
1529        return -EINVAL;
1530    }
1531
1532    sp<AMessage> reply = info->mNotify;
1533    info->mData->setRange(offset, size);
1534    info->mData->meta()->setInt64("timeUs", timeUs);
1535
1536    if (flags & BUFFER_FLAG_EOS) {
1537        info->mData->meta()->setInt32("eos", true);
1538    }
1539
1540    if (flags & BUFFER_FLAG_CODECCONFIG) {
1541        info->mData->meta()->setInt32("csd", true);
1542    }
1543
1544    if (mCrypto != NULL) {
1545        if (size > info->mEncryptedData->capacity()) {
1546            return -ERANGE;
1547        }
1548
1549        AString *errorDetailMsg;
1550        CHECK(msg->findPointer("errorDetailMsg", (void **)&errorDetailMsg));
1551
1552        ssize_t result = mCrypto->decrypt(
1553                (mFlags & kFlagIsSecure) != 0,
1554                key,
1555                iv,
1556                mode,
1557                info->mEncryptedData->base() + offset,
1558                subSamples,
1559                numSubSamples,
1560                info->mData->base(),
1561                errorDetailMsg);
1562
1563        if (result < 0) {
1564            return result;
1565        }
1566
1567        info->mData->setRange(0, result);
1568    }
1569
1570    reply->setBuffer("buffer", info->mData);
1571    reply->post();
1572
1573    info->mNotify = NULL;
1574    info->mOwnedByClient = false;
1575
1576    return OK;
1577}
1578
1579status_t MediaCodec::onReleaseOutputBuffer(const sp<AMessage> &msg) {
1580    size_t index;
1581    CHECK(msg->findSize("index", &index));
1582
1583    int32_t render;
1584    if (!msg->findInt32("render", &render)) {
1585        render = 0;
1586    }
1587
1588    if (mState != STARTED) {
1589        return -EINVAL;
1590    }
1591
1592    if (index >= mPortBuffers[kPortIndexOutput].size()) {
1593        return -ERANGE;
1594    }
1595
1596    BufferInfo *info = &mPortBuffers[kPortIndexOutput].editItemAt(index);
1597
1598    if (info->mNotify == NULL || !info->mOwnedByClient) {
1599        return -EACCES;
1600    }
1601
1602    if (render) {
1603        info->mNotify->setInt32("render", true);
1604
1605        if (mSoftRenderer != NULL) {
1606            mSoftRenderer->render(
1607                    info->mData->data(), info->mData->size(), NULL);
1608        }
1609    }
1610
1611    info->mNotify->post();
1612    info->mNotify = NULL;
1613    info->mOwnedByClient = false;
1614
1615    return OK;
1616}
1617
1618ssize_t MediaCodec::dequeuePortBuffer(int32_t portIndex) {
1619    CHECK(portIndex == kPortIndexInput || portIndex == kPortIndexOutput);
1620
1621    List<size_t> *availBuffers = &mAvailPortBuffers[portIndex];
1622
1623    if (availBuffers->empty()) {
1624        return -EAGAIN;
1625    }
1626
1627    size_t index = *availBuffers->begin();
1628    availBuffers->erase(availBuffers->begin());
1629
1630    BufferInfo *info = &mPortBuffers[portIndex].editItemAt(index);
1631    CHECK(!info->mOwnedByClient);
1632    info->mOwnedByClient = true;
1633
1634    return index;
1635}
1636
1637status_t MediaCodec::setNativeWindow(
1638        const sp<Surface> &surfaceTextureClient) {
1639    status_t err;
1640
1641    if (mNativeWindow != NULL) {
1642        err = native_window_api_disconnect(
1643                mNativeWindow.get(), NATIVE_WINDOW_API_MEDIA);
1644
1645        if (err != OK) {
1646            ALOGW("native_window_api_disconnect returned an error: %s (%d)",
1647                    strerror(-err), err);
1648        }
1649
1650        mNativeWindow.clear();
1651    }
1652
1653    if (surfaceTextureClient != NULL) {
1654        err = native_window_api_connect(
1655                surfaceTextureClient.get(), NATIVE_WINDOW_API_MEDIA);
1656
1657        if (err != OK) {
1658            ALOGE("native_window_api_connect returned an error: %s (%d)",
1659                    strerror(-err), err);
1660
1661            return err;
1662        }
1663
1664        mNativeWindow = surfaceTextureClient;
1665    }
1666
1667    return OK;
1668}
1669
1670void MediaCodec::postActivityNotificationIfPossible() {
1671    if (mActivityNotify == NULL) {
1672        return;
1673    }
1674
1675    if ((mFlags & (kFlagStickyError
1676                    | kFlagOutputBuffersChanged
1677                    | kFlagOutputFormatChanged))
1678            || !mAvailPortBuffers[kPortIndexInput].empty()
1679            || !mAvailPortBuffers[kPortIndexOutput].empty()) {
1680        mActivityNotify->post();
1681        mActivityNotify.clear();
1682    }
1683}
1684
1685status_t MediaCodec::setParameters(const sp<AMessage> &params) {
1686    sp<AMessage> msg = new AMessage(kWhatSetParameters, id());
1687    msg->setMessage("params", params);
1688
1689    sp<AMessage> response;
1690    return PostAndAwaitResponse(msg, &response);
1691}
1692
1693status_t MediaCodec::onSetParameters(const sp<AMessage> &params) {
1694    mCodec->signalSetParameters(params);
1695
1696    return OK;
1697}
1698
1699}  // namespace android
1700