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