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