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