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