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