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