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