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