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