MediaCodec.cpp revision a35b4278582175ee7e4082c0e93ddb4a83726f47
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                msg->setInt32("err", ERROR_END_OF_STREAM);
1510            }
1511            msg->post();
1512        }
1513    }
1514
1515    mAvailPortBuffers[portIndex].clear();
1516}
1517
1518size_t MediaCodec::updateBuffers(
1519        int32_t portIndex, const sp<AMessage> &msg) {
1520    CHECK(portIndex == kPortIndexInput || portIndex == kPortIndexOutput);
1521
1522    void *bufferID;
1523    CHECK(msg->findPointer("buffer-id", &bufferID));
1524
1525    Vector<BufferInfo> *buffers = &mPortBuffers[portIndex];
1526
1527    for (size_t i = 0; i < buffers->size(); ++i) {
1528        BufferInfo *info = &buffers->editItemAt(i);
1529
1530        if (info->mBufferID == bufferID) {
1531            CHECK(info->mNotify == NULL);
1532            CHECK(msg->findMessage("reply", &info->mNotify));
1533
1534            mAvailPortBuffers[portIndex].push_back(i);
1535
1536            return i;
1537        }
1538    }
1539
1540    TRESPASS();
1541
1542    return 0;
1543}
1544
1545status_t MediaCodec::onQueueInputBuffer(const sp<AMessage> &msg) {
1546    size_t index;
1547    size_t offset;
1548    size_t size;
1549    int64_t timeUs;
1550    uint32_t flags;
1551    CHECK(msg->findSize("index", &index));
1552    CHECK(msg->findSize("offset", &offset));
1553    CHECK(msg->findInt64("timeUs", &timeUs));
1554    CHECK(msg->findInt32("flags", (int32_t *)&flags));
1555
1556    const CryptoPlugin::SubSample *subSamples;
1557    size_t numSubSamples;
1558    const uint8_t *key;
1559    const uint8_t *iv;
1560    CryptoPlugin::Mode mode = CryptoPlugin::kMode_Unencrypted;
1561
1562    // We allow the simpler queueInputBuffer API to be used even in
1563    // secure mode, by fabricating a single unencrypted subSample.
1564    CryptoPlugin::SubSample ss;
1565
1566    if (msg->findSize("size", &size)) {
1567        if (mCrypto != NULL) {
1568            ss.mNumBytesOfClearData = size;
1569            ss.mNumBytesOfEncryptedData = 0;
1570
1571            subSamples = &ss;
1572            numSubSamples = 1;
1573            key = NULL;
1574            iv = NULL;
1575        }
1576    } else {
1577        if (mCrypto == NULL) {
1578            return -EINVAL;
1579        }
1580
1581        CHECK(msg->findPointer("subSamples", (void **)&subSamples));
1582        CHECK(msg->findSize("numSubSamples", &numSubSamples));
1583        CHECK(msg->findPointer("key", (void **)&key));
1584        CHECK(msg->findPointer("iv", (void **)&iv));
1585
1586        int32_t tmp;
1587        CHECK(msg->findInt32("mode", &tmp));
1588
1589        mode = (CryptoPlugin::Mode)tmp;
1590
1591        size = 0;
1592        for (size_t i = 0; i < numSubSamples; ++i) {
1593            size += subSamples[i].mNumBytesOfClearData;
1594            size += subSamples[i].mNumBytesOfEncryptedData;
1595        }
1596    }
1597
1598    if (index >= mPortBuffers[kPortIndexInput].size()) {
1599        return -ERANGE;
1600    }
1601
1602    BufferInfo *info = &mPortBuffers[kPortIndexInput].editItemAt(index);
1603
1604    if (info->mNotify == NULL || !info->mOwnedByClient) {
1605        return -EACCES;
1606    }
1607
1608    if (offset + size > info->mData->capacity()) {
1609        return -EINVAL;
1610    }
1611
1612    sp<AMessage> reply = info->mNotify;
1613    info->mData->setRange(offset, size);
1614    info->mData->meta()->setInt64("timeUs", timeUs);
1615
1616    if (flags & BUFFER_FLAG_EOS) {
1617        info->mData->meta()->setInt32("eos", true);
1618    }
1619
1620    if (flags & BUFFER_FLAG_CODECCONFIG) {
1621        info->mData->meta()->setInt32("csd", true);
1622    }
1623
1624    if (mCrypto != NULL) {
1625        if (size > info->mEncryptedData->capacity()) {
1626            return -ERANGE;
1627        }
1628
1629        AString *errorDetailMsg;
1630        CHECK(msg->findPointer("errorDetailMsg", (void **)&errorDetailMsg));
1631
1632        ssize_t result = mCrypto->decrypt(
1633                (mFlags & kFlagIsSecure) != 0,
1634                key,
1635                iv,
1636                mode,
1637                info->mEncryptedData->base() + offset,
1638                subSamples,
1639                numSubSamples,
1640                info->mData->base(),
1641                errorDetailMsg);
1642
1643        if (result < 0) {
1644            return result;
1645        }
1646
1647        info->mData->setRange(0, result);
1648    }
1649
1650    reply->setBuffer("buffer", info->mData);
1651    reply->post();
1652
1653    info->mNotify = NULL;
1654    info->mOwnedByClient = false;
1655
1656    return OK;
1657}
1658
1659status_t MediaCodec::onReleaseOutputBuffer(const sp<AMessage> &msg) {
1660    size_t index;
1661    CHECK(msg->findSize("index", &index));
1662
1663    int32_t render;
1664    if (!msg->findInt32("render", &render)) {
1665        render = 0;
1666    }
1667
1668    if (mState != STARTED) {
1669        return -EINVAL;
1670    }
1671
1672    if (index >= mPortBuffers[kPortIndexOutput].size()) {
1673        return -ERANGE;
1674    }
1675
1676    BufferInfo *info = &mPortBuffers[kPortIndexOutput].editItemAt(index);
1677
1678    if (info->mNotify == NULL || !info->mOwnedByClient) {
1679        return -EACCES;
1680    }
1681
1682    if (render && (info->mData == NULL || info->mData->size() != 0)) {
1683        info->mNotify->setInt32("render", true);
1684
1685        if (mSoftRenderer != NULL) {
1686            mSoftRenderer->render(
1687                    info->mData->data(), info->mData->size(), NULL);
1688        }
1689    }
1690
1691    info->mNotify->post();
1692    info->mNotify = NULL;
1693    info->mOwnedByClient = false;
1694
1695    return OK;
1696}
1697
1698ssize_t MediaCodec::dequeuePortBuffer(int32_t portIndex) {
1699    CHECK(portIndex == kPortIndexInput || portIndex == kPortIndexOutput);
1700
1701    List<size_t> *availBuffers = &mAvailPortBuffers[portIndex];
1702
1703    if (availBuffers->empty()) {
1704        return -EAGAIN;
1705    }
1706
1707    size_t index = *availBuffers->begin();
1708    availBuffers->erase(availBuffers->begin());
1709
1710    BufferInfo *info = &mPortBuffers[portIndex].editItemAt(index);
1711    CHECK(!info->mOwnedByClient);
1712    info->mOwnedByClient = true;
1713
1714    return index;
1715}
1716
1717status_t MediaCodec::setNativeWindow(
1718        const sp<Surface> &surfaceTextureClient) {
1719    status_t err;
1720
1721    if (mNativeWindow != NULL) {
1722        err = native_window_api_disconnect(
1723                mNativeWindow.get(), NATIVE_WINDOW_API_MEDIA);
1724
1725        if (err != OK) {
1726            ALOGW("native_window_api_disconnect returned an error: %s (%d)",
1727                    strerror(-err), err);
1728        }
1729
1730        mNativeWindow.clear();
1731    }
1732
1733    if (surfaceTextureClient != NULL) {
1734        err = native_window_api_connect(
1735                surfaceTextureClient.get(), NATIVE_WINDOW_API_MEDIA);
1736
1737        if (err != OK) {
1738            ALOGE("native_window_api_connect returned an error: %s (%d)",
1739                    strerror(-err), err);
1740
1741            return err;
1742        }
1743
1744        mNativeWindow = surfaceTextureClient;
1745    }
1746
1747    return OK;
1748}
1749
1750void MediaCodec::postActivityNotificationIfPossible() {
1751    if (mActivityNotify == NULL) {
1752        return;
1753    }
1754
1755    if ((mFlags & (kFlagStickyError
1756                    | kFlagOutputBuffersChanged
1757                    | kFlagOutputFormatChanged))
1758            || !mAvailPortBuffers[kPortIndexInput].empty()
1759            || !mAvailPortBuffers[kPortIndexOutput].empty()) {
1760        mActivityNotify->post();
1761        mActivityNotify.clear();
1762    }
1763}
1764
1765status_t MediaCodec::setParameters(const sp<AMessage> &params) {
1766    sp<AMessage> msg = new AMessage(kWhatSetParameters, id());
1767    msg->setMessage("params", params);
1768
1769    sp<AMessage> response;
1770    return PostAndAwaitResponse(msg, &response);
1771}
1772
1773status_t MediaCodec::onSetParameters(const sp<AMessage> &params) {
1774    mCodec->signalSetParameters(params);
1775
1776    return OK;
1777}
1778
1779status_t MediaCodec::amendOutputFormatWithCodecSpecificData(
1780        const sp<ABuffer> &buffer) {
1781    AString mime;
1782    CHECK(mOutputFormat->findString("mime", &mime));
1783
1784    if (!strcasecmp(mime.c_str(), MEDIA_MIMETYPE_VIDEO_AVC)) {
1785        // Codec specific data should be SPS and PPS in a single buffer,
1786        // each prefixed by a startcode (0x00 0x00 0x00 0x01).
1787        // We separate the two and put them into the output format
1788        // under the keys "csd-0" and "csd-1".
1789
1790        unsigned csdIndex = 0;
1791
1792        const uint8_t *data = buffer->data();
1793        size_t size = buffer->size();
1794
1795        const uint8_t *nalStart;
1796        size_t nalSize;
1797        while (getNextNALUnit(&data, &size, &nalStart, &nalSize, true) == OK) {
1798            sp<ABuffer> csd = new ABuffer(nalSize + 4);
1799            memcpy(csd->data(), "\x00\x00\x00\x01", 4);
1800            memcpy(csd->data() + 4, nalStart, nalSize);
1801
1802            mOutputFormat->setBuffer(
1803                    StringPrintf("csd-%u", csdIndex).c_str(), csd);
1804
1805            ++csdIndex;
1806        }
1807
1808        if (csdIndex != 2) {
1809            return ERROR_MALFORMED;
1810        }
1811    } else {
1812        // For everything else we just stash the codec specific data into
1813        // the output format as a single piece of csd under "csd-0".
1814        mOutputFormat->setBuffer("csd-0", buffer);
1815    }
1816
1817    return OK;
1818}
1819
1820}  // namespace android
1821