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