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