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