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