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