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